diff -u --recursive --new-file v1.3.44/linux/CREDITS linux/CREDITS
--- v1.3.44/linux/CREDITS	Tue Nov 21 13:22:04 1995
+++ linux/CREDITS	Sun Nov 26 11:43:15 1995
@@ -231,12 +231,13 @@
 D: RADIOLINUX Amateur Radio software for Linux list collator.
 
 N: Todd J. Derr
-E: tjd@cs.pitt.edu
+E: tjd@fore.com
+D: x86 VESA console blanking enhancements
 D: maintainer of dual-monitor patches for 1.0+
 D: MouseMan driver for selection
-S: Department of Computer Science
-S: University of Pittsburgh
-S: Pittsburgh, Pennsylvania 15260
+S: Fore Systems, Inc.
+S: 5800 Corporate Drive
+S: Pittsburgh, Pennsylvania 15237-5829
 S: USA
 
 N: Thomas Dunbar
@@ -504,6 +505,13 @@
 D: Unicode, time, standards
 S: Schlehenweg 9
 S: D-91080 Uttenreuth
+S: Germany
+
+N: Gero Kuhlmann
+E: gero@gkminix.han.de
+D: mounting root via NFS
+S: Donarweg 4
+S: D-30657 Hannover
 S: Germany
 
 N: Bas Laarhoven
diff -u --recursive --new-file v1.3.44/linux/Makefile linux/Makefile
--- v1.3.44/linux/Makefile	Sat Nov 25 19:04:35 1995
+++ linux/Makefile	Sat Nov 25 19:55:10 1995
@@ -1,6 +1,6 @@
 VERSION = 1
 PATCHLEVEL = 3
-SUBLEVEL = 44
+SUBLEVEL = 45
 
 ARCH = i386
 
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/Makefile linux/arch/ppc/Makefile
--- v1.3.44/linux/arch/ppc/Makefile	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/Makefile	Fri Oct 13 21:49:04 1995
@@ -0,0 +1,106 @@
+#
+# ppc/Makefile
+#
+# This file is included by the global makefile so that you can add your own
+# architecture-specific flags and dependencies. Remember to do have actions
+# for "archclean" and "archdep" for cleaning up and making dependencies for
+# this architecture
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1994 by Linus Torvalds
+# Changes for PPC by Gary Thomas
+#
+
+# PowerPC (cross) tools
+AS		= as.ppc
+ASFLAGS		=
+LD		= ld.ppc
+#LINKFLAGS	= -T arch/ppc/ld.script -Ttext 0x90000000 -Map vmlinux.map
+LINKFLAGS	= -T arch/ppc/ld.script -Ttext 0x90000000 
+HOSTCC		= gcc
+CC		= gcc.ppc
+CFLAGS		= -D__KERNEL__ -I$(TOPDIR)/include \
+		-Wstrict-prototypes \
+		-fomit-frame-pointer \
+		-fno-builtin \
+		-finhibit-size-directive \
+		-O2 -pipe
+#-Wall
+CPP		= $(CC) -E $(CFLAGS)
+AR		= ar.ppc
+RANLIB		= ranlib.ppc
+STRIP		= strip.ppc
+NM		= nm.ppc
+
+#
+# Set these to indicate how to link it..
+#
+# -zmagic:   
+#
+# ZLINKFLAGS   = -Ttext 0x1000
+# LINKFLAGS    = -Ttext 0x100000
+#
+# -qmagic (we need to remove the 32 byte header for bootup purposes)
+#
+## ZLINKFLAGS =-qmagic -Ttext 0xfe0
+## LINKFLAGS =-qmagic -Ttext 0xfffe0
+## CFLAGS := $(CFLAGS) -pipe
+
+## ifdef CONFIG_M486
+## CFLAGS := $(CFLAGS) -m486
+## else
+## ifdef CONFIG_M586
+## CFLAGS := $(CFLAGS) -mpentium
+## else
+## CFLAGS := $(CFLAGS) -m386
+## endif
+## endif
+
+HEAD := arch/ppc/kernel/head.o
+
+ARCH_SUBDIRS = arch/ppc/kernel arch/ppc/mm
+SUBDIRS := $(SUBDIRS) $(ARCH_SUBDIRS)
+ARCHIVES := arch/ppc/kernel/kernel.o arch/ppc/mm/mm.o $(ARCHIVES)
+
+## ifdef CONFIG_IBCS
+## SUBDIRS := $(SUBDIRS) arch/ppc/ibcs
+## DRIVERS := $(DRIVERS) arch/ppc/ibcs/ibcs.o
+## endif
+
+## ifdef CONFIG_MATH_EMULATION
+## SUBDIRS := $(SUBDIRS) arch/ppc/math-emu
+## DRIVERS := $(DRIVERS) arch/ppc/math-emu/math.a
+## endif
+
+arch/ppc/kernel: dummy
+	$(MAKE) linuxsubdirs SUBDIRS=arch/ppc/kernel
+
+arch/ppc/mm: dummy
+	$(MAKE) linuxsubdirs SUBDIRS=arch/ppc/mm
+
+## MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot
+## 
+## zImage: vmlinux
+## 	@$(MAKEBOOT) zImage
+## 
+## compressed: zImage
+## 
+## zlilo: vmlinux
+## 	@$(MAKEBOOT) zlilo
+## 
+## zdisk: vmlinux
+## 	@$(MAKEBOOT) zdisk
+## 
+## install: vmlinux
+## 	@$(MAKEBOOT) install
+
+archclean:
+#	@$(MAKEBOOT) clean
+
+archdep:
+#	@$(MAKEBOOT) dep
+
+
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/boot/Makefile linux/arch/ppc/boot/Makefile
--- v1.3.44/linux/arch/ppc/boot/Makefile	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/boot/Makefile	Sat May  6 03:59:58 1995
@@ -0,0 +1,34 @@
+#
+# arch/ppc/boot/Makefile
+#
+# This file is subject to the terms and conditions of the GNU General Public
+# License.  See the file "COPYING" in the main directory of this archive
+# for more details.
+#
+# Copyright (C) 1994 by Linus Torvalds
+# Adapted for PowerPC by Gary Thomas
+#
+
+.c.s:
+	$(CC) $(CFLAGS) -S -o $*.s $<
+.s.o:
+	$(AS) -o $*.o $<
+.c.o:
+	$(CC) $(CFLAGS) -c -o $*.o $<
+.S.s:
+	$(CC) -D__ASSEMBLY__ -traditional -E -o $*.o $<
+.S.o:
+	$(CC) -D__ASSEMBLY__ -traditional -c -o $*.o $<
+
+OBJECTS = head.o main.o
+
+all:	linux.boot
+
+linux.boot: $(TOPDIR)/vmlinux
+	mkboot $(TOPDIR)/vmlinux $@ 0
+
+clean:
+	rm -f linux.boot 
+
+dep:
+
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/config.in linux/arch/ppc/config.in
--- v1.3.44/linux/arch/ppc/config.in	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/config.in	Tue Oct 24 18:35:16 1995
@@ -0,0 +1,320 @@
+#
+# For a description of the syntax of this configuration file,
+# see the Configure script.
+#
+# This is a stripped down version to just get us what we need to
+# get the kernel to its knees for now.
+#                   -- Cort
+
+comment 'General setup'
+
+#bool 'Kernel math emulation' CONFIG_MATH_EMULATION n
+tristate 'Normal floppy disk support' CONFIG_BLK_DEV_FD y
+#bool 'Normal (MFM/RLL) disk and IDE disk/cdrom support' CONFIG_ST506 
+if [ "$CONFIG_ST506" = "y" ]; then
+  comment 'Please see drivers/block/README.ide for help/info on IDE drives'
+  bool '   Use old disk-only driver for primary i/f' CONFIG_BLK_DEV_HD n
+  if [ "$CONFIG_BLK_DEV_HD" = "y" ]; then
+    bool '   Include new IDE driver for secondary i/f support' CONFIG_BLK_DEV_IDE n
+  else
+    bool '   Use new IDE driver for primary/secondary i/f' CONFIG_BLK_DEV_IDE y
+  fi
+  if [ "$CONFIG_BLK_DEV_IDE" = "y" ]; then
+    bool '   Include support for IDE/ATAPI CDROMs' CONFIG_BLK_DEV_IDECD n
+  fi
+fi
+
+#bool 'XT harddisk support' CONFIG_BLK_DEV_XD n
+bool 'Networking support' CONFIG_NET y
+#bool 'Limit memory to low 16MB' CONFIG_MAX_16M n
+bool 'PCI bios support' CONFIG_PCI y
+if [ "$CONFIG_PCI" = "y" ]; then
+  bool '   PCI bridge optimisation (experimental)' CONFIG_PCI_OPTIMIZE n
+  if [ "$CONFIG_BLK_DEV_IDE" = "y" ]; then
+    bool '   PCI Triton IDE Bus Master DMA support' CONFIG_BLK_DEV_TRITON y
+  fi
+fi
+bool 'System V IPC' CONFIG_SYSVIPC y
+tristate 'Kernel support for ELF binaries' CONFIG_BINFMT_ELF y
+if [ "$CONFIG_BINFMT_ELF" = "y" ]; then
+bool 'Compile kernel as ELF - if your GCC is ELF-GCC' CONFIG_KERNEL_ELF y
+fi
+#bool 'Use -mpentium flag for Pentium-specific optimizations' CONFIG_M586 n
+#if [ "$CONFIG_M586" = "n" ]; then
+#bool 'Use -m486 flag for 486-specific optimizations' CONFIG_M486 y
+#fi
+
+comment 'Loadable module support'
+bool 'Set version information on all symbols for modules' CONFIG_MODVERSIONS n
+
+if [ "$CONFIG_NET" = "y" ]; then
+comment 'Networking options'
+bool 'TCP/IP networking' CONFIG_INET y
+if [ "$CONFIG_INET" = "y" ]; then
+bool 'IP: forwarding/gatewaying' CONFIG_IP_FORWARD n
+bool 'IP: multicasting' CONFIG_IP_MULTICAST n
+bool 'IP: firewalling' CONFIG_IP_FIREWALL n
+bool 'IP: accounting' CONFIG_IP_ACCT n
+tristate 'IP: tunneling' CONFIG_NET_IPIP n
+if [ "$CONFIG_IP_FORWARD" = "y" -a "$CONFIG_IP_FIREWALL" = "y" ]; then
+  bool 'IP: firewall packet logging' CONFIG_IP_FIREWALL_VERBOSE y
+  bool 'IP: masquerading (ALPHA)' CONFIG_IP_MASQUERADE n
+fi
+if [ "$CONFIG_IP_FORWARD" = "y" -a "$CONFIG_IP_MULTICAST" = "y" -a "$CONFIG_NET_IPIP" = "y" ]; then
+  bool 'IP: multicast routing(in progress)' CONFIG_IP_MROUTE n
+fi
+comment '(it is safe to leave these untouched)'
+bool 'IP: PC/TCP compatibility mode' CONFIG_INET_PCTCP n
+tristate 'IP: Reverse ARP' CONFIG_INET_RARP n
+bool 'IP: Assume subnets are local' CONFIG_INET_SNARL y
+bool 'IP: Disable NAGLE algorithm (normally enabled)' CONFIG_TCP_NAGLE_OFF n
+bool 'IP: Drop source routed frames' CONFIG_IP_NOSR y
+bool 'IP: Allow large windows (not recommended if <16Mb of memory)' CONFIG_SKB_LARGE y
+fi
+bool 'The IPX protocol' CONFIG_IPX n
+bool 'Appletalk DDP' CONFIG_ATALK n
+bool 'Amateur Radio AX.25 Level 2' CONFIG_AX25 n
+if [ "$CONFIG_AX25" = "y" ]; then
+  bool 'Amateur Radio NET/ROM' CONFIG_NETROM n
+fi
+fi
+
+comment 'SCSI support'
+
+tristate 'SCSI support' CONFIG_SCSI y
+
+if [ "$CONFIG_SCSI" = "n" ]; then
+
+comment 'Skipping SCSI configuration options...'
+
+else
+
+comment 'SCSI support type (disk, tape, CDrom)'
+
+dep_tristate 'SCSI disk support' CONFIG_BLK_DEV_SD y $CONFIG_SCSI
+dep_tristate 'SCSI tape support' CONFIG_CHR_DEV_ST n $CONFIG_SCSI
+dep_tristate 'SCSI CDROM support' CONFIG_BLK_DEV_SR y $CONFIG_SCSI
+dep_tristate 'SCSI generic support' CONFIG_CHR_DEV_SG n $CONFIG_SCSI
+
+comment 'Some SCSI devices (e.g. CD jukebox) support multiple LUNs'
+
+bool 'Probe all LUNs on each SCSI device' CONFIG_SCSI_MULTI_LUN y
+
+comment 'SCSI low-level drivers'
+
+dep_tristate 'Adaptec AHA152X support' CONFIG_SCSI_AHA152X n $CONFIG_SCSI
+dep_tristate 'Adaptec AHA1542 support' CONFIG_SCSI_AHA1542 n $CONFIG_SCSI
+dep_tristate 'Adaptec AHA1740 support' CONFIG_SCSI_AHA1740 n $CONFIG_SCSI
+dep_tristate 'Adaptec AHA274X/284X/294X support' CONFIG_SCSI_AIC7XXX n $CONFIG_SCSI
+dep_tristate 'BusLogic SCSI support' CONFIG_SCSI_BUSLOGIC n $CONFIG_SCSI
+dep_tristate 'EATA-DMA (DPT, NEC, ATT, Olivetti) support' CONFIG_SCSI_EATA_DMA n $CONFIG_SCSI
+dep_tristate 'EATA-PIO (old DPT PM2001, PM2012A) support' CONFIG_SCSI_EATA_PIO n $CONFIG_SCSI
+dep_tristate 'UltraStor 14F/34F support' CONFIG_SCSI_U14_34F n $CONFIG_SCSI
+dep_tristate 'Future Domain 16xx SCSI support' CONFIG_SCSI_FUTURE_DOMAIN n $CONFIG_SCSI
+bool 'Generic NCR5380 SCSI support' CONFIG_SCSI_GENERIC_NCR5380 y
+if [ "$CONFIG_PCI" = "y" ]; then
+  dep_tristate 'NCR53c7,8xx SCSI support'  CONFIG_SCSI_NCR53C7xx y $CONFIG_SCSI
+fi
+dep_tristate 'Always IN2000 SCSI support (test release)' CONFIG_SCSI_IN2000 n $CONFIG_SCSI
+bool 'PAS16 SCSI support' CONFIG_SCSI_PAS16 n
+dep_tristate 'QLOGIC SCSI support' CONFIG_SCSI_QLOGIC n $CONFIG_SCSI
+dep_tristate 'Seagate ST-02 and Future Domain TMC-8xx SCSI support' CONFIG_SCSI_SEAGATE n $CONFIG_SCSI
+bool 'Trantor T128/T128F/T228 SCSI support' CONFIG_SCSI_T128 n
+dep_tristate 'UltraStor SCSI support' CONFIG_SCSI_ULTRASTOR n $CONFIG_SCSI
+dep_tristate '7000FASST SCSI support' CONFIG_SCSI_7000FASST n $CONFIG_SCSI
+dep_tristate 'EATA ISA/EISA (DPT PM2011/021/012/022/122/322) support' CONFIG_SCSI_EATA n $CONFIG_SCSI
+#dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG n $CONFIG_SCSI
+fi
+
+
+if [ "$CONFIG_NET" = "y" ]; then
+
+comment 'Network device support'
+
+bool 'Network device support' CONFIG_NETDEVICES y
+if [ "$CONFIG_NETDEVICES" = "n" ]; then
+
+comment 'Skipping network driver configuration options...'
+
+else
+tristate 'Dummy net driver support' CONFIG_DUMMY y
+tristate 'SLIP (serial line) support' CONFIG_SLIP n
+if [ "$CONFIG_SLIP" != "n" ]; then
+  bool ' CSLIP compressed headers' CONFIG_SLIP_COMPRESSED y
+fi
+tristate 'PPP (point-to-point) support' CONFIG_PPP n
+if [ "$CONFIG_PPP" != "n" ]; then
+  bool ' 16 channels instead of 4' CONFIG_PPP_LOTS n
+fi
+if [ "$CONFIG_AX25" = "y" ]; then
+	bool 'Z8530 SCC kiss emulation driver for AX.25' CONFIG_SCC y
+else
+	bool 'Z8530 SCC kiss emulation driver for AX.25' CONFIG_SCC n
+fi
+tristate 'PLIP (parallel port) support' CONFIG_PLIP n
+tristate 'EQL (serial line load balancing) support' CONFIG_EQUALIZER n
+bool 'Do you want to be offered ALPHA test drivers' CONFIG_NET_ALPHA n
+bool 'Western Digital/SMC cards' CONFIG_NET_VENDOR_SMC n
+if [ "$CONFIG_NET_VENDOR_SMC" = "y" ]; then
+	tristate 'WD80*3 support' CONFIG_WD80x3 n
+	tristate 'SMC Ultra support' CONFIG_ULTRA n
+fi
+bool 'AMD LANCE and PCnet (AT1500 and NE2100) support' CONFIG_LANCE n
+bool '3COM cards' CONFIG_NET_VENDOR_3COM n
+if [ "$CONFIG_NET_VENDOR_3COM" = "y" ]; then
+	tristate '3c501 support' CONFIG_EL1 n
+	tristate '3c503 support' CONFIG_EL2 n
+	if [ "$CONFIG_NET_ALPHA" = "y" ]; then
+		tristate '3c505 support' CONFIG_ELPLUS n
+		tristate '3c507 support' CONFIG_EL16 n
+	fi
+	tristate '3c509/3c579 support' CONFIG_EL3 y
+fi
+bool 'Other ISA cards' CONFIG_NET_ISA n
+if [ "$CONFIG_NET_ISA" = "y" ]; then
+	tristate 'Cabletron E21xx support' CONFIG_E2100 n
+	tristate 'DEPCA support' CONFIG_DEPCA n
+	tristate 'EtherWorks 3 support' CONFIG_EWRK3 n
+	if [ "$CONFIG_NET_ALPHA" = "y" ]; then
+		bool 'SEEQ8005 support' CONFIG_SEEQ8005 n
+		tristate 'AT1700 support' CONFIG_AT1700 n
+		tristate 'EtherExpressPro support' CONFIG_EEXPRESS_PRO n
+		tristate 'EtherExpress support' CONFIG_EEXPRESS n
+		bool 'NI5210 support' CONFIG_NI52 n
+		bool 'NI6510 support' CONFIG_NI65 n
+		if [ "$CONFIG_AX25" = "y" ]; then
+			bool 'Ottawa PI and PI/2 support' CONFIG_PI y
+		fi
+		tristate 'WaveLAN support' CONFIG_WAVELAN n
+	fi
+	tristate 'HP PCLAN+ (27247B and 27252A) support' CONFIG_HPLAN_PLUS n
+	tristate 'HP PCLAN (27245 and other 27xxx series) support' CONFIG_HPLAN n
+	tristate 'HP 10/100VG PCLAN (ISA, EISA, PCI) support' CONFIG_HP100 n
+	tristate 'NE2000/NE1000 support' CONFIG_NE2000 n
+	bool 'SK_G16 support' CONFIG_SK_G16 n
+fi
+bool 'EISA, VLB, PCI and on board controllers' CONFIG_NET_EISA n
+if [ "$CONFIG_NET_EISA" = "y" ]; then
+	if [ "$CONFIG_NET_ALPHA" = "y" ]; then
+		tristate 'Ansel Communications EISA 3200 support' CONFIG_AC3200 n
+	fi
+	tristate 'Apricot Xen-II on board ethernet' CONFIG_APRICOT n
+	tristate 'DE425, DE434, DE435, DE500 support' CONFIG_DE4X5 n
+	tristate 'DEC 21040 PCI support' CONFIG_DEC_ELCP y
+	bool 'LPL T100V 100Mbs support' CONFIG_LPL_T100 n
+	bool 'PCnet32 (32 bit VLB and PCI LANCE) support' CONFIG_PCNET32 n
+	bool 'Zenith Z-Note support' CONFIG_ZNET n
+fi
+bool 'Pocket and portable adaptors' CONFIG_NET_POCKET n
+if [ "$CONFIG_NET_POCKET" = "y" ]; then
+	bool 'AT-LAN-TEC/RealTek pocket adaptor support' CONFIG_ATP n
+	tristate 'D-Link DE600 pocket adaptor support' CONFIG_DE600 n
+	tristate 'D-Link DE620 pocket adaptor support' CONFIG_DE620 n
+#	bool 'Silicom pocket adaptor support' CONFIG_SILICOM_PEA n
+#	bool 'WaveLAN PCMCIA support' CONFIG_WaveLAN n
+#	bool '3 Com 3c589 PCMCIA support' CONFIG_3C589 n
+fi
+bool 'Token Ring driver support' CONFIG_TR n
+if [ "$CONFIG_TR" = "y" ]; then
+	tristate 'IBM Tropic chipset based adaptor support' CONFIG_IBMTR y
+fi
+tristate 'Arcnet support' CONFIG_ARCNET n
+fi
+fi
+
+comment 'CD-ROM drivers (not for SCSI or IDE/ATAPI drives)'
+
+bool 'Support non-SCSI/IDE/ATAPI drives' CONFIG_CD_NO_IDESCSI n
+if [ "$CONFIG_CD_NO_IDESCSI" = "y" ]; then
+  tristate 'Sony CDU31A/CDU33A CDROM support' CONFIG_CDU31A n
+  tristate 'Standard Mitsumi [no XA/Multisession] CDROM support' CONFIG_MCD n
+  tristate 'Experimental Mitsumi [XA/MultiSession] support' CONFIG_MCDX n
+  tristate 'Matsushita/Panasonic/Creative, Longshine, TEAC CDROM support' CONFIG_SBPCD n
+  if [ "$CONFIG_SBPCD" = "y" ]; then
+    bool 'Matsushita/Panasonic, ... second CDROM controller support' CONFIG_SBPCD2 n
+    if [ "$CONFIG_SBPCD2" = "y" ]; then
+      bool 'Matsushita/Panasonic, ... third CDROM controller support' CONFIG_SBPCD3 n
+      if [ "$CONFIG_SBPCD3" = "y" ]; then
+        bool 'Matsushita/Panasonic, ... fourth CDROM controller support' CONFIG_SBPCD4 n
+      fi
+    fi
+  fi
+  tristate 'Aztech/Orchid/Okano/Wearnes (non IDE) CDROM support' CONFIG_AZTCD n
+  tristate 'Sony CDU535 CDROM support' CONFIG_CDU535 n
+  tristate 'Goldstar R420 CDROM support' CONFIG_GSCD n
+  tristate 'Philips/LMS CM206 CDROM support' CONFIG_CM206 n
+  tristate 'Experimental Optics Storage DOLPHIN 8000AT CDROM support' CONFIG_OPTCD n
+  bool 'Experimental Sanyo H94A CDROM support' CONFIG_SJCD n
+fi
+
+comment 'Filesystems'
+
+tristate 'Standard (minix) fs support' CONFIG_MINIX_FS y
+tristate 'Extended fs support' CONFIG_EXT_FS y
+tristate 'Second extended fs support' CONFIG_EXT2_FS y
+tristate 'xiafs filesystem support' CONFIG_XIA_FS n
+tristate 'msdos fs support' CONFIG_MSDOS_FS n
+if [ "$CONFIG_MSDOS_FS" != "n" ]; then
+  tristate 'umsdos: Unix like fs on top of std MSDOS FAT fs' CONFIG_UMSDOS_FS n
+fi
+bool '/proc filesystem support' CONFIG_PROC_FS y
+if [ "$CONFIG_INET" = "y" ]; then
+  tristate 'NFS filesystem support' CONFIG_NFS_FS y
+fi
+tristate 'ISO9660 cdrom filesystem support' CONFIG_ISO9660_FS y
+tristate 'OS/2 HPFS filesystem support (read only)' CONFIG_HPFS_FS n
+tristate 'System V and Coherent filesystem support' CONFIG_SYSV_FS n
+tristate 'SMB filesystem (to mount WfW shares etc..) support' CONFIG_SMB_FS n
+
+comment 'character devices'
+
+bool 'Cyclades async mux support' CONFIG_CYCLADES n
+bool 'Stallion multiport serial support' CONFIG_STALDRV n
+if [ "$CONFIG_STALDRV" = "y" ]; then
+  tristate '  Stallion EasyIO or EC8/32 support' CONFIG_STALLION n
+  tristate '  Stallion EC8/64, ONboard, Brumby support' CONFIG_ISTALLION n
+fi
+tristate 'Parallel printer support' CONFIG_PRINTER n
+tristate 'Logitech busmouse support' CONFIG_BUSMOUSE n
+tristate 'PS/2 mouse (aka "auxiliary device") support' CONFIG_PSMOUSE n
+if [ "$CONFIG_PSMOUSE" = "y" ]; then
+  bool 'C&T 82C710 mouse port support (as on TI Travelmate)' CONFIG_82C710_MOUSE y
+fi
+tristate 'Microsoft busmouse support' CONFIG_MS_BUSMOUSE n
+tristate 'ATIXL busmouse support' CONFIG_ATIXL_BUSMOUSE n
+
+
+bool 'QIC-02 tape support' CONFIG_QIC02_TAPE n
+if [ "$CONFIG_QIC02_TAPE" = "y" ]; then
+  bool 'Do you want runtime configuration for QIC-02' CONFIG_QIC02_DYNCONF y
+if [ "$CONFIG_QIC02_DYNCONF" != "y" ]; then
+
+comment '>>> Edit configuration parameters in ./include/linux/tpqic02.h!'
+
+else
+
+comment '>>> Setting runtime QIC-02 configuration is done with qic02conf'
+comment '>>> Which is available from ftp://ftp.funet.fi/pub/OS/Linux/BETA/QIC-02/'
+
+fi
+fi
+
+bool 'QIC-117 tape support' CONFIG_FTAPE n
+if [ "$CONFIG_FTAPE" = "y" ]; then
+  int ' number of ftape buffers' NR_FTAPE_BUFFERS 3
+fi
+
+comment 'Sound'
+
+tristate 'Sound card support' CONFIG_SOUND y
+
+comment 'Kernel hacking'
+
+#bool 'Debug kmalloc/kfree' CONFIG_DEBUG_MALLOC n
+bool 'Kernel profiling support' CONFIG_PROFILE n
+if [ "$CONFIG_PROFILE" = "y" ]; then
+  int ' Profile shift count' CONFIG_PROFILE_SHIFT 2
+fi
+if [ "$CONFIG_SCSI" = "y" ]; then
+bool 'Verbose SCSI error reporting (kernel size +=12K)' CONFIG_SCSI_CONSTANTS y
+fi
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/Makefile linux/arch/ppc/kernel/Makefile
--- v1.3.44/linux/arch/ppc/kernel/Makefile	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/Makefile	Fri Nov 10 06:05:52 1995
@@ -0,0 +1,81 @@
+#
+# Makefile for the linux kernel.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definitions are now in the main makefile...
+
+.c.s:
+	$(CC) $(CFLAGS) -S $<
+.s.o:
+	$(AS) $(ASFLAGS) -o $*.o $<
+.c.o:
+	$(CC) $(CFLAGS) -c $<
+.S.s:
+#	$(CPP) $(CFLAGS) -D__ASSEMBLY__ -traditional $< -o $*.s
+	$(CPP) $(CFLAGS) -D__ASSEMBLY__ $< -o $*.s
+.S.o:
+#	$(CC) -D__ASSEMBLY__ -traditional -c $< -o $*.o
+	$(CPP) $(CFLAGS) -D__ASSEMBLY__ $< -o $*.s
+	$(AS) $(ASFLAGS) -o $*.o $*.s
+
+HOST_CC = gcc
+
+OBJS  = misc.o setup.o port_io.o irq.o pci.o traps.o stubs.o process.o \
+	signal.o raw_printf.o ramdisk.o 
+
+all: head.o kernel.o cortstrip mkboot
+
+head.o: head.s
+head.s: head.S $(TOPDIR)/include/linux/tasks.h ppc_defs.h
+
+ppc_defs.h: mk_defs $(TOPDIR)/include/asm/mmu.h $(TOPDIR)/include/asm/processor.h $(TOPDIR)/include/asm/pgtable.h $(TOPDIR)/include/asm/ptrace.h
+#	simppc mk_defs -- $@
+	mk_defs ppc_defs.h
+
+ramdisk.o: ramdisk.s
+
+ramdisk.s: ramdisk.image mk_ramdisk
+	mk_ramdisk ramdisk.image ramdisk.s
+
+mk_ramdisk: mk_ramdisk.c
+	$(HOST_CC) -o mk_ramdisk mk_ramdisk.c	
+
+
+
+cortstrip : cortstrip.c
+	${HOST_CC} -o cortstrip cortstrip.c
+
+mkboot : mkboot.c
+	${HOST_CC} -o mkboot mkboot.c
+
+mk_defs: mk_defs.c $(TOPDIR)/include/asm/mmu.h $(TOPDIR)/include/asm/processor.h $(TOPDIR)/include/asm/pgtable.h $(TOPDIR)/include/asm/ptrace.h
+#	$(CC) ${CFLAGS} -c mk_defs -T ld.script-user -Ttext 0x1000 mk_defs.c
+#	$(LD) -T ld.script-user -Ttext 0x1000  -o mk_defs mk_defs.o
+	$(HOST_CC) -DMKDEFS ${CFLAGS} -o mk_defs mk_defs.c
+
+
+kernel.o: $(OBJS)
+	$(LD) -r -o kernel.o $(OBJS)
+	sync
+
+
+dep:
+	$(CPP) -M *.c > .depend
+
+fastdep:
+	$(CPP) -M *.c > .depend
+
+
+modules:
+
+dummy:
+
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/cortstrip.c linux/arch/ppc/kernel/cortstrip.c
--- v1.3.44/linux/arch/ppc/kernel/cortstrip.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/cortstrip.c	Fri Oct 13 22:16:53 1995
@@ -0,0 +1,62 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+/* amount to skip */
+/*#define PLACE 0x10000*/
+
+/* size of read buffer */
+#define SIZE 0x10000
+
+void main(int argc, char **argv )
+{
+  int fd, fdo;
+  unsigned char data[SIZE];
+  int i, n, skip;
+
+  if ( argc != 4 )
+  {
+    fprintf(stderr,"%s infile outfile skip\n", argv[0]);
+    exit(-1);
+  }
+
+
+  fd = open(argv[1], O_RDONLY);
+  if ( fd == -1 )
+  {
+    fprintf(stderr,"Couldn't open %s\n", argv[1]);
+    perror("open()");
+    exit(-1);
+  }
+  
+  fdo = open(argv[2], O_WRONLY|O_CREAT, 755);
+  if ( fdo == -1 )
+  {
+    fprintf(stderr,"Couldn't open %s\n", argv[2]);
+    perror("open()");
+    exit(-1);
+  }
+
+  skip = atoi(argv[3]);
+  i = lseek(fd, skip, SEEK_SET);
+  printf("lseek'd %d bytes\n", i);
+  if ( i == -1 )
+  {
+      perror("lseek()");
+  }
+
+  while ( (n = read(fd, data, SIZE)) > 0 )
+  {
+    printf("Read %d bytes\n", n);
+    i = write(fdo, data, n);
+    printf("Wrote %d bytes\n", i);    
+  }
+
+
+  close(fdo);
+  close(fd);
+  return(0);
+}
+
+
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/head.S linux/arch/ppc/kernel/head.S
--- v1.3.44/linux/arch/ppc/kernel/head.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/head.S	Thu Nov 16 22:15:13 1995
@@ -0,0 +1,1497 @@
+#include "ppc_asm.tmpl"
+#include "ppc_defs.h"
+
+#define SYNC() \
+	isync; \
+	sync
+
+/* #define TLB_STATS /* Trace TLB exceptions */
+
+/* Keep track of low-level exceptions - rather crude, but informative */	
+#define STATS
+
+/*
+ * Increment a [64 bit] statistic counter
+ * Uses R2, R3
+ */
+#define BUMP(ctr) /*\
+	lis	r2,ctr@h; \
+	ori	r2,r2,ctr@l; \
+	lwz	r3,4(r2); \
+	addic	r3,r3,1; \
+	stw	r3,4(r2); \
+	lwz	r3,0(r2); \
+	addze	r3,r3; \
+	stw	r3,0(r2)*/
+
+/* The same as 'BUMP' but running unmapped (TLB code) */	
+#define BUMP_UNMAPPED(ctr) /*\
+	mfspr	r0,XER; \
+	lis	r2,ctr@h; \
+	ori	r2,r2,ctr@l; \
+	lis	r3,0xF000; \
+	andc	r2,r2,r3; \
+	lwz	r3,4(r2); \
+	addic	r3,r3,1; \
+	stw	r3,4(r2); \
+	lwz	r3,0(r2); \
+	addze	r3,r3; \
+	mtspr	XER,r0; \
+	stw	r3,0(r2)*/
+
+/* These macros can be used to generate very raw traces of low-level */
+/* operations (where printf, etc. can't help).  All they provide is */
+/* some after-the-fact documentation of what took place.  Since [in */
+/* most instances] they have no registers to work with, they use the */
+/* hardware "special" registers SPRx for storage.  Because of this, */
+/* defining more than one of them simultaneously will yield incorrect */
+/* results and a non-functional system.  Note: the trick here is to */
+/* gather some data without disturbing anything - Heisenberg are you watching? */
+
+/* CAUTION! Don't turn on more than one of these at once! */	
+/* #define DO_TRAP_TRACE   */
+/* #define DO_TLB_TRACE    */
+/* #define DO_RFI_TRACE   */
+
+#ifdef DO_RFI_TRACE
+#define DO_RFI_TRACE_UNMAPPED(mark) \
+	mtspr	SPR0,r1; \
+	mtspr	SPR1,r2; \
+	mtspr	SPR2,r3; \
+	mfcr	r3; \
+	mtspr	SPR3,r3; \
+	lis	r1,_RFI_ptr@h; \
+	ori	r1,r1,_RFI_ptr@l; \
+	lis	r3,0xF000; \
+	andc	r1,r1,r3; \
+	lwz	r1,0(r1); \
+	andc	r1,r1,r3; \
+	subi	r1,r1,4; \
+	lis	r2,(mark>>16); \
+	ori	r2,r2,(mark&0xFFFF); \
+	stwu	r2,4(r1); \
+	mfspr	r2,SRR0; \
+	stwu	r2,4(r1); \
+	mfspr	r2,SRR1; \
+	stwu	r2,4(r1); \
+	addi	r1,r1,4+4; \
+	lis	r2,_RFI_ptr@h; \
+	ori	r2,r2,_RFI_ptr@l; \
+	andc	r2,r2,r3; \
+	stw	r1,0(r2); \
+	mfspr	r3,SPR3; \
+	mtcrf	0xFF,r3; \
+	mfspr	r1,SPR0; \
+	mfspr	r2,SPR1; \
+	mfspr	r3,SPR2
+#define DO_RFI_TRACE_MAPPED(mark) \
+	mtspr	SPR0,r1; \
+	mtspr	SPR1,r2; \
+	mtspr	SPR2,r3; \
+	mfcr	r3; \
+	mtspr	SPR3,r3; \
+	lis	r1,_RFI_ptr@h; \
+	ori	r1,r1,_RFI_ptr@l; \
+	lwz	r1,0(r1); \
+	lis	r3,0x9000; \
+	or	r1,r1,r3; \
+	subi	r1,r1,4; \
+	lis	r2,(mark>>16); \
+	ori	r2,r2,(mark&0xFFFF); \
+	stwu	r2,4(r1); \
+	mfspr	r2,SRR0; \
+	stwu	r2,4(r1); \
+	mfspr	r2,SRR1; \
+	stwu	r2,4(r1); \
+	addi	r1,r1,4+4; \
+	lis	r2,_RFI_ptr@h; \
+	ori	r2,r2,_RFI_ptr@l; \
+	stw	r1,0(r2); \
+	mfspr	r3,SPR3; \
+	mtcrf	0xFF,r3; \
+	mfspr	r1,SPR0; \
+	mfspr	r2,SPR1; \
+	mfspr	r3,SPR2
+#else
+#define DO_RFI_TRACE_UNMAPPED(mark)
+#define DO_RFI_TRACE_MAPPED(mark)
+#endif
+
+#ifdef DO_TRAP_TRACE
+#define DEFAULT_TRAP(offset) \
+	mtspr	SPR0,r1; \
+	mtspr	SPR1,r2; \
+	mtspr	SPR2,r3; \
+	lis	r1,_TRAP_ptr@h; \
+	ori	r1,r1,_TRAP_ptr@l; \
+	lis	r3,0xF000; \
+	andc	r1,r1,r3; \
+	lwz	r1,0(r1); \
+	andc	r1,r1,r3; \
+	subi	r1,r1,4; \
+	lis	r2,0xCACA; \
+	ori	r2,r2,offset; \
+	stwu	r2,4(r1); \
+	mfspr	r2,SRR0; \
+	stwu	r2,4(r1); \
+	mfspr	r2,SRR1; \
+	stwu	r2,4(r1); \
+	mfspr	r2,SPR0; \
+	stwu	r2,4(r1); \
+	addi	r1,r1,4; \
+	lis	r2,_TRAP_ptr@h; \
+	ori	r2,r2,_TRAP_ptr@l; \
+	andc	r2,r2,r3; \
+	stw	r1,0(r2); \
+	mfspr	r1,SPR0; \
+	mfspr	r2,SPR1; \
+	mfspr	r3,SPR2; \
+	li	r13,0; \
+	ori	r13,r13,HID0_ICE; \
+	mtspr	HID0,r13; \
+	lis	r13,0xFFF00000>>16; \
+	ori	r13,r13,offset; \
+	mtlr	r13; \
+	b	hang
+#define TRACE_TRAP(offset) \
+	mtspr	SPR0,r1; \
+	mtspr	SPR1,r2; \
+	mtspr	SPR2,r3; \
+	mfcr	r3; \
+	mtspr	SPR3,r3; \
+	lis	r1,_TRAP_ptr@h; \
+	ori	r1,r1,_TRAP_ptr@l; \
+	lis	r3,0xF000; \
+	andc	r1,r1,r3; \
+	lwz	r1,0(r1); \
+	andc	r1,r1,r3; \
+	subi	r1,r1,4; \
+	lis	r2,0xCABB; \
+	ori	r2,r2,offset; \
+	stwu	r2,4(r1); \
+	dcbst	0,r1; \
+	mfspr	r2,SRR0; \
+	stwu	r2,4(r1); \
+	dcbst	0,r1; \
+	mfspr	r2,SRR1; \
+	stwu	r2,4(r1); \
+	dcbst	0,r1; \
+	li	r2,offset; \
+	cmpi	0,r2,0x0C00; \
+	beq	01f; \
+	cmpi	0,r2,0x0300; \
+	beq	00f; \
+	cmpi	0,r2,0x0400; \
+	beq	00f; \
+	mfspr	r2,SPR0; \
+	b	02f; \
+00:	mfspr	r2,DAR; \
+	b	02f; \
+01:	mr	r2,r0; \
+02:	stwu	r2,4(r1); \
+	dcbst	0,r1; \
+	addi	r1,r1,4; \
+	mflr	r2; \
+	stw	r2,0(r1); \
+	bl	check_trace; \
+	lwz	r2,0(r1); \
+	mtlr	r2; \
+02:	lis	r2,_TRAP_ptr@h; \
+	ori	r2,r2,_TRAP_ptr@l; \
+	oris	r1,r1,0x9000; \
+	cmp	0,r1,r2; \
+	bne	00f; \
+	lis	r1,_TRAP_TRACE@h; \
+	ori	r1,r1,_TRAP_TRACE@l; \
+00:	lis	r3,0xF000; \
+	andc	r2,r2,r3; \
+	stw	r1,0(r2); \
+	mfspr	r1,SPR0; \
+	mfspr	r2,SPR1; \
+	mfspr	r3,SPR3; \
+	mtcrf	0xFF,r3; \
+	mfspr	r3,SPR2
+#else
+#define DEFAULT_TRAP(offset) \
+	li	r13,0; \
+	ori	r13,r13,HID0_ICE; \
+	mtspr	HID0,r13; \
+	lis	r13,0xFFF00000>>16; \
+	ori	r13,r13,offset; \
+	mtlr	r13; \
+	blr
+#define TRACE_TRAP(offset)	
+#endif
+
+#define DATA_CACHE_OFF() \
+	mfspr	r2,HID0; \
+	li	r3,0; \
+	ori	r3,r3,HID0_DCE; \
+	andc	r2,r2,r3; \
+	mtspr	HID0,r2;
+
+#define DATA_CACHE_ON() \
+	mfspr	r2,HID0; \
+	ori	r2,r2,HID0_DCE; \
+	mtspr	HID0,r2;
+
+/* This instruction is not implemented on the PPC 603 */
+#define tlbia \
+	li	r4,32; \
+	mtspr	CTR,r4; \
+	lis	r4,0x9000; \
+0:	tlbie	r4; \
+	addi	r4,r4,0x1000; \
+	bdnz	0b
+
+/* Validate kernel stack - check for overflow */
+#define CHECK_STACK()
+#define _CHECK_STACK()\
+	mtspr	SPR0,r3; \
+	lis	r2,current@ha; \
+	lwz	r2,current@l(r2); \
+	lwz	r2,KERNEL_STACK_PAGE(r2); \
+	lis	r3,sys_stack@h; \
+	ori	r3,r3,sys_stack@l; \
+	cmpl	0,r1,r3; \
+	ble	02f; \
+	li	r3,0x0FFF; \
+	andc	r2,r2,r3; \
+	andc	r3,r1,r3; \
+	cmp	0,r3,r2; \
+	beq	02f; \
+	mr	r3,r1; \
+	bl	_EXTERN(bad_stack); \
+02:	mfspr	r3,SPR0
+
+/* Save all registers on kernel stack during an exception */	
+#define SAVE_REGS(mark) \
+	subi	r1,r1,INT_FRAME_SIZE;	/* Make room for frame */ \
+	stmw	r3,GPR3(r1);	/* Save R3..R31 */ \
+	stw	r3,ORIG_GPR3(r1); \
+	stw	r0,GPR0(r1); \
+	mfspr	r2,SPR0; \
+	stw	r2,GPR1(r1); \
+	mfspr	r2,SPR1; \
+	stw	r2,GPR2(r1); \
+	mfspr	r2,SPR2; \
+	stw	r2,_NIP(r1); \
+	mfspr	r2,SPR3; \
+	stw	r2,_MSR(r1); \
+	mfctr	r2; \
+	stw	r2,_CTR(r1); \
+	mflr	r2; \
+	stw	r2,_LINK(r1); \
+	mfcr	r2; \
+	stw	r2,_CCR(r1); \
+	mfspr	r2,XER; \
+	stw	r2,_XER(r1); \
+	stfd	fr0,FPR0(r1); \
+	stfd	fr1,FPR1(r1); \
+	stfd	fr2,FPR2(r1); \
+	stfd	fr3,FPR3(r1); \
+	mffs	fr0; \
+	stfd	fr0,FPCSR(r1); \
+	lis	r2,_break_lwarx@h; \
+	ori	r2,r2,_break_lwarx@l; \
+	stwcx.	r2,0,r2; \
+	li	r2,mark; \
+	stw	r2,TRAP(r1); \
+	lis	r2,0xDEAD; \
+	ori	r2,r2,0xDEAD; \
+	stw	r2,MARKER(r1); \
+	li	r2,0; \
+	stw	r2,RESULT(r1)
+
+#define SAVE_PAGE_FAULT_REGS(offset) \
+	mfspr	r2,DAR; \
+	stw	r2,_DAR(r1); \
+	mfspr	r2,DSISR; \
+	stw	r2,_DSISR(r1); \
+	mfspr	r2,HASH1; \
+	stw	r2,_HASH1(r1); \
+	mfspr	r2,HASH2; \
+	stw	r2,_HASH2(r1); \
+	mfspr	r2,IMISS; \
+	stw	r2,_IMISS(r1); \
+	mfspr	r2,DMISS; \
+	stw	r2,_DMISS(r1); \
+	mfspr	r2,ICMP; \
+	stw	r2,_ICMP(r1); \
+	mfspr	r2,DCMP; \
+	stw	r2,_DCMP(r1)
+	
+#define SAVE_INT_REGS(mark) \
+	mtspr	SPR0,r1;	/* Save current stack pointer */ \
+	mtspr	SPR1,r2;	/* Scratch */ \
+	mfcr	r2; \
+	mtspr	SPR2,r2; \
+	mfspr	r2,SRR1;	/* Interrupt from user/system mode */ \
+	andi.	r2,r2,MSR_PR; \
+	beq+	10f;		/* Jump if system - already have stack */ \
+	mfspr	r2,SPR2;	/* Restore CCR */ \
+	mtcrf	0xFF,r2; \
+	mfspr	r2,SRR0;	/* Preserve interrupt registers */ \
+	mtspr	SPR2,r2; \
+	mfspr	r2,SRR1; \
+	mtspr	SPR3,r2; \
+	lis	r2,05f@h; \
+	ori	r2,r2,05f@l; \
+	mtspr	SRR0,r2; \
+	mfmsr	r2; \
+	ori	r2,r2,MSR_|MSR_DR|MSR_IR; \
+	mtspr	SRR1,r2; \
+	rfi; \
+05:	lis	r2,current@ha; \
+	lwz	r2,current@l(r2); \
+	mfspr	r1,SPR2; \
+	stw	r1,TSS+LAST_PC(r2); \
+	lwz	r1,TSS+KSP(r2); \
+	b	20f; \
+10:	mfspr	r2,SPR2;	/* Restore CCR */ \
+	mtcrf	0xFF,r2; \
+	mfspr	r2,SRR0;	/* Preserve interrupt registers */ \
+	mtspr	SPR2,r2; \
+	mfspr	r2,SRR1; \
+	mtspr	SPR3,r2; \
+	lis	r2,20f@h; \
+	ori	r2,r2,20f@l; \
+	mtspr	SRR0,r2; \
+	mfmsr	r2; \
+	ori	r2,r2,MSR_|MSR_DR|MSR_IR; \
+	mtspr	SRR1,r2; \
+	SYNC(); \
+	rfi; \
+20:   SAVE_REGS(mark); \
+	CHECK_STACK()
+
+#define RETURN_FROM_INT(mark) \
+90:	mfmsr	r0;		/* Disable interrupts */ \
+	li	r4,0; \
+	ori	r4,r4,MSR_EE; \
+	andc	r0,r0,r4; \
+	mtmsr	r0; \
+	SYNC(); \
+	lis	r2,intr_count@ha; /* Need to run 'bottom half' */ \
+	lwz	r3,intr_count@l(r2); \
+	cmpi	0,r3,0; \
+	bne	00f; \
+	lis	r4,bh_mask@ha; \
+	lwz	r4,bh_mask@l(r4); \
+	lis	r5,bh_active@ha; \
+	lwz	r5,bh_active@l(r5); \
+	and.	r4,r4,r5; \
+	beq	00f; \
+	addi	r3,r3,1; \
+	stw	r3,intr_count@l(r2); \
+	bl	_EXTERN(_do_bottom_half); \
+	lis	r2,intr_count@ha; \
+	lwz	r3,intr_count@l(r2); \
+	subi	r3,r3,1; \
+	stw	r3,intr_count@l(r2); \
+00:	lwz	r2,_MSR(r1); /* Returning to user mode? */ \
+	andi.	r2,r2,MSR_PR; \
+	beq+	10f;		/* no - no need to mess with stack */ \
+	lis	r2,kernel_pages_are_copyback@ha; \
+	lwz	r2,kernel_pages_are_copyback@l(r2); \
+	cmpi	0,r2,0; \
+	beq	05f; \
+	bl	_EXTERN(flush_instruction_cache); \
+05:	lis	r3,current@ha;	/* need to save kernel stack pointer */ \
+	lwz	r3,current@l(r3); \
+	addi	r4,r1,INT_FRAME_SIZE;	/* size of frame */ \
+	stw	r4,TSS+KSP(r3); \
+	lwz	r4,STATE(r3);	/* If state != 0, can't run */ \
+	cmpi	0,r4,0; \
+	beq	06f; \
+	bl	_EXTERN(schedule); \
+	b	90b; \
+06:	lwz	r4,COUNTER(r3);	/* Time quantum expired? */ \
+	cmpi	0,r4,0; \
+	bne	07f; \
+	bl	_EXTERN(schedule); \
+	b	90b; \
+07:	lwz	r4,BLOCKED(r3);	/* Check for pending unblocked signals */ \
+	lwz	r5,SIGNAL(r3); \
+	andc.	r0,r5,r4;	/* Lets thru any unblocked */ \
+	beq	10f; \
+	mr	r3,r4; \
+	mr	r4,r1; \
+	bl	_EXTERN(do_signal); \
+10:	lwz	r2,_NIP(r1);	/* Restore environment */ \
+	mtspr	SRR0,r2; \
+	lwz	r2,_MSR(r1); \
+	mtspr	SRR1,r2; \
+	lmw	r3,GPR3(r1); \
+	lwz	r2,_CTR(r1); \
+	mtctr	r2; \
+	lwz	r2,_LINK(r1); \
+	mtlr	r2; \
+	lwz	r2,_XER(r1); \
+	mtspr	XER,r2; \
+	lwz	r2,_CCR(r1); \
+	mtcrf	0xFF,r2; \
+	lfd	fr0,FPCSR(r1); \
+	mtfsf	0xFF,fr0; \
+	lfd	fr0,FPR0(r1); \
+	lfd	fr1,FPR1(r1); \
+	lfd	fr2,FPR2(r1); \
+	lfd	fr3,FPR3(r1); \
+	lwz	r0,GPR0(r1); \
+	lwz	r2,GPR2(r1); \
+	lwz	r1,GPR1(r1); \
+	SYNC(); \
+	rfi
+
+_TEXT()
+	.globl	_start
+_start:
+	.globl  _stext
+_stext:
+
+hang:
+	ori	r0,r0,0
+	b	hang
+	
+_ORG(0x0100)
+
+/* Hard Reset */
+	.globl	HardReset
+HardReset:
+	b	Reset
+
+_ORG(0x0200)
+	b	MachineCheck
+
+_ORG(0x0300)
+	b	DataAccess
+
+_ORG(0x0400)
+	b	InstructionAccess
+
+_ORG(0x0500)
+	b	HardwareInterrupt
+	
+_ORG(0x0600)
+	b	Alignment
+
+_ORG(0x0700)
+	b	ProgramCheck
+
+_ORG(0x0800)
+	b	FloatingPointCheck
+
+/* Decrementer register - ignored for now... */
+_ORG(0x0900)
+/* TRACE_TRAP(0x900) */
+	mtspr	SPR0,r1
+	lis	r1,0x7FFF
+	ori	r1,r1,0xFFFF
+	mtspr	DEC,r1
+	mfspr	r1,SPR0
+#if 0	
+	SYNC
+#endif	
+	rfi
+	
+_ORG(0x0A00)
+DEFAULT_TRAP(0x0A00)	
+_ORG(0x0B00)
+DEFAULT_TRAP(0x0B00)
+
+/*
+ * System call
+ */
+_ORG(0x0C00)
+	b	SystemCall
+
+_ORG(0x0D00)
+DEFAULT_TRAP(0x0D00)	
+_ORG(0x0E00)
+DEFAULT_TRAP(0x0E00)	
+_ORG(0x0F00)
+DEFAULT_TRAP(0x0F00)	
+
+/*
+ * Handle TLB Miss on an instruction load
+ */
+_ORG(0x1000)
+/* Note: It is *unsafe* to use the TRACE TRAP macro here since there */
+/* could be a 'trace' in progress when the TLB miss occurs.          */
+/* TRACE_TRAP(0x1000) */
+#ifdef TLB_STATS
+	lis	r2,DataLoadTLB_trace_ptr@h
+	ori	r2,r2,DataLoadTLB_trace_ptr@l
+	lis	r3,0xF000
+	andc	r2,r2,r3
+	lwz	r1,0(r2)
+	andc	r1,r1,r3
+	li	r0,0x1000
+	stw	r0,0(r1)
+	mftbu	r0
+	stw	r0,4(r1)
+	mftb	r0
+	stw	r0,8(r1)
+	mfspr	r0,IMISS
+	mfspr	r3,SRR1
+	extrwi	r3,r3,1,14
+	or	r0,r0,r3
+	stw	r0,12(r1)
+	addi	r1,r1,16
+	mfcr	r0
+	cmpl	0,r1,r2
+	blt	00f
+	lis	r1,DataLoadTLB_trace_buf@h
+	ori	r1,r1,DataLoadTLB_trace_buf@l
+	lis	r3,0xF000
+	andc	r1,r1,r3
+00:	mtcrf	0xFF,r0
+	stw	r1,0(r2)
+#endif	
+	b	InstructionTLBMiss
+
+/*
+ * Handle TLB Miss on a data item load
+ */
+_ORG(0x1100)
+/* TRACE_TRAP(0x1100) */
+#ifdef TLB_STATS
+	lis	r2,DataLoadTLB_trace_ptr@h
+	ori	r2,r2,DataLoadTLB_trace_ptr@l
+	lis	r3,0xF000
+	andc	r2,r2,r3
+	lwz	r1,0(r2)
+	andc	r1,r1,r3
+	li	r0,0x1100
+	stw	r0,0(r1)
+	mftbu	r0
+	stw	r0,4(r1)
+	mftb	r0
+	stw	r0,8(r1)
+	mfspr	r0,DMISS
+	mfspr	r3,SRR1
+	extrwi	r3,r3,1,14
+	or	r0,r0,r3
+	stw	r0,12(r1)
+	addi	r1,r1,16
+	mfcr	r0
+	cmpl	0,r1,r2
+	blt	00f
+	lis	r1,DataLoadTLB_trace_buf@h
+	ori	r1,r1,DataLoadTLB_trace_buf@l
+	lis	r3,0xF000
+	andc	r1,r1,r3
+00:	mtcrf	0xFF,r0
+	stw	r1,0(r2)
+	.data
+DataLoadTLB_trace_buf:
+	.space	64*1024*4
+DataLoadTLB_trace_ptr:
+	.long	DataLoadTLB_trace_buf
+	.text
+#endif	
+	b	DataLoadTLBMiss
+
+/*
+ * Handle TLB Miss on a store operation
+ */
+_ORG(0x1200)
+/* TRACE_TRAP(0x1200) */
+#ifdef TLB_STATS
+	lis	r2,DataLoadTLB_trace_ptr@h
+	ori	r2,r2,DataLoadTLB_trace_ptr@l
+	lis	r3,0xF000
+	andc	r2,r2,r3
+	lwz	r1,0(r2)
+	andc	r1,r1,r3
+	li	r0,0x1200
+	stw	r0,0(r1)
+	mftbu	r0
+	stw	r0,4(r1)
+	mftb	r0
+	stw	r0,8(r1)
+	mfspr	r0,DMISS
+	mfspr	r3,SRR1
+	extrwi	r3,r3,1,14
+	or	r0,r0,r3
+	stw	r0,12(r1)
+	addi	r1,r1,16
+	mfcr	r0
+	cmpl	0,r1,r2
+	blt	00f
+	lis	r1,DataLoadTLB_trace_buf@h
+	ori	r1,r1,DataLoadTLB_trace_buf@l
+	lis	r3,0xF000
+	andc	r1,r1,r3
+00:	mtcrf	0xFF,r0
+	stw	r1,0(r2)
+#endif	
+	b	DataStoreTLBMiss
+
+_ORG(0x1300)
+InstructionAddressBreakpoint:
+	DEFAULT_TRAP(0x1300)
+
+_ORG(0x1400)
+SystemManagementInterrupt:
+	DEFAULT_TRAP(0x1400)
+
+_ORG(0x1500)
+
+/*
+ * This space [buffer] is used to forceably flush the data cache when
+ * running in copyback mode.  This is necessary IFF the data cache could
+ * contain instructions for which the instruction cache has stale data.
+ * Since the instruction cache NEVER snoops the data cache, memory must
+ * be made coherent with the data cache to insure that the instruction
+ * cache gets a valid instruction stream.  Note that this flushing is
+ * only performed when switching from system to user mode since this is
+ * the only juncture [as far as the OS goes] where the data cache may
+ * contain instructions, e.g. after a disk read.
+ */
+#define NUM_CACHE_LINES 128*2
+#define CACHE_LINE_SIZE 32 
+cache_flush_buffer:
+	.space	NUM_CACHE_LINES*CACHE_LINE_SIZE	/* CAUTION! these need to match hardware */
+
+#if NUM_CACHE_LINES < 512	
+_ORG(0x4000)
+#endif
+
+/*
+ * Hardware reset [actually from bootstrap]
+ * Initialize memory management & call secondary init
+ */	
+Reset:
+	lis	r7,0xF000		/* To mask upper 4 bits */
+/* Copy argument string */
+	li	r0,0		/* Null terminate string */
+	stb	r0,0(r12)
+	lis	r1,cmd_line@h
+	ori	r1,r1,cmd_line@l
+	andc	r1,r1,r7	/* No MMU yet - need unmapped address */
+	subi	r1,r1,1
+	subi	r11,r11,1
+00:	lbzu	r0,1(r11)
+	cmpi	0,r0,0
+	stbu	r0,1(r1)
+	bne	00b	
+	lis	r1,sys_stack@h
+	ori	r1,r1,sys_stack@l
+	li	r2,0x0FFF	/* Mask stack address down to page boundary */
+	andc	r1,r1,r2
+	subi	r1,r1,INT_FRAME_SIZE	/* Padding for first frame */
+	li	r2,0		/* TOC pointer for nanokernel */
+	li	r0,MSR_		/* Make sure FPU enabled */
+	mtmsr	r0
+	lis	r3,_edata@h	/* Clear BSS */
+	ori	r3,r3,_edata@l
+	andc	r3,r3,r7	/* make unmapped address */
+	lis	r4,_end@h
+	ori	r4,r4,_end@l
+	andc	r4,r4,r7	/* make unmapped address */
+	subi	r3,r3,4
+	li	r0,0
+00:	stwu	r0,4(r3)
+	cmp	0,r3,r4
+	blt	00b
+/* Initialize BAT registers */
+	lis	r3,BAT0@h
+	ori	r3,r3,BAT0@l
+	andc	r3,r3,r7	/* make unmapped address */
+	lwz	r0,0(r3)
+	mtspr	IBAT0U,r0
+	mtspr	DBAT0U,r0
+	lwz	r0,4(r3)
+	mtspr	IBAT0L,r0
+	mtspr	DBAT0L,r0
+	lis	r3,BAT1@h
+	ori	r3,r3,BAT1@l
+	andc	r3,r3,r7	/* make unmapped address */
+	lwz	r0,0(r3)
+	mtspr	IBAT1U,r0
+	mtspr	DBAT1U,r0
+	lwz	r0,4(r3)
+	mtspr	IBAT1L,r0
+	mtspr	DBAT1L,r0
+	lis	r3,TMP_BAT2@h
+	ori	r3,r3,TMP_BAT2@l
+	andc	r3,r3,r7	/* make unmapped address */
+	lwz	r0,0(r3)
+	mtspr	IBAT2U,r0
+	mtspr	DBAT2U,r0
+	lwz	r0,4(r3)
+	mtspr	IBAT2L,r0
+	mtspr	DBAT2L,r0
+/* Now we can turn on the MMU */
+	mfmsr	r3
+	ori	r3,r3,MSR_DR|MSR_IR
+	mtspr	SRR1,r3
+	lis	r3,10f@h
+	ori	r3,r3,10f@l
+	mtspr	SRR0,r3
+DO_RFI_TRACE_UNMAPPED(0xDEAD0000)	
+	SYNC
+	rfi				/* enables MMU */
+10:	bl	_EXTERN(MMU_init)	/* initialize MMU environment */
+DO_RFI_TRACE_MAPPED(0xDEAD0100)	
+/* Withdraw BAT2->RAM mapping */
+#if 1
+	lis	r7,0xF000		/* To mask upper 4 bits */
+	lis	r3,20f@h
+	ori	r3,r3,20f@l
+	andc	r3,r3,r7	/* make unmapped address */
+	mtspr	SRR0,r3
+	mfmsr	r3
+	li	r4,MSR_DR|MSR_IR
+	andc	r3,r3,r4
+	mtspr	SRR1,r3
+	SYNC
+DO_RFI_TRACE_MAPPED(0xDEAD0200)	
+	SYNC
+	rfi
+20:
+DO_RFI_TRACE_UNMAPPED(0xDEAD0400)	
+20:	lis	r3,BAT2@h
+	ori	r3,r3,BAT2@l
+	andc	r3,r3,r7	/* make unmapped address */
+	lwz	r0,0(r3)
+	mtspr	IBAT2U,r0
+	mtspr	DBAT2U,r0
+	lwz	r0,4(r3)
+	mtspr	IBAT2L,r0
+	mtspr	DBAT2L,r0
+#endif
+
+/* Load up the kernel context */
+	lis	r2,init_task@h
+	ori	r2,r2,init_task@l
+	addi	r2,r2,TSS
+	andc	r2,r2,r7	/* make unmapped address */
+	SYNC			/* Force all PTE updates to finish */
+	tlbia			/* Clear all TLB entries */
+	lis	r3,_SDR1@h
+	ori	r3,r3,_SDR1@l
+	andc	r3,r3,r7	/* make unmapped address */
+	lwz	r3,0(r3)
+	mtspr	SDR1,r3
+	lwz	r0,MMU_SEG0(r2)
+	mtsr	SR0,r0
+	lwz	r0,MMU_SEG1(r2)
+	mtsr	SR1,r0
+	lwz	r0,MMU_SEG2(r2)
+	mtsr	SR2,r0
+	lwz	r0,MMU_SEG3(r2)
+	mtsr	SR3,r0
+	lwz	r0,MMU_SEG4(r2)
+	mtsr	SR4,r0
+	lwz	r0,MMU_SEG5(r2)
+	mtsr	SR5,r0
+	lwz	r0,MMU_SEG6(r2)
+	mtsr	SR6,r0
+	lwz	r0,MMU_SEG7(r2)
+	mtsr	SR7,r0
+	lwz	r0,MMU_SEG8(r2)
+	mtsr	SR8,r0
+	lwz	r0,MMU_SEG9(r2)
+	mtsr	SR9,r0
+	lwz	r0,MMU_SEG10(r2)
+	mtsr	SR10,r0
+	lwz	r0,MMU_SEG11(r2)
+	mtsr	SR11,r0
+	lwz	r0,MMU_SEG12(r2)
+	mtsr	SR12,r0
+	lwz	r0,MMU_SEG13(r2)
+	mtsr	SR13,r0
+	lwz	r0,MMU_SEG14(r2)
+	mtsr	SR14,r0
+	lwz	r0,MMU_SEG15(r2)
+	mtsr	SR15,r0
+/* Now turn on the MMU for real! */
+	mfmsr	r3
+	ori	r3,r3,MSR_DR|MSR_IR
+	mtspr	SRR1,r3
+	lis	r3,30f@h
+	ori	r3,r3,30f@l
+	mtspr	SRR0,r3
+DO_RFI_TRACE_UNMAPPED(0xDEAD0500)	
+	SYNC
+	rfi				/* enables MMU */
+30:
+DO_RFI_TRACE_MAPPED(0xDEAD0600)
+/* Turn on L1 Data Cache */
+	mfspr	r3,HID0		/* Caches are controlled by this register */
+	ori	r4,r3,(HID0_ICE|HID0_ICFI)
+	ori	r3,r3,(HID0_ICE)
+	ori	r4,r4,(HID0_DCE|HID0_DCI)
+	ori	r3,r3,(HID0_DCE)
+	sync
+	mtspr	HID0,r4
+	mtspr	HID0,r3
+/* L1 cache enable */	
+	b	_EXTERN(start_kernel)		/* call main code */
+	.long	0		# Illegal!
+
+/*
+ * Machine Check (Bus Errors, etc)
+ */
+MachineCheck:	
+	TRACE_TRAP(0x0200)
+	SAVE_INT_REGS(0x0200)
+	mr	r3,r1		/* Set pointer to saved regs */
+	bl	_EXTERN(MachineCheckException)
+	RETURN_FROM_INT(0x0200)
+
+/*
+ * Data Access exception
+ */
+DataAccess:
+	TRACE_TRAP(0x0300)
+	SAVE_INT_REGS(0x0300)
+	SAVE_PAGE_FAULT_REGS(0x0300)
+	BUMP(__Data_Page_Faults)
+	mr	r3,r1		/* Set pointer to saved regs */
+	bl	_EXTERN(DataAccessException)
+	RETURN_FROM_INT(0x0300)
+
+/*
+ * Instruction Access Exception
+ */
+InstructionAccess:
+	TRACE_TRAP(0x0400)
+	SAVE_INT_REGS(0x0400)
+	SAVE_PAGE_FAULT_REGS(0x0400)
+	BUMP(__Instruction_Page_Faults)
+	mr	r3,r1		/* Set pointer to saved regs */
+	bl	_EXTERN(InstructionAccessException)
+	bl	_EXTERN(flush_instruction_cache)
+	RETURN_FROM_INT(0x0400)
+
+/*
+ * Hardware Interrupt
+ */
+HardwareInterrupt:	
+	SAVE_INT_REGS(0x0500)
+	BUMP(__Hardware_Interrupts)
+	mr	r3,r1		/* Set pointer to saved regs */
+	bl	_EXTERN(handle_IRQ)
+	RETURN_FROM_INT(0x0500)
+
+/*
+ * Alignment
+ */
+Alignment:	
+	TRACE_TRAP(0x0600)
+	SAVE_INT_REGS(0x0600)
+	mr	r3,r1		/* Set pointer to saved regs */
+	bl	_EXTERN(AlignmentException)
+	RETURN_FROM_INT(0x0600)
+
+/*
+ * Illegal instruction
+ */
+ProgramCheck:
+	TRACE_TRAP(0x0700)
+	SAVE_INT_REGS(0x0700)
+	mr	r3,r1		/* Set pointer to saved regs */
+	bl	_EXTERN(ProgramCheckException)
+	RETURN_FROM_INT(0x0700)
+
+/*
+ * Floating point [not available, etc]
+ */
+FloatingPointCheck:	
+	TRACE_TRAP(0x0800)
+	SAVE_INT_REGS(0x0800)
+	mr	r3,r1		/* Set pointer to saved regs */
+	bl	_EXTERN(FloatingPointCheckException)
+	RETURN_FROM_INT(0x0200)
+
+/*
+ * System Call exception
+ */	
+SystemCall:
+	SAVE_INT_REGS(0x0C00)
+	lwz	r2,_CCR(r1)	/* Clear SO bit in CR */
+	lis	r9,0x1000
+	andc	r2,r2,r9
+	stw	r2,_CCR(r1)
+	cmpi	0,r0,0x7777	/* Special case for 'sys_sigreturn' */
+	bne+	10f
+	mr	r3,r1
+	bl	_EXTERN(sys_sigreturn)
+	cmpi	0,r3,0		/* Check for restarted system call */
+	bge	99f
+	b	20f
+10:	lis	r2,sys_call_table@h
+	ori	r2,r2,sys_call_table@l
+	slwi	r0,r0,2
+	lwzx	r2,r2,r0	/* Fetch system call handler [ptr] */
+ 
+	mtlr	r2
+	mr	r9,r1
+	blrl			/* Call handler */
+20:	stw	r3,RESULT(r1)	/* Save result */	
+	cmpi	0,r3,0
+	bge	30f
+	neg	r3,r3
+	lwz	r2,_CCR(r1)	/* Set SO bit in CR */
+	oris	r2,r2,0x1000
+	stw	r2,_CCR(r1)
+30:	stw	r3,GPR3(r1)	/* Update return value */
+99:
+	RETURN_FROM_INT(0x0C00)
+
+/*
+ * Handle TLB miss for instruction
+ */
+InstructionTLBMiss:
+	BUMP_UNMAPPED(__Instruction_TLB_Misses)
+#ifdef DO_TLB_TRACE
+	lis	r1,_TLB_ptr@h
+	ori	r1,r1,_TLB_ptr@l
+	lis	r2,0xF000
+	andc	r1,r1,r2
+	lwz	r1,0(r1)
+	andc	r1,r1,r2
+	subi	r1,r1,4
+	lis	r2,0xBEBE
+	ori	r2,r2,0x0100
+	stwu	r2,4(r1)
+	mfspr	r2,SRR0
+	stwu	r2,4(r1)
+	mfspr	r2,SRR1
+	stwu	r2,4(r1)
+	mfspr	r2,HASH1
+	stwu	r2,4(r1)
+	mfspr	r2,HASH2
+	stwu	r2,4(r1)
+	mfspr	r2,ICMP
+	stwu	r2,4(r1)
+	mfspr	r2,IMISS
+	stwu	r2,4(r1)
+	addi	r1,r1,4+(1*4)
+	lis	r3,_TLB_ptr@h
+	ori	r3,r3,_TLB_ptr@l
+	lis	r2,0xF000
+	andc	r3,r3,r2
+	stw	r1,0(r3)
+#endif	
+	mfctr	r0		/* Need to save this - CTR can't be touched! */
+	mfspr	r2,HASH1	/* Get PTE pointer */
+	mfspr	r3,ICMP		/* Partial item compare value */
+00:	li	r1,8		/* 8 items / bucket */
+	mtctr	r1
+	subi	r2,r2,8		/* Preset pointer */
+10:	lwzu	r1,8(r2)	/* Get next PTE */
+	cmp	0,r1,r3		/* Found entry yet? */
+	bdne	10b		/* Jump back if not, until CTR==0 */
+	bne	30f		/* Try secondary hash if CTR==0 */
+	lwz	r1,4(r2)	/* Get second word of entry */
+#if 0	
+	andi.	r3,r1,0x08	/* Check guard bit - invalid access if set */
+	bne	InstructionFetchError
+#endif	
+	andi.	r3,r1,0x100	/* Check R bit (referenced) */
+	bne	20f		/* If set, all done */
+	ori	r1,r1,0x100	/* Set bit */
+	stw	r1,4(r2)	/* Update memory image */
+20:	mtctr	r0		/* Restore CTR */
+	mfspr	r3,SRR1		/* Need to restore CR0 */
+	mtcrf	0x80,r3
+	mfspr	r0,IMISS	/* Set to update TLB */
+	mtspr	RPA,r1
+	tlbli	r0
+#if 0	
+	SYNC
+#endif
+	rfi			/* All done */
+/* Secondary hash */
+30:	andi.	r1,r3,0x40	/* Already doing secondary hash? */
+	bne	InstructionAddressInvalid /* Yes - item not in hash table */
+	mfspr	r2,HASH2	/* Get hash table pointer */
+	ori	r3,r3,0x40	/* Set secondary hash */
+	b	00b			/* Try lookup again */
+
+/*
+ * Handle TLB miss for DATA Load operation
+ */	
+DataLoadTLBMiss:
+	BUMP_UNMAPPED(__DataLoad_TLB_Misses)
+#ifdef DO_TLB_TRACE
+	lis	r1,_TLB_ptr@h
+	ori	r1,r1,_TLB_ptr@l
+	lis	r2,0xF000
+	andc	r1,r1,r2
+	lwz	r1,0(r1)
+	andc	r1,r1,r2
+	subi	r1,r1,4
+	lis	r2,0xBEBE
+	ori	r2,r2,0x0200
+	stwu	r2,4(r1)
+	mfspr	r2,SRR0
+	stwu	r2,4(r1)
+	mfspr	r2,SRR1
+	stwu	r2,4(r1)
+	mfspr	r2,HASH1
+	stwu	r2,4(r1)
+	mfspr	r2,HASH2
+	stwu	r2,4(r1)
+	mfspr	r2,DCMP
+	stwu	r2,4(r1)
+	mfspr	r2,DMISS
+	stwu	r2,4(r1)
+	addi	r1,r1,4+(1*4)
+	lis	r3,_TLB_ptr@h
+	ori	r3,r3,_TLB_ptr@l
+	lis	r2,0xF000
+	andc	r3,r3,r2
+	stw	r1,0(r3)
+#endif	
+	mfctr	r0		/* Need to save this - CTR can't be touched! */
+	mfspr	r2,HASH1	/* Get PTE pointer */
+	mfspr	r3,DCMP		/* Partial item compare value */
+00:	li	r1,8		/* 8 items / bucket */
+	mtctr	r1
+	subi	r2,r2,8		/* Preset pointer */
+10:	lwzu	r1,8(r2)	/* Get next PTE */
+	cmp	0,r1,r3		/* Found entry yet? */
+	bdne	10b		/* Jump back if not, until CTR==0 */
+	bne	30f		/* Try secondary hash if CTR==0 */
+	lwz	r1,4(r2)	/* Get second word of entry */
+	andi.	r3,r1,0x100	/* Check R bit (referenced) */
+	ori	r1,r1,0x100	/* Set bit */
+	bne	20f		/* If set, all done */
+	stw	r1,4(r2)	/* Update memory image */
+20:	mtctr	r0		/* Restore CTR */
+	mfspr	r3,SRR1		/* Need to restore CR0 */
+	mtcrf	0x80,r3
+	mfspr	r0,DMISS	/* Set to update TLB */
+	mtspr	RPA,r1
+/*	SYNC() */
+	tlbld	r0
+#if 0	
+	SYNC
+#endif	
+	rfi			/* All done */
+/* Secondary hash */
+30:	andi.	r1,r3,0x40	/* Already doing secondary hash? */
+	bne	DataAddressInvalid /* Yes - item not in hash table */
+	mfspr	r2,HASH2	/* Get hash table pointer */
+	ori	r3,r3,0x40	/* Set secondary hash */
+	b	00b			/* Try lookup again */
+
+/*
+ * Handle TLB miss for DATA STORE
+ */
+DataStoreTLBMiss:
+	BUMP_UNMAPPED(__DataStore_TLB_Misses)
+#ifdef DO_TLB_TRACE
+	lis	r1,_TLB_ptr@h
+	ori	r1,r1,_TLB_ptr@l
+	lis	r2,0xF000
+	andc	r1,r1,r2
+	lwz	r1,0(r1)
+	andc	r1,r1,r2
+	subi	r1,r1,4
+	lis	r2,0xBEBE
+	ori	r2,r2,0x0300
+	stwu	r2,4(r1)
+	mfspr	r2,SRR0
+	stwu	r2,4(r1)
+	mfspr	r2,SRR1
+	stwu	r2,4(r1)
+	mfspr	r2,HASH1
+	stwu	r2,4(r1)
+	mfspr	r2,HASH2
+	stwu	r2,4(r1)
+	mfspr	r2,DCMP
+	stwu	r2,4(r1)
+	mfspr	r2,DMISS
+	stwu	r2,4(r1)
+	addi	r1,r1,4+(1*4)
+	lis	r3,_TLB_ptr@h
+	ori	r3,r3,_TLB_ptr@l
+	lis	r2,0xF000
+	andc	r3,r3,r2
+	stw	r1,0(r3)
+#endif	
+	mfctr	r0		/* Need to save this - CTR can't be touched! */
+	mfspr	r2,HASH1	/* Get PTE pointer */
+	mfspr	r3,DCMP		/* Partial item compare value */
+00:	li	r1,8		/* 8 items / bucket */
+	mtctr	r1
+	subi	r2,r2,8		/* Preset pointer */
+10:	lwzu	r1,8(r2)	/* Get next PTE */
+	cmp	0,r1,r3		/* Found entry yet? */
+	bdne	10b		/* Jump back if not, until CTR==0 */
+	bne	30f		/* Try secondary hash if CTR==0 */
+	lwz	r1,4(r2)	/* Get second word of entry */
+	andi.	r3,r1,0x80	/* Check C bit (changed) */
+#if 0 /* Note: no validation */
+	beq	40f		/* If not set (first time) validate access */
+#else
+	ori	r1,r1,0x180	/* Set changed, accessed */
+	bne	20f
+	stw	r1,4(r2)
+#endif	
+20:	mtctr	r0		/* Restore CTR */
+	mfspr	r3,SRR1		/* Need to restore CR0 */
+	mtcrf	0x80,r3
+	mfspr	r0,DMISS	/* Set to update TLB */
+	mtspr	RPA,r1
+	tlbld	r0
+#if 0	
+	SYNC
+#endif	
+	rfi			/* All done */	
+/* Secondary hash */
+30:	andi.	r1,r3,0x40	/* Already doing secondary hash? */
+	bne	DataAddressInvalid /* Yes - item not in hash table */
+	mfspr	r2,HASH2	/* Get hash table pointer */
+	ori	r3,r3,0x40	/* Set secondary hash */
+	b	00b			/* Try lookup again */
+/* PTE found - validate access */
+40:	rlwinm. r3,r1,30,0,1	/* Extract PP bits */
+	bge-	50f		/* Jump if PP=0,1 */
+	andi.	r3,r1,1
+	beq+	70f		/* Access OK */
+	b	WriteProtectError	/* Not OK - fail! */
+50:	mfspr	r3,SRR1		/* Check privilege */
+	andi.	r3,r3,MSR_PR
+	beq+	60f		/* Jump if supervisor mode */
+	mfspr	r3,DMISS	/* Get address */
+	mfsrin	r3,r3		/* Get segment register */
+	andis.	r3,r3,0x2000	/* If Kp==0, OK */
+	beq+	70f
+	b	WriteProtectError	/* Bad access */
+60:	mfspr	r3,DMISS	/* Get address */
+	mfsrin	r3,r3		/* Get segment register */
+	andis.	r3,r3,0x4000	/* If Ks==0, OK */
+	beq+	70f
+	b	WriteProtectError	/* Bad access */
+70:	ori	r1,r1,0x180	/* Set changed, accessed */
+	stw	r1,4(r2)	/* Update PTE in memory */
+	b	20b
+	
+/*
+ * These routines are error paths/continuations of the exception
+ * handlers above.  They are placed here to avoid the problems
+ * of only 0x100 bytes per exception handler.
+ */
+ 
+/* Invalid address */
+InstructionAddressInvalid:
+	mfspr	r3,SRR1
+	rlwinm	r1,r3,9,6,6	/* Get load/store bit */
+	addis	r1,r1,0x4000	/* Set bit 1 -> PTE not found */
+	b	10f
+
+/* Fetch from guarded or no-access page */
+InstructionFetchError:
+	mfspr	r3,SRR1
+	rlwinm	r1,r3,9,6,6	/* Get load/store bit */
+	addis	r1,r1,0x0800	/* Set bit 4 -> protection error */
+10:	mtspr	DSISR,r1
+	mtctr	r0		/* Restore CTR */
+	andi.	r2,r3,0xFFFF	/* Clear upper bits of SRR1 */
+	mtspr	SRR1,r2
+	mfspr	r1,IMISS	/* Get failing address */
+	rlwinm.	r2,r2,0,31,31	/* Check for little endian access */
+	beq	20f		/* Jump if big endian */
+	xori	r1,r1,3
+20:	mtspr	DAR,r1		/* Set fault address */
+	mfmsr	r0		/* Restore "normal" registers */
+	xoris	r0,r0,MSR_TGPR>>16
+	mtcrf	0x80,r3		/* Restore CR0 */
+	ori	r0,r0,MSR_FP	/* Need to keep FP enabled */
+	mtmsr	r0
+	b	InstructionAccess
+
+/* Invalid address */
+DataAddressInvalid:
+	mfspr	r3,SRR1
+	rlwinm	r1,r3,9,6,6	/* Get load/store bit */
+	addis	r1,r1,0x4000	/* Set bit 1 -> PTE not found */
+	b	10f
+
+/* Write to read-only space */
+WriteProtectError:
+	mfspr	r3,SRR1
+	rlwinm	r1,r3,9,6,6	/* Get load/store bit */
+	addis	r1,r1,0x0800	/* Set bit 4 -> protection error */
+10:	mtspr	DSISR,r1
+	mtctr	r0		/* Restore CTR */
+	andi.	r2,r3,0xFFFF	/* Clear upper bits of SRR1 */
+	mtspr	SRR1,r2
+	mfspr	r1,DMISS	/* Get failing address */
+	rlwinm.	r2,r2,0,31,31	/* Check for little endian access */
+	beq	20f		/* Jump if big endian */
+	xori	r1,r1,3
+20:	mtspr	DAR,r1		/* Set fault address */
+	mfmsr	r0		/* Restore "normal" registers */
+	xoris	r0,r0,MSR_TGPR>>16
+	mtcrf	0x80,r3		/* Restore CR0 */
+	ori	r0,r0,MSR_FP	/* Need to keep FP enabled */
+	mtmsr	r0
+	b	DataAccess
+
+/*
+ * Flush instruction cache
+ * *** I'm really paranoid here!
+ */
+_GLOBAL(flush_instruction_cache)
+	mflr	r5
+	bl	_EXTERN(flush_data_cache)
+	mfspr	r3,HID0	/* Caches are controlled by this register */
+	li	r4,0
+	ori	r4,r4,(HID0_ICE|HID0_ICFI)
+	andc	r3,r3,r4
+	isync
+	mtspr	HID0,r3		/* Disable cache */
+	isync
+	ori	r3,r3,HID0_ICFI
+	isync
+	mtspr	HID0,r3		/* Invalidate cache */
+	isync
+	andc	r3,r3,r4
+	isync
+	mtspr	HID0,r3		/* Invalidate (step 2) */
+	isync
+	ori	r3,r3,HID0_ICE
+	isync
+	mtspr	HID0,r3		/* Enable cache */
+	isync
+	mtlr	r5
+	blr
+
+/*
+ * Flush data cache
+ * *** I'm really paranoid here!
+ */
+_GLOBAL(flush_data_cache)
+	BUMP(__Cache_Flushes)
+	lis	r3,cache_is_copyback@ha
+	lwz	r3,cache_is_copyback@l(r3)
+	cmpi	0,r3,0
+	beq	10f
+/* When DATA CACHE is copy-back */
+	lis	r3,cache_flush_buffer@h
+	ori	r3,r3,cache_flush_buffer@l
+	li	r4,NUM_CACHE_LINES
+	mtctr	r4
+00:	dcbz	0,r3			/* Flush cache line with minimal BUS traffic */
+	addi	r3,r3,CACHE_LINE_SIZE	/* Next line, please */
+	bdnz	00b	
+10:	blr
+	
+/*
+ * This routine switches between two different tasks.  The process
+ * state of one is saved on it's kernel stack.  Then the state
+ * of the other is restored from it's kernel stack.  The memory
+ * management hardware is updated to the second processes's state.
+ * Finally, we can return to the second process, via the 'return'.
+ *
+ * Note: there are two ways to get to the "going out" portion
+ * of this code; either by coming in via the entry (_switch)
+ * or via "fork" which must set up an environment equivalent
+ * to the "_switch" path.  If you change this (or in particular, the
+ * SAVE_REGS macro), you'll have to change the fork code also.
+ *
+ * The code which creates the new task context is in 'copy_thread'
+ * in arch/ppc/kernel/process.c
+ */	
+_GLOBAL(_switch)
+	mtspr	SPR0,r1		/* SAVE_REGS prologue */
+	mtspr	SPR1,r2
+	mflr	r2		/* Return to switch caller */
+	mtspr	SPR2,r2
+	mfmsr	r2
+	mtspr	SPR3,r2
+	SAVE_REGS(0x0FF0)
+	SYNC()
+	stw	r1,KSP(r3)	/* Set old stack pointer */
+	BUMP(__Context_Switches)
+	lwz	r1,KSP(r4)	/* Load new stack pointer */
+	CHECK_STACK()
+	lwz	r0,MMU_SEG0(r4)
+	mtsr	SR0,r0
+	lwz	r0,MMU_SEG1(r4)
+	mtsr	SR1,r0
+	lwz	r0,MMU_SEG2(r4)
+	mtsr	SR2,r0
+	lwz	r0,MMU_SEG3(r4)
+	mtsr	SR3,r0
+	lwz	r0,MMU_SEG4(r4)
+	mtsr	SR4,r0
+	lwz	r0,MMU_SEG5(r4)
+	mtsr	SR5,r0
+	lwz	r0,MMU_SEG6(r4)
+	mtsr	SR6,r0
+	lwz	r0,MMU_SEG7(r4)
+	mtsr	SR7,r0
+	lwz	r0,MMU_SEG8(r4)
+	mtsr	SR8,r0
+	lwz	r0,MMU_SEG9(r4)
+	mtsr	SR9,r0
+	lwz	r0,MMU_SEG10(r4)
+	mtsr	SR10,r0
+	lwz	r0,MMU_SEG11(r4)
+	mtsr	SR11,r0
+	lwz	r0,MMU_SEG12(r4)
+	mtsr	SR12,r0
+	lwz	r0,MMU_SEG13(r4)
+	mtsr	SR13,r0
+	lwz	r0,MMU_SEG14(r4)
+	mtsr	SR14,r0
+	lwz	r0,MMU_SEG15(r4)
+	mtsr	SR15,r0
+	tlbia				/* Invalidate entire TLB */
+	BUMP(__TLBIAs)
+#ifdef TLB_STATS
+/* TEMP */
+	lis	r2,DataLoadTLB_trace_ptr@h
+	ori	r2,r2,DataLoadTLB_trace_ptr@l
+	lis	r3,0x9000
+	lwz	r4,0(r2)
+	or	r4,r4,r3
+	li	r0,0
+	stw	r0,0(r4)
+	stw	r0,4(r4)
+	stw	r0,8(r4)
+	stw	r0,12(r4)
+	addi	r4,r4,4
+	cmpl	0,r4,r2
+	blt	00f
+	lis	r4,DataLoadTLB_trace_buf@h
+	ori	r4,r4,DataLoadTLB_trace_buf@l
+00:	stw	r4,0(r2)
+/* TEMP */	
+#endif
+	lwz	r2,_NIP(r1)	/* Force TLB/MMU hit */
+	lwz	r2,0(r2)
+	RETURN_FROM_INT(0xF000)
+	
+
+/*
+ * This routine is just here to keep GCC happy - sigh...
+ */	
+_GLOBAL(__main)
+	blr
+
+#ifdef DO_TRAP_TRACE
+check_trace:
+	sync				/* Force all writes out */
+	lwz	r2,-8(r1)
+	andi.	r2,r2,MSR_PR
+	bne	99f
+	lwz	r2,-32(r1)
+	lwz	r3,-16(r1)
+	cmp	0,r2,r3
+	bne	99f
+	andi.	r2,r2,0x7FFF
+	cmpi	0,r2,0x0C00
+	bge	99f
+	lwz	r2,-32+4(r1)
+	lwz	r3,-16+4(r1)
+	cmp	0,r2,r3
+	bne	99f
+	lwz	r2,-32+8(r1)
+	lwz	r3,-16+8(r1)
+	cmp	0,r2,r3
+	bne	99f
+	lwz	r2,-32(r1)
+	lwz	r3,-16(r1)
+	cmp	0,r2,r3
+	bne	99f
+	andi.	r2,r2,0x7FFF
+	cmpi	0,r2,0x0600
+	beq	00f
+	lwz	r2,-32+12(r1)
+	lwz	r3,-16+12(r1)
+	cmp	0,r2,r3
+	bne	99f
+00:	li	r2,0x7653
+	stw	r2,0(r1)
+	b	00b
+99:	blr
+#endif	
+
+	.data
+	.globl	sdata
+sdata:
+	.space	2*4096
+sys_stack:
+
+	.globl	empty_zero_page
+empty_zero_page:
+	.space	4096
+
+/*
+ * This space gets a copy of optional info passed to us by the bootstrap
+ * Used to pass parameters into the kernel like root=/dev/sda1, etc.
+ */	
+	.globl	cmd_line
+cmd_line:
+	.space	512	
+
+#ifdef STATS	
+/*
+ * Miscellaneous statistics - gathered just for performance info
+ */
+
+ 	.globl	_INTR_stats
+_INTR_stats:
+__Instruction_TLB_Misses:
+	.long	0,0	/* Instruction TLB misses */
+__DataLoad_TLB_Misses:
+	.long	0,0	/* Data [load] TLB misses */
+__DataStore_TLB_Misses:
+	.long	0,0	/* Data [store] TLB misses */
+__Instruction_Page_Faults:	
+	.long	0,0	/* Instruction page faults */
+__Data_Page_Faults:	
+	.long	0,0	/* Data page faults */
+__Cache_Flushes:	
+	.long	0,0	/* Explicit cache flushes */
+__Context_Switches:	
+	.long	0,0	/* Context switches */
+__Hardware_Interrupts:	
+	.long	0,0	/* I/O interrupts (disk, timer, etc) */
+	.globl	__TLBIAs
+__TLBIAs:
+	.long	0,0	/* TLB cache forceably flushed */
+	.globl	__TLBIEs
+__TLBIEs:
+	.long	0,0	/* Specific TLB entry flushed */	
+#endif
+
+/*
+ * This location is used to break any outstanding "lock"s when
+ * changing contexts.
+ */
+_break_lwarx:	.long	0
+
+/*
+ * Various trace buffers
+ */	
+#ifdef DO_TRAP_TRACE
+	.data
+_TRAP_TRACE: .space	32*1024
+_TRAP_ptr:   .long	_TRAP_TRACE
+	.text
+#endif
+
+#ifdef DO_TLB_TRACE
+	.data
+_TLB_TRACE: .space	128*1024
+_TLB_ptr:   .long	_TLB_TRACE
+	.text
+#endif
+
+#ifdef DO_RFI_TRACE
+	.data
+_RFI_DATA: .space	128*1024
+_RFI_ptr:  .long	_RFI_DATA
+	.text	
+#endif
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/irq.c linux/arch/ppc/kernel/irq.c
--- v1.3.44/linux/arch/ppc/kernel/irq.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/irq.c	Mon Oct 30 21:21:45 1995
@@ -0,0 +1,383 @@
+/*
+ *	linux/arch/ppc/kernel/irq.c
+ *
+ *	Copyright (C) 1992 Linus Torvalds
+ *      Adapted from arch/i386 by Gary Thomas
+ *
+ * This file contains the code used by various IRQ handling routines:
+ * asking for different IRQ's should be done through these routines
+ * instead of just grabbing them. Thus setups with different IRQ numbers
+ * shouldn't result in any weird surprises, and installing new handlers
+ * should be easier.
+ */
+
+/*
+ * IRQ's are in fact implemented a bit like signal handlers for the kernel.
+ * Naturally it's not a 1:1 relation, but there are similarities.
+ */
+
+#include <linux/ptrace.h>
+#include <linux/errno.h>
+#include <linux/kernel_stat.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <linux/interrupt.h>
+#include <linux/timex.h>
+
+#include <asm/system.h>
+#include <asm/io.h>
+#include <asm/irq.h>
+#include <asm/bitops.h>
+
+#define CR0_NE 32
+
+static unsigned char cache_21 = 0xff;
+static unsigned char cache_A1 = 0xff;
+
+void disable_irq(unsigned int irq_nr)
+{
+	unsigned char mask;
+	int s = _disable_interrupts();
+
+	mask = 1 << (irq_nr & 7);
+	if (irq_nr < 8) {
+		cache_21 |= mask;
+		outb(cache_21,0x21);
+		_enable_interrupts(s);
+		return;
+	}
+	cache_A1 |= mask;
+	outb(cache_A1,0xA1);
+	_enable_interrupts(s);
+}
+
+void enable_irq(unsigned int irq_nr)
+{
+	unsigned char mask;
+	int s = _disable_interrupts();
+
+	mask = ~(1 << (irq_nr & 7));
+	if (irq_nr < 8) {
+		cache_21 &= mask;
+		outb(cache_21,0x21);
+		_enable_interrupts(s);
+		return;
+	}
+	cache_A1 &= mask;
+	outb(cache_A1,0xA1);
+	_enable_interrupts(s);
+}
+
+/*
+ * Irq handlers.
+ */
+struct irqaction {
+	void (*handler)(int, struct pt_regs *);
+	unsigned long flags;
+	unsigned long mask;
+	const char *name;
+	int notified;
+};
+
+static struct irqaction irq_action[16] = {
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL },
+	{ NULL, 0, 0, NULL }, { NULL, 0, 0, NULL }
+};
+
+int get_irq_list(char *buf)
+{
+	int i, len = 0;
+	struct irqaction * action = irq_action;
+
+	for (i = 0 ; i < 16 ; i++, action++) {
+		if (!action->handler)
+			continue;
+		len += sprintf(buf+len, "%2d: %8d %c %s\n",
+			i, kstat.interrupts[i],
+			(action->flags & SA_INTERRUPT) ? '+' : ' ',
+			action->name);
+	}
+	return len;
+}
+
+asmlinkage void handle_IRQ(struct pt_regs *regs)
+{
+	int irq, s;
+	struct irqaction *action;
+	intr_count++;
+	/* Figure out IRQ#, etc. */
+	outb(0x0C, 0x20);  /* Poll interrupt controller */
+	irq = inb(0x20);
+	irq &= 0x07;  /* Caution! */
+	if (irq == 2)
+	{ /* Cascaded interrupt -> IRQ8..IRQ15 */
+		outb(0x0C, 0xA0);
+		irq = inb(0xA0) & 0x07;
+		irq += 8;
+	}
+	/* Mask interrupt & Issue EOI to interrupt controller */
+	if (irq > 7)
+	{
+		outb(cache_A1 | (1<<(irq-7)), 0xA1);
+		outb(0x20, 0xA0);
+		/* Need to ack cascade controller as well */
+		outb(0x20, 0x20);
+	} else
+	{
+		outb(cache_21 | (1<<irq), 0x21);
+		outb(0x20, 0x20);
+	}
+	action = irq + irq_action;
+	kstat.interrupts[irq]++;
+	if (action->handler)
+	{
+		action->handler(irq, regs);
+	} else
+	{
+		_printk("Bogus interrupt #%d\n", irq);
+	}
+	if (_disable_interrupts() && !action->notified)
+	{
+		action->notified = 1;
+		printk("*** WARNING! %s handler [IRQ %d] turned interrupts on!\n", action->name, irq);
+	}
+	/* Re-enable interrupt */
+	if (irq > 7)
+	{
+		outb(cache_A1, 0xA1);
+	} else
+	{
+		outb(cache_21, 0x21);
+	}
+	intr_count--;
+}
+
+/*
+ * This routine gets called when the SCSI times out on an operation.
+ * I don't know why this happens, but every so often it does and it
+ * seems to be a problem with the interrupt controller [state].  It
+ * happens a lot when there is also network activity (both devices
+ * are on the PCI bus with interrupts on the cascaded controller).
+ * Re-initializing the interrupt controller [which might lose some
+ * pending edge detected interrupts] seems to fix it.
+ */
+void check_irq(void )
+{
+	int s = _disable_interrupts();
+	unsigned char _a0, _a1, _20, _21;
+	_a1 = inb(0xA1);
+	_21 = inb(0x21);
+	outb(0x0C, 0x20);  _20 = inb(0x20);	
+	outb(0x0C, 0xA0);  _a0 = inb(0xA0);
+#if 0	
+	printk("IRQ 0x20 = %x, 0x21 = %x/%x, 0xA0 = %x, 0xA1 = %x/%x\n",
+		_20, _21, cache_21, _a0, _a1, cache_A1);
+#endif		
+	/* Reset interrupt controller - see if this fixes it! */
+	/* Initialize interrupt controllers */
+	outb(0x11, 0x20); /* Start init sequence */
+	outb(0x40, 0x21); /* Vector base */
+	outb(0x04, 0x21); /* Cascade (slave) on IRQ2 */
+	outb(0x01, 0x21); /* Select 8086 mode */
+	outb(0xFF, 0x21); /* Mask all */
+	outb(0x00, 0x4D0); /* All edge triggered */
+	outb(0x11, 0xA0); /* Start init sequence */
+	outb(0x48, 0xA1); /* Vector base */
+	outb(0x02, 0xA1); /* Cascade (slave) on IRQ2 */
+	outb(0x01, 0xA1); /* Select 8086 mode */
+	outb(0xFF, 0xA1); /* Mask all */
+	outb(0xCF, 0x4D1); /* Trigger mode */
+	outb(cache_A1, 0xA1);
+	outb(cache_21, 0x21);
+	enable_irq(2);  /* Enable cascade interrupt */
+	_enable_interrupts(s);
+}
+
+#define SA_PROBE SA_ONESHOT
+
+int request_irq(unsigned int irq, void (*handler)(int, struct pt_regs *),
+	unsigned long irqflags, const char * devname)
+{
+	struct irqaction * action;
+	unsigned long flags;
+
+#if 0
+_printk("Request IRQ #%d, Handler: %x\n", irq, handler);
+cnpause();
+#endif
+	if (irq > 15)
+		return -EINVAL;
+	action = irq + irq_action;
+	if (action->handler)
+		return -EBUSY;
+	if (!handler)
+		return -EINVAL;
+	save_flags(flags);
+	cli();
+	action->handler = handler;
+	action->flags = irqflags;
+	action->mask = 0;
+	action->name = devname;
+#if 0	
+	if (!(action->flags & SA_PROBE)) { /* SA_ONESHOT is used by probing */
+		if (action->flags & SA_INTERRUPT)
+			set_intr_gate(0x20+irq,fast_interrupt[irq]);
+		else
+			set_intr_gate(0x20+irq,interrupt[irq]);
+	}
+#endif	
+	if (irq < 8) {
+		cache_21 &= ~(1<<irq);
+		outb(cache_21,0x21);
+	} else {
+		cache_21 &= ~(1<<2);
+		cache_A1 &= ~(1<<(irq-8));
+		outb(cache_21,0x21);
+		outb(cache_A1,0xA1);
+	}
+	restore_flags(flags);
+	return 0;
+}
+		
+void free_irq(unsigned int irq)
+{
+	struct irqaction * action = irq + irq_action;
+	unsigned long flags;
+
+	if (irq > 15) {
+		printk("Trying to free IRQ%d\n",irq);
+		return;
+	}
+	if (!action->handler) {
+		printk("Trying to free free IRQ%d\n",irq);
+		return;
+	}
+	save_flags(flags);
+	cli();
+	if (irq < 8) {
+		cache_21 |= 1 << irq;
+		outb(cache_21,0x21);
+	} else {
+		cache_A1 |= 1 << (irq-8);
+		outb(cache_A1,0xA1);
+	}
+#if 0	
+	set_intr_gate(0x20+irq,bad_interrupt[irq]);
+#endif	
+	action->handler = NULL;
+	action->flags = 0;
+	action->mask = 0;
+	action->name = NULL;
+	restore_flags(flags);
+}
+
+static void no_action(int cpl, struct pt_regs * regs) { }
+
+unsigned /*int*/ long probe_irq_on (void)
+{
+	unsigned int i, irqs = 0, irqmask;
+	unsigned long delay;
+
+	/* first, snaffle up any unassigned irqs */
+	for (i = 15; i > 0; i--) {
+		if (!request_irq(i, no_action, SA_PROBE, "probe")) {
+			enable_irq(i);
+			irqs |= (1 << i);
+		}
+	}
+
+	/* wait for spurious interrupts to mask themselves out again */
+	for (delay = jiffies + 2; delay > jiffies; );	/* min 10ms delay */
+
+	/* now filter out any obviously spurious interrupts */
+	irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21;
+	for (i = 15; i > 0; i--) {
+		if (irqs & (1 << i) & irqmask) {
+			irqs ^= (1 << i);
+			free_irq(i);
+		}
+	}
+#ifdef DEBUG
+	printk("probe_irq_on:  irqs=0x%04x irqmask=0x%04x\n", irqs, irqmask);
+#endif
+	return irqs;
+}
+
+int probe_irq_off (unsigned /*int*/ long irqs)
+{
+	unsigned int i, irqmask;
+
+	irqmask = (((unsigned int)cache_A1)<<8) | (unsigned int)cache_21;
+	for (i = 15; i > 0; i--) {
+		if (irqs & (1 << i)) {
+			free_irq(i);
+		}
+	}
+#ifdef DEBUG
+	printk("probe_irq_off: irqs=0x%04x irqmask=0x%04x\n", irqs, irqmask);
+#endif
+	irqs &= irqmask;
+	if (!irqs)
+		return 0;
+	i = ffz(~irqs);
+	if (irqs != (irqs & (1 << i)))
+		i = -i;
+	return i;
+}
+
+void init_IRQ(void)
+{
+	unsigned long *vme2_ie  = (unsigned long *)0xFEFF006C;
+	unsigned long *vme2_ic  = (unsigned long *)0xFEFF0074;
+	unsigned long *vme2_il2 = (unsigned long *)0xFEFF007C;
+	unsigned long *vme2_ioc = (unsigned long *)0xFEFF0088;
+	unsigned char *vme2pci_ic = (unsigned char *)0x80802050;
+	unsigned char *ibc_pirq = (unsigned char *)0x80800860;
+	unsigned char *ibc_pcicon = (unsigned char *)0x80800840;
+	int i;
+
+	/* set the clock to 100 Hz */
+	outb_p(0x34,0x43);		/* binary, mode 2, LSB/MSB, ch 0 */
+	outb_p(LATCH & 0xff , 0x40);	/* LSB */
+	outb(LATCH >> 8 , 0x40);	/* MSB */
+	if (request_irq(2, no_action, SA_INTERRUPT, "cascade"))
+		printk("Unable to get IRQ2 for cascade\n");
+	request_region(0x20,0x20,"pic1");
+	request_region(0xa0,0x20,"pic2");
+#if 0	
+	/* Enable SIG0 */
+	*vme2_ie = (*vme2_ie & 0xFFFBFFFF) | 0x00040000;
+	/* Clear any pending interrupts */
+	*vme2_ic = 0xFFFFFFFF;
+	/* SIG0 -> Level 5 */
+	*vme2_il2 = (*vme2_il2 & 0xFFFFF0FF) | 0x00000500;
+	/* Master interrupt enable */
+	*vme2_ioc |= 0x00800000;
+#endif	
+	/* Enable interrupts from VMECHIP */
+	*vme2pci_ic |= 0x08;
+	/* Route PCI interrupts */
+	ibc_pirq[0] = 0x0A;  /* PIRQ0 -> ISA10 */
+	ibc_pirq[1] = 0x0B;  /* PIRQ1 -> ISA11 */
+	ibc_pirq[2] = 0x0E;  /* PIRQ2 -> ISA14 */
+	ibc_pirq[3] = 0x0F;  /* PIRQ3 -> ISA15 */
+	/* Enable PCI interrupts */
+	*ibc_pcicon |= 0x20;
+} 
+
+PCI_irq(int irq)
+{
+	static short _irq[] = {10, 11, 14, 15};
+	int res = _irq[(irq-1)&0x03];
+#if 0	
+	_printk("PCI IRQ #%d = %d\n", irq, res);
+#endif	
+	return (res);
+}
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/ld.script-user linux/arch/ppc/kernel/ld.script-user
--- v1.3.44/linux/arch/ppc/kernel/ld.script-user	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/ld.script-user	Thu Oct 26 03:34:24 1995
@@ -0,0 +1,74 @@
+OUTPUT_ARCH(powerpc)
+SEARCH_DIR(/usr/local/lib/gcc-lib/powerpc-linux-elf/2.7.0/);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+  .init          : { *(.init)	} =0
+  .plt : { *(.plt) }
+  .text      :
+  {
+    *(.text)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+  .rodata    : { *(.rodata)  }
+  .rodata1   : { *(.rodata1) }
+  /* Read-write section, merged into data segment: */
+/*  . = (. + 0x0FFF) & 0xFFFFF000; */
+  .data    :
+  {
+    *(.data)
+    CONSTRUCTORS
+  }
+  .data1   : { *(.data1) }
+  .got           : { *(.got.plt) *(.got) }
+  .dynamic       : { *(.dynamic) }
+  /* We want the small data sections together, so single-instruction offsets
+     can access them all, and initialized data all before uninitialized, so
+     we can shorten the on-disk segment size.  */
+  .sdata     : { *(.sdata) }
+  _edata  =  .;
+  PROVIDE (edata = .);
+  __bss_start = .;
+  .sbss      : { *(.sbss) *(.scommon) }
+  .bss       :
+  {
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+  /* These are needed for ELF backends which have not yet been
+     converted to the new style linker.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  /* These must appear regardless of  .  */
+}
+
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/misc.S linux/arch/ppc/kernel/misc.S
--- v1.3.44/linux/arch/ppc/kernel/misc.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/misc.S	Fri Nov 17 23:37:02 1995
@@ -0,0 +1,626 @@
+/*
+ * This module contains the PowerPC interrupt fielders
+ * set of code at specific locations, based on function
+ */
+
+#include <linux/sys.h>
+#include "ppc_asm.tmpl"
+
+/* Keep track of low-level exceptions - rather crude, but informative */	
+#define STATS
+
+/*
+ * Increment a [64 bit] statistic counter
+ * Uses R2, R3
+ */
+#define BUMP(ctr) \
+	lis	r2,ctr@h; \
+	ori	r2,r2,ctr@l; \
+	lwz	r3,4(r2); \
+	addic	r3,r3,1; \
+	stw	r3,4(r2); \
+	lwz	r3,0(r2); \
+	addze	r3,r3; \
+	stw	r3,0(r2)
+
+/* This instruction is not implemented on the PPC 603 */
+#define tlbia \
+	li	r4,32; \
+	mtspr	CTR,r4; \
+	li	r4,0; \
+0:	tlbie	r4; \
+	addi	r4,r4,0x1000; \
+	bdnz	0b
+	
+_TEXT()
+
+/*
+ * Disable interrupts
+ *	rc = _disable_interrupts()
+ */
+_GLOBAL(_disable_interrupts)
+	mfmsr	r0		/* Get current interrupt state */
+	rlwinm	r3,r0,16+1,32-1,31	/* Extract old value of 'EE' */
+	li	r4,0		/* Need [unsigned] value of MSR_EE */
+	ori	r4,r4,MSR_EE	/* Set to turn off bit */
+	andc	r0,r0,r4	/* Clears bit in (r4) */
+	mtmsr	r0		/* Update machine state */
+	blr			/* Done */
+
+/*
+ * Enable interrupts
+ *	_enable_interrupts(int state)
+ * turns on interrupts if state = 1.
+ */
+_GLOBAL(_enable_interrupts)
+	mfmsr	r0		/* Get current state */
+	rlwimi	r0,r3,16-1,32-16,32-16	/* Insert bit */
+	mtmsr	r0		/* Update machine state */
+	blr
+
+/*
+ * Get 'flags' (aka machine status register)
+ *	__save_flags(long *ptr)
+ */
+_GLOBAL(__save_flags)
+	mfmsr	r0		/* Get current state */
+	stw	r0,0(r3)
+	mr	r3,r0
+	blr
+
+/*
+ * Restore 'flags'
+ *	__restore_flags(long val)
+ */
+_GLOBAL(__restore_flags)
+	mtmsr	r3
+	isync
+	blr
+
+/*
+ * Disable interrupts - like an 80x86
+ *	cli()
+ */
+_GLOBAL(cli)
+	mfmsr	r0		/* Get current interrupt state */
+	rlwinm	r3,r0,16+1,32-1,31	/* Extract old value of 'EE' */
+	li	r4,0		/* Need [unsigned] value of MSR_EE */
+	ori	r4,r4,MSR_EE	/* Set to turn off bit */
+	andc	r0,r0,r4	/* Clears bit in (r4) */
+	mtmsr	r0		/* Update machine state */
+	blr			/* Done */
+
+/*
+ * Enable interrupts - like an 80x86
+ *	sti()
+ */
+_GLOBAL(sti)
+	mfmsr	r0		/* Get current state */
+	ori	r0,r0,MSR_EE	/* Turn on 'EE' bit */
+	mtmsr	r0		/* Update machine state */
+	blr
+
+/*
+ * Flush MMU TLB
+ */
+_GLOBAL(_tlbia)
+	tlbia
+	BUMP(__TLBIAs)
+	blr	
+
+/*
+ * Flush MMU TLB for a particular address
+ */
+_GLOBAL(_tlbie)
+	tlbie	r3
+	BUMP(__TLBIEs)
+	blr	
+
+/*
+ * Atomic [test&set] exchange
+ *
+ *	void *xchg_u32(void *ptr, unsigned long val)
+ * Changes the memory location '*ptr' to be val and returns
+ * the previous value stored there.
+ */
+_GLOBAL(xchg_u32)
+	mr	r5,r3		/* Save pointer */
+10:	lwarx	r3,0,r5		/* Fetch old value & reserve */
+	stwcx.	r4,0,r5		/* Update with new value */
+	bne-	10b		/* Retry if "reservation" (i.e. lock) lost */
+	blr
+
+/*
+ * Delay for a specific # of "loops"
+ *	__delay(int loops)
+ */
+_GLOBAL(__delay)
+	mtctr	r3
+00:	addi	r3,r3,0		/* NOP */
+	bdnz	00b
+	blr
+
+/*
+ * Delay for a number of microseconds
+ *	udelay(int usecs)
+ */
+_GLOBAL(udelay)
+00:	li	r0,86	/* Instructions / microsecond? */
+	mtctr	r0
+10:	addi	r0,r0,0 /* NOP */
+	bdnz	10b
+	subic.	r3,r3,1
+	bne	00b
+	blr
+
+/*
+ * Atomically increment [intr_count]
+ */
+_GLOBAL(start_bh_atomic)
+	lis	r3,intr_count@h
+	ori	r3,r3,intr_count@l
+10:	lwarx	r4,0,r3
+	addi	r4,r4,1
+	stwcx.	r4,0,r3
+	bne-	10b
+	blr
+
+/*
+ * Atomically decrement [intr_count]
+ */
+_GLOBAL(end_bh_atomic)
+	lis	r3,intr_count@h
+	ori	r3,r3,intr_count@l
+10:	lwarx	r4,0,r3
+	subic	r4,r4,1
+	stwcx.	r4,0,r3
+	bne-	10b
+	blr
+
+/*
+ *extern inline int find_first_zero_bit(void * vaddr, unsigned size)
+ *{
+ *	unsigned long res;
+ *	unsigned long *p;
+ *	unsigned long *addr = vaddr;
+ *
+ *	if (!size)
+ *		return 0;
+ *	__asm__ __volatile__ ("    moveq #-1,d0\n\t"
+ *			      "1:"
+ *			      "    cmpl  %1@+,d0\n\t"
+ *			      "    bne   2f\n\t"
+ *			      "    subql #1,%0\n\t"
+ *			      "    bne   1b\n\t"
+ *			      "    bra   5f\n\t"
+ *			      "2:"
+ *			      "    movel %1@-,d0\n\t"
+ *			      "    notl  d0\n\t"
+ *			      "    bfffo d0{#0,#0},%0\n\t"
+ *			      "5:"
+ *			      : "=d" (res), "=a" (p)
+ *			      : "0" ((size + 31) >> 5), "1" (addr)
+ *			      : "d0");
+ *	return ((p - addr) << 5) + res;
+ *}
+ */
+_GLOBAL(find_first_zero_bit)
+	li	r5,0		/* bit # */
+	subi	r3,r3,4		/* Adjust pointer for auto-increment */
+00:	lwzu	r0,4(r3)	/* Get next word */
+	not.	r7,r0		/* Complement to find ones */
+	beq	10f		/* Jump if all ones */
+02:	andi.	r7,r0,1		/* Check low-order bit */
+	beq	20f		/* All done when zero found */
+	srawi	r0,r0,1
+	addi	r5,r5,1
+	b	02b
+10:	addi	r5,r5,32	/* Update bit # */
+	subic.	r4,r4,32	/* Any more? */
+	bgt	00b
+20:	mr	r3,r5		/* Compute result */	
+	blr
+ 
+/*
+ *static inline int find_next_zero_bit (void *vaddr, int size,
+ *				      int offset)
+ *{
+ *	unsigned long *addr = vaddr;
+ *	unsigned long *p = addr + (offset >> 5);
+ *	int set = 0, bit = offset & 31, res;
+ *
+ *	if (bit) {
+ *		// Look for zero in first longword 
+ *		__asm__("bfffo %1{#0,#0},%0"
+ *			: "=d" (set)
+ *			: "d" (~*p << bit));
+ *		if (set < (32 - bit))
+ *			return set + offset;
+ *                set = 32 - bit;
+ *		p++;
+ *	}
+ *	// No zero yet, search remaining full bytes for a zero 
+ *	res = find_first_zero_bit (p, size - 32 * (p - addr));
+ *	return (offset + set + res);
+ *}
+ */
+_GLOBAL(find_next_zero_bit)
+	addi	r5,r5,1		/* bump offset to start */
+	srawi	r6,r5,5		/* word offset */
+	add	r6,r6,r6	/* byte offset */
+	add	r6,r6,r6	/* byte offset */
+	add	r3,r3,r6	/* compute byte position */
+	sub	r4,r4,r5	/* adjust size by starting index */
+	andi.	r0,r5,0x1F	/* offset in current word? */
+	beq	10f		/* at start of word */
+	lwz	r0,0(r3)	/* get word */
+	sraw	r0,r0,r5	/* shift right */
+	not.	r7,r0
+	beq	07f		/* jump if only ones remain */
+05:	andi.	r7,r0,1		/* found zero? */
+	beq	90f		/* yes - all done */
+	srawi	r0,r0,1
+	addi	r5,r5,1
+	b	05b
+07:	andi.	r6,r5,0x1F
+	subfic	r0,r6,32
+	add	r5,r5,r0
+	sub	r4,r4,r0
+	b	20f
+10:	subi	r3,r3,4		/* Adjust pointer for auto-increment */
+20:	lwzu	r0,4(r3)	/* Get next word */
+	not.	r7,r0		/* Complement to find ones */
+	beq	40f		/* Jump if all ones */
+30:	andi.	r7,r0,1		/* Check low-order bit */
+	beq	90f		/* All done when zero found */
+	srawi	r0,r0,1
+	addi	r5,r5,1
+	b	30b
+40:	addi	r5,r5,32	/* Update bit # */
+	subic.	r4,r4,32	/* Any more? */
+	bgt	20b
+90:	mr	r3,r5		/* Compute result */	
+	blr
+ 
+/*
+ *
+ * ffz = Find First Zero in word. Undefined if no zero exists,
+ * so code should check against ~0UL first..
+ *
+ *extern inline unsigned long ffz(unsigned long word)
+ *{
+ *	__asm__ __volatile__ ("bfffo %1{#0,#0},%0"
+ *			      : "=d" (word)
+ *			      : "d" (~(word)));
+ *	return word;
+ *}
+ */
+_GLOBAL(ffz)
+	mr	r4,r3
+	li	r3,0
+10:	andi.	r0,r4,1		/* Find the zero we know is there */
+	srawi	r4,r4,1
+	beq	90f
+	addi	r3,r3,1
+	b	10b
+90:	blr
+
+/*
+ * Extended precision shifts
+ *
+ * R3/R4 has 64 bit value
+ * R5    has shift count
+ * result in R3/R4
+ *
+ *  ashrdi3:     XXXYYY/ZZZAAA -> SSSXXX/YYYZZZ
+ *  ashldi3:     XXXYYY/ZZZAAA -> YYYZZZ/AAA000
+ */
+_GLOBAL(__ashrdi3)
+	li	r6,32
+	sub	r6,r6,r5
+	slw	r7,r3,r6	/* isolate YYY */
+	srw	r4,r4,r5	/* isolate ZZZ */
+	or	r4,r4,r7	/* YYYZZZ */
+	sraw	r3,r3,r5	/* SSSXXX */
+	blr
+	
+_GLOBAL(__ashldi3)
+	li	r6,32
+	sub	r6,r6,r5
+	srw	r7,r4,r6	/* isolate ZZZ */
+	slw	r4,r4,r5	/* AAA000 */
+	slw	r3,r3,r5	/* YYY--- */
+	or	r3,r3,r7	/* YYYZZZ */
+	blr
+	
+_GLOBAL(abort)
+	.long	0
+
+_GLOBAL(bzero)
+#define bufp r3
+#define len  r4
+#define pat  r5
+/* R3 has buffer */
+/* R4 has length */
+/* R5 has pattern */
+	cmpi	0,len,0		/* Exit if len <= 0 */
+	ble	99f
+	andi.	r0,bufp,3	/* Must be on longword boundary */
+	bne	10f		/* Use byte loop if not aligned */
+	andi.	r0,len,3	/* Check for overrage */
+	subi	bufp,bufp,4	/* Adjust pointer */
+	srawi	len,len,2	/* Divide by 4 */
+	blt	99f		/* If negative - bug out! */
+	mtspr	CTR,len		/* Set up counter */
+	li	pat,0
+00:	stwu	pat,4(bufp)	/* Store value */
+	bdnz	00b		/* Loop [based on counter] */
+	mr	len,r0		/* Get remainder (bytes) */
+10:	cmpi	0,len,0		/* Any bytes left */
+	ble	99f		/* No - all done */
+	mtspr	CTR,len		/* Set up counter */
+	subi	bufp,bufp,1	/* Adjust pointer */
+	li	pat,0
+20:	stbu	pat,1(bufp)	/* Store value */
+	bdnz	20b		/* Loop [based on counter] */
+99:	blr
+
+_GLOBAL(abs)
+	cmpi	0,r3,0
+	bge	10f
+	neg	r3,r3
+10:	blr
+
+/*
+ * Compute IP checksums
+ *   _ip_fast_csum(buf, len) -- Optimized for IP header
+ *   _ip_compute_csum(buf, len)
+ */
+
+_GLOBAL(_ip_fast_csum)
+	li	r0,0
+	addic	r0,r0,0		/* Clear initial carry */
+	lwz	r4,0(r3)
+	lwz	r5,4(r3)
+	adde	r0,r0,r4
+	lwz	r4,8(r3)
+	adde	r0,r0,r5
+	lwz	r5,12(r3)
+	adde	r0,r0,r4
+	lwz	r4,16(r3)
+	adde	r0,r0,r5
+	adde	r0,r0,r4
+	mr	r3,r0
+	andi.	r3,r3,0xFFFF
+	srwi	r0,r0,16
+	adde	r3,r3,r0
+	andis.	r0,r3,1
+	beq	10f
+	addi	r3,r3,1
+10:	not	r3,r3
+	andi.	r3,r3,0xFFFF
+	blr
+
+_GLOBAL(_ip_compute_csum)
+	li	r0,0
+	addic	r0,r0,0
+finish_ip_csum:	
+	subi	r3,r3,4
+	andi.	r5,r3,2		/* Align buffer to longword boundary */
+	beq	10f
+	lhz	r5,4(r3)
+	adde	r0,r0,r5
+	addi	r3,r3,2
+	subi	r4,r4,2
+10:	cmpi	0,r4,16		/* unrolled loop - 16 bytes at a time */
+	blt	20f
+	lwz	r5,4(r3)
+	lwz	r6,8(r3)
+	adde	r0,r0,r5
+	lwz	r5,12(r3)
+	adde	r0,r0,r6
+	lwzu	r6,16(r3)
+	adde	r0,r0,r5
+	adde	r0,r0,r6
+	subi	r4,r4,16
+	b	10b
+20:	cmpi	0,r4,4
+	blt	30f
+	lwzu	r5,4(r3)
+	adde	r0,r0,r5
+	subi	r4,r4,4
+	b	20b
+30:	cmpi	0,r4,2
+	blt	40f
+	lhz	r5,4(r3)
+	addi	r3,r3,2
+	adde	r0,r0,r5
+	subi	r4,r4,2
+40:	cmpi	0,r4,1
+	bne	50f
+	lbz	r5,4(r3)
+	slwi	r5,r5,8		/* Upper byte of word */
+	adde	r0,r0,r5
+50:	mr	r3,r0
+	andi.	r3,r3,0xFFFF
+	srwi	r0,r0,16
+	adde	r3,r3,r0
+	andis.	r0,r3,1
+	beq	60f
+	addi	r3,r3,1
+60:	not	r3,r3
+	andi.	r3,r3,0xFFFF
+	blr
+
+_GLOBAL(_udp_check)
+	addc	r0,r5,r6	/* Add in header fields */
+	adde	r0,r0,r7
+	b	finish_ip_csum	
+#if 0
+_GLOBAL(_tcp_check)
+	addc	r0,r5,r6	/* Add in header fields */
+	adde	r0,r0,r7
+	b	finish_ip_csum	
+#endif
+_GLOBAL(_get_SP)
+	mr	r3,r1		/* Close enough */
+	blr	
+
+/* Why isn't this a) automatic, b) written in 'C'? */	
+	.data
+	.align 4
+	.globl	sys_call_table
+sys_call_table:
+	.long sys_setup		/* 0 */
+	.long sys_exit
+	.long sys_fork
+	.long sys_read
+	.long sys_write
+	.long sys_open			/* 5 */
+	.long sys_close
+	.long sys_waitpid
+	.long sys_creat
+	.long sys_link
+	.long sys_unlink		/* 10 */
+	.long sys_execve
+	.long sys_chdir
+	.long sys_time
+	.long sys_mknod
+	.long sys_chmod		/* 15 */
+	.long sys_chown
+	.long sys_break
+	.long sys_stat
+	.long sys_lseek
+	.long sys_getpid		/* 20 */
+	.long sys_mount
+	.long sys_umount
+	.long sys_setuid
+	.long sys_getuid
+	.long sys_stime		/* 25 */
+	.long sys_ptrace
+	.long sys_alarm
+	.long sys_fstat
+	.long sys_pause
+	.long sys_utime		/* 30 */
+	.long sys_stty
+	.long sys_gtty
+	.long sys_access
+	.long sys_nice
+	.long sys_ftime		/* 35 */
+	.long sys_sync
+	.long sys_kill
+	.long sys_rename
+	.long sys_mkdir
+	.long sys_rmdir		/* 40 */
+	.long sys_dup
+	.long sys_pipe
+	.long sys_times
+	.long sys_prof
+	.long sys_brk			/* 45 */
+	.long sys_setgid
+	.long sys_getgid
+	.long sys_signal
+	.long sys_geteuid
+	.long sys_getegid		/* 50 */
+	.long sys_acct
+	.long sys_phys
+	.long sys_lock
+	.long sys_ioctl
+	.long sys_fcntl		/* 55 */
+	.long sys_mpx
+	.long sys_setpgid
+	.long sys_ulimit
+	.long sys_olduname
+	.long sys_umask		/* 60 */
+	.long sys_chroot
+	.long sys_ustat
+	.long sys_dup2
+	.long sys_getppid
+	.long sys_getpgrp		/* 65 */
+	.long sys_setsid
+	.long sys_sigaction
+	.long sys_sgetmask
+	.long sys_ssetmask
+	.long sys_setreuid		/* 70 */
+	.long sys_setregid
+	.long sys_sigsuspend
+	.long sys_sigpending
+	.long sys_sethostname
+	.long sys_setrlimit		/* 75 */
+	.long sys_getrlimit
+	.long sys_getrusage
+	.long sys_gettimeofday
+	.long sys_settimeofday
+	.long sys_getgroups		/* 80 */
+	.long sys_setgroups
+	.long sys_select
+	.long sys_symlink
+	.long sys_lstat
+	.long sys_readlink		/* 85 */
+	.long sys_uselib
+	.long sys_swapon
+	.long sys_reboot
+	.long sys_readdir
+	.long sys_mmap			/* 90 */
+	.long sys_munmap
+	.long sys_truncate
+	.long sys_ftruncate
+	.long sys_fchmod
+	.long sys_fchown		/* 95 */
+	.long sys_getpriority
+	.long sys_setpriority
+	.long sys_profil
+	.long sys_statfs
+	.long sys_fstatfs		/* 100 */
+	.long sys_ioperm
+	.long sys_socketcall
+	.long sys_syslog
+	.long sys_setitimer
+	.long sys_getitimer		/* 105 */
+	.long sys_newstat
+	.long sys_newlstat
+	.long sys_newfstat
+	.long sys_uname
+	.long sys_iopl			/* 110 */
+	.long sys_vhangup
+	.long sys_idle
+	.long sys_vm86
+	.long sys_wait4
+	.long sys_swapoff		/* 115 */
+	.long sys_sysinfo
+	.long sys_ipc
+	.long sys_fsync
+	.long sys_sigreturn
+	.long sys_clone		/* 120 */
+	.long sys_setdomainname
+	.long sys_newuname
+	.long sys_modify_ldt
+	.long sys_adjtimex
+	.long sys_mprotect		/* 125 */
+	.long sys_sigprocmask
+	.long sys_create_module
+	.long sys_init_module
+	.long sys_delete_module
+	.long sys_get_kernel_syms	/* 130 */
+	.long sys_quotactl
+	.long sys_getpgid
+	.long sys_fchdir
+	.long sys_bdflush
+	.long sys_sysfs		/* 135 */
+	.long sys_personality
+	.long 0				/* for afs_syscall */
+	.long sys_setfsuid
+	.long sys_setfsgid
+	.long sys_llseek		/* 140 */
+        .long sys_getdents
+	.long sys_newselect
+	.long sys_flock
+	.long sys_msync
+        .space (NR_syscalls-144)*4
+
+	.data
+#if 0
+	.globl	floppy_track_buffer
+floppy_track_buffer:
+	.space	512*2*38		/* Space for one entire cylinder! */	
+#endif
\ No newline at end of file
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/mk_defs.c linux/arch/ppc/kernel/mk_defs.c
--- v1.3.44/linux/arch/ppc/kernel/mk_defs.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/mk_defs.c	Thu Oct 26 04:07:18 1995
@@ -0,0 +1,157 @@
+/*
+ * This program is used to generate definitions needed by
+ * assembly language modules.
+ */
+
+#include <stdio.h> 
+
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/head.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+#include <asm/pgtable.h>
+
+extern int errno;
+
+main(int argc, char *argv[])
+{
+	FILE *out;
+	struct task_struct task;
+	struct thread_struct tss;
+	struct pt_regs regs;
+	if (!(out = fopen(argv[1], "w")))
+	{
+		fprintf(stderr, "Can't create output file: %d\n", errno);
+		exit(1);
+	}
+	fprintf(out, "/*\n");
+	fprintf(out, " * WARNING! This file is automatically generated - DO NOT EDIT!\n");
+	fprintf(out, " */\n");
+	put_line(out, "STATE", (int)&task.state-(int)&task);
+	put_line(out, "COUNTER", (int)&task.counter-(int)&task);
+	put_line(out, "BLOCKED", (int)&task.blocked-(int)&task);
+	put_line(out, "SIGNAL", (int)&task.signal-(int)&task);
+	put_line(out, "KERNEL_STACK_PAGE", (int)&task.kernel_stack_page-(int)&task);
+	put_line(out, "TSS", (int)&task.tss-(int)&task);
+	put_line(out, "KSP", (int)&tss.ksp-(int)&tss);
+	put_line(out, "LAST_PC", (int)&tss.last_pc-(int)&tss);
+	put_line(out, "MMU_SEG0", (int)&tss.segs[0]-(int)&tss);
+	put_line(out, "MMU_SEG1", (int)&tss.segs[1]-(int)&tss);
+	put_line(out, "MMU_SEG2", (int)&tss.segs[2]-(int)&tss);
+	put_line(out, "MMU_SEG3", (int)&tss.segs[3]-(int)&tss);
+	put_line(out, "MMU_SEG4", (int)&tss.segs[4]-(int)&tss);
+	put_line(out, "MMU_SEG5", (int)&tss.segs[5]-(int)&tss);
+	put_line(out, "MMU_SEG6", (int)&tss.segs[6]-(int)&tss);
+	put_line(out, "MMU_SEG7", (int)&tss.segs[7]-(int)&tss);
+	put_line(out, "MMU_SEG8", (int)&tss.segs[8]-(int)&tss);
+	put_line(out, "MMU_SEG9", (int)&tss.segs[9]-(int)&tss);
+	put_line(out, "MMU_SEG10", (int)&tss.segs[10]-(int)&tss);
+	put_line(out, "MMU_SEG11", (int)&tss.segs[11]-(int)&tss);
+	put_line(out, "MMU_SEG12", (int)&tss.segs[12]-(int)&tss);
+	put_line(out, "MMU_SEG13", (int)&tss.segs[13]-(int)&tss);
+	put_line(out, "MMU_SEG14", (int)&tss.segs[14]-(int)&tss);
+	put_line(out, "MMU_SEG15", (int)&tss.segs[15]-(int)&tss);
+	put_line(out, "TSS_FPR0", (int)&tss.fpr[0]-(int)&tss);
+	put_line(out, "TSS_FPR1", (int)&tss.fpr[1]-(int)&tss);
+	put_line(out, "TSS_FPR2", (int)&tss.fpr[2]-(int)&tss);
+	put_line(out, "TSS_FPR3", (int)&tss.fpr[3]-(int)&tss);
+	put_line(out, "TSS_FPR4", (int)&tss.fpr[4]-(int)&tss);
+	put_line(out, "TSS_FPR5", (int)&tss.fpr[5]-(int)&tss);
+	put_line(out, "TSS_FPR6", (int)&tss.fpr[6]-(int)&tss);
+	put_line(out, "TSS_FPR7", (int)&tss.fpr[7]-(int)&tss);
+	put_line(out, "TSS_FPR8", (int)&tss.fpr[8]-(int)&tss);
+	put_line(out, "TSS_FPR9", (int)&tss.fpr[9]-(int)&tss);
+	put_line(out, "TSS_FPR10", (int)&tss.fpr[10]-(int)&tss);
+	put_line(out, "TSS_FPR11", (int)&tss.fpr[11]-(int)&tss);
+	put_line(out, "TSS_FPR12", (int)&tss.fpr[12]-(int)&tss);
+	put_line(out, "TSS_FPR13", (int)&tss.fpr[13]-(int)&tss);
+	put_line(out, "TSS_FPR14", (int)&tss.fpr[14]-(int)&tss);
+	put_line(out, "TSS_FPR15", (int)&tss.fpr[15]-(int)&tss);
+	put_line(out, "TSS_FPR16", (int)&tss.fpr[16]-(int)&tss);
+	put_line(out, "TSS_FPR17", (int)&tss.fpr[17]-(int)&tss);
+	put_line(out, "TSS_FPR18", (int)&tss.fpr[18]-(int)&tss);
+	put_line(out, "TSS_FPR19", (int)&tss.fpr[19]-(int)&tss);
+	put_line(out, "TSS_FPR20", (int)&tss.fpr[20]-(int)&tss);
+	put_line(out, "TSS_FPR21", (int)&tss.fpr[21]-(int)&tss);
+	put_line(out, "TSS_FPR22", (int)&tss.fpr[22]-(int)&tss);
+	put_line(out, "TSS_FPR23", (int)&tss.fpr[23]-(int)&tss);
+	put_line(out, "TSS_FPR24", (int)&tss.fpr[24]-(int)&tss);
+	put_line(out, "TSS_FPR25", (int)&tss.fpr[25]-(int)&tss);
+	put_line(out, "TSS_FPR26", (int)&tss.fpr[26]-(int)&tss);
+	put_line(out, "TSS_FPR27", (int)&tss.fpr[27]-(int)&tss);
+	put_line(out, "TSS_FPR28", (int)&tss.fpr[28]-(int)&tss);
+	put_line(out, "TSS_FPR29", (int)&tss.fpr[29]-(int)&tss);
+	put_line(out, "TSS_FPR30", (int)&tss.fpr[30]-(int)&tss);
+	put_line(out, "TSS_FPR31", (int)&tss.fpr[31]-(int)&tss);
+	/* Interrupt register frame */
+	put_line(out, "INT_FRAME_SIZE", sizeof(regs));
+	put_line(out, "GPR0", (int)&regs.gpr[0]-(int)&regs);
+	put_line(out, "GPR1", (int)&regs.gpr[1]-(int)&regs);
+	put_line(out, "GPR2", (int)&regs.gpr[2]-(int)&regs);
+	put_line(out, "GPR3", (int)&regs.gpr[3]-(int)&regs);
+	put_line(out, "GPR4", (int)&regs.gpr[4]-(int)&regs);
+	put_line(out, "GPR5", (int)&regs.gpr[5]-(int)&regs);
+	put_line(out, "GPR6", (int)&regs.gpr[6]-(int)&regs);
+	put_line(out, "GPR7", (int)&regs.gpr[7]-(int)&regs);
+	put_line(out, "GPR8", (int)&regs.gpr[8]-(int)&regs);
+	put_line(out, "GPR9", (int)&regs.gpr[9]-(int)&regs);
+	put_line(out, "GPR10", (int)&regs.gpr[10]-(int)&regs);
+	put_line(out, "GPR11", (int)&regs.gpr[11]-(int)&regs);
+	put_line(out, "GPR12", (int)&regs.gpr[12]-(int)&regs);
+	put_line(out, "GPR13", (int)&regs.gpr[13]-(int)&regs);
+	put_line(out, "GPR14", (int)&regs.gpr[14]-(int)&regs);
+	put_line(out, "GPR15", (int)&regs.gpr[15]-(int)&regs);
+	put_line(out, "GPR16", (int)&regs.gpr[16]-(int)&regs);
+	put_line(out, "GPR17", (int)&regs.gpr[17]-(int)&regs);
+	put_line(out, "GPR18", (int)&regs.gpr[18]-(int)&regs);
+	put_line(out, "GPR19", (int)&regs.gpr[19]-(int)&regs);
+	put_line(out, "GPR20", (int)&regs.gpr[20]-(int)&regs);
+	put_line(out, "GPR21", (int)&regs.gpr[21]-(int)&regs);
+	put_line(out, "GPR22", (int)&regs.gpr[22]-(int)&regs);
+	put_line(out, "GPR23", (int)&regs.gpr[23]-(int)&regs);
+	put_line(out, "GPR24", (int)&regs.gpr[24]-(int)&regs);
+	put_line(out, "GPR25", (int)&regs.gpr[25]-(int)&regs);
+	put_line(out, "GPR26", (int)&regs.gpr[26]-(int)&regs);
+	put_line(out, "GPR27", (int)&regs.gpr[27]-(int)&regs);
+	put_line(out, "GPR28", (int)&regs.gpr[28]-(int)&regs);
+	put_line(out, "GPR29", (int)&regs.gpr[29]-(int)&regs);
+	put_line(out, "GPR30", (int)&regs.gpr[30]-(int)&regs);
+	put_line(out, "GPR31", (int)&regs.gpr[31]-(int)&regs);
+	put_line(out, "FPR0", (int)&regs.fpr[0]-(int)&regs);
+	put_line(out, "FPR1", (int)&regs.fpr[1]-(int)&regs);
+	put_line(out, "FPR2", (int)&regs.fpr[2]-(int)&regs);
+	put_line(out, "FPR3", (int)&regs.fpr[3]-(int)&regs);
+	put_line(out, "FPCSR", (int)&regs.fpcsr-(int)&regs);
+	/* Note: these symbols include "_" because they overlap with special register names */
+	put_line(out, "_NIP", (int)&regs.nip-(int)&regs);
+	put_line(out, "_MSR", (int)&regs.msr-(int)&regs);
+	put_line(out, "_CTR", (int)&regs.ctr-(int)&regs);
+	put_line(out, "_LINK", (int)&regs.link-(int)&regs);
+	put_line(out, "_CCR", (int)&regs.ccr-(int)&regs);
+	put_line(out, "_XER", (int)&regs.xer-(int)&regs);
+	put_line(out, "_DAR", (int)&regs.dar-(int)&regs);
+	put_line(out, "_DSISR", (int)&regs.dsisr-(int)&regs);
+	put_line(out, "_HASH1", (int)&regs.hash1-(int)&regs);
+	put_line(out, "_HASH2", (int)&regs.hash2-(int)&regs);
+	put_line(out, "_IMISS", (int)&regs.imiss-(int)&regs);
+	put_line(out, "_DMISS", (int)&regs.dmiss-(int)&regs);
+	put_line(out, "_ICMP", (int)&regs.icmp-(int)&regs);
+	put_line(out, "_DCMP", (int)&regs.dcmp-(int)&regs);
+	put_line(out, "ORIG_GPR3", (int)&regs.orig_gpr3-(int)&regs);
+	put_line(out, "RESULT", (int)&regs.result-(int)&regs);
+	put_line(out, "TRAP", (int)&regs.trap-(int)&regs);
+	put_line(out, "MARKER", (int)&regs.marker-(int)&regs);
+	exit(0);
+}
+
+put_line(FILE *out, char *name, int offset)
+{
+	fprintf(out, "#define %s %d\n", name, offset);
+}
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/mk_ramdisk.c linux/arch/ppc/kernel/mk_ramdisk.c
--- v1.3.44/linux/arch/ppc/kernel/mk_ramdisk.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/mk_ramdisk.c	Fri Jun 16 13:40:06 1995
@@ -0,0 +1,65 @@
+#include <stdio.h>
+
+extern long ce_exec_config[];
+
+main(int argc, char *argv[])
+{
+	FILE *out, *in;
+	int i, cnt, pos;
+	unsigned char *lp;
+	unsigned char buf[4096];
+	if (argc != 3)
+	{
+		fprintf(stderr, "usage: %s <in-file> <out-file>\n", argv[0]);
+		exit(1);
+	}
+	if ((out = fopen(argv[2], "w")) == (FILE *)0)
+	{
+		fprintf(stderr, "Can't create '%s'\n", argv[2]);
+		exit(1);
+	}
+	if ((in = fopen(argv[1], "r")) == (FILE *)0)
+	{
+		fprintf(stderr, "Can't open '%s'\n", argv[1]);
+		exit(1);
+	}
+	fprintf(out, "#\n");
+	fprintf(out, "# Miscellaneous data structures:\n");
+	fprintf(out, "# WARNING - this file is automatically generated!\n");
+	fprintf(out, "#\n");
+	fprintf(out, "\n");
+	fprintf(out, "\t.data\n");
+	fprintf(out, "\t.globl builtin_ramdisk_image\n");
+	fprintf(out, "builtin_ramdisk_image:\n");
+	pos = 0;
+	while (fread(buf, sizeof(buf), 1, in) == 1)
+	{
+		cnt = 0;
+		lp = (unsigned char *)buf;
+		for (i = 0;  i < sizeof(buf);  i += 4)
+		{
+			if (cnt == 0)
+			{
+				fprintf(out, "\t.long\t");
+			}
+			fprintf(out, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]);
+			lp += 4;
+			if (++cnt == 4)
+			{
+				cnt = 0;
+				fprintf(out, " # %x \n", pos+i-12);
+				fflush(out);
+			} else
+			{
+				fprintf(out, ",");
+			}
+		}
+		pos += sizeof(buf);
+	}
+	fprintf(out, "\t.globl builtin_ramdisk_size\n");
+	fprintf(out, "builtin_ramdisk_size:\t.long\t0x%x\n", pos);
+	fflush(out);
+	fclose(out);
+	exit(0);
+}
+
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/mkboot.c linux/arch/ppc/kernel/mkboot.c
--- v1.3.44/linux/arch/ppc/kernel/mkboot.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/mkboot.c	Mon Oct 30 05:26:02 1995
@@ -0,0 +1,67 @@
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <fcntl.h>
+
+/* amount to skip */
+#define PLACE 65536
+
+/* size of read buffer */
+#define SIZE 0x200000
+
+
+void main(int argc, char **argv )
+{
+  int fd, fdo;
+  unsigned char data[SIZE];
+  int i, n, skip;
+
+  if ( argc != 3 )
+  {
+    fprintf(stderr,"%s infile outfile\n", argv[0]);
+    exit(-1);
+  }
+
+
+  fd = open(argv[1], O_RDONLY);
+  if ( fd == -1 )
+  {
+    fprintf(stderr,"Couldn't open %s\n", argv[1]);
+    perror("open()");
+    exit(-1);
+  }
+  
+  fdo = open(argv[2], O_WRONLY|O_CREAT);
+  if ( fdo == -1 )
+  {
+    fprintf(stderr,"Couldn't open %s\n", argv[2]);
+    perror("open()");
+    exit(-1);
+  }
+
+#if 0
+  skip = atoi(argv[3]);
+#else
+  skip = PLACE;
+#endif
+  i = lseek(fd, skip, SEEK_SET);
+  printf("lseek'd %d bytes\n", i);
+  if ( i == -1 )
+  {
+      perror("lseek()");
+  }
+
+  while ( (n = read(fd, data, SIZE)) > 0 )
+  {
+    printf("Read %d bytes\n", n);
+    i = write(fdo, data, n);
+    printf("Wrote %d bytes\n", i);    
+  }
+
+
+  close(fdo);
+  close(fd);
+  return(0);
+}
+
+
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/mmu.h linux/arch/ppc/kernel/mmu.h
--- v1.3.44/linux/arch/ppc/kernel/mmu.h	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/mmu.h	Fri May  5 03:44:02 1995
@@ -0,0 +1,159 @@
+/*
+ * PowerPC memory management structures
+ */
+
+#ifndef _PPC_MMU_H_
+#define _PPC_MMU_H_
+
+/* Hardware Page Table Entry */
+ 
+typedef struct _PTE
+   {
+      unsigned long v:1;	/* Entry is valid */
+      unsigned long vsid:24;	/* Virtual segment identifier */
+      unsigned long h:1;	/* Hash algorithm indicator */
+      unsigned long api:6;	/* Abbreviated page index */
+      unsigned long rpn:20;	/* Real (physical) page number */
+      unsigned long    :3;	/* Unused */
+      unsigned long r:1;	/* Referenced */
+      unsigned long c:1;	/* Changed */
+      unsigned long w:1;	/* Write-thru cache mode */
+      unsigned long i:1;	/* Cache inhibited */
+      unsigned long m:1;	/* Memory coherence */
+      unsigned long g:1;	/* Guarded */
+      unsigned long    :1;	/* Unused */
+      unsigned long pp:2;	/* Page protection */
+   } PTE; 
+
+/* Values for PP (assumes Ks=0, Kp=1) */
+#define PP_RWXX	0	/* Supervisor read/write, User none */
+#define PP_RWRX 1	/* Supervisor read/write, User read */
+#define PP_RWRW 2	/* Supervisor read/write, User read/write */
+
+/* Segment Register */
+
+typedef struct _SEGREG
+   {
+      unsigned long t:1;	/* Normal or I/O  type */
+      unsigned long ks:1;	/* Supervisor 'key' (normally 0) */
+      unsigned long kp:1;	/* User 'key' (normally 1) */
+      unsigned long n:1;	/* No-execute */
+      unsigned long :4;		/* Unused */
+      unsigned long vsid:24;	/* Virtual Segment Identifier */
+   } SEGREG;
+
+/* Block Address Translation (BAT) Registers */
+
+typedef struct _BATU		/* Upper part of BAT */
+   {
+      unsigned long bepi:15;	/* Effective page index (virtual address) */
+      unsigned long :4;		/* Unused */
+      unsigned long bl:11;	/* Block size mask */
+      unsigned long vs:1;	/* Supervisor valid */
+      unsigned long vp:1;	/* User valid */
+   } BATU;   
+
+typedef struct _BATL		/* Lower part of BAT */
+   {
+      unsigned long brpn:15;	/* Real page index (physical address) */
+      unsigned long :10;	/* Unused */
+      unsigned long w:1;	/* Write-thru cache */
+      unsigned long i:1;	/* Cache inhibit */
+      unsigned long m:1;	/* Memory coherence */
+      unsigned long g:1;	/* Guarded (MBZ) */
+      unsigned long :1;		/* Unused */
+      unsigned long pp:2;	/* Page access protections */
+   } BATL;
+
+typedef struct _BAT
+   {
+      BATU batu;		/* Upper register */
+      BATL batl;		/* Lower register */
+   } BAT;
+
+/* Block size masks */
+#define BL_128K	0x000
+#define BL_256K 0x001
+#define BL_512K 0x003
+#define BL_1M   0x007
+#define BL_2M   0x00F
+#define BL_4M   0x01F
+#define BL_8M   0x03F
+#define BL_16M  0x07F
+#define BL_32M  0x0FF
+#define BL_64M  0x1FF
+#define BL_128M 0x3FF
+#define BL_256M 0x7FF
+
+/* BAT Access Protection */
+#define BPP_XX	0x00		/* No access */
+#define BPP_RX	0x01		/* Read only */
+#define BPP_RW	0x02		/* Read/write */
+
+/*
+ * Simulated two-level MMU.  This structure is used by the kernel
+ * to keep track of MMU mappings and is used to update/maintain
+ * the hardware HASH table which is really a cache of mappings.
+ *
+ * The simulated structures mimic the hardware available on other
+ * platforms, notably the 80x86 and 680x0.
+ */
+
+typedef struct _pte
+   {
+   	unsigned long page_num:20;
+   	unsigned long unused:6;
+   	unsigned long acc:3;		/* Read/write/execute permissions */
+   	unsigned long r:1;		/* Page has been referenced */
+   	unsigned long m:1;		/* Page has been modified */
+   	unsigned long v:1;		/* Entry is valid */
+   } pte;
+
+#define ACC_Rxx	0x04
+#define ACC_xWx 0x02
+#define ACC_xxX 0x01
+#define ACC_RWX (ACC_Rxx|ACC_xWx|ACC_xxX)
+
+#define PD_SHIFT (10+12)		/* Page directory */
+#define PD_MASK  0x02FF
+#define PT_SHIFT (12)			/* Page Table */
+#define PT_MASK  0x02FF
+#define PG_SHIFT (12)			/* Page Entry */
+ 
+
+/* MMU context */
+
+typedef struct _MMU_context
+   {
+      SEGREG	segs[16];	/* Segment registers */
+      pte	**pmap;		/* Two-level page-map structure */
+   } MMU_context;
+
+#if 0
+BAT	ibat[4];	/* Instruction BAT images */
+BAT	dbat[4];	/* Data BAT images */
+PTE	*hash_table;	/* Hardware hashed page table */
+int	hash_table_size;
+int	hash_table_mask;
+unsigned long sdr;	/* Hardware image of SDR */
+#endif   
+
+/* Used to set up SDR register */
+#define HASH_TABLE_SIZE_64K	0x00010000
+#define HASH_TABLE_SIZE_128K	0x00020000
+#define HASH_TABLE_SIZE_256K	0x00040000
+#define HASH_TABLE_SIZE_512K	0x00080000
+#define HASH_TABLE_SIZE_1M	0x00100000
+#define HASH_TABLE_SIZE_2M	0x00200000
+#define HASH_TABLE_SIZE_4M	0x00400000
+#define HASH_TABLE_MASK_64K	0x000   
+#define HASH_TABLE_MASK_128K	0x001   
+#define HASH_TABLE_MASK_256K	0x003   
+#define HASH_TABLE_MASK_512K	0x007
+#define HASH_TABLE_MASK_1M	0x00F   
+#define HASH_TABLE_MASK_2M	0x01F   
+#define HASH_TABLE_MASK_4M	0x03F   
+
+#define MMU_PAGE_SIZE	4096
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/newppcdefs.h linux/arch/ppc/kernel/newppcdefs.h
--- v1.3.44/linux/arch/ppc/kernel/newppcdefs.h	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/newppcdefs.h	Thu Oct 26 04:01:07 1995
@@ -0,0 +1,114 @@
+/*
+ * WARNING! This file is automatically generated - DO NOT EDIT!
+ */
+#define STATE 0
+#define COUNTER 4
+#define BLOCKED 16
+#define SIGNAL 12
+#define KERNEL_STACK_PAGE 88
+#define TSS 504
+#define KSP 0
+#define MMU_SEG0 8
+#define MMU_SEG1 12
+#define MMU_SEG2 16
+#define MMU_SEG3 20
+#define MMU_SEG4 24
+#define MMU_SEG5 28
+#define MMU_SEG6 32
+#define MMU_SEG7 36
+#define MMU_SEG8 40
+#define MMU_SEG9 44
+#define MMU_SEG10 48
+#define MMU_SEG11 52
+#define MMU_SEG12 56
+#define MMU_SEG13 60
+#define MMU_SEG14 64
+#define MMU_SEG15 68
+#define TSS_FPR0 72
+#define TSS_FPR1 80
+#define TSS_FPR2 88
+#define TSS_FPR3 96
+#define TSS_FPR4 104
+#define TSS_FPR5 112
+#define TSS_FPR6 120
+#define TSS_FPR7 128
+#define TSS_FPR8 136
+#define TSS_FPR9 144
+#define TSS_FPR10 152
+#define TSS_FPR11 160
+#define TSS_FPR12 168
+#define TSS_FPR13 176
+#define TSS_FPR14 184
+#define TSS_FPR15 192
+#define TSS_FPR16 200
+#define TSS_FPR17 208
+#define TSS_FPR18 216
+#define TSS_FPR19 224
+#define TSS_FPR20 232
+#define TSS_FPR21 240
+#define TSS_FPR22 248
+#define TSS_FPR23 256
+#define TSS_FPR24 264
+#define TSS_FPR25 272
+#define TSS_FPR26 280
+#define TSS_FPR27 288
+#define TSS_FPR28 296
+#define TSS_FPR29 304
+#define TSS_FPR30 312
+#define TSS_FPR31 320
+#define INT_FRAME_SIZE 384
+#define GPR0 56
+#define GPR1 60
+#define GPR2 64
+#define GPR3 68
+#define GPR4 72
+#define GPR5 76
+#define GPR6 80
+#define GPR7 84
+#define GPR8 88
+#define GPR9 92
+#define GPR10 96
+#define GPR11 100
+#define GPR12 104
+#define GPR13 108
+#define GPR14 112
+#define GPR15 116
+#define GPR16 120
+#define GPR17 124
+#define GPR18 128
+#define GPR19 132
+#define GPR20 136
+#define GPR21 140
+#define GPR22 144
+#define GPR23 148
+#define GPR24 152
+#define GPR25 156
+#define GPR26 160
+#define GPR27 164
+#define GPR28 168
+#define GPR29 172
+#define GPR30 176
+#define GPR31 180
+#define FPR0 256
+#define FPR1 264
+#define FPR2 272
+#define FPR3 280
+#define FPCSR 288
+#define _NIP 184
+#define _MSR 188
+#define _CTR 192
+#define _LINK 196
+#define _CCR 200
+#define _XER 208
+#define _DAR 212
+#define _DSISR 216
+#define _HASH1 220
+#define _HASH2 224
+#define _IMISS 228
+#define _DMISS 232
+#define _ICMP 236
+#define _DCMP 240
+#define ORIG_GPR3 244
+#define RESULT 248
+#define TRAP 296
+#define MARKER 300
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/pci.c linux/arch/ppc/kernel/pci.c
--- v1.3.44/linux/arch/ppc/kernel/pci.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/pci.c	Fri Oct 27 10:22:45 1995
@@ -0,0 +1,241 @@
+/*
+ * PCI support
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/bios32.h>
+#include <linux/pci.h>
+
+/* #define PCI_DEBUG */
+
+int PCI_conversions[2];
+
+unsigned long pcibios_init(unsigned long mem_start,
+			   unsigned long mem_end)
+{
+	printk("PPC init stub -- cort\n");
+
+	return mem_start;
+}
+
+unsigned long pcibios_fixup(unsigned long mem_start, unsigned long mem_end)
+{
+  return mem_start;
+}
+
+unsigned long
+_LE_to_BE_long(unsigned long val)
+{
+	unsigned char *p = (unsigned char *)&val;
+	PCI_conversions[0]++;
+	return ((p[3] << 24) | (p[2] << 16) | (p[1] << 8) | (p[0] << 0));
+}
+
+unsigned short
+_LE_to_BE_short(unsigned long val)
+{
+	unsigned char *p = (unsigned char *)&val;
+	PCI_conversions[1]++;
+	return ((p[3] << 8) | (p[2] << 0));
+}
+
+int
+pcibios_present (void)
+{
+#ifdef PCI_DEBUG	
+	_printk("PCI [BIOS] present?\n");
+#endif	
+	return (1);
+}
+
+int
+pcibios_read_config_dword (unsigned char bus,
+    unsigned char dev, unsigned char offset, unsigned int *val)
+{
+	unsigned long _val;
+	unsigned long *ptr;
+	dev >>= 3;
+#ifdef PCI_DEBUG	
+	_printk("PCI Read config dword[%d.%d.%x] = ", bus, dev, offset);
+#endif	
+	if ((bus != 0) || (dev < 11) || (dev > 16))
+	{
+		*val = 0xFFFFFFFF;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	} else
+	{
+		ptr = (unsigned long *)(0x80800000 | (1<<dev) | offset);
+#ifdef PCI_DEBUG	
+		_printk("[%x] ", ptr);
+#endif		
+		_val = _LE_to_BE_long(*ptr);
+	}
+#ifdef PCI_DEBUG	
+	_printk("%x\n", _val);
+#endif	
+	*val = _val;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pcibios_read_config_word (unsigned char bus,
+    unsigned char dev, unsigned char offset, unsigned short *val)
+{
+	unsigned short _val;
+	unsigned short *ptr;
+	dev >>= 3;
+#ifdef PCI_DEBUG	
+	_printk("PCI Read config word[%d.%d.%x] = ", bus, dev, offset);
+#endif	
+	if ((bus != 0) || (dev < 11) || (dev > 16))
+	{
+		*val = 0xFFFFFFFF;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	} else
+	{
+		ptr = (unsigned short *)(0x80800000 | (1<<dev) | offset);
+#ifdef PCI_DEBUG	
+		_printk("[%x] ", ptr);
+#endif		
+		_val = _LE_to_BE_short(*ptr);
+	}
+#ifdef PCI_DEBUG	
+	_printk("%x\n", _val);
+#endif		
+	*val = _val;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pcibios_read_config_byte (unsigned char bus,
+    unsigned char dev, unsigned char offset, unsigned char *val)
+{
+	unsigned char _val;
+	unsigned char *ptr;
+	dev >>= 3;
+#ifdef PCI_DEBUG	
+	_printk("PCI Read config byte[%d.%d.%x] = ", bus, dev, offset);
+#endif		
+	if ((bus != 0) || (dev < 11) || (dev > 16))
+	{
+		*val = 0xFFFFFFFF;
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	} else
+	{
+		ptr = (unsigned char *)(0x80800000 | (1<<dev) | offset ^ 1);
+#ifdef PCI_DEBUG	
+		_printk("[%x] ", ptr);
+#endif		
+		_val = *ptr;
+	}
+#ifdef PCI_DEBUG	
+	_printk("%x\n", _val);
+#endif		
+	*val = _val;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pcibios_write_config_dword (unsigned char bus,
+    unsigned char dev, unsigned char offset, unsigned int val)
+{
+	unsigned long _val;
+	unsigned long *ptr;
+	dev >>= 3;
+	_val = _LE_to_BE_long(val);
+#ifdef PCI_DEBUG	
+	_printk("PCI Write config dword[%d.%d.%x] = %x\n", bus, dev, offset, _val);
+#endif		
+	if ((bus != 0) || (dev < 11) || (dev > 16))
+	{
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	} else
+	{
+		ptr = (unsigned long *)(0x80800000 | (1<<dev) | offset);
+		*ptr = _val;
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pcibios_write_config_word (unsigned char bus,
+    unsigned char dev, unsigned char offset, unsigned short val)
+{
+	unsigned short _val;
+	unsigned short *ptr;
+	dev >>= 3;
+	_val = _LE_to_BE_short(val);
+#ifdef PCI_DEBUG	
+	_printk("PCI Write config word[%d.%d.%x] = %x\n", bus, dev, offset, _val);
+#endif		
+	if ((bus != 0) || (dev < 11) || (dev > 16))
+	{
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	} else
+	{
+		ptr = (unsigned short *)(0x80800000 | (1<<dev) | offset);
+		*ptr = _val;
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pcibios_write_config_byte (unsigned char bus,
+    unsigned char dev, unsigned char offset, unsigned char val)
+{
+	unsigned char _val;
+	unsigned char *ptr;
+	dev >>= 3;
+	_val = val;
+#ifdef PCI_DEBUG	
+	_printk("PCI Write config byte[%d.%d.%x] = %x\n", bus, dev, offset, _val);
+#endif		
+	if ((bus != 0) || (dev < 11) || (dev > 16))
+	{
+		return PCIBIOS_DEVICE_NOT_FOUND;
+	} else
+	{
+		ptr = (unsigned char *)(0x80800000 | (1<<dev) | offset ^ 1);
+		*ptr = _val;
+	}
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int
+pcibios_find_device (unsigned short vendor, unsigned short device_id,
+		     unsigned short index, unsigned char *bus,
+		     unsigned char *dev)
+{
+	unsigned long w, desired = (device_id << 16) | vendor;
+	int devnr;
+
+	if (vendor == 0xffff) {
+		return PCIBIOS_BAD_VENDOR_ID;
+	}
+
+	for (devnr = 11;  devnr < 16;  devnr++)
+	{
+		pcibios_read_config_dword(0, devnr<<3, PCI_VENDOR_ID, &w);
+		if (w == desired) {
+			if (index == 0) {
+				*bus = 0;
+				*dev = devnr<<3;
+				return PCIBIOS_SUCCESSFUL;
+			}
+			--index;
+		}
+	}
+	return PCIBIOS_DEVICE_NOT_FOUND;
+}
+
+int
+pcibios_find_class (unsigned int class_code, unsigned short index, 
+    unsigned char *bus, unsigned char *dev)
+{
+	printk("pcibios_find_class\n");
+	return PCIBIOS_FUNC_NOT_SUPPORTED;
+}    
+
+const char *pcibios_strerror(int error) { _panic("pcibios_strerror"); } 
+/*int get_pci_list(char *buf) { _panic("get_pci_list"); } */
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/port_io.c linux/arch/ppc/kernel/port_io.c
--- v1.3.44/linux/arch/ppc/kernel/port_io.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/port_io.c	Sat Jun  3 17:55:59 1995
@@ -0,0 +1,73 @@
+/*
+ * I/O 'port' access routines
+ */
+
+/* This is really only correct for the MVME16xx (PreP)? */
+
+#define _IO_BASE ((unsigned long)0x80000000)
+
+unsigned char
+inb(int port)
+{
+	return (*((unsigned  char *)(_IO_BASE+port)));
+}
+
+unsigned short
+inw(int port)
+{
+	return (_LE_to_BE_short(*((unsigned short *)(_IO_BASE+port))));
+}
+
+unsigned long
+inl(int port)
+{
+	return (_LE_to_BE_long(*((unsigned  long *)(_IO_BASE+port))));
+}
+
+void insl(int port, long *ptr, int len)
+{
+	unsigned long *io_ptr = (unsigned long *)(_IO_BASE+port);
+	while (len-- > 0)
+	{
+		*ptr++ = _LE_to_BE_long(*io_ptr);
+	}
+}
+
+unsigned char  inb_p(int port) {return (inb(port)); }
+unsigned short inw_p(int port) {return (inw(port)); }
+unsigned long  inl_p(int port) {return (inl(port)); }
+
+unsigned char
+outb(unsigned char val,int port)
+{
+	*((unsigned  char *)(_IO_BASE+port)) = (val);
+	return (val);
+}
+
+unsigned short
+outw(unsigned short val,int port)
+{
+	*((unsigned  short *)(_IO_BASE+port)) = _LE_to_BE_short(val);
+	return (val);
+}
+
+unsigned long
+outl(unsigned long val,int port)
+{
+	*((unsigned  long *)(_IO_BASE+port)) = _LE_to_BE_long(val);
+	return (val);
+}
+
+void outsl(int port, long *ptr, int len)
+{
+	unsigned long *io_ptr = (unsigned long *)(_IO_BASE+port);
+	while (len-- > 0)
+	{
+		*io_ptr = _LE_to_BE_long(*ptr++);
+	}
+}
+
+unsigned char  outb_p(unsigned char val,int port) { return (outb(val,port)); }
+unsigned short outw_p(unsigned short val,int port) { return (outw(val,port)); }
+unsigned long  outl_p(unsigned long val,int port) { return (outl(val,port)); }
+
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/ppc_asm.tmpl linux/arch/ppc/kernel/ppc_asm.tmpl
--- v1.3.44/linux/arch/ppc/kernel/ppc_asm.tmpl	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/ppc_asm.tmpl	Wed Jun 28 03:56:47 1995
@@ -0,0 +1,168 @@
+/*
+ * This file contains all the macros and symbols which define
+ * a PowerPC assembly language environment.
+ */
+
+#define _TEXT()\
+	.text
+
+#if 0 /* Old way */	
+#define _EXTERN(n) .##n	
+
+#define _GLOBAL(n)\
+	.globl n;\
+n:	.long	_EXTERN(n);\
+	.globl _EXTERN(n);\
+_EXTERN(n):
+#else
+#define _EXTERN(n) n	
+
+#define _GLOBAL(n)\
+	.globl n;\
+n:
+#endif
+
+#ifndef FALSE
+#define FALSE	0
+#define TRUE	1
+#endif
+	
+#define _ORG(n)\
+	.org	n
+
+/* Register names */
+#define	r0	0
+#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	r16	16
+#define	r17	17
+#define	r18	18
+#define	r19	19
+#define	r20	20
+#define	r21	21
+#define	r22	22
+#define	r23	23
+#define	r24	24
+#define	r25	25
+#define	r26	26
+#define	r27	27
+#define	r28	28
+#define	r29	29
+#define	r30	30
+#define	r31	31
+
+#define	fr0	0
+#define	fr1	1
+#define	fr2	2
+#define	fr3	3
+#define	fr4	4
+#define	fr5	5
+#define	fr6	6
+#define	fr7	7
+#define	fr8	8
+#define	fr9	9
+#define	fr10	10
+#define	fr11	11
+#define	fr12	12
+#define	fr13	13
+#define	fr14	14
+#define	fr15	15
+#define	fr16	16
+#define	fr17	17
+#define	fr18	18
+#define	fr19	19
+#define	fr20	20
+#define	fr21	21
+#define	fr22	22
+#define	fr23	23
+#define	fr24	24
+#define	fr25	25
+#define	fr26	26
+#define	fr27	27
+#define	fr28	28
+#define	fr29	29
+#define	fr30	30
+#define	fr31	31
+
+/* Some special registers */
+
+#define	TBRU	269	/* Time base Upper/Lower (Reading) */
+#define	TBRL	268
+#define TBWU	284	/* Time base Upper/Lower (Writing) */
+#define TBWL	285
+#define	XER	1
+#define LR	8
+#define CTR	9
+#define HID0	1008	/* Hardware Implementation */
+#define PVR	287	/* Processor Version */
+#define IBAT0U	528	/* Instruction BAT #0 Upper/Lower */
+#define IBAT0L	529
+#define IBAT1U	530	/* Instruction BAT #1 Upper/Lower */
+#define IBAT1L	531
+#define IBAT2U	532	/* Instruction BAT #2 Upper/Lower */
+#define IBAT2L	533
+#define IBAT3U	534	/* Instruction BAT #3 Upper/Lower */
+#define IBAT3L	535
+#define DBAT0U	536	/* Data BAT #0 Upper/Lower */
+#define DBAT0L	537
+#define DBAT1U	538	/* Data BAT #1 Upper/Lower */
+#define DBAT1L	539
+#define DBAT2U	540	/* Data BAT #2 Upper/Lower */
+#define DBAT2L	541
+#define DBAT3U	542	/* Data BAT #3 Upper/Lower */
+#define DBAT3L	543
+#define DMISS	976	/* TLB Lookup/Refresh registers */
+#define DCMP	977
+#define HASH1	978
+#define HASH2	979
+#define IMISS	980
+#define ICMP	981
+#define RPA	982
+#define SDR1	25	/* MMU hash base register */
+#define DAR	19	/* Data Address Register */
+#define SPR0	272	/* Supervisor Private Registers */
+#define SPR1	273
+#define SPR2	274
+#define SPR3	275
+#define DSISR	18
+#define SRR0	26	/* Saved Registers (exception) */
+#define SRR1	27
+#define IABR	1010	/* Instruction Address Breakpoint */
+#define DEC	22	/* Decrementer */
+#define EAR	282	/* External Address Register */
+
+/* Segment Registers */
+#define SR0	0
+#define SR1	1
+#define SR2	2
+#define SR3	3
+#define SR4	4
+#define SR5	5
+#define SR6	6
+#define SR7	7
+#define SR8	8
+#define SR9	9
+#define SR10	10
+#define SR11	11
+#define SR12	12
+#define SR13	13
+#define SR14	14
+#define SR15	15
+
+/* Missing instructions */
+#define bdne	bc 0,2,
+
+#include "ppc_machine.h"
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/ppc_defs.h linux/arch/ppc/kernel/ppc_defs.h
--- v1.3.44/linux/arch/ppc/kernel/ppc_defs.h	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/ppc_defs.h	Sat Nov 25 14:59:03 1995
@@ -0,0 +1,115 @@
+/*
+ * WARNING! This file is automatically generated - DO NOT EDIT!
+ */
+#define STATE 0
+#define COUNTER 4
+#define BLOCKED 16
+#define SIGNAL 12
+#define KERNEL_STACK_PAGE 88
+#define TSS 504
+#define KSP 0
+#define LAST_PC 72
+#define MMU_SEG0 8
+#define MMU_SEG1 12
+#define MMU_SEG2 16
+#define MMU_SEG3 20
+#define MMU_SEG4 24
+#define MMU_SEG5 28
+#define MMU_SEG6 32
+#define MMU_SEG7 36
+#define MMU_SEG8 40
+#define MMU_SEG9 44
+#define MMU_SEG10 48
+#define MMU_SEG11 52
+#define MMU_SEG12 56
+#define MMU_SEG13 60
+#define MMU_SEG14 64
+#define MMU_SEG15 68
+#define TSS_FPR0 80
+#define TSS_FPR1 88
+#define TSS_FPR2 96
+#define TSS_FPR3 104
+#define TSS_FPR4 112
+#define TSS_FPR5 120
+#define TSS_FPR6 128
+#define TSS_FPR7 136
+#define TSS_FPR8 144
+#define TSS_FPR9 152
+#define TSS_FPR10 160
+#define TSS_FPR11 168
+#define TSS_FPR12 176
+#define TSS_FPR13 184
+#define TSS_FPR14 192
+#define TSS_FPR15 200
+#define TSS_FPR16 208
+#define TSS_FPR17 216
+#define TSS_FPR18 224
+#define TSS_FPR19 232
+#define TSS_FPR20 240
+#define TSS_FPR21 248
+#define TSS_FPR22 256
+#define TSS_FPR23 264
+#define TSS_FPR24 272
+#define TSS_FPR25 280
+#define TSS_FPR26 288
+#define TSS_FPR27 296
+#define TSS_FPR28 304
+#define TSS_FPR29 312
+#define TSS_FPR30 320
+#define TSS_FPR31 328
+#define INT_FRAME_SIZE 384
+#define GPR0 56
+#define GPR1 60
+#define GPR2 64
+#define GPR3 68
+#define GPR4 72
+#define GPR5 76
+#define GPR6 80
+#define GPR7 84
+#define GPR8 88
+#define GPR9 92
+#define GPR10 96
+#define GPR11 100
+#define GPR12 104
+#define GPR13 108
+#define GPR14 112
+#define GPR15 116
+#define GPR16 120
+#define GPR17 124
+#define GPR18 128
+#define GPR19 132
+#define GPR20 136
+#define GPR21 140
+#define GPR22 144
+#define GPR23 148
+#define GPR24 152
+#define GPR25 156
+#define GPR26 160
+#define GPR27 164
+#define GPR28 168
+#define GPR29 172
+#define GPR30 176
+#define GPR31 180
+#define FPR0 248
+#define FPR1 256
+#define FPR2 264
+#define FPR3 272
+#define FPCSR 280
+#define _NIP 184
+#define _MSR 188
+#define _CTR 192
+#define _LINK 196
+#define _CCR 200
+#define _XER 204
+#define _DAR 208
+#define _DSISR 212
+#define _HASH1 216
+#define _HASH2 220
+#define _IMISS 224
+#define _DMISS 228
+#define _ICMP 232
+#define _DCMP 236
+#define ORIG_GPR3 240
+#define RESULT 244
+#define TRAP 288
+#define MARKER 292
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/ppc_machine.h.isin.processor.h linux/arch/ppc/kernel/ppc_machine.h.isin.processor.h
--- v1.3.44/linux/arch/ppc/kernel/ppc_machine.h.isin.processor.h	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/ppc_machine.h.isin.processor.h	Sun May 28 14:36:15 1995
@@ -0,0 +1,48 @@
+/*
+ * PowerPC machine specifics
+ */
+
+#ifndef _PPC_MACHINE_H_
+#define _PPC_MACHINE_H_ 
+
+/* Bit encodings for Machine State Register (MSR) */
+#define MSR_POW		(1<<18)		/* Enable Power Management */
+#define MSR_TGPR	(1<<17)		/* TLB Update registers in use */
+#define MSR_ILE		(1<<16)		/* Interrupt Little-Endian enable */
+#define MSR_EE		(1<<15)		/* External Interrupt enable */
+#define MSR_PR		(1<<14)		/* Supervisor/User privelege */
+#define MSR_FP		(1<<13)		/* Floating Point enable */
+#define MSR_ME		(1<<12)		/* Machine Check enable */
+#define MSR_FE0		(1<<11)		/* Floating Exception mode 0 */
+#define MSR_SE		(1<<10)		/* Single Step */
+#define MSR_BE		(1<<9)		/* Branch Trace */
+#define MSR_FE1		(1<<8)		/* Floating Exception mode 1 */
+#define MSR_IP		(1<<6)		/* Exception prefix 0x000/0xFFF */
+#define MSR_IR		(1<<5)		/* Instruction MMU enable */
+#define MSR_DR		(1<<4)		/* Data MMU enable */
+#define MSR_RI		(1<<1)		/* Recoverable Exception */
+#define MSR_LE		(1<<0)		/* Little-Endian enable */
+
+#define MSR_		MSR_FP|MSR_FE0|MSR_FE1|MSR_ME
+#define MSR_USER	MSR_|MSR_PR|MSR_EE|MSR_IR|MSR_DR
+
+/* Bit encodings for Hardware Implementation Register (HID0) */
+#define HID0_EMCP	(1<<31)		/* Enable Machine Check pin */
+#define HID0_EBA	(1<<29)		/* Enable Bus Address Parity */
+#define HID0_EBD	(1<<28)		/* Enable Bus Data Parity */
+#define HID0_SBCLK	(1<<27)
+#define HID0_EICE	(1<<26)
+#define HID0_ECLK	(1<<25)
+#define HID0_PAR	(1<<24)
+#define HID0_DOZE	(1<<23)
+#define HID0_NAP	(1<<22)
+#define HID0_SLEEP	(1<<21)
+#define HID0_DPM	(1<<20)
+#define HID0_ICE	(1<<15)		/* Instruction Cache Enable */
+#define HID0_DCE	(1<<14)		/* Data Cache Enable */
+#define HID0_ILOCK	(1<<13)		/* Instruction Cache Lock */
+#define HID0_DLOCK	(1<<12)		/* Data Cache Lock */
+#define HID0_ICFI	(1<<11)		/* Instruction Cache Flash Invalidate */
+#define HID0_DCI	(1<<10)		/* Data Cache Invalidate */
+ 
+#endif
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/process.c linux/arch/ppc/kernel/process.c
--- v1.3.44/linux/arch/ppc/kernel/process.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/process.c	Sat Nov 25 13:52:39 1995
@@ -0,0 +1,238 @@
+/* * Last edited: Nov  8 12:32 1995 (cort) */
+/*
+ *  linux/arch/ppc/kernel/process.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Adapted for PowerPC by Gary Thomas
+ */
+
+/*
+ * This file handles the architecture-dependent parts of process handling..
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/malloc.h>
+#include <linux/ldt.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+
+#include <asm/pgtable.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+#include <asm/processor.h>
+
+int dump_fpu (struct user_i387_struct* fpu)
+{
+  return 1;		/* all ppc's have a fpu */
+}
+
+void
+switch_to(struct task_struct *new)
+{
+	struct pt_regs *regs;
+	struct thread_struct *new_tss, *old_tss;
+	int s;
+	regs = (struct pt_regs *)new->tss.ksp;
+/*
+printk("Task %x(%d) -> %x(%d)", current, current->pid, new, new->pid);
+printk(" - IP: %x, SR: %x, SP: %x\n", regs->nip, regs->msr, regs);
+*/
+	s = _disable_interrupts();
+	new_tss = &new->tss;
+	old_tss = &current->tss;
+	current = new;
+	_switch(old_tss, new_tss);
+
+/*	printk("Back in task %x(%d)\n", current, current->pid);*/
+
+	_enable_interrupts(s);
+}
+
+asmlinkage int sys_idle(void)
+{
+
+	if (current->pid != 0)
+		return -EPERM;
+/*panic("process.c: sys_idle()\n");*/
+	/* endless idle loop with no priority at all */
+	current->counter = -100;
+	for (;;) {
+
+		schedule();
+	}
+}
+
+void hard_reset_now(void)
+{
+	halt();
+}
+
+void show_regs(struct pt_regs * regs)
+{
+	_panic("show_regs");
+}
+
+/*
+ * Free current thread data structures etc..
+ */
+void exit_thread(void)
+{
+}
+
+void flush_thread(void)
+{
+}
+
+/*
+ * Copy a thread..
+ */
+void copy_thread(int nr, unsigned long clone_flags, unsigned long usp,
+	struct task_struct * p, struct pt_regs * regs)
+{
+	int i;
+	SEGREG *segs;
+	struct pt_regs * childregs;
+
+/*printk("copy thread - NR: %d, Flags: %x, USP: %x, Task: %x, Regs: %x\n", nr, clone_flags, usp, p, regs);*/
+
+	/* Construct segment registers */
+	segs = (SEGREG *)p->tss.segs;
+	for (i = 0;  i < 8;  i++)
+	{
+		segs[i].ks = 0;
+		segs[i].kp = 1;
+		segs[i].vsid = i | (nr << 4);
+	}
+	/* Last 8 are shared with kernel & everybody else... */
+	for (i = 8;  i < 16;  i++)
+	{
+		segs[i].ks = 0;
+		segs[i].kp = 1;
+		segs[i].vsid = i;
+	}
+	/* Copy registers */
+	childregs = ((struct pt_regs *) (p->kernel_stack_page + 2*PAGE_SIZE)) - 2;
+	*childregs = *regs;	/* STRUCT COPY */
+	childregs->gpr[3] = 0;  /* Result from fork() */
+	p->tss.ksp = childregs;
+	if (usp >= (unsigned long)regs)
+	{ /* Stack is in kernel space - must adjust */
+		childregs->gpr[1] = childregs+1;
+	} else
+	{ /* Provided stack is in user space */
+		childregs->gpr[1] = usp;
+	}
+}
+
+/*
+ * fill in the user structure for a core dump..
+ */
+void dump_thread(struct pt_regs * regs, struct user * dump)
+{
+}
+
+#if 0 /* mfisk */
+/*
+ * Do necessary setup to start up a newly executed thread.
+ */
+void start_thread(struct pt_regs * regs, unsigned long eip, unsigned long esp)
+{
+  regs->nip = eip;
+  regs->gpr[1] = esp;
+  regs->msr = MSR_USER;
+#if 0
+/*  printk("current = %x current->mm = %x\n", current, current->mm);
+  printk("task[0] = %x task[0]->mm = %x\n", task[0],task[0]->mm);*/
+  printk("Start thread [%x] at PC: %x, SR: %x, SP: %x\n",
+    regs, eip, regs->msr, esp);
+/*  dump_buf(esp, 64);*/
+/*  dump_buf(eip, 64);*/
+#endif
+}
+#endif
+
+asmlinkage int sys_newselect(int p1, int p2, int p3, int p4, int p5, int p6, struct pt_regs *regs)
+{
+  panic("sys_newselect unimplemented");
+}
+
+asmlinkage int sys_fork(int p1, int p2, int p3, int p4, int p5, int p6, struct pt_regs *regs)
+{
+printk("process.c: sys_fork() called\n");
+	return do_fork( CLONE_VM|SIGCHLD, regs->gpr[1], regs);
+}
+
+asmlinkage int sys_execve(unsigned long a0, unsigned long a1, unsigned long a2,
+	unsigned long a3, unsigned long a4, unsigned long a5,
+	struct pt_regs *regs)
+{
+	int error;
+	char * filename;
+/*	printk("process.c: sys_execve(a0 = %s, a1 = %x, a2 = %x)\n",a0,a1,a2);*/
+
+#if 1
+	/* paranoia check.  I really don't trust head.S  -- Cort */
+	if ( regs->marker != 0xDEADDEAD )
+	{
+	  panic("process.c: sys_execve(): regs->marker != DEADDEAD\n");
+	}
+#endif
+	error = getname((char *) a0, &filename);
+	if (error)
+	  return error;
+	error = do_execve(filename, (char **) a1, (char **) a2, regs);
+#if 0
+	if (error)
+	{
+	  printk("EXECVE - file = '%s', error = %d\n", filename, error);
+	}
+#endif
+	putname(filename);
+	return error;
+}
+
+
+asmlinkage int sys_clone(unsigned long clone_flags, unsigned long usp, unsigned long a2,
+	unsigned long a3, unsigned long a4, unsigned long a5,
+	struct pt_regs *regs)
+{
+  int i;
+  
+  if (!usp)
+    usp = regs->gpr[1];
+  
+
+  i = do_fork(CLONE_VM/*clone_flags*/, /*usp*/regs->gpr[1], regs);
+/*  printk("sys_clone going to return %d\n", i);*/
+  return i;
+}
+
+
+
+void
+print_backtrace(void)
+{
+	unsigned long *sp = (unsigned long *)_get_SP();
+	int cnt = 0;
+	printk("... Call backtrace:\n");
+	while (*sp)
+	{
+		printk("%08X ", sp[2]);
+		sp = *sp;
+		if (++cnt == 8)
+		{
+			printk("\n");
+		}
+		if (cnt > 16) break;
+	}
+	printk("\n");
+}
+
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/raw_printf.c linux/arch/ppc/kernel/raw_printf.c
--- v1.3.44/linux/arch/ppc/kernel/raw_printf.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/raw_printf.c	Tue Nov  7 02:40:53 1995
@@ -0,0 +1,1187 @@
+#define FALSE 0
+#define TRUE  1
+#include <stdarg.h>
+
+extern void cnputc(char c);
+
+static char *_sprintk_ptr;
+
+static _sputc(char c)
+{
+   *_sprintk_ptr++ = c;
+   *_sprintk_ptr = '\0';
+}
+
+_sprintk(char *buf, char const *fmt, ...)
+{
+	int ret;
+	va_list ap;
+
+	va_start(ap, fmt);
+	_sprintk_ptr = buf;
+	ret = _vprintk(_sputc, fmt, ap);
+	va_end(ap);
+	return (ret);
+}
+
+_vsprintk(char *buf, char const *fmt, va_list ap)
+{
+	int ret;
+
+	_sprintk_ptr = buf;
+	ret = _vprintk(_sputc, fmt, ap);
+	return (ret);
+}
+
+_printk(char const *fmt, ...)
+{
+	int ret;
+	va_list ap;
+
+	va_start(ap, fmt);
+	ret = _vprintk(cnputc, fmt, ap);
+	va_end(ap);
+	return (ret);
+}
+
+#define is_digit(c) ((c >= '0') && (c <= '9'))
+
+int
+_vprintk(putc, fmt0, ap)
+   int (*putc)();
+   const char *fmt0;
+   va_list ap;
+{
+   char c, sign, *cp;
+   int left_prec, right_prec, zero_fill, length, pad, pad_on_right;
+   char buf[32];
+   long val;
+   while (c = *fmt0++)
+   {
+      if (c == '%')
+      {
+         c = *fmt0++;
+         left_prec = right_prec = pad_on_right = 0;
+         if (c == '-')
+         {
+            c = *fmt0++;
+            pad_on_right++;
+         }
+         if (c == '0')
+         {
+            zero_fill = TRUE;
+            c = *fmt0++;
+         } else
+         {
+            zero_fill = FALSE;
+         }
+         while (is_digit(c))
+         {
+            left_prec = (left_prec * 10) + (c - '0');
+            c = *fmt0++;
+         }
+         if (c == '.')
+         {
+            c = *fmt0++;
+            zero_fill++;
+            while (is_digit(c))
+            {
+               right_prec = (right_prec * 10) + (c - '0');
+               c = *fmt0++;
+            }
+         } else
+         {
+            right_prec = left_prec;
+         }
+         sign = '\0';
+         switch (c)
+         {
+            case 'd':
+            case 'x':
+            case 'X':
+               val = va_arg(ap, long);
+               switch (c)
+               {
+                  case 'd':
+                     if (val < 0)
+                     {
+                        sign = '-';
+                        val = -val;
+                     }
+                     length = _cvt(val, buf, 10, "0123456789");
+                     break;
+                  case 'x':
+                     length = _cvt(val, buf, 16, "0123456789abcdef");
+                     break;
+                  case 'X':
+                     length = _cvt(val, buf, 16, "0123456789ABCDEF");
+                     break;
+               }
+               cp = buf;
+               break;
+            case 's':
+               cp = va_arg(ap, char *);
+               length = strlen(cp);
+               break;
+            case 'c':
+               c = va_arg(ap, long /*char*/);
+               (*putc)(c);
+               continue;
+            default:
+               (*putc)('?');
+         }
+         pad = left_prec - length;
+         if (sign != '\0')
+         {
+            pad--;
+         }
+         if (zero_fill)
+         {
+            c = '0';
+            if (sign != '\0')
+            {
+               (*putc)(sign);
+               sign = '\0';
+            }
+         } else
+         {
+            c = ' ';
+         }
+         if (!pad_on_right)
+         {
+            while (pad-- > 0)
+            {
+               (*putc)(c);
+            }
+         }
+         if (sign != '\0')
+         {
+            (*putc)(sign);
+         }
+         while (length-- > 0)
+         {
+            (*putc)(c = *cp++);
+            if (c == '\n')
+            {
+               (*putc)('\r');
+            }
+         }
+         if (pad_on_right)
+         {
+            while (pad-- > 0)
+            {
+               (*putc)(c);
+            }
+         }
+      } else
+      {
+         (*putc)(c);
+         if (c == '\n')
+         {
+            (*putc)('\r');
+         }
+      }
+   }
+}
+
+static _cvt(unsigned long val, char *buf, long radix, char *digits)
+{
+   char temp[80];
+   char *cp = temp;
+   int length = 0;
+   if (val == 0)
+   { /* Special case */
+      *cp++ = '0';
+   } else
+   while (val)
+   {
+      *cp++ = digits[val % radix];
+      val /= radix;
+   }
+   while (cp != temp)
+   {
+      *buf++ = *--cp;
+      length++;
+   }
+   *buf = '\0';
+   return (length);
+}
+
+/*
+ * Console I/O interface
+ */
+
+typedef const (*proc)();
+typedef int dev_t;
+
+#define FALSE 0
+#define TRUE  1
+
+#define CRT_PORT 0x3D4  /* Pick one */
+
+static int init = FALSE;
+static int is_crt = 0;
+static int port = 0;
+static int line_num = 0;
+#define MAX_LINES 24
+
+char
+cngetc()
+{
+   int s = _disable_interrupts();
+   char c = '\0';
+   if (port == CRT_PORT)
+   {
+      c = CRT_getc(port);
+   } else
+   if (port)
+   {
+      c = NS16550_getc(port);
+   }
+   _enable_interrupts(s);
+   return (c);
+}
+
+cntstc()
+{
+   return (0);
+}
+
+char _cn_trace[1024];
+char *_cnp = _cn_trace;
+
+/*
+ * Console kernel output character routine.
+ */
+void
+cnputc(char c)
+{
+   *_cnp++ = c;
+   if (_cnp == &_cn_trace[sizeof(_cn_trace)])
+   {
+      _cnp = _cn_trace;
+   }
+   if (!init)
+   {
+      if (is_crt = CRT_init())
+      {
+         port = CRT_PORT;
+      } else
+      {
+         port = NS16550_init(0);
+      }
+      init = TRUE;
+   }
+   if (port == CRT_PORT)
+   {
+      CRT_putc(port, c);
+   } else
+   if (port)
+   {
+      NS16550_putc(port, c);
+   }
+   if (c == '\n')
+   {
+      if (line_num >= 0) line_num++;
+   }
+   if (c == '\r')
+   {
+      if (line_num >= MAX_LINES)
+      {
+         line_num = 0;
+         _cnpause();
+      }
+   }
+}
+
+_cnpause()
+{
+   int c;
+   int s = _disable_interrupts();
+   _printk("-- More? ");
+   while ((c = cngetc()) == 0);
+   _printk("\r         \r");  /* Erase prompt */
+   if (c == ' ')
+   {
+      line_num = 0;
+   } else
+   if (c == 'n')
+   {
+      line_num = -1;  /* Turn off pause */
+   } else
+   if ((c == '\r') || (c == '\n'))
+   {
+      line_num = MAX_LINES-1;
+   } else
+   if (c == 0x03) /* ^C */
+   {
+   	abort();
+   } else
+   {
+      line_num = MAX_LINES - (MAX_LINES/3);
+   }
+   _enable_interrupts(s);
+}
+
+cnpause()
+{
+   int c;
+   int s = _disable_interrupts();
+   printk("-- More? ");
+   while ((c = cngetc()) == 0);
+   printk("\r         \r");  /* Erase prompt */
+   _enable_interrupts(s);
+}
+
+/*
+ * COM1 NS16550 support
+ */
+
+struct NS16550
+	{
+		unsigned char rbr;  /* 0 */
+		unsigned char ier;  /* 1 */
+		unsigned char fcr;  /* 2 */
+		unsigned char lcr;  /* 3 */
+		unsigned char mcr;  /* 4 */
+		unsigned char lsr;  /* 5 */
+		unsigned char msr;  /* 6 */
+		unsigned char scr;  /* 7 */
+	};
+
+#define thr rbr
+#define iir fcr
+#define dll rbr
+#define dlm ier
+
+#define LSR_DR   0x01  /* Data ready */
+#define LSR_OE   0x02  /* Overrun */
+#define LSR_PE   0x04  /* Parity error */
+#define LSR_FE   0x08  /* Framing error */
+#define LSR_BI   0x10  /* Break */
+#define LSR_THRE 0x20  /* Xmit holding register empty */
+#define LSR_TEMT 0x40  /* Xmitter empty */
+#define LSR_ERR  0x80  /* Error */
+
+#define COM1	0x800003F8
+#define COM2	0x800002F8
+
+typedef struct NS16550 *NS16550_t;
+
+const NS16550_t COM_PORTS[] = { COM1, COM2};
+
+volatile struct NS16550 *
+NS16550_init(int chan)
+{
+	volatile struct NS16550 *com_port;
+	volatile unsigned char xx;
+	com_port = (struct NS16550 *) COM_PORTS[chan];
+	/* See if port is present */
+	com_port->lcr = 0x00;
+	com_port->ier = 0xFF;
+#if 0	
+	if (com_port->ier != 0x0F) return ((struct NS16550 *)0);
+#endif	
+	com_port->ier = 0x00;
+	com_port->lcr = 0x80;  /* Access baud rate */
+	com_port->dll = 12;  /* 9600 baud */
+	com_port->dlm = 12 >> 8;
+	com_port->lcr = 0x03;  /* 8 data, 1 stop, no parity */
+	com_port->mcr = 0x03;  /* RTS/DTR */
+	com_port->fcr = 0x07;  /* Clear & enable FIFOs */
+	return (com_port);
+}
+
+
+NS16550_putc(volatile struct NS16550 *com_port, unsigned char c)
+{
+	volatile int i;
+	while ((com_port->lsr & LSR_THRE) == 0) ;
+	com_port->thr = c;
+}
+
+unsigned char NS16550_getc(volatile struct NS16550 *com_port)
+{
+	while ((com_port->lsr & LSR_DR) == 0) ;
+	return (com_port->rbr);
+}
+
+NS16550_test(volatile struct NS16550 *com_port)
+{
+	return ((com_port->lsr & LSR_DR) != 0);
+}
+
+typedef unsigned short u_short;
+typedef unsigned char  u_char;
+
+#define	COL		80
+#define	ROW		25
+#define	CHR		2
+#define MONO_BASE	0x3B4
+#define MONO_BUF	0xB0000
+#define CGA_BASE	0x3D4
+#define CGA_BUF		0xB8000
+#define ISA_mem		((unsigned char *)0xC0000000)
+#define ISA_io		((unsigned char *)0x80000000)
+
+unsigned char background = 0;
+unsigned char foreground = 6;
+
+unsigned int addr_6845;
+unsigned short *Crtat;
+int lastpos;
+int scroll;
+
+static void
+outb(int port, unsigned char c)
+{
+	ISA_io[port] = c;
+}
+
+static unsigned char
+inb(int port)
+{
+	return (ISA_io[port]);
+}
+
+/*
+ * The current state of virtual displays
+ */
+struct screen {
+	u_short *cp;		/* the current character address */
+	enum state {
+		NORMAL,			/* no pending escape */
+		ESC,			/* saw ESC */
+		EBRAC,			/* saw ESC[ */
+		EBRACEQ			/* saw ESC[= */
+	} state;		/* command parser state */
+	int	cx;		/* the first escape seq argument */
+	int	cy;		/* the second escap seq argument */
+	int	*accp;		/* pointer to the current processed argument */
+	int	row;		/* current column */
+	int	so;		/* standout mode */
+	u_short color;		/* normal character color */
+	u_short color_so;	/* standout color */
+	u_short save_color;	/* saved normal color */
+	u_short save_color_so;	/* saved standout color */
+} screen;
+
+/*
+ * Color and attributes for normal, standout and kernel output
+ * are stored in the least-significant byte of a u_short
+ * so they don't have to be shifted for use.
+ * This is all byte-order dependent.
+ */
+#define	CATTR(x) (x)		/* store color/attributes un-shifted */
+#define	ATTR_ADDR(which) (((u_char *)&(which))+1) /* address of attributes */
+
+unsigned short	pccolor;		/* color/attributes for tty output */
+unsigned short	pccolor_so;		/* color/attributes, standout mode */
+
+/*
+ * cursor() sets an offset (0-1999) into the 80x25 text area   
+ */
+static void
+cursor()
+{
+ 	int pos = screen.cp - Crtat;
+
+	if (lastpos != pos) {
+		outb(addr_6845, 14);
+		outb(addr_6845+1, pos >> 8);
+		outb(addr_6845, 15);
+		outb(addr_6845+1, pos);
+		lastpos = pos;
+	}
+}
+
+static void
+initscreen()
+{
+	struct screen *d = &screen;
+
+	pccolor = CATTR((background<<4)|foreground);
+	pccolor_so = CATTR((foreground<<4)|background);
+	d->color = pccolor;
+	d->save_color = pccolor;
+	d->color_so = pccolor_so;
+	d->save_color_so = pccolor_so;
+}
+
+
+#define	wrtchar(c, d) { \
+	*(d->cp) = c; \
+	d->cp++; \
+	d->row++; \
+}
+
+fillw(unsigned short val, unsigned short *buf, int num)
+{
+	/* Need to byte swap value */
+	unsigned short tmp;
+	tmp = val;
+	while (num-- > 0)
+	{
+		*buf++ = tmp;
+	}
+}
+
+/*
+ * CRT_putc (nee sput) has support for emulation of the 'ibmpc' termcap entry.
+ * This is a bare-bones implementation of a bare-bones entry
+ * One modification: Change li#24 to li#25 to reflect 25 lines
+ * "ca" is the color/attributes value (left-shifted by 8)
+ * or 0 if the current regular color for that screen is to be used.
+ */
+void 
+CRT_putc(int port, u_char c)
+{
+	struct screen *d = &screen;
+	u_short *base;
+	int i, j;
+	u_short *pp;
+
+	base = Crtat;
+
+	switch (d->state) {
+	case NORMAL:
+		switch (c) {
+		case 0x0:		/* Ignore pad characters */
+			return;
+
+		case 0x1B:
+			d->state = ESC;
+			break;
+
+		case '\t':
+			do {
+				wrtchar(d->color | ' ', d);
+			} while (d->row % 8);
+			break;
+
+		case '\b':  /* non-destructive backspace */
+			if (d->cp > base) {
+				d->cp--;
+				d->row--;
+				if (d->row < 0)
+					d->row += COL;	/* prev column */
+			}
+			break;
+
+		case '\r':
+			d->cp -= d->row;
+			d->row = 0;
+			break;
+
+		case '\n':
+			d->cp += COL;
+			break;
+
+		case '\007':
+			break;
+
+		default:
+			if (d->so) {
+				wrtchar(d->color_so|(c<<8), d); 
+			} else {
+				wrtchar(d->color | (c<<8), d); 
+			}
+			if (d->row >= COL)
+				d->row = 0;
+			break;
+		}
+		break;
+
+	case EBRAC:
+		/*
+		 * In this state, the action at the end of the switch
+		 * on the character type is to go to NORMAL state,
+		 * and intermediate states do a return rather than break.
+		 */
+		switch (c) {
+		case 'm':
+			d->so = d->cx;
+			break;
+
+		case 'A': /* back one row */
+			if (d->cp >= base + COL)
+				d->cp -= COL;
+			break;
+
+		case 'B': /* down one row */
+			d->cp += COL;
+			break;
+
+		case 'C': /* right cursor */
+			d->cp++;
+			d->row++;
+			break;
+
+		case 'D': /* left cursor */
+			if (d->cp > base) {
+				d->cp--;
+				d->row--;
+				if (d->row < 0)
+					d->row += COL;	/* prev column ??? */
+			}
+			break;
+
+		case 'J': /* Clear to end of display */
+			fillw(d->color|(' '<<8), d->cp, base + COL * ROW - d->cp);
+			break;
+
+		case 'K': /* Clear to EOL */
+			fillw(d->color|(' '<<8), d->cp, COL - (d->cp - base) % COL);
+			break;
+
+		case 'H': /* Cursor move */
+			if (d->cx > ROW)
+				d->cx = ROW;
+			if (d->cy > COL)
+				d->cy = COL;
+			if (d->cx == 0 || d->cy == 0) {
+				d->cp = base;
+				d->row = 0;
+			} else {
+				d->cp = base + (d->cx - 1) * COL + d->cy - 1;
+				d->row = d->cy - 1;
+			}
+			break;
+
+		case '_': /* set cursor */
+			if (d->cx)
+				d->cx = 1;		/* block */
+			else
+				d->cx = 12;	/* underline */
+			outb(addr_6845, 10);
+			outb(addr_6845+1, d->cx);
+			outb(addr_6845, 11);
+			outb(addr_6845+1, 13);
+			break;
+
+		case ';': /* Switch params in cursor def */
+			d->accp = &d->cy;
+			return;
+
+		case '=': /* ESC[= color change */
+			d->state = EBRACEQ;
+			return;
+
+		case 'L':	/* Insert line */
+			i = (d->cp - base) / COL;
+			/* avoid deficiency of bcopy implementation */
+			pp = base + COL * (ROW-2);
+			for (j = ROW - 1 - i; j--; pp -= COL)
+				bcopy(pp, pp + COL, COL * CHR);
+			fillw(d->color|(' '<<8), base + i * COL, COL);
+			break;
+			
+		case 'M':	/* Delete line */
+			i = (d->cp - base) / COL;
+			pp = base + i * COL;
+			bcopy(pp + COL, pp, (ROW-1 - i)*COL*CHR);
+			fillw(d->color|(' '<<8), base + COL * (ROW - 1), COL);
+			break;
+
+		default: /* Only numbers valid here */
+			if ((c >= '0') && (c <= '9')) {
+				*(d->accp) *= 10;
+				*(d->accp) += c - '0';
+				return;
+			} else
+				break;
+		}
+		d->state = NORMAL;
+		break;
+
+	case EBRACEQ: {
+		/*
+		 * In this state, the action at the end of the switch
+		 * on the character type is to go to NORMAL state,
+		 * and intermediate states do a return rather than break.
+		 */
+		u_char *colp;
+
+		/*
+		 * Set foreground/background color
+		 * for normal mode, standout mode
+		 * or kernel output.
+		 * Based on code from kentp@svmp03.
+		 */
+		switch (c) {
+		case 'F':
+			colp = ATTR_ADDR(d->color);
+	do_fg:
+			*colp = (*colp & 0xf0) | (d->cx);
+			break;
+
+		case 'G':
+			colp = ATTR_ADDR(d->color);
+	do_bg:
+			*colp = (*colp & 0xf) | (d->cx << 4);
+			break;
+
+		case 'H':
+			colp = ATTR_ADDR(d->color_so);
+			goto do_fg;
+
+		case 'I':
+			colp = ATTR_ADDR(d->color_so);
+			goto do_bg;
+
+		case 'S':
+			d->save_color = d->color;
+			d->save_color_so = d->color_so;
+			break;
+
+		case 'R':
+			d->color = d->save_color;
+			d->color_so = d->save_color_so;
+			break;
+
+		default: /* Only numbers valid here */
+			if ((c >= '0') && (c <= '9')) {
+				d->cx *= 10;
+				d->cx += c - '0';
+				return;
+			} else
+				break;
+		}
+		d->state = NORMAL;
+	    }
+	    break;
+
+	case ESC:
+		switch (c) {
+		case 'c':	/* Clear screen & home */
+			fillw(d->color|(' '<<8), base, COL * ROW);
+			d->cp = base;
+			d->row = 0;
+			d->state = NORMAL;
+			break;
+		case '[':	/* Start ESC [ sequence */
+			d->state = EBRAC;
+			d->cx = 0;
+			d->cy = 0;
+			d->accp = &d->cx;
+			break;
+		default: /* Invalid, clear state */
+			d->state = NORMAL;
+			break;
+		}
+		break;
+	}
+	if (d->cp >= base + (COL * ROW)) { /* scroll check */
+		bcopy(base + COL, base, COL * (ROW - 1) * CHR);
+		fillw(d->color|(' '<<8), base + COL * (ROW - 1), COL);
+		d->cp -= COL;
+	}	
+	cursor();
+}
+
+video_on()
+{ /* Enable video */
+	outb(0x3C4, 0x01);
+	outb(0x3C5, inb(0x3C5)&~20);
+}
+
+CRT_init()
+{
+	unsigned long *PCI_base = (unsigned long *)0x80808010;  /* Magic */
+	struct screen *d = &screen;
+	if (*PCI_base)
+	{ /* No CRT configured */
+		return (0);
+	}
+	video_on();
+	d->cp = Crtat = (u_short *)&ISA_mem[0x0B8000];
+	addr_6845 = CGA_BASE;
+	initscreen();
+	fillw(pccolor|(' '<<8), d->cp, COL * ROW);
+	return (1);
+}
+
+/* Keyboard handler */
+
+#define	L		0x0001	/* locking function */
+#define	SHF		0x0002	/* keyboard shift */
+#define	ALT		0x0004	/* alternate shift -- alternate chars */
+#define	NUM		0x0008	/* numeric shift  cursors vs. numeric */
+#define	CTL		0x0010	/* control shift  -- allows ctl function */
+#define	CPS		0x0020	/* caps shift -- swaps case of letter */
+#define	ASCII		0x0040	/* ascii code for this key */
+#define	STP		0x0080	/* stop output */
+#define	FUNC		0x0100	/* function key */
+#define	SCROLL		0x0200	/* scroll lock key */
+
+/* #include "pcconstab.US" */
+/*	BSDI $Id: pcconstab.US,v 1.1.1.1 1994/03/31 13:29:09 gary Exp $	*/
+/*-
+ * Copyright (c) 1990 The Regents of the University of California.
+ * All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * William Jolitz and Don Ahn.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ *    must display the following acknowledgement:
+ *	This product includes software developed by the University of
+ *	California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ *    may be used to endorse or promote products derived from this software
+ *    without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ *
+ *	from @(#)pccons.c	5.11 (Berkeley) 5/21/91
+ */
+
+/*
+ *	US Keyboard mapping tables
+ */
+
+const unsigned short action[] = {
+	0,     ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,	/* scan  0- 7 */
+	ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,	/* scan  8-15 */
+	ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,	/* scan 16-23 */
+	ASCII, ASCII, ASCII, ASCII, ASCII,   CTL, ASCII, ASCII,	/* scan 24-31 */
+	ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,	/* scan 32-39 */
+	ASCII, ASCII,   SHF, ASCII, ASCII, ASCII, ASCII, ASCII,	/* scan 40-47 */
+	ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,   SHF, ASCII,	/* scan 48-55 */
+	  ALT, ASCII,   CPS,  FUNC,  FUNC,  FUNC,  FUNC,  FUNC,	/* scan 56-63 */
+	 FUNC,  FUNC,  FUNC,  FUNC,  FUNC,   NUM,SCROLL, ASCII,	/* scan 64-71 */
+	ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII, ASCII,	/* scan 72-79 */
+	ASCII, ASCII, ASCII, ASCII,     0,     0,     0,     0,	/* scan 80-87 */
+	0,0,0,0,0,0,0,0,	/* scan 88-95 */
+	0,0,0,0,0,0,0,0,	/* scan 96-103 */
+	0,0,0,0,0,0,0,0,	/* scan 104-111 */
+	0,0,0,0,0,0,0,0,	/* scan 112-119 */
+	0,0,0,0,0,0,0,0,	/* scan 120-127 */
+};
+
+const unsigned char unshift[] = {	/* no shift */
+	  0,   033,   '1',   '2',   '3',   '4',   '5',   '6',	/* scan  0- 7 */
+	'7',   '8',   '9',   '0',   '-',   '=',   010,  '\t',	/* scan  8-15 */
+	'q',   'w',   'e',   'r',   't',   'y',   'u',   'i',	/* scan 16-23 */
+	'o',   'p',   '[',   ']',  '\r',   CTL,   'a',   's',	/* scan 24-31 */
+	'd',   'f',   'g',   'h',   'j',   'k',   'l',   ';',	/* scan 32-39 */
+	'\'',  '`',   SHF,   '\\',  'z',   'x',   'c',   'v',	/* scan 40-47 */
+	'b',   'n',   'm',   ',',   '.',   '/',   SHF,   '*',	/* scan 48-55 */
+	ALT,   ' ',   CPS,     1,     2,     3,     4,     5,	/* scan 56-63 */
+	  6,     7,     8,     9,    10,   NUM,   STP,   '7',	/* scan 64-71 */
+	'8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',	/* scan 72-79 */
+	'2',   '3',   '0',   0177,    0,     0,     0,     0,	/* scan 80-87 */
+	0,0,0,0,0,0,0,0,	/* scan 88-95 */
+	0,0,0,0,0,0,0,0,	/* scan 96-103 */
+	0,0,0,0,0,0,0,0,	/* scan 104-111 */
+	0,0,0,0,0,0,0,0,	/* scan 112-119 */
+	0,0,0,0,0,0,0,0,	/* scan 120-127 */
+};
+
+const unsigned char shift[] = {	/* shift shift */
+	  0,   033,   '!',   '@',   '#',   '$',   '%',   '^',	/* scan  0- 7 */
+	'&',   '*',   '(',   ')',   '_',   '+',   010,  '\t',	/* scan  8-15 */
+	'Q',   'W',   'E',   'R',   'T',   'Y',   'U',   'I',	/* scan 16-23 */
+	'O',   'P',   '{',   '}',  '\r',   CTL,   'A',   'S',	/* scan 24-31 */
+	'D',   'F',   'G',   'H',   'J',   'K',   'L',   ':',	/* scan 32-39 */
+	'"',   '~',   SHF,   '|',   'Z',   'X',   'C',   'V',	/* scan 40-47 */
+	'B',   'N',   'M',   '<',   '>',   '?',   SHF,   '*',	/* scan 48-55 */
+	ALT,   ' ',   CPS,     0,     0,   ' ',     0,     0,	/* scan 56-63 */
+	  0,     0,     0,     0,     0,   NUM,   STP,   '7',	/* scan 64-71 */
+	'8',   '9',   '-',   '4',   '5',   '6',   '+',   '1',	/* scan 72-79 */
+	'2',   '3',   '0',  0177,     0,     0,     0,     0,	/* scan 80-87 */
+	0,0,0,0,0,0,0,0,	/* scan 88-95 */
+	0,0,0,0,0,0,0,0,	/* scan 96-103 */
+	0,0,0,0,0,0,0,0,	/* scan 104-111 */
+	0,0,0,0,0,0,0,0,	/* scan 112-119 */
+	0,0,0,0,0,0,0,0,	/* scan 120-127 */
+};
+
+const unsigned char ctl[] = {	/* CTL shift */
+	  0,   033,   '!',   000,   '#',   '$',   '%',   036,	/* scan  0- 7 */
+	'&',   '*',   '(',   ')',   037,   '+',   034,'\177',	/* scan  8-15 */
+	021,   027,   005,   022,   024,   031,   025,   011,	/* scan 16-23 */
+	017,   020,   033,   035,  '\r',   CTL,   001,   023,	/* scan 24-31 */
+	004,   006,   007,   010,   012,   013,   014,   ';',	/* scan 32-39 */
+	'\'',  '`',   SHF,   034,   032,   030,   003,   026,	/* scan 40-47 */
+	002,   016,   015,   '<',   '>',   '?',   SHF,   '*',	/* scan 48-55 */
+	ALT,   ' ',   CPS,     0,     0,   ' ',     0,     0,	/* scan 56-63 */
+	CPS,     0,     0,     0,     0,     0,     0,     0,	/* scan 64-71 */
+	  0,     0,     0,     0,     0,     0,     0,     0,	/* scan 72-79 */
+	  0,     0,     0,  0177,     0,     0,     0,     0,	/* scan 80-87 */
+	  0,     0,   033,   '7',   '4',   '1',     0,   NUM,	/* scan 88-95 */
+	'8',   '5',   '2',     0,   STP,   '9',   '6',   '3',	/* scan 96-103*/
+	'.',     0,   '*',   '-',   '+',     0,     0,     0,	/*scan 104-111*/
+	0,0,0,0,0,0,0,0,	/* scan 112-119 */
+	0,0,0,0,0,0,0,0,	/* scan 120-127 */
+};
+
+
+unsigned char shfts, ctls, alts, caps, num, stp;
+
+#define	KBDATAP		0x60	/* kbd data port */
+#define	KBSTATUSPORT	0x61	/* kbd status */
+#define	KBSTATP		0x64	/* kbd status port */
+#define	KBINRDY		0x01
+#define	KBOUTRDY	0x02
+
+#define _x__ 0x00  /* Unknown / unmapped */
+
+const unsigned char keycode[] = {
+	_x__, 0x43, 0x41, 0x3F, 0x3D, 0x3B, 0x3C, _x__, /* 0x00-0x07 */
+	_x__, 0x44, 0x42, 0x40, 0x3E, 0x0F, 0x29, _x__, /* 0x08-0x0F */
+	_x__, 0x38, 0x2A, _x__, 0x1D, 0x10, 0x02, _x__, /* 0x10-0x17 */
+	_x__, _x__, 0x2C, 0x1F, 0x1E, 0x11, 0x03, _x__, /* 0x18-0x1F */
+	_x__, 0x2E, 0x2D, 0x20, 0x12, 0x05, 0x04, _x__, /* 0x20-0x27 */
+	_x__, 0x39, 0x2F, 0x21, 0x14, 0x13, 0x06, _x__, /* 0x28-0x2F */
+	_x__, 0x31, 0x30, 0x23, 0x22, 0x15, 0x07, _x__, /* 0x30-0x37 */
+	_x__, _x__, 0x32, 0x24, 0x16, 0x08, 0x09, _x__, /* 0x38-0x3F */
+	_x__, 0x33, 0x25, 0x17, 0x18, 0x0B, 0x0A, _x__, /* 0x40-0x47 */
+	_x__, 0x34, 0x35, 0x26, 0x27, 0x19, 0x0C, _x__, /* 0x48-0x4F */
+	_x__, _x__, 0x28, _x__, 0x1A, 0x0D, _x__, _x__, /* 0x50-0x57 */
+	0x3A, 0x36, 0x1C, 0x1B, _x__, 0x2B, _x__, _x__, /* 0x58-0x5F */
+	_x__, _x__, _x__, _x__, _x__, _x__, 0x0E, _x__, /* 0x60-0x67 */
+	_x__, 0x4F, _x__, 0x4B, 0x47, _x__, _x__, _x__, /* 0x68-0x6F */
+	0x52, 0x53, 0x50, 0x4C, 0x4D, 0x48, 0x01, 0x45, /* 0x70-0x77 */
+	_x__, 0x4E, 0x51, 0x4A, _x__, 0x49, 0x46, 0x54, /* 0x78-0x7F */
+};
+
+int
+kbd(noblock)
+	int noblock;
+{
+	unsigned char dt, brk, act;
+	int first = 1;	
+loop:
+	if (noblock) {
+		if ((inb(KBSTATP) & KBINRDY) == 0)
+			return (-1);
+	} else while((inb(KBSTATP) & KBINRDY) == 0)
+		;
+	dt = inb(KBDATAP);
+
+	brk = dt & 0x80;	/* brk == 1 on key release */
+	dt = dt & 0x7f;		/* keycode */
+
+	act = action[dt];
+	if (act&SHF)
+		shfts = brk ? 0 : 1;
+	if (act&ALT)
+		alts = brk ? 0 : 1;
+	if (act&NUM)
+		if (act&L) {
+			/* NUM lock */
+			if(!brk)
+				num = !num;
+		} else
+			num = brk ? 0 : 1;
+	if (act&CTL)
+		ctls = brk ? 0 : 1;
+	if (act&CPS)
+		if (act&L) {
+			/* CAPS lock */
+			if(!brk)
+				caps = !caps;
+		} else
+			caps = brk ? 0 : 1;
+	if (act&STP)
+		if (act&L) {
+			if(!brk)
+				stp = !stp;
+		} else
+			stp = brk ? 0 : 1;
+
+	if ((act&ASCII) && !brk) {
+		unsigned char chr;
+
+		if (shfts)
+			chr = shift[dt];
+		else if (ctls)
+			chr = ctl[dt];
+		else
+			chr = unshift[dt];
+
+		if (alts)
+			chr |= 0x80;
+
+		if (caps && (chr >= 'a' && chr <= 'z'))
+			chr -= 'a' - 'A' ;
+#define CTRL(s) (s & 0x1F)			
+		if ((chr == '\r') || (chr == '\n') || (chr == CTRL('A')) || (chr == CTRL('S')))
+		{
+			/* Wait for key up */
+			while (1)
+			{
+				while((inb(KBSTATP) & KBINRDY) == 0) ;
+				dt = inb(KBDATAP);
+				if (dt & 0x80) /* key up */ break;
+			}
+		}
+		return (chr);
+	}
+	if (first && brk) return (0);  /* Ignore initial 'key up' codes */
+	goto loop;
+}
+
+scankbd() {
+	return (kbd(1) != -1);
+}
+
+kbdreset()
+{
+	unsigned char c;
+
+	/* Enable interrupts and keyboard controller */
+	while (inb(KBSTATP) & KBOUTRDY)
+		;
+	outb(KBSTATP,0x60);
+	while (inb(KBSTATP) & KBOUTRDY)
+		;
+	outb(KBDATAP,0x4D);
+
+	/* Start keyboard stuff RESET */
+	while (inb(KBSTATP) & KBOUTRDY)
+		;	/* wait input ready */
+	outb(KBDATAP,0xFF);	/* RESET */
+
+	while ((c = inb(KBDATAP)) != 0xFA)
+		;
+}
+
+CRT_getc()
+{
+	int c;
+	while ((c = kbd(0)) == 0) ;
+	return(c);
+}
+
+CRT_test()
+{
+	return ((inb(KBSTATP) & KBINRDY) != 0);
+}
+
+
+_dump_buf_with_offset(unsigned char *p, int s, unsigned char *base)
+{
+   int i, c;
+   if ((unsigned int)s > (unsigned int)p)
+   {
+   	s = (unsigned int)s - (unsigned int)p;
+   }
+   while (s > 0)
+   {
+      if (base)
+      {
+         _printk("%06X: ", (int)p - (int)base);
+      } else
+      {
+         _printk("%06X: ", p);
+      }
+      for (i = 0;  i < 16;  i++)
+      {
+         if (i < s)
+         {
+            _printk("%02X", p[i] & 0xFF);
+         } else
+         {
+            _printk("  ");
+         }
+         if ((i % 2) == 1) _printk(" ");
+         if ((i % 8) == 7) _printk(" ");
+      }
+      _printk(" |");
+      for (i = 0;  i < 16;  i++)
+      {
+         if (i < s)
+         {
+            c = p[i] & 0xFF;
+            if ((c < 0x20) || (c >= 0x7F)) c = '.';
+         } else
+         {
+            c = ' ';
+         }
+         _printk("%c", c);
+      }
+      _printk("|\n");
+      s -= 16;
+      p += 16;
+   }
+}
+
+_dump_buf(unsigned char *p, int s)
+{
+   _dump_buf_with_offset(p, s, 0);
+}
+
+
+dump_buf_with_offset(unsigned char *p, int s, unsigned char *base)
+{
+   int i, c;
+   if ((unsigned int)s > (unsigned int)p)
+   {
+   	s = (unsigned int)s - (unsigned int)p;
+   }
+   while (s > 0)
+   {
+      if (base)
+      {
+         printk("%06X: ", (int)p - (int)base);
+      } else
+      {
+         printk("%06X: ", p);
+      }
+      for (i = 0;  i < 16;  i++)
+      {
+         if (i < s)
+         {
+            printk("%02X", p[i] & 0xFF);
+         } else
+         {
+            printk("  ");
+         }
+         if ((i % 2) == 1) printk(" ");
+         if ((i % 8) == 7) printk(" ");
+      }
+      printk(" |");
+      for (i = 0;  i < 16;  i++)
+      {
+         if (i < s)
+         {
+            c = p[i] & 0xFF;
+            if ((c < 0x20) || (c >= 0x7F)) c = '.';
+         } else
+         {
+            c = ' ';
+         }
+         printk("%c", c);
+      }
+      printk("|\n");
+      s -= 16;
+      p += 16;
+   }
+}
+
+dump_buf(unsigned char *p, int s)
+{
+   dump_buf_with_offset(p, s, 0);
+}
+
+
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/setup.c linux/arch/ppc/kernel/setup.c
--- v1.3.44/linux/arch/ppc/kernel/setup.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/setup.c	Wed Nov 15 00:37:15 1995
@@ -0,0 +1,172 @@
+/*
+ *  linux/arch/ppc/kernel/setup.c
+ *
+ *  Copyright (C) 1995  Linus Torvalds
+ *  Adapted from 'alpha' version by Gary Thomas
+ */
+
+/*
+ * bootup setup stuff..
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/malloc.h>
+#include <linux/ldt.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+#include <linux/tty.h>
+
+#include <asm/pgtable.h>
+extern PTE *Hash;
+extern unsigned long Hash_size, Hash_mask;
+
+char sda_root[] = "root=/dev/sda1";
+
+unsigned char aux_device_present;
+int get_cpuinfo(char *buffer)
+{
+}
+/*
+ * The format of "screen_info" is strange, and due to early
+ * i386-setup code. This is just enough to make the console
+ * code think we're on a EGA+ colour display.
+ */
+struct screen_info screen_info = {
+	0, 0,			/* orig-x, orig-y */
+	0, 0,			/* unused */
+	0,			/* orig-video-page */
+	0,			/* orig-video-mode */
+	80,			/* orig-video-cols */
+	0,0,0,			/* ega_ax, ega_bx, ega_cx */
+	25			/* orig-video-lines */
+};
+
+unsigned long bios32_init(unsigned long memory_start, unsigned long memory_end)
+{
+	return memory_start;
+}
+
+unsigned long find_end_of_memory(void)
+{
+	unsigned char dram_size = inb(0x0804);
+	unsigned long total;
+_printk("DRAM Size = %x\n", dram_size);
+_printk("Config registers = %x/%x/%x\n", inb(0x0800), inb(0x0801), inb(0x0802));
+	switch (dram_size & 0x07)
+	{
+		case 0:
+			total = 0x08000000;  /* 128M */
+			break;
+		case 1:
+			total = 0x02000000;  /* 32M */
+			break;
+		case 2:
+			total = 0x00800000;  /* 8M */
+			break;
+		case 3:
+			total = 0x00400000;  /* 4M - can't happen! */
+			break;
+		case 4:
+			total = 0x10000000;  /* 256M */
+			break;
+		case 5:
+			total = 0x04000000;  /* 64M */
+			break;
+		case 6:
+			total = 0x01000000;  /* 16M */
+			break;
+		case 7:
+			total = 0x04000000;  /* Can't happen */
+			break;
+	}
+	switch ((dram_size>>4) & 0x07)
+	{
+		case 0:
+			total += 0x08000000;  /* 128M */
+			break;
+		case 1:
+			total += 0x02000000;  /* 32M */
+			break;
+		case 2:
+			total += 0x00800000;  /* 8M */
+			break;
+		case 3:
+			total += 0x00000000;  /* Module not present */
+			break;
+		case 4:
+			total += 0x10000000;  /* 256M */
+			break;
+		case 5:
+			total += 0x04000000;  /* 64M */
+			break;
+		case 6:
+			total += 0x01000000;  /* 16M */
+			break;
+		case 7:
+			total += 0x00000000;  /* Module not present */
+			break;
+	}
+_printk("register total = %08X\n", total);	
+/* TEMP */ total = 0x01000000;
+/*_cnpause();	*/
+/* CAUTION!! This can be done more elegantly! */	
+	if (total < 0x01000000)
+	{
+		Hash_size = HASH_TABLE_SIZE_64K;
+		Hash_mask = HASH_TABLE_MASK_64K;
+	} else
+	{
+		Hash_size = HASH_TABLE_SIZE_128K;
+		Hash_mask = HASH_TABLE_MASK_128K;
+	}
+	Hash = (PTE *)((total-Hash_size)+KERNELBASE);
+	bzero(Hash, Hash_size);
+	return ((unsigned long)Hash);
+}
+
+int size_memory;
+
+#define DEFAULT_ROOT_DEVICE 0x0200	/* fd0 */
+
+void setup_arch(char **cmdline_p,
+	unsigned long * memory_start_p, unsigned long * memory_end_p)
+{
+
+  extern int _end;
+	extern char cmd_line[];
+
+	ROOT_DEV = DEFAULT_ROOT_DEVICE;
+	aux_device_present = 0xaa;
+	*cmdline_p = cmd_line;
+	*memory_start_p = (unsigned long) &_end;
+	*memory_end_p = (unsigned long *)Hash;
+	size_memory = *memory_end_p - KERNELBASE;  /* Relative size of memory */
+
+/*	_printk("setup_arch() done!  memory_start = %08X memory_end = %08X\n"
+		,*memory_start_p,*memory_end_p);*/
+
+}
+
+asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on)
+{
+	return -EIO;
+}
+
+extern char builtin_ramdisk_image;
+extern long builtin_ramdisk_size;
+
+void
+builtin_ramdisk_init(void)
+{
+	if (ROOT_DEV == DEFAULT_ROOT_DEVICE)
+	{
+		rd_preloaded_init(&builtin_ramdisk_image, builtin_ramdisk_size);
+	}
+}
+
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/signal.c linux/arch/ppc/kernel/signal.c
--- v1.3.44/linux/arch/ppc/kernel/signal.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/signal.c	Tue Oct 24 21:30:25 1995
@@ -0,0 +1,234 @@
+/*
+ *  linux/arch/ppc/kernel/signal.c
+ *
+ *  Copyright (C) 1991, 1992  Linus Torvalds
+ *  Adapted for PowerPC by Gary Thomas
+ */
+
+#include <linux/sched.h>
+#include <linux/mm.h>
+#include <linux/kernel.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/wait.h>
+#include <linux/ptrace.h>
+#include <linux/unistd.h>
+
+#define _S(nr) (1<<((nr)-1))
+
+#define _BLOCKABLE (~(_S(SIGKILL) | _S(SIGSTOP)))
+
+asmlinkage int sys_waitpid(pid_t pid,unsigned long * stat_addr, int options);
+
+/*
+ * atomically swap in the new signal mask, and wait for a signal.
+ */
+asmlinkage int sys_sigsuspend(unsigned long set, int p2, int p3, int p4, int p6, int p7, struct pt_regs *regs)
+{
+	unsigned long mask;
+
+	mask = current->blocked;
+	current->blocked = set & _BLOCKABLE;
+	regs->gpr[3] = -EINTR;
+#if 0	
+printk("Task: %x[%d] - SIGSUSPEND at %x, Mask: %x\n", current, current->pid, regs->nip, set);	
+#endif
+	while (1) {
+		current->state = TASK_INTERRUPTIBLE;
+		schedule();
+		if (do_signal(mask,regs))
+			return -EINTR;
+	}
+}
+
+/*
+ * This sets regs->esp even though we don't actually use sigstacks yet..
+ */
+asmlinkage int sys_sigreturn(struct pt_regs *regs)
+{
+	struct sigcontext_struct *sc;
+	struct pt_regs *int_regs;
+	int signo;
+	sc = (struct sigcontext_struct *)regs->gpr[1];
+	current->blocked = sc->oldmask & _BLOCKABLE;
+	int_regs = sc->regs;
+	signo = sc->signal;
+	sc++;  /* Pop signal 'context' */
+	if (sc == (struct sigcontext_struct *)(int_regs))
+	{ /* Last stacked signal */
+		memcpy(regs, int_regs, sizeof(*regs));
+		if ((int)regs->orig_gpr3 >= 0 &&
+		    ((int)regs->result == -ERESTARTNOHAND ||
+		     (int)regs->result == -ERESTARTSYS ||
+		     (int)regs->result == -ERESTARTNOINTR))
+		{
+			regs->gpr[3] = regs->orig_gpr3;
+			regs->nip -= 4; /* Back up & retry system call */
+			regs->result = 0;
+		}
+		return (regs->result);
+	} else
+	{ /* More signals to go */
+		regs->gpr[1] = (unsigned long)sc;
+		regs->gpr[3] = sc->signal;
+		regs->gpr[4] = sc->regs;
+		regs->link = (unsigned long)((sc->regs)+1);
+		regs->nip = sc->handler;
+		return (sc->signal);
+	}
+}
+
+
+/*
+ * Note that 'init' is a special process: it doesn't get signals it doesn't
+ * want to handle. Thus you cannot kill init even with a SIGKILL even by
+ * mistake.
+ *
+ * Note that we go through the signals twice: once to check the signals that
+ * the kernel can handle, and then we build all the user-level signal handling
+ * stack-frames in one go after that.
+ */
+asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs)
+{
+	unsigned long mask = ~current->blocked;
+	unsigned long handler_signal = 0;
+	unsigned long *frame = NULL;
+	unsigned long *trampoline;
+	unsigned long *regs_ptr;
+	unsigned long nip = 0;
+	unsigned long signr;
+	int bitno;
+	struct sigcontext_struct *sc;
+	struct sigaction * sa;
+	int s = _disable_interrupts();
+
+	while ((signr = current->signal & mask)) {
+#if 0
+		signr = ffz(~signr);  /* Compute bit # */
+#else
+		for (bitno = 0;  bitno < 32;  bitno++)
+		{
+			if (signr & (1<<bitno)) break;
+		}
+		signr = bitno;
+#endif		
+		current->signal &= ~(1<<signr);  /* Clear bit */
+		sa = current->sig->action + signr;
+		signr++;
+		if ((current->flags & PF_PTRACED) && signr != SIGKILL) {
+			current->exit_code = signr;
+			current->state = TASK_STOPPED;
+			notify_parent(current);
+			schedule();
+			if (!(signr = current->exit_code))
+				continue;
+			current->exit_code = 0;
+			if (signr == SIGSTOP)
+				continue;
+			if (_S(signr) & current->blocked) {
+				current->signal |= _S(signr);
+				continue;
+			}
+			sa = current->sig->action + signr - 1;
+		}
+		if (sa->sa_handler == SIG_IGN) {
+			if (signr != SIGCHLD)
+				continue;
+			/* check for SIGCHLD: it's special */
+			while (sys_waitpid(-1,NULL,WNOHANG) > 0)
+				/* nothing */;
+			continue;
+		}
+		if (sa->sa_handler == SIG_DFL) {
+			if (current->pid == 1)
+				continue;
+			switch (signr) {
+			case SIGCONT: case SIGCHLD: case SIGWINCH:
+				continue;
+
+			case SIGSTOP: case SIGTSTP: case SIGTTIN: case SIGTTOU:
+				if (current->flags & PF_PTRACED)
+					continue;
+				current->state = TASK_STOPPED;
+				current->exit_code = signr;
+				if (!(current->p_pptr->sig->action[SIGCHLD-1].sa_flags &
+						SA_NOCLDSTOP))
+					notify_parent(current);
+				schedule();
+				continue;
+
+			case SIGQUIT: case SIGILL: case SIGTRAP:
+			case SIGIOT: case SIGFPE: case SIGSEGV:
+				if (current->binfmt && current->binfmt->core_dump) {
+					if (current->binfmt->core_dump(signr, regs))
+						signr |= 0x80;
+				}
+				/* fall through */
+			default:
+				current->signal |= _S(signr & 0x7f);
+				do_exit(signr);
+			}
+		}
+		/*
+		 * OK, we're invoking a handler
+		 */
+		if ((int)regs->orig_gpr3 >= 0) {
+			if ((int)regs->result == -ERESTARTNOHAND ||
+			   ((int)regs->result == -ERESTARTSYS && !(sa->sa_flags & SA_RESTART)))
+				(int)regs->result = -EINTR;
+		}
+		handler_signal |= 1 << (signr-1);
+		mask &= ~sa->sa_mask;
+	}
+	if (!handler_signal)		/* no handler will be called - return 0 */
+	{
+		_enable_interrupts(s);
+		return 0;
+	}
+	nip = regs->nip;
+	frame = (unsigned long *) regs->gpr[1];
+	/* Build trampoline code on stack */
+	frame -= 2;
+	trampoline = frame;
+	trampoline[0] = 0x38007777;  /* li r0,0x7777 */
+	trampoline[1] = 0x44000002;  /* sc           */
+	frame -= sizeof(*regs) / sizeof(long);
+	regs_ptr = frame;
+	memcpy(regs_ptr, regs, sizeof(*regs));
+	signr = 1;
+	sa = current->sig->action;
+	for (mask = 1 ; mask ; sa++,signr++,mask += mask) {
+		if (mask > handler_signal)
+			break;
+		if (!(mask & handler_signal))
+			continue;
+		frame -= sizeof(struct sigcontext_struct) / sizeof(long);
+		sc = (struct sigcontext_struct *)frame;
+		nip = (unsigned long) sa->sa_handler;
+#if 0 /* Old compiler */		
+		nip = *(unsigned long *)nip;
+#endif		
+		if (sa->sa_flags & SA_ONESHOT)
+			sa->sa_handler = NULL;
+		sc->handler = nip;
+		sc->oldmask = current->blocked;
+		sc->regs = (unsigned long)regs_ptr;
+		sc->signal = signr;
+		current->blocked |= sa->sa_mask;
+		regs->gpr[3] = signr;
+		regs->gpr[4] = (unsigned long)regs_ptr;
+	}
+	regs->link = (unsigned long)trampoline;
+	regs->nip = nip;
+	regs->gpr[1] = (unsigned long)sc;
+	/* The DATA cache must be flushed here to insure coherency */
+	/* between the DATA & INSTRUCTION caches.  Since we just */
+	/* created an instruction stream using the DATA [cache] space */
+	/* and since the instruction cache will not look in the DATA */
+	/* cache for new data, we have to force the data to go on to */
+	/* memory and flush the instruction cache to force it to look */
+	/* there.  The following function performs this magic */
+	flush_instruction_cache();
+	_enable_interrupts(s);
+	return 1;
+}
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/stubs.c linux/arch/ppc/kernel/stubs.c
--- v1.3.44/linux/arch/ppc/kernel/stubs.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/stubs.c	Tue Oct 31 10:43:13 1995
@@ -0,0 +1,114 @@
+#include <linux/in.h>
+
+void sys_ptrace(void) { _panic("sys_ptrace"); }
+void sys_iopl(void) { _panic("sys_iopl"); }
+void sys_vm86(void) { _panic("sys_vm86"); }
+void sys_modify_ldt(void) { _panic("sys_modify_ldt"); }
+void sys_quotactl(void) { _panic("sys_quotactl"); }
+
+void sys_pipe(void) {_panic("sys_pipe"); }
+void sys_ipc(void) {_panic("sys_ipc"); }
+void sys_mmap(void) {_panic("sys_mmap"); }
+void sys_readdir(void) {_panic("sys_readdir"); }
+
+
+halt()
+{
+	_printk("\n...Halt!\n");
+	abort();
+}
+
+_panic(char *msg)
+{
+	_printk("Panic: %s\n", msg);
+	printk("Panic: %s\n", msg);
+	abort();
+}
+
+_warn(char *msg)
+{
+	_printk("*** Warning: %s UNIMPLEMENTED!\n", msg);
+}
+
+extern unsigned short _ip_fast_csum(unsigned char *buf, int len);
+
+unsigned short
+ip_fast_csum(unsigned char *buf, int len)
+{
+	unsigned short _val;
+	_val = _ip_fast_csum(buf, len);
+#if 0	
+	printk("IP CKSUM(%x, %d) = %x\n", buf, len, _val);
+#endif	
+	return (_val);
+}
+
+extern unsigned short _ip_compute_csum(unsigned char *buf, int len);
+
+unsigned short
+ip_compute_csum(unsigned char *buf, int len)
+{
+	unsigned short _val;
+	_val = _ip_compute_csum(buf, len);
+#if 0	
+	printk("Compute IP CKSUM(%x, %d) = %x\n", buf, len, _val);
+#endif	
+	return (_val);
+}
+
+unsigned short
+_udp_check(unsigned char *buf, int len, int saddr, int daddr, int hdr);
+
+unsigned short
+udp_check(unsigned char *buf, int len, int saddr, int daddr)
+{
+	unsigned short _val;
+	int hdr;
+	hdr = (len << 16) + IPPROTO_UDP;
+	_val = _udp_check(buf, len, saddr, daddr, hdr);
+#if 0	
+	printk("UDP CSUM(%x,%d,%x,%x) = %x\n", buf, len, saddr, daddr, _val);
+	dump_buf(buf, len);
+#endif	
+	return (_val);
+}
+#if 0
+unsigned short
+_tcp_check(unsigned char *buf, int len, int saddr, int daddr, int hdr);
+
+unsigned short
+tcp_check(unsigned char *buf, int len, int saddr, int daddr)
+{
+	unsigned short _val;
+	int hdr;
+	hdr = (len << 16) + IPPROTO_TCP;
+	if (saddr == 0) saddr = ip_my_addr();
+	_val = _tcp_check(buf, len, saddr, daddr, hdr);
+#if 0	
+	printk("TCP CSUM(%x,%d,%x,%x) = %x\n", buf, len, saddr, daddr, _val);
+	dump_buf(buf, len);
+#endif	
+	return (_val);
+}
+#endif
+_do_bottom_half()
+{
+	_enable_interrupts(1);
+	do_bottom_half();
+	_disable_interrupts();
+}
+
+unsigned int csum_partial(unsigned char * buff, int len, unsigned int sum)
+{
+  panic("csum_partial");
+}
+
+
+unsigned int csum_partial_copy(char *src, char *dst, int len, int sum)
+{
+  panic("csum_partial_copy");
+}
+
+unsigned int csum_tcpudp_magic()
+{
+  }
Binary files v1.3.44/linux/arch/ppc/kernel/test and linux/arch/ppc/kernel/test differ
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/test.S linux/arch/ppc/kernel/test.S
--- v1.3.44/linux/arch/ppc/kernel/test.S	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/test.S	Sun Oct 15 01:08:24 1995
@@ -0,0 +1,100 @@
+#include "ppc_asm.tmpl"
+#include "ppc_defs.h"
+
+#define SYNC() \
+	isync; \
+	sync
+
+#define BEEF ori r0,r0,0; ori r0,r0,0 ;.word 0 ; .word 0xBEEF
+_BEG:	
+	lis	r7,0xF000		/* To mask upper 4 bits */
+	
+
+/* Initialize BAT registers */
+	lis	r3,OFF_BAT@h
+	ori	r3,r3,OFF_BAT@l
+	andc	r3,r3,r7	/* make unmapped address */
+	lwz	r0,0(r3)
+
+	mtspr	IBAT0U,r0
+	mtspr	DBAT0U,r0
+	lwz	r0,4(r3)
+	mtspr	IBAT0L,r0
+	mtspr	DBAT0L,r0
+	
+	lis	r3,OFF_BAT@h
+	ori	r3,r3,OFF_BAT@l
+	andc	r3,r3,r7	/* make unmapped address */
+	lwz	r0,0(r3)
+	mtspr	IBAT1U,r0
+	mtspr	DBAT1U,r0
+	lwz	r0,4(r3)
+	mtspr	IBAT1L,r0
+	mtspr	DBAT1L,r0
+	
+	lis	r3,ZERO_BAT@h
+	ori	r3,r3,ZERO_BAT@l
+	andc	r3,r3,r7	/* make unmapped address */
+	lwz	r0,0(r3)
+	mtspr	IBAT2U,r0
+	mtspr	DBAT2U,r0
+	lwz	r0,4(r3)
+	mtspr	IBAT2L,r0
+	mtspr	DBAT2L,r0
+
+
+	lis	r3,TMP_BAT2@h
+	ori	r3,r3,TMP_BAT2@l
+	andc	r3,r3,r7	/* make unmapped address */
+	lwz	r0,0(r3)
+	mtspr	IBAT3U,r0
+	mtspr	DBAT3U,r0
+	lwz	r0,4(r3)
+	mtspr	IBAT3L,r0
+	mtspr	DBAT3L,r0
+	
+
+/* Now we can turn on the MMU */
+/* set srr1 for rfi */
+	mfmsr	r3
+	ori	r3,r3,MSR_DR|MSR_IR|MSR_
+
+	mtspr	SRR1,r3
+
+/* set srr0 for rfi */
+	subf	r2, r2, r2
+/*	lis	r2,10f@h*/
+	lis	r2,0
+	ori	r2,r2,10f@l
+	mtspr	SRR0,r2
+
+	SYNC()
+	rfi
+
+	ori r0, r0, 0
+	ori r0, r0, 0
+10:	ori r0, r0, 0
+	ori r0, r0, 0
+	BEEF
+	
+#if 0	
+/* check bptr to see if it actually has the correct values */
+
+	subf	r2,r2,r2
+	lis	r2,bptr@h
+	ori	r2,r2,bptr@l
+	lwz	r0,0(r2)
+
+/* rfi to the beef */
+	mtspr	SRR1,r3
+	mtspr	SRR0,r2
+
+	SYNC()
+	rfi	
+		
+bptr:	ori r0, r0, 0
+	BEEF
+	BEEF
+	BEEF
+#endif
+_END:	
\ No newline at end of file
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/test1.c linux/arch/ppc/kernel/test1.c
--- v1.3.44/linux/arch/ppc/kernel/test1.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/test1.c	Sat Oct 14 23:42:46 1995
@@ -0,0 +1,145 @@
+
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/head.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+
+#include <asm/pgtable.h>
+
+/*pgd_t *swapper_pg_dir;*/
+
+
+
+BAT BAT0 =
+   {
+   	{
+   		0x80000000>>17, 	/* bepi */
+   		BL_256M,		/* bl */
+   		1,			/* vs */
+   		1,			/* vp */
+   	},
+   	{
+   		0x80000000>>17,		/* brpn */
+   		1,			/* w */
+   		1,			/* i (cache disabled) */
+   		0,			/* m */
+   		0,			/* g */
+   		BPP_RW			/* pp */
+   	}
+   };
+BAT BAT1 =
+   {
+   	{
+   		0xC0000000>>17, 	/* bepi */
+   		BL_256M,		/* bl */
+   		1,			/* vs */
+   		1,			/* vp */
+   	},
+   	{
+   		0xC0000000>>17,		/* brpn */
+   		1,			/* w */
+   		1,			/* i (cache disabled) */
+   		0,			/* m */
+   		0,			/* g */
+   		BPP_RW			/* pp */
+   	}
+   };
+BAT BAT2 =
+   {
+   	{
+   		0x00000000>>17, 	/* bepi */
+   		BL_256M,		/* bl */
+   		0,			/* vs */
+   		0,			/* vp */
+   	},
+   	{
+   		0x00000000>>17,		/* brpn */
+   		1,			/* w */
+   		1,			/* i (cache disabled) */
+   		0,			/* m */
+   		0,			/* g */
+   		BPP_RW			/* pp */
+   	}
+   };
+BAT BAT3 =
+   {
+   	{
+   		0x00000000>>17, 	/* bepi */
+   		BL_256M,		/* bl */
+   		0,			/* vs */
+   		0,			/* vp */
+   	},
+   	{
+   		0x00000000>>17,		/* brpn */
+   		1,			/* w */
+   		1,			/* i (cache disabled) */
+   		0,			/* m */
+   		0,			/* g */
+   		BPP_RW			/* pp */
+   	}
+   };
+
+
+BAT TMP_BAT2 =
+   { /* 0x9XXXXXXX -> 0x0XXXXXXX */
+   	{
+   		0x90000000>>17, 	/* bepi */
+   		BL_256M,		/* bl */
+   		1,			/* vs */
+   		1,			/* vp */
+   	},
+   	{
+   		0x00000000>>17,		/* brpn */
+   		1,			/* w */
+   		0,			/* i (cache enabled) */
+   		0,			/* m */
+   		0,			/* g */
+   		BPP_RW			/* pp */
+   	}
+   };
+
+
+
+BAT ZERO_BAT =
+   { /* 0x0XXXXXXX -> 0x0XXXXXXX */
+   	{
+   		0x00000000>>17, 	/* bepi */
+   		BL_256M,		/* bl */
+   		1,			/* vs */
+   		1,			/* vp */
+   	},
+   	{
+   		0x00000000>>17,		/* brpn */
+   		1,			/* w */
+   		0,			/* i (cache enabled) */
+   		0,			/* m */
+   		0,			/* g */
+   		BPP_RW			/* pp */
+   	}
+   };
+
+
+BAT OFF_BAT =
+   { /* 0x0XXXXXXX -> 0x0XXXXXXX */
+   	{
+   		0x00000000>>17, 	/* bepi */
+   		BL_256M,		/* bl */
+   		0,			/* vs */
+   		0,			/* vp */
+   	},
+   	{
+   		0x00000000>>17,		/* brpn */
+   		1,			/* w */
+   		0,			/* i (cache enabled) */
+   		0,			/* m */
+   		0,			/* g */
+   		BPP_RW			/* pp */
+   	}
+   };
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/kernel/traps.c linux/arch/ppc/kernel/traps.c
--- v1.3.44/linux/arch/ppc/kernel/traps.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/kernel/traps.c	Sat Nov 25 13:52:23 1995
@@ -0,0 +1,119 @@
+/*
+ *  linux/arch/ppc/kernel/traps.c
+ *
+ *  Copyright (C) 1995  Gary Thomas
+ *  Adapted for PowerPC by Gary THomas
+ */
+
+/*
+ * This file handles the architecture-dependent parts of hardware exceptions
+ */
+
+#include <linux/errno.h>
+#include <linux/sched.h>
+#include <linux/kernel.h>
+#include <linux/mm.h>
+#include <linux/stddef.h>
+#include <linux/unistd.h>
+#include <linux/ptrace.h>
+#include <linux/malloc.h>
+#include <linux/ldt.h>
+#include <linux/user.h>
+#include <linux/a.out.h>
+
+#include <asm/pgtable.h>
+#include <asm/segment.h>
+#include <asm/system.h>
+#include <asm/io.h>
+
+#include <asm/processor.h>
+
+/*
+ * Trap & Exception support
+ */
+
+void
+trap_init(void)
+{
+}
+
+void
+_exception(int signr, struct pt_regs *regs)
+{
+	dump_regs(regs);
+	send_sig(signr, current, 1);
+	if (!user_mode(regs))
+	{
+		printk("Failure in kernel at PC: %x, MSR: %x\n", regs->nip, regs->msr);
+		while (1) ;
+	}
+}
+
+MachineCheckException(struct pt_regs *regs)
+{
+	unsigned long *eagle_ip = (unsigned long *)0x80000CF8;
+	unsigned long *eagle_id = (unsigned long *)0x80000CFC;
+	printk("Machine check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);
+#if 0	
+	*eagle_ip = 0xC0000080;  /* Memory error register */
+	printk("Error regs = %08X", *eagle_id);
+	*eagle_ip = 0xC4000080;  /* Memory error register */
+	printk("/%08X", *eagle_id);
+	*eagle_ip = 0xC8000080;  /* Memory error register */
+	printk("/%08X\n", *eagle_id);
+#endif
+	_exception(SIGSEGV, regs);	
+}
+
+ProgramCheckException(struct pt_regs *regs)
+{
+	printk("Program check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);
+	_exception(SIGILL, regs);	
+}
+
+FloatingPointCheckException(struct pt_regs *regs)
+{
+	printk("Floating point check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);
+	_exception(SIGFPE, regs);	
+}
+
+AlignmentException(struct pt_regs *regs)
+{
+	printk("Alignment error at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);
+	_exception(SIGBUS, regs);	
+}
+
+bad_stack(struct pt_regs *regs)
+{
+	printk("Kernel stack overflow at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);
+	dump_regs(regs);
+	while (1) ;
+}
+
+dump_regs(struct pt_regs *regs)
+{
+	int i;
+	printk("NIP: %08X, MSR: %08X, XER: %08X, LR: %08X, FRAME: %08X\n", regs->nip, regs->msr, regs->xer, regs->link, regs);
+	printk("HASH = %08X/%08X, MISS = %08X/%08X, CMP = %08X/%08X\n", regs->hash1, regs->hash2, regs->imiss, regs->dmiss, regs->icmp, regs->dcmp);
+	printk("TASK = %x[%d] '%s'\n", current, current->pid, current->comm);
+	for (i = 0;  i < 32;  i++)
+	{
+		if ((i % 8) == 0)
+		{
+			printk("GPR%02d: ", i);
+		}
+		printk("%08X ", regs->gpr[i]);
+		if ((i % 8) == 7)
+		{
+			printk("\n");
+		}
+	}
+	dump_buf(regs->nip, 32);
+	dump_buf((regs->nip&0x0FFFFFFF)|KERNELBASE, 32);
+}
+
+trace_syscall(struct pt_regs *regs)
+{
+	printk("Task: %08X(%d), PC: %08X/%08X, Syscall: %3d, Result: %d\n", current, current->pid, regs->nip, regs->link, regs->gpr[0], regs->gpr[3]);
+}
+
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/ld.script linux/arch/ppc/ld.script
--- v1.3.44/linux/arch/ppc/ld.script	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/ld.script	Fri Oct 13 22:12:57 1995
@@ -0,0 +1,74 @@
+OUTPUT_ARCH(powerpc)
+/*SEARCH_DIR(/lib); SEARCH_DIR(/usr/lib); SEARCH_DIR(/usr/local/lib);*/ SEARCH_DIR(/usr/local/powerpc-any-elf/lib);
+/* Do we need any of these for elf?
+   __DYNAMIC = 0;    */
+SECTIONS
+{
+  /* Read-only sections, merged into text segment: */
+  . = + SIZEOF_HEADERS;
+  .interp : { *(.interp) }
+  .hash          : { *(.hash)		}
+  .dynsym        : { *(.dynsym)		}
+  .dynstr        : { *(.dynstr)		}
+  .rel.text      : { *(.rel.text)		}
+  .rela.text     : { *(.rela.text) 	}
+  .rel.data      : { *(.rel.data)		}
+  .rela.data     : { *(.rela.data) 	}
+  .rel.rodata    : { *(.rel.rodata) 	}
+  .rela.rodata   : { *(.rela.rodata) 	}
+  .rel.got       : { *(.rel.got)		}
+  .rela.got      : { *(.rela.got)		}
+  .rel.ctors     : { *(.rel.ctors)	}
+  .rela.ctors    : { *(.rela.ctors)	}
+  .rel.dtors     : { *(.rel.dtors)	}
+  .rela.dtors    : { *(.rela.dtors)	}
+  .rel.bss       : { *(.rel.bss)		}
+  .rela.bss      : { *(.rela.bss)		}
+  .rel.plt       : { *(.rel.plt)		}
+  .rela.plt      : { *(.rela.plt)		}
+  .init          : { *(.init)	} =0
+  .plt : { *(.plt) }
+  .text      :
+  {
+    *(.text)
+    *(.rodata)
+    *(.rodata1)
+    *(.got1)
+  }
+  _etext = .;
+  PROVIDE (etext = .);
+  .fini      : { *(.fini)    } =0
+  .ctors     : { *(.ctors)   }
+  .dtors     : { *(.dtors)   }
+  /* Read-write section, merged into data segment: */
+  .data    :
+  {
+    *(.data)
+    CONSTRUCTORS
+  }
+  .data1   : { *(.data1) }
+  .got           : { *(.got.plt) *(.got) }
+  .dynamic       : { *(.dynamic) }
+  /* We want the small data sections together, so single-instruction offsets
+     can access them all, and initialized data all before uninitialized, so
+     we can shorten the on-disk segment size.  */
+  .sdata     : { *(.sdata) }
+  _edata  =  .;
+  PROVIDE (edata = .);
+  __bss_start = .;
+  .sbss      : { *(.sbss) *(.scommon) }
+  .bss       :
+  {
+   *(.dynbss)
+   *(.bss)
+   *(COMMON)
+  }
+  _end = . ;
+  PROVIDE (end = .);
+  /* These are needed for ELF backends which have not yet been
+     converted to the new style linker.  */
+  .stab 0 : { *(.stab) }
+  .stabstr 0 : { *(.stabstr) }
+  /* These must appear regardless of  .  */
+}
+
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/mm/Makefile linux/arch/ppc/mm/Makefile
--- v1.3.44/linux/arch/ppc/mm/Makefile	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/mm/Makefile	Fri May 19 03:31:39 1995
@@ -0,0 +1,32 @@
+#
+# Makefile for the linux ppc-specific parts of the memory manager.
+#
+# Note! Dependencies are done automagically by 'make dep', which also
+# removes any old dependencies. DON'T put your own dependencies here
+# unless it's something special (ie not a .c file).
+#
+# Note 2! The CFLAGS definition is now in the main makefile...
+
+.c.o:
+	$(CC) $(CFLAGS) -c $<
+.s.o:
+	$(AS) -o $*.o $<
+.c.s:
+	$(CC) $(CFLAGS) -S $<
+
+OBJS	= fault.o init.o
+
+mm.o: $(OBJS)
+	$(LD) -r -o mm.o $(OBJS)
+
+modules:
+
+dep:
+	$(CPP) -M *.c > .depend
+
+#
+# include a dependency file if one exists
+#
+ifeq (.depend,$(wildcard .depend))
+include .depend
+endif
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/mm/fault.c linux/arch/ppc/mm/fault.c
--- v1.3.44/linux/arch/ppc/mm/fault.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/mm/fault.c	Sat Nov 25 12:39:10 1995
@@ -0,0 +1,288 @@
+/*
+ *  ARCH/ppc/mm/fault.c
+ *
+ *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ *  Ported to PPC by Gary Thomas
+ */
+
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/head.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+
+#include <asm/page.h>
+#include <asm/pgtable.h>
+
+extern void die_if_kernel(char *, struct pt_regs *, long);
+extern void do_page_fault(struct pt_regs *, unsigned long, unsigned long);
+
+#if 0
+#define SHOW_FAULTS
+#endif
+
+void
+DataAccessException(struct pt_regs *regs)
+{
+  pgd_t *dir;
+  pmd_t *pmd;
+  pte_t *pte;
+  int tries, mode = 0;
+  if (user_mode(regs)) mode |= 0x04;
+  if (regs->dsisr & 0x02000000) mode |= 0x02;  /* Load/store */
+  if (regs->dsisr & 0x08000000) mode |= 0x01;  /* Protection violation */
+#if 0
+  /*#ifdef SHOW_FAULTS*/
+  printk("Data Access Fault - Loc: %x, DSISR: %x, PC: %x", regs->dar, regs->dsisr, regs->nip);
+  printk(" PR: %d\n", regs->msr &&(1<<14));
+#endif
+  if (mode & 0x01)
+  {
+#if 0
+    printk("Write Protect Fault - Loc: %x, DSISR: %x, PC: %x\n", regs->dar, regs->dsisr, regs->nip);
+#endif
+    do_page_fault(regs, regs->dar, mode);
+    return;
+  }
+  for (tries = 0;  tries < 1;  tries++)
+  {
+    dir = pgd_offset(current->mm, regs->dar & PAGE_MASK);
+    if (dir)
+    {
+      pmd = pmd_offset(dir, regs->dar & PAGE_MASK);
+      if (pmd && pmd_present(*pmd))
+      {
+	pte = pte_offset(pmd, regs->dar & PAGE_MASK);
+	if (pte && pte_present(*pte))
+	{
+#if 0
+	  printk("Page mapped - PTE: %x[%x]\n", pte, *(long *)pte);
+#endif
+	  MMU_hash_page(&current->tss, regs->dar & PAGE_MASK, pte);
+	  return;
+	}
+      }
+    } else
+    {
+      printk("No PGD\n");
+    }
+    do_page_fault(regs, regs->dar, mode);
+  }
+}
+
+void
+InstructionAccessException(struct pt_regs *regs)
+{
+  pgd_t *dir;
+  pmd_t *pmd;
+  pte_t *pte;
+  int tries, mode = 0;
+#if 0
+  panic("Instruction Access Fault - Loc: %x, DSISR: %x, PC: %x\n", regs->dar, regs->dsisr, regs->nip);
+#endif	
+  if (user_mode(regs)) mode |= 0x04;
+  if (regs->dsisr & 0x02000000) mode |= 0x02;  /* Load/store */
+  if (regs->dsisr & 0x08000000) mode |= 0x01;  /* Protection violation */
+  if (mode & 0x01)
+  {
+    do_page_fault(regs, regs->dar, mode);
+    return;
+  }
+  for (tries = 0;  tries < 1;  tries++)
+  {
+    dir = pgd_offset(current->mm, regs->dar & PAGE_MASK);
+    if (dir)
+    {
+      pmd = pmd_offset(dir, regs->dar & PAGE_MASK);
+      if (pmd && pmd_present(*pmd))
+      {
+	pte = pte_offset(pmd, regs->dar & PAGE_MASK);
+	if (pte && pte_present(*pte))
+	{
+#if 0
+	  printk("Page mapped - PTE: %x[%x]\n", pte, *(long *)pte);
+#endif
+	  MMU_hash_page(&current->tss, regs->dar & PAGE_MASK, pte);
+	  return;
+	}
+      }
+    } else
+    {
+#if 1
+  panic("No PGD Instruction Access Fault - Loc: %x, DSISR: %x, PC: %x\n", regs->dar, regs->dsisr, regs->nip);
+#endif	
+      printk("No PGD\n");
+    }
+    do_page_fault(regs, regs->dar, mode);
+  }
+}
+
+/*
+ * This routine handles page faults.  It determines the address,
+ * and the problem, and then passes it off to one of the appropriate
+ * routines.
+ *
+ * The error_code parameter just the same as in the i386 version:
+ *
+ *	bit 0 == 0 means no page found, 1 means protection fault
+ *	bit 1 == 0 means read, 1 means write
+ *	bit 2 == 0 means kernel, 1 means user-mode
+ */
+void do_page_fault(struct pt_regs *regs, unsigned long address, unsigned long error_code)
+{
+  struct vm_area_struct * vma;
+  unsigned long page;
+/*  printk("\ndo_page_fault()\n");*/
+#if 1
+  for (vma = current->mm->mmap ; ; vma = vma->vm_next)
+  {
+    if (!vma)
+    {
+#if 0 /* mfisk */
+        {   struct vm_area_struct * mmp;
+
+          for(mmp=current->mm->mmap; mmp; mmp=mmp->vm_next) {
+            printk("notinmap: current: %x; mm: %x; mmap: %x; vma: %x to %x flags: %x\n",
+                   current, current->mm, mmp, mmp->vm_start, mmp->vm_end, mmp->vm_flags);
+          }
+        }
+#endif
+       panic("do_page_fault()  !vma \n");
+      panic("not in map: ip = %x; current=%x; mm=%x; mmap=%x; address = %x error_code = %x\n",
+	    regs->nip, current, current->mm, current->mm->mmap, address, error_code);
+      goto bad_area;
+    }
+    if (vma->vm_end > address)
+      break;
+  }
+#else
+  vma = find_vma(current, address);
+  if (!vma)
+    goto bad_area;
+#endif
+  if (vma->vm_start <= address){
+    goto good_area;
+  }
+  if (!(vma->vm_flags & VM_GROWSDOWN))
+  {
+    panic("stack\n");
+    goto bad_area;
+  }
+  if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur)
+  {    panic("stack 2\n");
+    goto bad_area;
+     }
+  vma->vm_offset -= vma->vm_start - (address & PAGE_MASK);
+  vma->vm_start = (address & PAGE_MASK);
+  
+  /*
+   * Ok, we have a good vm_area for this memory access, so
+   * we can handle it..
+   */
+good_area:
+  /*
+   * was it a write?
+   */
+  if (error_code & 2) {
+    if (!(vma->vm_flags & VM_WRITE))
+    {
+      panic("\ndo_page_fault()  write\n");
+      panic("\ndo_page_fault() write! current: %x, address:%x, vm_flags: %x, mm: %x; vma(%x) %x to %x\n",
+	    current,address,vma->vm_flags,current->mm,vma,vma->vm_start,vma->vm_end);
+      goto bad_area;
+    }
+  } else {
+    /* read with protection fault? */
+    if (error_code & 1)
+    {
+      panic("do_page_fault()  error code thing\n");	    
+      goto bad_area;
+    }
+    if (!(vma->vm_flags & (VM_READ | VM_EXEC)))
+    {
+#if 0
+      _printk("vma = %x\n", vma);
+      _printk("vma->vm_flags = %x\n", vma->vm_flags);      
+      _printk("VM_READ = %x VM_EXEC = %x\n",VM_READ,VM_EXEC);
+#endif
+#if 0
+      printk("vma = %x VM_READ = %x VM_EXEC = %x\n",
+	     vma, VM_READ,VM_EXEC);
+      printk("vma->vm_start = %x vma->vm_end = %d\n",
+	     vma->vm_start, vma->vm_end);
+      printk("error_code = %x\n", error_code);      
+      printk("regs = %x\n", regs);
+      printk("vma->vm_flags = %x\n", vma->vm_flags);
+#endif
+/*      printk("do_page_fault()  multi thing\n"); */
+      goto bad_area; 
+    }
+  }
+  handle_mm_fault(vma, address, error_code & 2); 
+  return;
+  
+  /*
+   * Something tried to access memory that isn't in our memory map..
+   * Fix it, but check if it's kernel or user first..
+   */
+bad_area:
+  if (user_mode(regs)) {
+    panic("Task: %x, PC: %x, bad area! - Addr: %x\n", current, regs->nip, address);
+    send_sig(SIGSEGV, current, 1);
+    return;
+  }
+#if 0
+  panic("\nKERNEL! Task: %x, PC: %x, bad area! - Addr: %x, PGDIR: %x\n",
+	 current, regs->nip, address, current->tss.pg_tables);
+#else
+  panic("\nKERNELmm! current: %x, address:%x, vm_flags: %x, mm: %x; vma(%x) %x to %x\n",
+	current,address,vma->vm_flags,current->mm,vma,vma->vm_start,vma->vm_end);
+#endif
+  
+  while (1) ;
+}
+
+va_to_phys(unsigned long address)
+{
+  pgd_t *dir;
+  pmd_t *pmd;
+  pte_t *pte;
+  dir = pgd_offset(current->mm, address & PAGE_MASK);
+  if (dir)
+  {
+    pmd = pmd_offset(dir, address & PAGE_MASK);
+    if (pmd && pmd_present(*pmd))
+    {
+      pte = pte_offset(pmd, address & PAGE_MASK);
+      if (pte && pte_present(*pte))
+      {
+	return(pte_page(*pte) | (address & ~(PAGE_MASK-1)));
+      }
+    } else
+    {
+      return (0);
+    }
+  } else
+  {
+    return (0);
+  }
+}
+
+
+
+
+
+
+
+
+
+
+
+
+
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/mm/init.c linux/arch/ppc/mm/init.c
--- v1.3.44/linux/arch/ppc/mm/init.c	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/mm/init.c	Thu Nov 16 22:19:12 1995
@@ -0,0 +1,773 @@
+/*
+ *  arch/ppc/mm/init.c
+ *
+ *  Copyright (C) 1991, 1992, 1993, 1994  Linus Torvalds
+ *  Ported to PPC by Gary Thomas
+ */
+
+#include <linux/config.h>
+#include <linux/signal.h>
+#include <linux/sched.h>
+#include <linux/head.h>
+#include <linux/kernel.h>
+#include <linux/errno.h>
+#include <linux/string.h>
+#include <linux/types.h>
+#include <linux/ptrace.h>
+#include <linux/mman.h>
+#include <linux/mm.h>
+
+#include <asm/pgtable.h>
+
+
+/* made this a static array since alpha and intel aren't.
+   thomas made it a dynamic array and had to add lots of stuff to other parts
+   of linux to make sure the pages were contigous and such.  the static array
+   seems much easier
+   making it 8k for now.  will change later.
+      -- Cort
+   */
+pgd_t swapper_pg_dir[1024*8];
+/*pgd_t *swapper_pg_dir;*/
+
+pte *MMU_get_page(void);
+
+
+#if 0
+#include <asm/system.h>
+#include <asm/segment.h>
+#include <asm/mipsconfig.h>
+
+extern unsigned long pg0[1024];		/* page table for 0-4MB for everybody */
+#endif
+
+#ifdef CONFIG_DESKSTATION_TYNE
+extern void deskstation_tyne_dma_init(void);
+#endif
+#ifdef CONFIG_SCSI
+extern void scsi_mem_init(unsigned long);
+#endif
+#ifdef CONFIG_SOUND
+extern void sound_mem_init(void);
+#endif
+extern void die_if_kernel(char *,struct pt_regs *,long);
+extern void show_net_buffers(void);
+
+/*
+ * BAD_PAGE is the page that is used for page faults when linux
+ * is out-of-memory. Older versions of linux just did a
+ * do_exit(), but using this instead means there is less risk
+ * for a process dying in kernel mode, possibly leaving a inode
+ * unused etc..
+ *
+ * BAD_PAGETABLE is the accompanying page-table: it is initialized
+ * to point to BAD_PAGE entries.
+ *
+ * ZERO_PAGE is a special page that is used for zero-initialized
+ * data and COW.
+ */
+pte_t * __bad_pagetable(void)
+{
+	panic("__bad_pagetable");
+#if 0
+	extern char empty_bad_page_table[PAGE_SIZE];
+	unsigned long dummy;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		"1:\tsw\t%2,(%0)\n\t"
+		"subu\t%1,%1,1\n\t"
+		"bne\t$0,%1,1b\n\t"
+		"addiu\t%0,%0,1\n\t"
+		".set\treorder"
+		:"=r" (dummy),
+		 "=r" (dummy)
+		:"r" (pte_val(BAD_PAGE)),
+		 "0" ((long) empty_bad_page_table),
+		 "1" (PTRS_PER_PAGE));
+
+	return (pte_t *) empty_bad_page_table;
+#endif
+}
+
+pte_t __bad_page(void)
+{
+	panic("__bad_page");
+#if 0
+	extern char empty_bad_page[PAGE_SIZE];
+	unsigned long dummy;
+
+	__asm__ __volatile__(
+		".set\tnoreorder\n\t"
+		"1:\tsw\t$0,(%0)\n\t"
+		"subu\t%1,%1,1\n\t"
+		"bne\t$0,%1,1b\n\t"
+		"addiu\t%0,%0,1\n\t"
+		".set\treorder"
+		:"=r" (dummy),
+		 "=r" (dummy)
+		:"0" ((long) empty_bad_page),
+		 "1" (PTRS_PER_PAGE));
+
+	return pte_mkdirty(mk_pte((unsigned long) empty_bad_page, PAGE_SHARED));
+#endif
+}
+
+unsigned long __zero_page(void)
+{
+#if 0
+	panic("__zero_page");
+#else	
+	extern char empty_zero_page[PAGE_SIZE];
+	bzero(empty_zero_page, PAGE_SIZE);
+	return (unsigned long) empty_zero_page;
+#endif	
+}
+
+void show_mem(void)
+{
+	int i,free = 0,total = 0,reserved = 0;
+	int shared = 0;
+
+	printk("Mem-info:\n");
+	show_free_areas();
+	printk("Free swap:       %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10));
+	i = high_memory >> PAGE_SHIFT;
+	while (i-- > 0) {
+		total++;
+                if (mem_map[i].reserved)
+			reserved++;
+		else if (!mem_map[i].count)
+			free++;
+		else
+			shared += mem_map[i].count-1;
+	}
+	printk("%d pages of RAM\n",total);
+	printk("%d free pages\n",free);
+	printk("%d reserved pages\n",reserved);
+	printk("%d pages shared\n",shared);
+	show_buffers();
+#ifdef CONFIG_NET
+	show_net_buffers();
+#endif
+}
+
+extern unsigned long free_area_init(unsigned long, unsigned long);
+
+/*
+ * paging_init() sets up the page tables - note that the first 4MB are
+ * already mapped by head.S.
+ *
+ * This routines also unmaps the page at virtual kernel address 0, so
+ * that we can trap those pesky NULL-reference errors in the kernel.
+ */
+unsigned long paging_init(unsigned long start_mem, unsigned long end_mem)
+{
+
+#if 0	
+	pgd_t * pg_dir;
+	pte_t * pg_table;
+	unsigned long tmp;
+	unsigned long address;
+
+	start_mem = PAGE_ALIGN(start_mem);
+	address = 0;
+	pg_dir = swapper_pg_dir;
+	while (address < end_mem) {
+		if (pgd_none(pg_dir[0])) {
+			pgd_set(pg_dir, (pte_t *) start_mem);
+			start_mem += PAGE_SIZE;
+		}
+		/*
+		 * also map it in at 0x00000000 for init
+		 */
+		pg_table = (pte_t *) pgd_page(pg_dir[0]);
+		pgd_set(pg_dir, pg_table);
+		pg_dir++;
+		for (tmp = 0 ; tmp < PTRS_PER_PAGE ; tmp++,pg_table++) {
+			if (address < end_mem)
+				*pg_table = mk_pte(address, PAGE_SHARED);
+			else
+				pte_clear(pg_table);
+			address += PAGE_SIZE;
+		}
+	}
+#if KERNELBASE == KSEG0
+	cacheflush();
+#endif
+	invalidate();
+#endif
+	return free_area_init(start_mem, end_mem);
+}
+
+void mem_init(unsigned long start_mem, unsigned long end_mem)
+{
+	int codepages = 0;
+	int reservedpages = 0;
+	int datapages = 0;
+	unsigned long tmp;
+	extern int etext;
+	
+	end_mem &= PAGE_MASK;
+	high_memory = end_mem;
+
+	/* mark usable pages in the mem_map[] */
+	start_mem = PAGE_ALIGN(start_mem);
+
+#if 0
+printk("Mem init - Start: %x, End: %x\n", start_mem, high_memory);
+#endif
+	while (start_mem < high_memory) {
+		mem_map[MAP_NR(start_mem)].reserved = 0;
+		start_mem += PAGE_SIZE;
+	}
+#ifdef CONFIG_DESKSTATION_TYNE
+	deskstation_tyne_dma_init();
+#endif
+#ifdef CONFIG_SCSI
+	scsi_mem_init(high_memory);
+#endif
+#ifdef CONFIG_SOUND
+	sound_mem_init();
+#endif
+	for (tmp = KERNELBASE ; tmp < high_memory ; tmp += PAGE_SIZE)
+	{
+		if (mem_map[MAP_NR(tmp)].reserved)
+		{
+			/*
+			 * We don't have any reserved pages on the
+			 * MIPS systems supported until now
+			 */
+			if (0)
+			{
+				reservedpages++;
+			} else if (tmp < (unsigned long) &etext)
+			{
+				codepages++;
+			} else
+			{
+				datapages++;
+			}
+			continue;
+		}
+		mem_map[MAP_NR(tmp)].count = 1;
+		free_page(tmp);
+	}
+	tmp = nr_free_pages << PAGE_SHIFT;
+	printk("Memory: %luk/%luk available (%dk kernel code, %dk reserved, %dk data)\n",
+		tmp >> 10,
+		((int)high_memory - (int)KERNELBASE) >> 10,
+		codepages << (PAGE_SHIFT-10),
+		reservedpages << (PAGE_SHIFT-10),
+		datapages << (PAGE_SHIFT-10));
+	invalidate();
+	return;
+}
+
+void si_meminfo(struct sysinfo *val)
+{
+#if 0	
+	int i;
+
+	i = high_memory >> PAGE_SHIFT;
+	val->totalram = 0;
+	val->sharedram = 0;
+	val->freeram = nr_free_pages << PAGE_SHIFT;
+	val->bufferram = buffermem;
+	while (i-- > 0)  {
+		if (mem_map[i] & MAP_PAGE_RESERVED)
+			continue;
+		val->totalram++;
+		if (!mem_map[i])
+			continue;
+		val->sharedram += mem_map[i]-1;
+	}
+	val->totalram <<= PAGE_SHIFT;
+	val->sharedram <<= PAGE_SHIFT;
+	return;
+#endif	
+}
+
+/* Kernel MMU setup & lowest level hardware support */
+
+/* Hardwired MMU segments */
+
+/* Segment 0x8XXXXXXX, 0xCXXXXXXX always mapped (for I/O) */
+/* Segment 0x9XXXXXXX mapped during init */
+
+BAT BAT0 =
+   {
+   	{
+   		0x80000000>>17, 	/* bepi */
+   		BL_256M,		/* bl */
+   		1,			/* vs */
+   		1,			/* vp */
+   	},
+   	{
+   		0x80000000>>17,		/* brpn */
+   		1,			/* w */
+   		1,			/* i (cache disabled) */
+   		0,			/* m */
+   		1,			/* g */
+   		BPP_RW			/* pp */
+   	}
+   };
+BAT BAT1 =
+   {
+   	{
+   		0xC0000000>>17, 	/* bepi */
+   		BL_256M,		/* bl */
+   		1,			/* vs */
+   		1,			/* vp */
+   	},
+   	{
+   		0xC0000000>>17,		/* brpn */
+   		1,			/* w */
+   		1,			/* i (cache disabled) */
+   		0,			/* m */
+   		1,			/* g */
+   		BPP_RW			/* pp */
+   	}
+   };
+BAT BAT2 =
+   {
+#if 1
+   	{
+   		0x00000000>>17, 	/* bepi */
+   		BL_256M,		/* bl */
+   		0,			/* vs */
+   		0,			/* vp */
+   	},
+   	{
+   		0x00000000>>17,		/* brpn */
+   		1,			/* w */
+   		1,			/* i (cache disabled) */
+   		0,			/* m */
+   		0,			/* g */
+   		BPP_RW			/* pp */
+   	}
+#else
+   	{
+   		0x90000000>>17, 	/* bepi */
+   		BL_256M,		/* bl */
+   		1,			/* vs */
+   		1,			/* vp */
+   	},
+   	{
+   		0x00000000>>17,		/* brpn */
+   		1,			/* w */
+   		0,			/* i (cache enabled) */
+   		0,			/* m */
+   		0,			/* g */
+   		BPP_RW			/* pp */
+   	}
+#endif
+   };
+BAT BAT3 =
+   {
+   	{
+   		0x00000000>>17, 	/* bepi */
+   		BL_256M,		/* bl */
+   		0,			/* vs */
+   		0,			/* vp */
+   	},
+   	{
+   		0x00000000>>17,		/* brpn */
+   		1,			/* w */
+   		1,			/* i (cache disabled) */
+   		0,			/* m */
+   		0,			/* g */
+   		BPP_RW			/* pp */
+   	}
+   };
+BAT TMP_BAT2 =
+   { /* 0x9XXXXXXX -> 0x0XXXXXXX */
+   	{
+   		0x90000000>>17, 	/* bepi */
+   		BL_256M,		/* bl */
+   		1,			/* vs */
+   		1,			/* vp */
+   	},
+   	{
+   		0x00000000>>17,		/* brpn */
+   		1,			/* w */
+   		0,			/* i (cache enabled) */
+   		0,			/* m */
+   		0,			/* g */
+   		BPP_RW			/* pp */
+   	}
+   };
+
+unsigned long _SDR1;		/* Hardware SDR1 image */
+PTE *Hash;
+int Hash_size, Hash_mask;
+int cache_is_copyback = 1;
+int kernel_pages_are_copyback = 1;
+
+#define NUM_MAPPINGS 8
+struct
+   {
+   	int va, pa, task;
+   } last_mappings[NUM_MAPPINGS];
+int next_mapping = 0;
+
+/* Generic linked list */
+struct item
+   {
+   	struct item *next;
+   };
+   
+#ifndef NULL   
+#define NULL 0
+#endif
+
+#define MAX_CONTEXTS	16
+#define MAX_MMU_PAGES	8
+
+static struct item _free_pages;
+static char mmu_pages[(MAX_MMU_PAGES+1)*MMU_PAGE_SIZE];
+
+/*
+ * Routines to support generic linked lists.
+ */
+
+MMU_free_item(struct item *hdr, struct item *elem)
+{
+	if (hdr->next == (struct item *)NULL)
+	{ /* First item in list */
+		elem->next = (struct item *)NULL;
+	} else
+	{
+		elem->next = hdr->next;
+	}
+	hdr->next = elem;
+}
+
+struct item *
+MMU_get_item(struct item *hdr)
+{
+	struct item *item;
+	if ((item = hdr->next) != (struct item *)NULL)
+	{
+		item = hdr->next;
+		hdr->next = item->next;
+	}
+	return (item);
+}
+
+/*
+ * This code is called to create a minimal mapped environment.
+ * It is called with the MMU on, but with only a BAT register
+ * set up to cover the code/data.  After this routine runs,
+ * the BAT mapping is withdrawn and all mappings must be complete.
+ */
+
+extern char _start[], _end[];
+ 
+void MMU_init(void)
+{
+	int i, p;
+	SEGREG *segs;
+	_printk("MMU init - started\n");
+	find_end_of_memory();
+	_printk("  Start at 0x%08X, End at 0x%08X, Hash at 0x%08X\n", _start, _end, Hash);
+	_SDR1 = ((unsigned long)Hash & 0x00FFFFFF) | Hash_mask;
+	p = (int)mmu_pages;
+	p = (p + (MMU_PAGE_SIZE-1)) & ~(MMU_PAGE_SIZE-1);
+	_free_pages.next = (struct item *)NULL;
+	for (i = 0;  i < MAX_MMU_PAGES;  i++)
+	{
+		MMU_free_item(&_free_pages, (struct item *)p);
+		p += MMU_PAGE_SIZE;
+	}
+	/* Force initial page tables */
+	/*swapper_pg_dir = (pgd_t *)MMU_get_page();*/
+	init_task.tss.pg_tables = (unsigned long *)swapper_pg_dir;
+
+	/* Segment registers */
+	segs = (SEGREG *)init_task.tss.segs;
+	for (i = 0;  i < 16;  i++)
+	{
+		segs[i].ks = 0;
+		segs[i].kp = 1;
+		segs[i].vsid = i;
+	}
+	/* Map kernel TEXT+DATA+BSS */
+#if 0	
+	for (i = (int)_start;  i <= (int)_end;  i += MMU_PAGE_SIZE)
+#else
+	/* Other parts of the kernel expect ALL RAM to be mapped */	
+	for (i = (int)_start;  i <= (int)Hash;  i += MMU_PAGE_SIZE)
+#endif	
+	{
+		MMU_map_page(&init_task.tss, i, i & 0x00FFFFFF, PAGE_KERNEL);
+	}
+	/* Map hardware HASH table */
+	for (i = (int)Hash;  i < (int)Hash+Hash_size;  i += MMU_PAGE_SIZE)
+	{
+		MMU_map_page(&init_task.tss, i, i & 0x00FFFFFF, PAGE_KERNEL);
+	}
+	_printk("MMU init - done!\n");
+}
+
+pte *
+MMU_get_page(void)
+{
+	pte *pg;
+	if ((pg = (pte *)MMU_get_item(&_free_pages)))
+	{
+		bzero((char *)pg, MMU_PAGE_SIZE);
+	}
+	_printk("MMU Allocate Page at %08X\n", pg);
+	return(pg);
+}
+
+MMU_map_page(struct thread_struct *tss, unsigned long va, unsigned long pa, int flags)
+{
+	pte *pd, *pg;
+if (va < (unsigned long)0x90000000)	
+  _printk("Thread: %x, Map VA: %08x -> PA: %08X, Flags: %x\n", tss, va, pa, flags);
+	if ((pte **)tss->pg_tables == (pte **)NULL)
+	{ /* Allocate upper level page map */
+		(pte **)tss->pg_tables = (pte **)MMU_get_page();
+		if ((pte **)tss->pg_tables == (pte **)NULL)
+		{
+			_panic("Out of MMU pages (PD)\n");
+		}
+	}
+	/* Use upper 10 bits of VA to index the first level map */
+	pd = ((pte **)tss->pg_tables)[(va>>PD_SHIFT)&PD_MASK];
+	if (pd == (pte *)NULL)
+	{ /* Need to allocate second-level table */
+		pd = (pte *)MMU_get_page();
+		if (pd == (pte *)NULL)
+		{
+			_panic("Out of MMU pages (PG)\n");
+		}
+		((pte **)tss->pg_tables)[(va>>PD_SHIFT)&PD_MASK] = (pte *)((unsigned long)pd | _PAGE_TABLE);
+	}
+	/* Use middle 10 bits of VA to index the second-level map */
+	pg = &pd[(va>>PT_SHIFT)&PT_MASK];
+	*(long *)pg = 0;  /* Clear out entry */
+	pg->page_num = pa>>PG_SHIFT;
+	pg->flags = flags;
+	MMU_hash_page(tss, va, pg);
+}
+
+/*
+ * Insert(create) a hardware page table entry
+ */
+MMU_hash_page(struct thread_struct *tss, unsigned long va, pte *pg)
+{
+	int hash, page_index, segment, i, h, _h, api, vsid, perms;
+	PTE *_pte, *empty, *slot;
+	PTE *slot0, *slot1;
+	extern char _etext;
+
+
+/*	printk("hashing tss = %x va = %x pg = %x\n", tss, va, pg);*/
+/* TEMP */
+	last_mappings[next_mapping].va = va;
+	last_mappings[next_mapping].pa = pg?*(int *)pg:0;
+	last_mappings[next_mapping].task = current;
+	if (++next_mapping == NUM_MAPPINGS) next_mapping = 0;
+
+/* TEMP */	
+	page_index = ((int)va & 0x0FFFF000) >> 12;
+	segment = (unsigned int)va >> 28;
+	api = page_index >> 10;
+	vsid = ((SEGREG *)tss->segs)[segment].vsid;
+	empty = slot = (PTE *)NULL;
+	for (_h = 0;  _h < 2;  _h++)
+	{
+		hash = page_index ^ vsid;		
+		if (_h)
+		{
+			hash = ~hash;  /* Secondary hash uses ones-complement */
+		}
+		hash &= 0x3FF | (Hash_mask << 10);
+		hash *= 8;  /* Eight entries / hash bucket */
+		_pte = &Hash[hash];
+		/* Save slot addresses in case we have to purge */
+		if (_h)
+		{
+			slot1 = _pte;
+		} else
+		{
+			slot0 = _pte;
+		}
+		for (i = 0;  i < 8;  i++, _pte++)
+		{
+			if (_pte->v && _pte->vsid == vsid && _pte->h == _h && _pte->api == api)
+			{ /* Found it! */
+				h = _h;
+				slot = _pte;
+				goto found_it;
+			}
+			if ((empty == (PTE *)NULL) && !_pte->v)
+			{
+				h = _h;
+				empty = _pte;
+			}
+		}
+	}
+	if (slot == (PTE *)NULL)
+	{
+		if (pg == (pte *)NULL)
+		{
+			return (0);
+		}
+		if (empty == (PTE *)NULL)
+		{ /* Table is totally full! */
+printk("Map VA: %08X, Slot: %08X[%08X/%08X], H: %d\n", va, slot, slot0, slot1, h);
+printk("Slot0:\n");
+_pte = slot0;
+for (i = 0;  i < 8;  i++, _pte++)
+{
+	printk("  V: %d, VSID: %05x, H: %d, RPN: %04x, R: %d, C: %d, PP: %x\n", _pte->v, _pte->vsid, _pte->h, _pte->rpn, _pte->r, _pte->c, _pte->pp);
+}
+printk("Slot1:\n");
+_pte = slot1;
+for (i = 0;  i < 8;  i++, _pte++)
+{
+	printk("  V: %d, VSID: %05x, H: %d, RPN: %04x, R: %d, C: %d, PP: %x\n", _pte->v, _pte->vsid, _pte->h, _pte->rpn, _pte->r, _pte->c, _pte->pp);
+}
+cnpause();
+printk("Last mappings:\n");
+for (i = 0;  i < NUM_MAPPINGS;  i++)
+{
+	printk("  VA: %08x, PA: %08X, TASK: %08X\n",
+		last_mappings[next_mapping].va,
+		last_mappings[next_mapping].pa,
+		last_mappings[next_mapping].task);
+	if (++next_mapping == NUM_MAPPINGS) next_mapping = 0;
+}
+cnpause();
+			_panic("Hash table full!\n");
+		}
+		slot = empty;
+	}
+found_it:
+#if 0
+_printk("Map VA: %08X, Slot: %08X[%08X/%08X], H: %d\n", va, slot, slot0, slot1, h);	
+#endif
+	_tlbie(va); /* Clear TLB */
+	if (pg)
+	{ /* Fill in table */
+		slot->v = 1;
+		slot->vsid = vsid;
+		slot->h = h;
+		slot->api = api;
+		if (((pg->page_num << 12) & 0xF0000000) == KERNELBASE)
+		{
+			slot->rpn = pg->page_num - (KERNELBASE>>12);
+		} else
+		{
+			slot->rpn = pg->page_num;
+		}
+		slot->r = 0;
+		slot->c = 0;
+		slot->i = 0;
+		slot->g = 0;
+		if (cache_is_copyback)
+		{
+			if (kernel_pages_are_copyback || (pg->flags & _PAGE_USER) || (va < (unsigned long)&_etext))
+			{ /* All User & Kernel TEXT pages are copy-back */
+				slot->w = 0;
+				slot->m = 1;
+			} else
+			{ /* Kernel DATA pages are write-thru */
+				slot->w = 1;
+				slot->m = 0;
+			}
+		} else
+		{
+			slot->w = 1;
+			slot->m = 0;
+		}
+		if (pg->flags & _PAGE_USER)
+		{
+			if (pg->flags & _PAGE_RW)
+			{ /* Read/write page */
+				perms = PP_RWRW;
+			} else
+			{ /* Read only page */
+				perms = PP_RWRX;
+			}
+		} else
+		{ /* Kernel pages */
+			perms = PP_RWRW;
+			perms = PP_RWXX;
+		}
+#ifdef SHOW_FAULTS
+if (va < KERNELBASE)		
+_printk("VA: %08X, PA: %08X, Flags: %x, Perms: %d\n", va, pg->page_num<<12, pg->flags, perms);
+#endif
+		slot->pp = perms;
+		return (0);
+	} else
+	{ /* Pull entry from tables */
+		int flags = 0;
+		if (slot->r) flags |= _PAGE_ACCESSED;
+		if (slot->c) flags |= _PAGE_DIRTY;
+		slot->v = 0;
+#ifdef SHOW_FAULTS
+_printk("Pull VA: %08X, Flags: %x\n", va, flags);
+#endif
+		return (flags);
+	}
+}
+
+/*
+ * Invalidate the MMU [hardware] tables (for current task?)
+ */
+void
+invalidate(void)
+{
+  int i, j, flags;
+  unsigned long address;
+  pgd_t *pgd;
+  pte_t *_pte;
+#if 0
+  _tlbia();  /* Flush TLB entries */
+#endif
+  pgd = pgd_offset(current->mm, 0);
+  if (!pgd) return;  /* No map? */
+  address = 0;
+  for (i = 0 ; (i < PTRS_PER_PGD) && (address < KERNELBASE); i++)
+  {
+    if (*(long *)pgd)
+    {
+      /* I know there are only two levels, but the macros don't */
+      _pte = pte_offset(pmd_offset(pgd,0),0);
+      if (_pte)
+      {
+	for (j = 0;  j < PTRS_PER_PTE;  j++)
+	{
+	  if (pte_present(*_pte))
+	  {
+	    flags = MMU_hash_page(&current->tss, address, 0);
+	    ((pte *)_pte)->flags |= flags;
+	  }
+	  _pte++;
+	  address += PAGE_SIZE;
+	}
+      } else
+      {
+	address += PAGE_SIZE*PTRS_PER_PTE;
+      }
+    } else
+    {
+      address += PAGE_SIZE*PTRS_PER_PTE;
+    }
+    pgd++;
+  }
+} 
+
+void
+cache_mode(char *str, int *ints)
+{
+	cache_is_copyback = ints[0];
+}
+
+
diff -u --recursive --new-file v1.3.44/linux/arch/ppc/mm/mmu.h linux/arch/ppc/mm/mmu.h
--- v1.3.44/linux/arch/ppc/mm/mmu.h	Thu Jan  1 02:00:00 1970
+++ linux/arch/ppc/mm/mmu.h	Fri May  5 03:44:02 1995
@@ -0,0 +1,159 @@
+/*
+ * PowerPC memory management structures
+ */
+
+#ifndef _PPC_MMU_H_
+#define _PPC_MMU_H_
+
+/* Hardware Page Table Entry */
+ 
+typedef struct _PTE
+   {
+      unsigned long v:1;	/* Entry is valid */
+      unsigned long vsid:24;	/* Virtual segment identifier */
+      unsigned long h:1;	/* Hash algorithm indicator */
+      unsigned long api:6;	/* Abbreviated page index */
+      unsigned long rpn:20;	/* Real (physical) page number */
+      unsigned long    :3;	/* Unused */
+      unsigned long r:1;	/* Referenced */
+      unsigned long c:1;	/* Changed */
+      unsigned long w:1;	/* Write-thru cache mode */
+      unsigned long i:1;	/* Cache inhibited */
+      unsigned long m:1;	/* Memory coherence */
+      unsigned long g:1;	/* Guarded */
+      unsigned long    :1;	/* Unused */
+      unsigned long pp:2;	/* Page protection */
+   } PTE; 
+
+/* Values for PP (assumes Ks=0, Kp=1) */
+#define PP_RWXX	0	/* Supervisor read/write, User none */
+#define PP_RWRX 1	/* Supervisor read/write, User read */
+#define PP_RWRW 2	/* Supervisor read/write, User read/write */
+
+/* Segment Register */
+
+typedef struct _SEGREG
+   {
+      unsigned long t:1;	/* Normal or I/O  type */
+      unsigned long ks:1;	/* Supervisor 'key' (normally 0) */
+      unsigned long kp:1;	/* User 'key' (normally 1) */
+      unsigned long n:1;	/* No-execute */
+      unsigned long :4;		/* Unused */
+      unsigned long vsid:24;	/* Virtual Segment Identifier */
+   } SEGREG;
+
+/* Block Address Translation (BAT) Registers */
+
+typedef struct _BATU		/* Upper part of BAT */
+   {
+      unsigned long bepi:15;	/* Effective page index (virtual address) */
+      unsigned long :4;		/* Unused */
+      unsigned long bl:11;	/* Block size mask */
+      unsigned long vs:1;	/* Supervisor valid */
+      unsigned long vp:1;	/* User valid */
+   } BATU;   
+
+typedef struct _BATL		/* Lower part of BAT */
+   {
+      unsigned long brpn:15;	/* Real page index (physical address) */
+      unsigned long :10;	/* Unused */
+      unsigned long w:1;	/* Write-thru cache */
+      unsigned long i:1;	/* Cache inhibit */
+      unsigned long m:1;	/* Memory coherence */
+      unsigned long g:1;	/* Guarded (MBZ) */
+      unsigned long :1;		/* Unused */
+      unsigned long pp:2;	/* Page access protections */
+   } BATL;
+
+typedef struct _BAT
+   {
+      BATU batu;		/* Upper register */
+      BATL batl;		/* Lower register */
+   } BAT;
+
+/* Block size masks */
+#define BL_128K	0x000
+#define BL_256K 0x001
+#define BL_512K 0x003
+#define BL_1M   0x007
+#define BL_2M   0x00F
+#define BL_4M   0x01F
+#define BL_8M   0x03F
+#define BL_16M  0x07F
+#define BL_32M  0x0FF
+#define BL_64M  0x1FF
+#define BL_128M 0x3FF
+#define BL_256M 0x7FF
+
+/* BAT Access Protection */
+#define BPP_XX	0x00		/* No access */
+#define BPP_RX	0x01		/* Read only */
+#define BPP_RW	0x02		/* Read/write */
+
+/*
+ * Simulated two-level MMU.  This structure is used by the kernel
+ * to keep track of MMU mappings and is used to update/maintain
+ * the hardware HASH table which is really a cache of mappings.
+ *
+ * The simulated structures mimic the hardware available on other
+ * platforms, notably the 80x86 and 680x0.
+ */
+
+typedef struct _pte
+   {
+   	unsigned long page_num:20;
+   	unsigned long unused:6;
+   	unsigned long acc:3;		/* Read/write/execute permissions */
+   	unsigned long r:1;		/* Page has been referenced */
+   	unsigned long m:1;		/* Page has been modified */
+   	unsigned long v:1;		/* Entry is valid */
+   } pte;
+
+#define ACC_Rxx	0x04
+#define ACC_xWx 0x02
+#define ACC_xxX 0x01
+#define ACC_RWX (ACC_Rxx|ACC_xWx|ACC_xxX)
+
+#define PD_SHIFT (10+12)		/* Page directory */
+#define PD_MASK  0x02FF
+#define PT_SHIFT (12)			/* Page Table */
+#define PT_MASK  0x02FF
+#define PG_SHIFT (12)			/* Page Entry */
+ 
+
+/* MMU context */
+
+typedef struct _MMU_context
+   {
+      SEGREG	segs[16];	/* Segment registers */
+      pte	**pmap;		/* Two-level page-map structure */
+   } MMU_context;
+
+#if 0
+BAT	ibat[4];	/* Instruction BAT images */
+BAT	dbat[4];	/* Data BAT images */
+PTE	*hash_table;	/* Hardware hashed page table */
+int	hash_table_size;
+int	hash_table_mask;
+unsigned long sdr;	/* Hardware image of SDR */
+#endif   
+
+/* Used to set up SDR register */
+#define HASH_TABLE_SIZE_64K	0x00010000
+#define HASH_TABLE_SIZE_128K	0x00020000
+#define HASH_TABLE_SIZE_256K	0x00040000
+#define HASH_TABLE_SIZE_512K	0x00080000
+#define HASH_TABLE_SIZE_1M	0x00100000
+#define HASH_TABLE_SIZE_2M	0x00200000
+#define HASH_TABLE_SIZE_4M	0x00400000
+#define HASH_TABLE_MASK_64K	0x000   
+#define HASH_TABLE_MASK_128K	0x001   
+#define HASH_TABLE_MASK_256K	0x003   
+#define HASH_TABLE_MASK_512K	0x007
+#define HASH_TABLE_MASK_1M	0x00F   
+#define HASH_TABLE_MASK_2M	0x01F   
+#define HASH_TABLE_MASK_4M	0x03F   
+
+#define MMU_PAGE_SIZE	4096
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/arch/sparc/kernel/entry.S linux/arch/sparc/kernel/entry.S
--- v1.3.44/linux/arch/sparc/kernel/entry.S	Sat Nov 25 19:04:36 1995
+++ linux/arch/sparc/kernel/entry.S	Sun Nov 26 11:50:02 1995
@@ -1,4 +1,4 @@
-/* $Id: entry.S,v 1.64 1995/11/25 00:57:53 davem Exp $
+/* $Id: entry.S,v 1.65 1995/11/25 14:36:22 zaitcev Exp $
  * arch/sparc/kernel/entry.S:  Sparc trap low-level entry points.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -124,17 +124,44 @@
 
 
 #ifdef CONFIG_BLK_DEV_FD
+#ifdef TRACE_FLOPPY_HARDINT
+/* Useful tracing */
+	.data
+	.align	4
+	.globl	C_LABEL(floppy_hardint_trace)
+C_LABEL(floppy_hardint_trace):
+	.skip	32
+	.globl	C_LABEL(floppy_hardint_index)
+C_LABEL(floppy_hardint_index):
+	.word	0
+#endif
+
+	.text
 	.align	4
 	.globl	C_LABEL(floppy_hardint)
 C_LABEL(floppy_hardint):
 	/* Can only use regs %l3->%l7:
 	 * %l3 -- base address of fdc registers
-	 * %l4 -- doing_pdma upon entry, AUXIO reg vaddr after
-	 * %l5 -- pdma_vaddr
+	 * %l4 -- pdma_vaddr
+	 * %l5 -- scratch for ld/st address
 	 * %l6 -- pdma_size
 	 * %l7 -- floppy_softint
 	 */
 
+#ifdef TRACE_FLOPPY_HARDINT
+        sethi   %hi(C_LABEL(floppy_hardint_trace)), %l5
+        or      %l5, %lo(C_LABEL(floppy_hardint_trace)), %l5
+        ld      [%l5 + 32], %l7
+        add     %l7, 1, %l7
+        and     %l7, 31, %l7
+        st      %l7, [%l5 + 32]
+        sub     %l7, 1, %l7
+        and     %l7, 31, %l7
+        add     %l7, %l5, %l5
+	or	%g0, 0xf, %l7
+	stb	%l7, [%l5]
+#endif
+
 	/* Do we have work to do? */
 	sethi	%hi(C_LABEL(doing_pdma)), %l4
 	ld	[%l4 + %lo(C_LABEL(doing_pdma))], %l4
@@ -152,7 +179,22 @@
 	sethi	%hi(C_LABEL(pdma_size)), %l5	! bytes to go
 	ld	[%l5 + %lo(C_LABEL(pdma_size))], %l6
 next_byte:
+#ifdef TRACE_FLOPPY_HARDINT
+	sethi	%hi(C_LABEL(floppy_hardint_trace)), %l5
+	or	%l5, %lo(C_LABEL(floppy_hardint_trace)), %l5
+	ld	[%l5 + 32], %l7
+	add	%l7, 1, %l7
+	and	%l7, 31, %l7
+	st	%l7, [%l5 + 32]
+	sub	%l7, 1, %l7
+	and	%l7, 31, %l7
+	add	%l7, %l5, %l5
 	ldub	[%l3], %l7
+	stb	%l7, [%l5]
+#else
+  	ldub	[%l3], %l7
+#endif
+
 	andcc	%l7, 0x80, %g0		! Does fifo still have data
 	bz	floppy_fifo_emptied	! fifo has been emptied...
 	 andcc	%l7, 0x20, %g0		! in non-dma mode still?
diff -u --recursive --new-file v1.3.44/linux/arch/sparc/kernel/probe.c linux/arch/sparc/kernel/probe.c
--- v1.3.44/linux/arch/sparc/kernel/probe.c	Sat Nov 25 19:04:36 1995
+++ linux/arch/sparc/kernel/probe.c	Sun Nov 26 11:50:02 1995
@@ -1,4 +1,4 @@
-/* $Id: probe.c,v 1.38 1995/11/25 00:58:14 davem Exp $
+/* $Id: probe.c,v 1.39 1995/11/26 00:54:37 davem Exp $
  * probe.c: Preliminary device tree probing routines...
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -30,8 +30,8 @@
  * XXX and smaller as time goes on...
  */
 enum sparc_clock_type sp_clock_typ;
-struct mostek48t02 *mstk48t02_regs;
-struct mostek48t08 *mstk48t08_regs;
+struct mostek48t02 *mstk48t02_regs = 0;
+struct mostek48t08 *mstk48t08_regs = 0;
 volatile unsigned int *master_l10_limit = 0;
 volatile unsigned int *master_l10_counter = 0;
 struct sun4m_timer_regs *sun4m_timers;
@@ -331,7 +331,7 @@
 			mstk48t02_regs = (struct mostek48t02 *) 
 				sparc_alloc_io((void *) clk_reg[0].phys_addr,
 					       (void *) 0, sizeof(*mstk48t02_regs),
-					       "clock", 0x0, 0x1);
+					       "clock", 0x0, 0x0);
 			mstk48t08_regs = 0;  /* To catch weirdness */
 			break;
 		}
@@ -348,7 +348,7 @@
 			mstk48t08_regs = (struct mostek48t08 *)
 				sparc_alloc_io((void *) clk_reg[0].phys_addr,
 					       (void *) 0, sizeof(*mstk48t08_regs),
-					       "clock", 0x0, 0x1);
+					       "clock", 0x0, 0x0);
 
 			mstk48t02_regs = &mstk48t08_regs->regs;
 			break;
diff -u --recursive --new-file v1.3.44/linux/arch/sparc/kernel/signal.c linux/arch/sparc/kernel/signal.c
--- v1.3.44/linux/arch/sparc/kernel/signal.c	Sat Nov 25 19:04:37 1995
+++ linux/arch/sparc/kernel/signal.c	Sun Nov 26 11:50:02 1995
@@ -1,4 +1,4 @@
-/*  $Id: signal.c,v 1.19 1995/11/25 00:58:24 davem Exp $
+/*  $Id: signal.c,v 1.20 1995/11/26 02:29:09 davem Exp $
  *  linux/arch/sparc/kernel/signal.c
  *
  *  Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -87,7 +87,6 @@
 
 asmlinkage void do_sigreturn(struct pt_regs *regs)
 {
-	int wsvd;
 	struct sigcontext_struct *scptr =
 		(struct sigcontext_struct *) regs->u_regs[UREG_I0];
 
diff -u --recursive --new-file v1.3.44/linux/arch/sparc/kernel/sunos_ioctl.c linux/arch/sparc/kernel/sunos_ioctl.c
--- v1.3.44/linux/arch/sparc/kernel/sunos_ioctl.c	Sat Nov 25 19:04:37 1995
+++ linux/arch/sparc/kernel/sunos_ioctl.c	Sun Nov 26 11:50:02 1995
@@ -1,4 +1,4 @@
-/* $Id: sunos_ioctl.c,v 1.7 1995/11/25 00:58:30 davem Exp $
+/* $Id: sunos_ioctl.c,v 1.8 1995/11/26 04:07:39 davem Exp $
  * sunos_ioctl.c: The Linux Operating system: SunOS ioctl compatibility.
  * 
  * Copyright (C) 1995 Miguel de Icaza (miguel@nuclecu.unam.mx)
@@ -20,7 +20,7 @@
 
 extern asmlinkage int sys_ioctl(unsigned int, unsigned int, unsigned long);
 
-asmlinkage int sunos_ioctl (int fd, unsigned long cmd, void *arg)
+asmlinkage int sunos_ioctl (int fd, unsigned long cmd, unsigned long arg)
 {
 	struct file *filp;
 	
diff -u --recursive --new-file v1.3.44/linux/arch/sparc/kernel/time.c linux/arch/sparc/kernel/time.c
--- v1.3.44/linux/arch/sparc/kernel/time.c	Sat Nov 25 19:04:37 1995
+++ linux/arch/sparc/kernel/time.c	Sun Nov 26 11:50:02 1995
@@ -1,4 +1,4 @@
-/* $Id: time.c,v 1.3 1995/11/25 00:58:45 davem Exp $
+/* $Id: time.c,v 1.4 1995/11/25 03:29:31 davem Exp $
  * linux/arch/sparc/kernel/time.c
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
@@ -13,8 +13,10 @@
 #include <linux/mm.h>
 #include <linux/timex.h>
 
+#include <asm/oplib.h>
 #include <asm/segment.h>
 #include <asm/timer.h>
+#include <asm/mostek.h>
 
 #define TIMER_IRQ  10    /* Also at level 14, but we ignore that one. */
 
@@ -45,9 +47,66 @@
 	    last_rtc_update = xtime.tv_sec - 600; /* do it again in 60 s */
 }
 
+/* Converts Gregorian date to seconds since 1970-01-01 00:00:00.
+ * Assumes input in normal date format, i.e. 1980-12-31 23:59:59
+ * => year=1980, mon=12, day=31, hour=23, min=59, sec=59.
+ *
+ * [For the Julian calendar (which was used in Russia before 1917,
+ * Britain & colonies before 1752, anywhere else before 1582,
+ * and is still in use by some communities) leave out the
+ * -year/100+year/400 terms, and add 10.]
+ *
+ * This algorithm was first published by Gauss (I think).
+ *
+ * WARNING: this function will overflow on 2106-02-07 06:28:16 on
+ * 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 int day, unsigned int hour,
+	unsigned int min, unsigned int sec)
+{
+	if (0 >= (int) (mon -= 2)) {	/* 1..12 -> 11,12,1..10 */
+		mon += 12;	/* Puts Feb last since it has leap day */
+		year -= 1;
+	}
+	return (((
+	    (unsigned long)(year/4 - year/100 + year/400 + 367*mon/12 + day) +
+	      year*365 - 719499
+	    )*24 + hour /* now have hours */
+	   )*60 + min /* now have minutes */
+	  )*60 + sec; /* finally seconds */
+}
+
+#ifndef BCD_TO_BIN
+#define BCD_TO_BIN(val) (((val)&15) + ((val)>>4)*10)
+#endif
+
+#ifndef BIN_TO_BCD
+#define BIN_TO_BCD(val) ((((val)/10)<<4) + (val)%10)
+#endif
+
 void time_init(void)
 {
+	unsigned int year, mon, day, hour, min, sec;
+	struct mostek48t02 *mregs;
+
 	request_irq(TIMER_IRQ, timer_interrupt, SA_INTERRUPT, "timer");
+	mregs = mstk48t02_regs;
+	if(!mregs) {
+		prom_printf("Something wrong, clock regs not mapped yet.\n");
+		prom_halt();
+	}		
+	mregs->creg |= MSTK_CREG_READ;
+	sec = BCD_TO_BIN(mregs->sec);
+	min = BCD_TO_BIN(mregs->min);
+	hour = BCD_TO_BIN(mregs->hour);
+	day = BCD_TO_BIN(mregs->dom);
+	mon = BCD_TO_BIN(mregs->mnth);
+	year = (BCD_TO_BIN(mregs->yr) + MSTK_YR_ZERO);
+	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
+	xtime.tv_usec = 0;
+	mregs->creg &= ~MSTK_CREG_READ;
 	return;
 }
 /* Nothing fancy on the Sparc yet. */
@@ -71,9 +130,32 @@
 	sti();
 }
 
-/* XXX Mostek RTC code needs to be written XXX */
 static int set_rtc_mmss(unsigned long nowtime)
 {
-	/* Just say we succeeded for now. */
-	return 0;
+	int retval = 0;
+	int real_seconds, real_minutes, mostek_minutes;
+	struct mostek48t02 *mregs = mstk48t02_regs;
+
+	if(!mregs)
+		retval = -1;
+	else {
+		mregs->creg |= MSTK_CREG_READ;
+		mostek_minutes = BCD_TO_BIN(mregs->min);
+		mregs->creg &= ~MSTK_CREG_READ;
+
+		real_seconds = nowtime % 60;
+		real_minutes = nowtime / 60;
+		if (((abs(real_minutes - mostek_minutes) + 15)/30) & 1)
+			real_minutes += 30;
+		real_minutes %= 60;
+		if (abs(real_minutes - mostek_minutes) < 30) {
+			mregs->creg |= MSTK_CREG_WRITE;
+			mregs->sec = real_seconds;
+			mregs->min = real_minutes;
+			mregs->creg &= ~MSTK_CREG_WRITE;
+		} else
+			retval = -1;
+	}
+
+	return retval;
 }
diff -u --recursive --new-file v1.3.44/linux/arch/sparc/mm/sun4c.c linux/arch/sparc/mm/sun4c.c
--- v1.3.44/linux/arch/sparc/mm/sun4c.c	Sat Nov 25 19:04:38 1995
+++ linux/arch/sparc/mm/sun4c.c	Sun Nov 26 11:50:02 1995
@@ -461,13 +461,11 @@
 void sun4c_pgd_free(pgd_t *pgd)
 {
 	free_page((unsigned long) pgd);
-	sun4c_unlock_tlb_entry((unsigned long) pgd);
 }
 
 pgd_t *sun4c_pgd_alloc(void)
 {
 	unsigned long new_pgd = get_free_page(GFP_KERNEL);
-	sun4c_lock_tlb_entry(new_pgd);
 	return (pgd_t *) new_pgd;
 }
 
diff -u --recursive --new-file v1.3.44/linux/drivers/block/README.ide linux/drivers/block/README.ide
--- v1.3.44/linux/drivers/block/README.ide	Sat Nov 25 19:04:38 1995
+++ linux/drivers/block/README.ide	Mon Nov 27 09:36:21 1995
@@ -34,6 +34,8 @@
 		- PCI support is automatic
 		- for VLB, use kernel command line option:   ide0=cmd640_vlb
 		- this support also enables the secondary i/f on most cards
+		- experimental interface timing parameter support
+NEW!	- experimental support for UMC 8672 interfaces
 NEW!	- support for secondary interface on the FGI/Holtek HT-6560B VLB i/f
 		- use kernel command line option:   ide1=ht6560
 NEW!	- experimental "fast" speed support for QD6580 interfaces
@@ -45,7 +47,10 @@
 NEW!	- transparent support for DiskManager 6.0x and "Dynamic Disk Overlay"
 	- works with Linux fdisk, LILO, loadlin, bootln, etc..
 NEW!	- mostly transparent support for EZ-Drive
-		- LILO is incompatible (also harmless) with EZ-Drive
+NEW!		- to use LILO with EZ, install LILO on the linux partition
+		  rather than on the master boot record, and then mark the
+		  linux partition as "bootable" or "active" using fdisk.
+		  (courtesy of Juha Laiho <jlaiho@ichaos.nullnet.fi>).
 NEW!	- ide-cd.c now compiles separate from ide.c
 NEW!	- Bus-Master DMA support for Intel PCI Triton chipset IDE interfaces
 		- for details, see comments at top of triton.c
@@ -466,24 +471,62 @@
 
 ================================================================================
 
- from:       'delman@mipg.upenn.edu'
- subject:    rz1000
+ 1995 Nov 16 at 08:25  EST
+ from:       'dwhysong@dolphin.physics.ucsb.edu' (BNR400)
 
-Hi Mark! Looks like you managed to get the info from Intel to disable
-the read-ahead feature of the RZ1000. My encounter with
-Zeos (subsidiary of Micron which owns PCTech) has not been as
-successful --- one guy needs to ask his supervisors about NDA, another
-guy thinks that there is too much of a performance hit with read-ahead
-disabled.
-
-Did the following benchmark to see how true the claim is.
-With Linux 1.2.13, average of 10 "hdparm -t" in MB/s:
-
-                       hdparm -c0        hdparm -c1
-read-ahead enabled        4.28              4.25
-read-ahead disabled       3.58              4.30
+[I'm cc'ing this to Mark Lord: FYI, I've got at DTC2278S VLB EIDE
+controller with a Connor CFA850A as /dev/hda and a Maxtor 7213A as
+/dev/hdb using Linux 1.2.13 w/patches for assembly strcpy and the kswap
+patches. I'm getting strange behavior and an unstable system when I try to
+use 32 bit VLB data transfer to the interface card. However, hdparm
+reports that the Connor is extremely fast when I can get the 32 bit mode
+enabled using hdparm -c1 /dev/hd(a|b). However, if I don't do hdparm -c1
+on both /dev/hda and /dev/hdb, then when I run "hdparm -t /dev/hda" the
+disk subsystem locks up... the disk LED comes on and stays on, and no
+other programs are able to get disk access (I can switch VC's, but I can't
+get past the username prompt). I thought you should know about this. I'm
+not sure if it's a problem with the support for the DTC cards, or a
+peculiarity with my hardware configuration. I doubt that my hardware
+itself is flaky, though that's always a possibility.]
+
+On Wed, 15 Nov 1995, Michael Faurot wrote:
+
+> > The trick is setting BOTH drives to use the 32 bit interface.
+>
+> Congrats on getting it going.  Those are some great transfer
+> rates.  I noticed you did switch on the unmasking.  Noticed any
+> problems with things under extreme load or with serial transfers?
+
+I've never had any problems which I could trace to interrupt unmasking.
+Of course, my system usually doesn't have a really heavy load, either.
+These numbers seem way too high for a disk with something like 3500 (?)
+RPM.
+
+Sleepy# hdparm -t /dev/hda
+
+/dev/hda:
+ Timing buffer-cache reads:   32 MB in  2.24 seconds =14.29 MB/sec
+ Timing buffered disk reads:  16 MB in  3.63 seconds = 4.41 MB/sec
+ Estimating raw driver speed: 16 MB in  2.51 seconds = 6.37 MB/sec
+
+> Not sure I was much help to you, but I'm glad to hear you got it
+> working--and pretty impressivly at that. :-)
+
+Mmm, well, about that... I've found that my Connor drive (/dev/hda) is
+pretty fast when I have my system configured like this. I'm still not
+sure I trust the "hdparm -t"  results, though. However, when I try
+"hdparm -t /dev/hdb" (/dev/hdb is an older Maxtor 7213A) I have the same
+problem I had before with my disk subsystem locking up.
+
+I've tried just about every possible combination of flags in ide.c and
+hdparm, and I can't get decent performance out of this drive/controller
+combination without some kind of instability creeping in. I'm living with
+the situation now only because /dev/hdb is a DOS-only drive, and I don't
+need it under Linux. However, I don't really like the situation.
 
-Maybe -c1 should be the default for the RZ1000, or as a suggestion in
-the README for people with the RZ1000.
+-Dave
+dwhysong@physics.ucsb.edu
+
+(Why can't this stuff be simple? Plug the card in, and it works? Every
+hardware manufacturer has to have their own way of doing things...)
 
-Cheers, Delman.
diff -u --recursive --new-file v1.3.44/linux/drivers/block/cmd640.c linux/drivers/block/cmd640.c
--- v1.3.44/linux/drivers/block/cmd640.c	Thu Jan  1 02:00:00 1970
+++ linux/drivers/block/cmd640.c	Mon Nov 27 09:36:21 1995
@@ -0,0 +1,444 @@
+/*
+ *  linux/drivers/block/cmd640.c	Version 0.01  Nov 16, 1995
+ *
+ *  Copyright (C) 1995  Linus Torvalds & author (see below)
+ */
+
+/*
+ *  Principal Author/Maintainer:  abramov@cecmow.enet.dec.com (Igor)
+ *
+ *  This file provides support for the advanced features and bugs
+ *  of IDE interfaces using the CMD Technologies 0640 IDE interface chip.
+ *
+ *  Version 0.01	Initial version, hacked out of ide.c,
+ *			and #include'd rather than compiled separately.
+ *			This will get cleaned up in a subsequent release.
+ */
+
+/* Interface to access cmd640x registers */
+static void (*put_cmd640_reg)(int key, int reg_no, int val);
+static byte (*get_cmd640_reg)(int key, int reg_no);
+
+enum { none, vlb, pci1, pci2 };
+static int	bus_type = none;
+static int	cmd640_chip_version;
+static int	cmd640_key;
+static byte	is_cmd640[MAX_HWIFS];
+
+/*
+ * For some unknown reasons pcibios functions which read and write registers
+ * do not work with cmd640. We use direct io instead.
+ */
+
+/* PCI method 1 access */
+
+static void put_cmd640_reg_pci1(int key, int reg_no, int val)
+{
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	outl_p((reg_no & 0xfc) | key, 0xcf8);
+	outb_p(val, (reg_no & 3) + 0xcfc);
+	restore_flags(flags);
+}
+
+static byte get_cmd640_reg_pci1(int key, int reg_no)
+{
+	byte b;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	outl_p((reg_no & 0xfc) | key, 0xcf8);
+	b = inb(0xcfc + (reg_no & 3));
+	restore_flags(flags);
+	return b;
+}
+
+/* PCI method 2 access (from CMD datasheet) */
+
+static void put_cmd640_reg_pci2(int key, int reg_no, int val)
+{
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	outb_p(0x10, 0xcf8);
+	outb_p(val, key + reg_no);
+	outb_p(0, 0xcf8);
+	restore_flags(flags);
+}
+
+static byte get_cmd640_reg_pci2(int key, int reg_no)
+{
+	byte b;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	outb_p(0x10, 0xcf8);
+	b = inb(key + reg_no);
+	outb_p(0, 0xcf8);
+	restore_flags(flags);
+	return b;
+}
+
+/* VLB access */
+
+static void put_cmd640_reg_vlb(int key, int reg_no, int val)
+{
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	outb(reg_no, key + 8);
+	outb(val, key + 0xc);
+	restore_flags(flags);
+}
+
+static byte get_cmd640_reg_vlb(int key, int reg_no)
+{
+	byte b;
+	unsigned long flags;
+
+	save_flags(flags);
+	cli();
+	outb(reg_no, key + 8);
+	b = inb(key + 0xc);
+	restore_flags(flags);
+	return b;
+}
+
+/*
+ * Probe for CMD640x -- pci method 1
+ */
+
+static int probe_for_cmd640_pci1(void)
+{
+	long id;
+	int	k;
+
+	for (k = 0x80000000; k <= 0x8000f800; k += 0x800) {
+		outl(k, 0xcf8);
+		id = inl(0xcfc);
+		if (id != 0x06401095)
+			continue;
+		put_cmd640_reg = put_cmd640_reg_pci1;
+		get_cmd640_reg = get_cmd640_reg_pci1;
+		cmd640_key = k;
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * Probe for CMD640x -- pci method 2
+ */
+
+static int probe_for_cmd640_pci2(void)
+{
+	int i;
+	int v_id;
+	int d_id;
+
+	for (i = 0xc000; i <= 0xcf00; i += 0x100) {
+		outb(0x10, 0xcf8);
+		v_id = inw(i);
+		d_id = inw(i + 2);
+		outb(0, 0xcf8);
+		if (v_id != 0x1095 || d_id != 0x640)
+			continue;
+		put_cmd640_reg = put_cmd640_reg_pci2;
+		get_cmd640_reg = get_cmd640_reg_pci2;
+		cmd640_key = i;
+		return 1;
+	}
+	return 0;
+}
+
+/*
+ * Probe for CMD640x -- vlb
+ */
+
+static int probe_for_cmd640_vlb(void) {
+	byte b;
+
+	outb(0x50, 0x178);
+	b = inb(0x17c);
+	if (b == 0xff || b == 0 || (b & 0x20)) {
+		outb(0x50, 0xc78);
+		b = inb(0x7c);
+		if (b == 0xff || b == 0 || !(b & 0x20))
+			return 0;
+		cmd640_key = 0x70;
+	} else {
+		cmd640_key = 0x170;
+	}
+	put_cmd640_reg = put_cmd640_reg_vlb;
+	get_cmd640_reg = get_cmd640_reg_vlb;
+	return 1;
+}
+
+/*
+ * Probe for Cmd640x and initialize it if found
+ */
+
+int ide_probe_for_cmd640x(void)
+{
+	int i;
+
+	for (i = 0; i < MAX_HWIFS; i++)
+		is_cmd640[i] = 0;
+
+	if (probe_for_cmd640_pci1()) {
+		bus_type = pci1;
+	} else if (probe_for_cmd640_pci2()) {
+		bus_type = pci2;
+	} else if (cmd640_vlb && probe_for_cmd640_vlb()) {
+		/* May be remove cmd640_vlb at all, and probe in any case */
+		bus_type = vlb;
+	} else {
+		return 0;
+	}
+
+	/*
+	 * Undocumented magic. (There is no 0x5b port in specs)
+	 */
+
+	put_cmd640_reg(cmd640_key, 0x5b, 0xbd);
+	if (get_cmd640_reg(cmd640_key, 0x5b) != 0xbd) {
+		printk("ide: can't initialize cmd640 -- wrong value in 0x5b\n");
+		return 0;
+	}
+	put_cmd640_reg(cmd640_key, 0x5b, 0);
+
+	/*
+	 * Documented magic.
+	 */
+
+	cmd640_chip_version = get_cmd640_reg(cmd640_key, 0x50) & 3;
+	if (cmd640_chip_version == 0) {
+		printk ("ide: wrong CMD640 version -- 0\n");
+		return 0;
+	}
+
+	put_cmd640_reg(cmd640_key, 0x51, get_cmd640_reg(cmd640_key, 0x51) | 0xc8);
+	put_cmd640_reg(cmd640_key, 0x57, 0);
+	put_cmd640_reg(cmd640_key, 0x57, get_cmd640_reg(cmd640_key, 0x57) | 0x0c);
+
+	serialized = 1;
+
+	printk("ide: buggy CMD640 interface at ");
+	switch (bus_type) {
+		case vlb :
+			printk("local bus, port 0x%x", cmd640_key);
+			break;
+		case pci1:
+			printk("pci, (0x%x)", cmd640_key);
+			break;
+		case pci2:
+			printk("pci,(access method 2) (0x%x)", cmd640_key);
+			break;
+	}
+
+	is_cmd640[0] = is_cmd640[1] = 1;
+
+	/*
+	 * Reset interface timings
+	 */
+
+	put_cmd640_reg(cmd640_key, 0x58, 0);
+	put_cmd640_reg(cmd640_key, 0x52, 0);
+
+	printk("\n ... serialized, disabled read-ahead, secondary interface enabled\n");
+
+	return 1;
+}
+
+static int as_clocks(int a) {
+	switch (a & 0xf0) {
+		case 0 :	return 4;
+		case 0x40 :	return 2;
+		case 0x80 :	return 3;
+		case 0xc0 :	return 5;
+		default :	return -1;
+	}
+}
+
+/*
+ * Tuning of drive parameters
+ */
+
+static void cmd640_set_timing(int if_num, int dr_num, int r1, int r2) {
+	int  b_reg;
+	byte b;
+	int  r52;
+
+	b_reg = if_num ? 0x57 : dr_num ? 0x55 : 0x53;
+
+	if (if_num == 0) {
+		put_cmd640_reg(cmd640_key, b_reg, r1);
+		put_cmd640_reg(cmd640_key, b_reg + 1, r2);
+	} else {
+		b = get_cmd640_reg(cmd640_key, b_reg);
+		if ((b&1) == 0) {
+			put_cmd640_reg(cmd640_key, b_reg, r1);
+		} else {
+			if (as_clocks(b) < as_clocks(r1))
+				put_cmd640_reg(cmd640_key, b_reg, r1);
+		}
+		b = get_cmd640_reg(cmd640_key, b_reg + 1);
+		if (b == 0) {
+			put_cmd640_reg(cmd640_key, b_reg + 1, r2);
+		} else {
+			r52 = (b&0xf) < (r2&0xf) ? (r2&0xf) : (b&0xf);
+			r52 |= (b&0xf0) < (r2&0xf0) ? (r2&0xf0) : (b&0xf0);
+			put_cmd640_reg(cmd640_key, b_reg+1, r52);
+		}
+	}
+
+	b = get_cmd640_reg(cmd640_key, 0x52);
+	if (b == 0) {
+		put_cmd640_reg(cmd640_key, 0x52, r2);
+	} else {
+		r52 = (b&0xf) < (r2&0xf) ? (r2&0xf) : (b&0xf);
+		r52 |= (b&0xf0) < (r2&0xf0) ? (r2&0xf0) : (b&0xf0);
+		put_cmd640_reg(cmd640_key, 0x52, r52);
+	}
+}
+
+static int bus_speed = 33; /* MHz */
+
+struct pio_timing {
+	int	mc_time;	/* Minimal cycle time (ns) */
+	int	av_time;	/* Address valid to DIOR-/DIOW- setup (ns) */
+	int	ds_time;	/* DIOR data setup	(ns) */
+} pio_timings[6] = {
+	{ 70,	165,	600 },	/* PIO Mode 0 */
+	{ 50,	125,	383 },	/* PIO Mode 1 */
+	{ 30,	100,	240 },	/* PIO Mode 2 */
+	{ 30,	80,	180 },	/* PIO Mode 3 */
+	{ 25,	70,	125 },	/* PIO Mode 4 */
+	{ 20,	50,	100 }	/* PIO Mode ? */
+};
+
+struct drive_pio_info {
+	const char	*name;
+	int		pio;
+} drive_pios[] = {
+	{ "Maxtor 7131 AT", 1 },
+	{ "Maxtor 7171 AT", 1 },
+	{ "Maxtor 7213 AT", 1 },
+	{ "Maxtor 7245 AT", 1 },
+	{ "SAMSUNG SHD-3122A", 1 },
+	{ "QUANTUM ELS127A", 0 },
+	{ "QUANTUM LPS240A", 0 },
+	{ "QUANTUM LPS270A", 3 },
+	{ "QUANTUM LPS540A", 3 },
+	{ NULL,	0 }
+};
+
+static int known_drive_pio(char* name) {
+	struct drive_pio_info* pi;
+
+	for (pi = drive_pios; pi->name != NULL; pi++) {
+		if (strcmp(pi->name, name) == 0)
+			return pi->pio;
+	}
+	return -1;
+}
+
+static void cmd640_timings_to_regvals(int mc_time, int av_time, int ds_time,
+				int clock_time,
+				int* r1, int* r2)
+{
+	int a, b;
+
+	a = (mc_time + clock_time - 1)/clock_time;
+	if (a <= 2) *r1 = 0x40;
+	else if (a == 3) *r1 = 0x80;
+	else if (a == 4) *r1 = 0;
+	else *r1 = 0xc0;
+
+	a = (av_time + clock_time - 1)/clock_time;
+	if (a < 2)
+		a = 2;
+	b = (ds_time + clock_time - 1)/clock_time - a;
+	if (b < 2)
+		b = 2;
+	if (b > 0x11) {
+		a += b - 0x11;
+		b = 0x11;
+	}
+	if (a > 0xf)
+		a = 0;
+	if (cmd640_chip_version > 1)
+		b -= 1;
+	if (b > 0xf)
+		b = 0;
+	*r2 = (a << 4) | b;
+}
+
+static void set_pio_mode(int if_num, int drv_num, int mode_num) {
+	int p_base;
+	int i;
+
+	p_base = if_num ? 0x170 : 0x1f0;
+	outb(3, p_base + 1);
+	outb(mode_num | 8, p_base + 2);
+	outb((drv_num | 0xa) << 4, p_base + 6);
+	outb(0xef, p_base + 7);
+	for (i = 0; (i < 100) && (inb (p_base + 7) & 0x80); i++)
+		delay_10ms();
+}
+
+void cmd640_tune_drive(ide_drive_t* drive) {
+	int interface_number;
+	int drive_number;
+	int clock_time; /* ns */
+	int max_pio;
+	int mc_time, av_time, ds_time;
+	struct hd_driveid* id;
+	int r1, r2;
+
+	/*
+	 * Determine if drive is under cmd640 control
+	 */
+	interface_number = HWIF(drive) - ide_hwifs;
+	if (!is_cmd640[interface_number])
+		return;
+
+	drive_number = drive - HWIF(drive)->drives;
+	clock_time = 1000/bus_speed;
+	id = drive->id;
+	if ((max_pio = known_drive_pio(id->model)) != -1) {
+		mc_time = pio_timings[max_pio].mc_time;
+		av_time = pio_timings[max_pio].av_time;
+		ds_time = pio_timings[max_pio].ds_time;
+	} else {
+		max_pio = id->tPIO;
+		mc_time = pio_timings[max_pio].mc_time;
+		av_time = pio_timings[max_pio].av_time;
+		ds_time = pio_timings[max_pio].ds_time;
+		if (id->field_valid & 2) {
+			if ((id->capability & 8) && (id->eide_pio_modes & 7)) {
+				if (id->eide_pio_modes & 4) max_pio = 5;
+				else if (id->eide_pio_modes & 2) max_pio = 4;
+				else max_pio = 3;
+				ds_time = id->eide_pio_iordy;
+				mc_time = pio_timings[max_pio].mc_time;
+				av_time = pio_timings[max_pio].av_time;
+			} else {
+				ds_time = id->eide_pio;
+			}
+			if (ds_time == 0)
+				ds_time = pio_timings[max_pio].ds_time;
+		}
+	}
+	cmd640_timings_to_regvals(mc_time, av_time, ds_time, clock_time,
+				&r1, &r2);
+	set_pio_mode(interface_number, drive_number, max_pio);
+	cmd640_set_timing(interface_number, drive_number, r1, r2);
+	printk ("Mode and Timing set to PIO%d (0x%x 0x%x)\n", max_pio, r1, r2);
+}
diff -u --recursive --new-file v1.3.44/linux/drivers/block/floppy.c linux/drivers/block/floppy.c
--- v1.3.44/linux/drivers/block/floppy.c	Tue Nov 21 13:22:07 1995
+++ linux/drivers/block/floppy.c	Sun Nov 26 19:23:09 1995
@@ -2608,7 +2608,7 @@
 		}
 		if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)
 			panic(DEVICE_NAME ": request list destroyed");
-		if (CURRENT->bh && !CURRENT->bh->b_lock)
+		if (CURRENT->bh && !buffer_locked(CURRENT->bh))
 			panic(DEVICE_NAME ": block not locked");
 
 		device = CURRENT->rq_dev;
@@ -3581,7 +3581,7 @@
 				process_fd_request();
 				return 1;
 			}
-			if (bh && !bh->b_uptodate)
+			if (bh && !buffer_uptodate(bh))
 				ll_rw_block(READ, 1, &bh);
 			process_fd_request();
 			wait_on_buffer(bh);
diff -u --recursive --new-file v1.3.44/linux/drivers/block/genhd.c linux/drivers/block/genhd.c
--- v1.3.44/linux/drivers/block/genhd.c	Wed Nov  8 07:11:30 1995
+++ linux/drivers/block/genhd.c	Sun Nov 26 19:23:09 1995
@@ -109,9 +109,7 @@
 	   * This block is from a device that we're about to stomp on.
 	   * So make sure nobody thinks this block is usable.
 	   */
-		bh->b_dirt = 0;
-		bh->b_uptodate = 0;
-		bh->b_req = 0;
+		bh->b_state = 0;
 
 		if (*(unsigned short *) (bh->b_data+510) != 0xAA55)
 			goto done;
@@ -194,9 +192,10 @@
 		return -1;
 	}
 	data = bh->b_data;
-	bh->b_dirt = 0;		/* In some cases we modify the geometry    */
-	bh->b_uptodate = 0;	/*  of the drive (below), so ensure that   */
-	bh->b_req = 0;		/*  nobody else tries to re-use this data. */
+	/* In some cases we modify the geometry    */
+	/*  of the drive (below), so ensure that   */
+	/*  nobody else tries to re-use this data. */
+	bh->b_state = 0;
 #ifdef CONFIG_BLK_DEV_IDE
 check_table:
 #endif
diff -u --recursive --new-file v1.3.44/linux/drivers/block/ide.c linux/drivers/block/ide.c
--- v1.3.44/linux/drivers/block/ide.c	Sat Nov 25 19:04:39 1995
+++ linux/drivers/block/ide.c	Mon Nov 27 09:36:21 1995
@@ -1,11 +1,11 @@
 /*
- *  linux/drivers/block/ide.c	Version 5.17  Nov 3, 1995
+ *  linux/drivers/block/ide.c	Version 5.18  Nov 16, 1995
  *
  *  Copyright (C) 1994, 1995  Linus Torvalds & authors (see below)
  */
 
 /*
- * This is the multiple IDE interface driver, as evolved from hd.c.  
+ * This is the multiple IDE interface driver, as evolved from hd.c.
  * It supports up to four IDE interfaces, on one or more IRQs (usually 14 & 15).
  * There can be up to two drives per interface, as per the ATA-2 spec.
  *
@@ -13,17 +13,17 @@
  * Secondary i/f:  ide1: major=22; (hdc or hd1a) minor=0; (hdd or hd1b) minor=64
  * Tertiary i/f:   ide2: major=33; (hde)         minor=0; (hdf)         minor=64
  * Quaternary i/f: ide3: major=34; (hdg)         minor=0; (hdh)         minor=64
- * 
+ *
  * It is easy to extend ide.c to handle more than four interfaces:
  *
  *	Change the MAX_HWIFS constant in ide.h.
- * 
+ *
  *	Define some new major numbers (in major.h), and insert them into
  *	the ide_hwif_to_major table in ide.c.
- * 
+ *
  *	Fill in the extra values for the new interfaces into the two tables
  *	inside ide.c:  default_io_base[]  and  default_irqs[].
- * 
+ *
  *	Create the new request handlers by cloning "do_ide3_request()"
  *	for each new interface, and add them to the switch statement
  *	in the ide_init() function in ide.c.
@@ -56,7 +56,7 @@
  *  Maintained by Mark Lord (mlord@bnr.ca):  ide.c, ide.h, triton.c, hd.c, ..
  *
  *  This was a rewrite of just about everything from hd.c, though some original
- *  code is still sprinkled about.  Think of it as a major evolution, with 
+ *  code is still sprinkled about.  Think of it as a major evolution, with
  *  inspiration from lots of linux users, esp.  hamish@zot.apana.org.au
  *
  *  Version 1.0 ALPHA	initial code, primary i/f working okay
@@ -167,15 +167,18 @@
  *			remove "Huh?" from cmd640 code
  *			added qd6580 interface speed select from Colten Edwards
  *  Version 5.17	kludge around bug in BIOS32 on Intel triton motherboards
+ *  Version 5.18	new CMD640 code, moved to cmd640.c, #include'd for now
+ *			new UMC8672 code, moved to umc8672.c, #include'd for now
+ *			disallow turning on DMA when h/w not capable of DMA
  *
  *  Driver compile-time options are in ide.h
  *
  *  To do, in likely order of completion:
+ *	- make cmd640.c and umc8672.c compile separately from ide.c
  *	- add ALI M1443/1445 chipset support from derekn@vw.ece.cmu.edu
- *	- add Promise Caching controller support from peterd@pnd-pc.demon.co.uk
  *	- add ioctls to get/set interface timings on various interfaces
+ *	- add Promise Caching controller support from peterd@pnd-pc.demon.co.uk
  *	- modify kernel to obtain BIOS geometry for drives on 2nd/3rd/4th i/f
- *	- improved CMD support:  handed this off to someone else
  *	- find someone to work on IDE *tape drive* support
  */
 
@@ -209,9 +212,14 @@
 
 #include "ide.h"
 
+#ifdef SUPPORT_CMD640
+void cmd640_tune_drive(ide_drive_t *);
+static int cmd640_vlb = 0;
+#endif
+
        ide_hwif_t	ide_hwifs[MAX_HWIFS];		/* hwif info */
 static ide_hwgroup_t	*irq_to_hwgroup [16];
-static const byte	ide_hwif_to_major[MAX_HWIFS]   = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR};
+static const byte	ide_hwif_to_major[MAX_HWIFS] = {IDE0_MAJOR, IDE1_MAJOR, IDE2_MAJOR, IDE3_MAJOR};
 
 static const unsigned short default_io_base[MAX_HWIFS] = {0x1f0, 0x170, 0x1e8, 0x168};
 static const byte	default_irqs[MAX_HWIFS]     = {14, 15, 11, 10};
@@ -999,7 +1007,7 @@
 
 /*
  * multwrite() transfers a block of one or more sectors of data to a drive
- * as part of a disk multwrite operation.  
+ * as part of a disk multwrite operation.
  */
 static void multwrite (ide_drive_t *drive)
 {
@@ -1232,7 +1240,7 @@
 	if (drive->select.b.lba) {
 #ifdef DEBUG
 		printk("%s: %sing: LBAsect=%ld, sectors=%ld, buffer=0x%08lx\n",
-			drive->name, (rq->cmd==READ)?"read":"writ", 
+			drive->name, (rq->cmd==READ)?"read":"writ",
 			block, rq->nr_sectors, (unsigned long) rq->buffer);
 #endif
 		OUT_BYTE(block,io_base+IDE_SECTOR_OFFSET);
@@ -1333,7 +1341,7 @@
 	}
 	drive = &hwif->drives[unit];
 #ifdef DEBUG
-	if (rq->bh && !rq->bh->b_lock) {
+	if (rq->bh && !buffer_locked(rq->bh)) {
 		printk("%s: block not locked\n", drive->name);
 		goto kill_rq;
 	}
@@ -1495,7 +1503,7 @@
 		printk("%s: marginal timeout\n", drive->name);
 	} else {				 /* drive not responding */
 		hwgroup->handler = NULL;
-		if (hwgroup->hwif->dmaproc) 
+		if (hwgroup->hwif->dmaproc)
 			(void) hwgroup->hwif->dmaproc (ide_dma_abort, drive);
 		if (!ide_error(drive, "irq timeout", GET_STAT()))
 			do_hwgroup_request (hwgroup);
@@ -1522,7 +1530,7 @@
  * In reality, this is a non-issue.  The new command is not sent unless the
  * drive is ready to accept one, in which case we know the drive is not
  * trying to interrupt us.  And ide_set_handler() is always invoked before
- * completing the issuance of any new drive command, so we will not be 
+ * completing the issuance of any new drive command, so we will not be
  * accidently invoked as a result of any valid command completion interrupt.
  *
  */
@@ -1806,24 +1814,24 @@
 		case BLKRAGET:
 			return write_fs_long(arg, read_ahead[MAJOR(inode->i_rdev)]);
 
-         	case BLKGETSIZE:   /* Return device size */
+	 	case BLKGETSIZE:   /* Return device size */
 			return write_fs_long(arg, drive->part[MINOR(inode->i_rdev)&PARTN_MASK].nr_sects);
 		case BLKRRPART: /* Re-read partition tables */
 			return revalidate_disk(inode->i_rdev);
 
-                case HDIO_GET_KEEPSETTINGS:
+		case HDIO_GET_KEEPSETTINGS:
 			return write_fs_long(arg, drive->keep_settings);
 
-                case HDIO_GET_UNMASKINTR:
+		case HDIO_GET_UNMASKINTR:
 			return write_fs_long(arg, drive->unmask);
 
-                case HDIO_GET_DMA:
+		case HDIO_GET_DMA:
 			return write_fs_long(arg, drive->using_dma);
 
-                case HDIO_GET_CHIPSET:
+		case HDIO_GET_CHIPSET:
 			return write_fs_long(arg, drive->chipset);
 
-                case HDIO_GET_MULTCOUNT:
+		case HDIO_GET_MULTCOUNT:
 			return write_fs_long(arg, drive->mult_count);
 
 		case HDIO_GET_IDENTITY:
@@ -1858,6 +1866,10 @@
 			cli();
 			switch (cmd) {
 				case HDIO_SET_DMA:
+					if (!(HWIF(drive)->dmaproc)) {
+						restore_flags(flags);
+						return -EPERM;
+					}
 					drive->using_dma = arg;
 					break;
 				case HDIO_SET_KEEPSETTINGS:
@@ -2046,7 +2058,7 @@
 		drive->present = 1;
 		drive->cyl     = drive->bios_cyl  = id->cyls;
 		drive->head    = drive->bios_head = id->heads;
-		drive->sect    = drive->bios_sect = id->sectors; 
+		drive->sect    = drive->bios_sect = id->sectors;
 	}
 	/* Handle logical geometry translation by the drive */
 	if ((id->field_valid & 1) && id->cur_cyls && id->cur_heads
@@ -2055,7 +2067,7 @@
 		/*
 		 * Extract the physical drive geometry for our use.
 		 * Note that we purposely do *not* update the bios info.
-		 * This way, programs that use it (like fdisk) will 
+		 * This way, programs that use it (like fdisk) will
 		 * still have the same logical view as the BIOS does,
 		 * which keeps the partition table from being screwed.
 		 *
@@ -2079,7 +2091,7 @@
 	if ((!drive->head || drive->head > 16) && id->heads && id->heads <= 16) {
 		drive->cyl  = id->cyls;
 		drive->head = id->heads;
-		drive->sect = id->sectors; 
+		drive->sect = id->sectors;
 	}
 	/* Correct the number of cyls if the bios value is too small */
 	if (drive->sect == drive->bios_sect && drive->head == drive->bios_head) {
@@ -2107,6 +2119,9 @@
 			printk(", DMA");
 	}
 	printk("\n");
+#ifdef SUPPORT_CMD640
+	cmd640_tune_drive(drive);	/* but can we tune a fish? */
+#endif
 }
 
 /*
@@ -2336,8 +2351,8 @@
  * The code enables the secondary IDE controller and the PIO4 (3?) timings on
  * the primary (EIDE). You may probably have to enable the 32-bit support to
  * get the full speed. You better get the disk interrupts disabled ( hdparm -u0
- * /dev/hd.. ) for the drives connected to the EIDE interface. (I get my 
- * filesystem  corrupted with -u1, but under heavy disk load only :-)  
+ * /dev/hd.. ) for the drives connected to the EIDE interface. (I get my
+ * filesystem  corrupted with -u1, but under heavy disk load only :-)
  *
  * From: mlord@bnr.ca -- this chipset is now forced to use the "serialize" feature,
  * which hopefully will make it more reliable to use.. maybe it has the same bugs
@@ -2417,59 +2432,13 @@
 }
 #endif /* SUPPORT_QD6580 */
 
-#if SUPPORT_CMD640
-/*
- * ??? fixme: 
- */
-byte read_cmd640_vlb (byte port, byte reg)
-{
-	byte val;
-
-	unsigned long flags;
-	save_flags(flags);
-	cli();
-	outw(reg, port);
-	val = inb(port+4);
-	restore_flags(flags);
-	return val;
-}
-
-void write_cmd640_vlb (byte port, byte reg, byte val)
-{
-	unsigned long flags;
-	save_flags(flags);
-	cli();
-	outw(reg, port);
-	outw(val, port+4);
-	restore_flags(flags);
-}
-
-void init_cmd640_vlb (void)
-{
-	byte reg;
-	unsigned short port = 0x178;
-
-	serialized = 1;
- 	printk("ide: buggy CMD640 interface: serialized, ");
-	reg = read_cmd640_vlb(port, 0x50);
-	if (reg == 0xff || (reg & 0x90) != 0x90) {
-#if TRY_CMD640_VLB_AT_0x78
-		port = 0x78;
-		reg = read_cmd640_vlb(port, 0x50);
-		if (reg == 0xff || (reg & 0x90) != 0x90)
+#ifdef SUPPORT_UMC8672
+#include "umc8672.c"	/* until we tidy up the interface some more */
 #endif
-		{
-			disallow_unmask = 1;
-			printk("(probe failed) disabled unmasking\n");
-			return;
-		}
-	}
-	write_cmd640_vlb(port, 0x51, read_cmd640_vlb(port, 0x51)|0xc8);
-	write_cmd640_vlb(port, 0x57, read_cmd640_vlb(port, 0x57)|0x0c);
-	printk("disabled read-ahead, enabled secondary\n");
 
-}
-#endif /* SUPPORT_CMD640 */
+#ifdef SUPPORT_CMD640
+#include "cmd640.c"	/* until we tidy up the interface some more */
+#endif
 
 /*
  * stridx() returns the offset of c within s,
@@ -2488,7 +2457,7 @@
  * 2. if the remainder matches one of the supplied keywords,
  *     the index (1 based) of the keyword is negated and returned.
  * 3. if the remainder is a series of no more than max_vals numbers
- *     separated by commas, the numbers are saved in vals[] and a 
+ *     separated by commas, the numbers are saved in vals[] and a
  *     count of how many were saved is returned.  Base10 is assumed,
  *     and base16 is allowed when prefixed with "0x".
  * 4. otherwise, zero is returned.
@@ -2511,7 +2480,7 @@
 		/*
 		 * Look for a series of no more than "max_vals"
 		 * numeric values separated by commas, in base10,
-		 * or base16 when prefixed with "0x".  
+		 * or base16 when prefixed with "0x".
 		 * Return a count of how many were found.
 		 */
 		for (n = 0; (i = stridx(decimal, *s)) >= 0;) {
@@ -2621,11 +2590,18 @@
 	 * Look for interface options:  "idex="
 	 */
 	if (s[0] == 'i' && s[1] == 'd' && s[2] == 'e' && s[3] >= '0' && s[3] <= max_hwif) {
-		const char *ide_words[] = {"noprobe", "serialize", "dtc2278", "ht6560b", "cmd640_vlb", "qd6580", NULL};
+		const char *ide_words[] = {"noprobe", "serialize", "dtc2278", "ht6560b",
+					"cmd640_vlb", "qd6580", "umc8672", NULL};
 		hw = s[3] - '0';
 		hwif = &ide_hwifs[hw];
 
 		switch (match_parm(&s[4], ide_words, vals, 3)) {
+#if SUPPORT_UMC8672
+			case -7: /* "umc8672" */
+				if (hw != 0) goto bad_hwif;
+				init_umc8672();
+				goto done;
+#endif /* SUPPORT_UMC8672 */
 #if SUPPORT_QD6580
 			case -6: /* "qd6580" */
 				if (hw != 0) goto bad_hwif;
@@ -2635,8 +2611,7 @@
 #if SUPPORT_CMD640
 			case -5: /* "cmd640_vlb" */
 				if (hw > 1) goto bad_hwif;
-				init_cmd640_vlb();
-				goto do_serialize; /* not necessary once we implement the above */
+				cmd640_vlb = 1;
 				break;
 #endif /* SUPPORT_CMD640 */
 #if SUPPORT_HT6560B
@@ -2709,7 +2684,7 @@
 
 	drive->cyl  = drive->bios_cyl  = drive->id->cyls;
 	drive->head = drive->bios_head = drive->id->heads;
-	drive->sect = drive->bios_sect = drive->id->sectors; 
+	drive->sect = drive->bios_sect = drive->id->sectors;
 	drive->special.b.set_geometry = 1;
 
 	tracks = drive->bios_cyl * drive->bios_head * drive->bios_sect / 63;
@@ -2745,7 +2720,7 @@
  * drives in the system -- the ones reflected as drive 1 or 2.  The first
  * drive is stored in the high nibble of CMOS byte 0x12, the second in the low
  * nibble.  This will be either a 4 bit drive type or 0xf indicating use byte
- * 0x19 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.  A non-zero value 
+ * 0x19 for an 8 bit type, drive 1, 0x1a for drive 2 in CMOS.  A non-zero value
  * means we have an AT controller hard disk for that drive.
  *
  * Of course, there is no guarantee that either drive is actually on the
@@ -2905,45 +2880,6 @@
 }
 #endif /* SUPPORT_RZ1000 */
 
-#if SUPPORT_CMD640
-void init_cmd640 (byte bus, byte fn)
-{
-	int rc;
-	unsigned char reg;
-
-	serialized = 1;
-	printk("ide: buggy CMD640 interface: ");
-
-#if 0	/* funny.. the cmd640b I tried this on claimed to not be enabled.. */
-	unsigned short sreg;
-	if ((rc = pcibios_read_config_word (bus, fn, PCI_COMMAND, &sreg))) {
-		ide_pci_access_error (rc);
-	} else if (!(sreg & 1)) {
-		printk("not enabled\n");
-	} else {
-
-	/*
-	 * The first part is undocumented magic from the DOS driver.
-	 * According to the datasheet, there is no port 0x5b on the cmd640.
-	 */
-	(void) pcibios_write_config_byte(bus, fn, 0x5b, 0xbd);
-	if (pcibios_write_config_byte(bus, fn, 0x5b, 0xbd) != 0xbd)
-		printk("init_cmd640: huh? 0x5b read back wrong\n");
-	(void) pcibios_write_config_byte(bus, fn, 0x5b, 0);
-#endif /* 0 */
-	/*
-	 * The rest is from the cmd640b datasheet.
-	 */
-	if ((rc = pcibios_read_config_byte(bus, fn, 0x51, &reg))
-	 || (rc =  pcibios_write_config_byte(bus, fn, 0x51, reg | 0xc0)) /* 0xc8 to enable 2nd i/f */
-	 || (rc =  pcibios_read_config_byte(bus, fn, 0x57, &reg))
-	 || (rc =  pcibios_write_config_byte(bus, fn, 0x57, reg | 0x0c)))
-		buggy_interface_fallback (rc);
-	else
-		printk("serialized, disabled read-ahead\n");
-}
-#endif /* SUPPORT_CMD640 */
-
 typedef void (ide_pci_init_proc_t)(byte, byte);
 
 /*
@@ -2966,7 +2902,7 @@
 
 /*
  * ide_init_pci() finds/initializes "known" PCI IDE interfaces
- * 
+ *
  * This routine should ideally be using pcibios_find_class() to find
  * all IDE interfaces, but that function causes some systems to "go weird".
  */
@@ -2975,9 +2911,6 @@
 #if SUPPORT_RZ1000
 	ide_probe_pci (PCI_VENDOR_ID_PCTECH, PCI_DEVICE_ID_PCTECH_RZ1000, &init_rz1000, 0);
 #endif
-#if SUPPORT_CMD640
-	ide_probe_pci (PCI_VENDOR_ID_CMD, PCI_DEVICE_ID_CMD_640, &init_cmd640, 0);
-#endif
 #ifdef CONFIG_BLK_DEV_TRITON
 	/*
 	 * Apparently the BIOS32 services on Intel motherboards are buggy,
@@ -3008,6 +2941,9 @@
 	if (pcibios_present())
 		ide_init_pci ();
 #endif /* CONFIG_PCI */
+#ifdef SUPPORT_CMD640
+	ide_probe_for_cmd640x();
+#endif
 
 	/*
 	 * Probe for drives in the usual way.. CMOS/BIOS, then poke at ports
diff -u --recursive --new-file v1.3.44/linux/drivers/block/ide.h linux/drivers/block/ide.h
--- v1.3.44/linux/drivers/block/ide.h	Sat Nov 25 19:04:39 1995
+++ linux/drivers/block/ide.h	Mon Nov 27 11:22:19 1995
@@ -40,6 +40,9 @@
 #ifndef SUPPORT_CMD640			/* 1 to support CMD640 chipset */
 #define SUPPORT_CMD640		1	/* 0 to reduce kernel size */
 #endif
+#ifndef SUPPORT_UMC8672			/* 1 to support UMC8672 chipset */
+#define SUPPORT_UMC8672		1	/* 0 to reduce kernel size */
+#endif
 #ifndef SUPPORT_HT6560B			/* 1 to support HT6560B chipset */
 #define SUPPORT_HT6560B		1	/* 0 to reduce kernel size */
 #endif
diff -u --recursive --new-file v1.3.44/linux/drivers/block/ll_rw_blk.c linux/drivers/block/ll_rw_blk.c
--- v1.3.44/linux/drivers/block/ll_rw_blk.c	Tue Nov 21 13:22:08 1995
+++ linux/drivers/block/ll_rw_blk.c	Sun Nov 26 23:45:33 1995
@@ -306,7 +306,7 @@
 /* buffer is locked, we just forget about it, else it's a normal read */
 	rw_ahead = (rw == READA || rw == WRITEA);
 	if (rw_ahead) {
-		if (bh->b_lock)
+		if (buffer_locked(bh))
 			return;
 		if (rw == READA)
 			rw = READ;
@@ -321,17 +321,16 @@
 	sector = bh->b_blocknr * count;
 	if (blk_size[major])
 		if (blk_size[major][MINOR(bh->b_dev)] < (sector + count)>>1) {
-			bh->b_dirt = bh->b_uptodate = 0;
-			bh->b_req = 0;
+			bh->b_state = 0;
 			printk("attempt to access beyond end of device\n");
 			return;
 		}
 	/* Uhhuh.. Nasty dead-lock possible here.. */
-	if (bh->b_lock)
+	if (buffer_locked(bh))
 		return;
 	/* Maybe the above fixes it, and maybe it doesn't boot. Life is interesting */
 	lock_buffer(bh);
-	if ((rw == WRITE && !bh->b_dirt) || (rw == READ && bh->b_uptodate)) {
+	if ((rw == WRITE && !buffer_dirty(bh)) || (rw == READ && buffer_uptodate(bh))) {
 		unlock_buffer(bh);
 		return;
 	}
@@ -523,7 +522,7 @@
 		plug_device(dev, &plug);
 	for (i = 0; i < nr; i++) {
 		if (bh[i]) {
-			bh[i]->b_req = 1;
+			set_bit(BH_Req, &bh[i]->b_state);
 			make_request(major, rw, bh[i]);
 			if (rw == READ || rw == READA)
 				kstat.pgpgin++;
@@ -536,8 +535,10 @@
 
       sorry:
 	for (i = 0; i < nr; i++) {
-		if (bh[i])
-			bh[i]->b_dirt = bh[i]->b_uptodate = 0;
+		if (bh[i]) {
+			clear_bit(BH_Dirty, &bh[i]->b_state);
+			clear_bit(BH_Uptodate, &bh[i]->b_state);
+		}
 	}
 	return;
 }
diff -u --recursive --new-file v1.3.44/linux/drivers/block/triton.c linux/drivers/block/triton.c
--- v1.3.44/linux/drivers/block/triton.c	Sat Nov 25 19:04:39 1995
+++ linux/drivers/block/triton.c	Mon Nov 27 09:36:21 1995
@@ -1,5 +1,5 @@
 /*
- *  linux/drivers/block/triton.c	Version 1.02  Oct 13, 1995
+ *  linux/drivers/block/triton.c	Version 1.03  Nov 16, 1995
  *
  *  Copyright (c) 1995  Mark Lord
  *  May be copied or modified under the terms of the GNU General Public License
@@ -64,8 +64,12 @@
  *	  the observation that WRITEs work most of the time, depending on
  *	  cache-buffer occupancy, but multi-sector reads seldom work.
  *
- * Drives like the AC31000H could likely be made to work if all DMA were done
- * one sector at a time, but that would likely negate any advantage over PIO.
+ * Testing was done with a Gigabyte GA-586 ATE system and the following drive:
+ * (Uwe Bonnes - bon@elektron.ikp.physik.th-darmstadt.de)
+ *
+ *   Western Digital AC31600H (1.6Gig w/128kB buffer), DMA mode2, PIO mode4.
+ *	- much better than its 1Gig cousin, this drive is reported to work
+ *	  very well with DMA (7.3MB/sec).
  *
  * If you have any drive models to add, email your results to:  mlord@bnr.ca
  * Keep an eye on /var/adm/messages for "DMA disabled" messages.
diff -u --recursive --new-file v1.3.44/linux/drivers/block/umc8672.c linux/drivers/block/umc8672.c
--- v1.3.44/linux/drivers/block/umc8672.c	Thu Jan  1 02:00:00 1970
+++ linux/drivers/block/umc8672.c	Mon Nov 27 09:36:21 1995
@@ -0,0 +1,108 @@
+/*
+ *  linux/drivers/block/umc8672.c	Version 0.01  Nov 16, 1995
+ *
+ *  Copyright (C) 1995  Linus Torvalds & author (see below)
+ */
+
+/*
+ *  Principal Author/Maintainer:  PODIEN@hml2.atlas.de (Wolfram Podien)
+ *
+ *  This file provides support for the advanced features
+ *  of the UMC 8672 IDE interface.
+ *
+ *  Version 0.01	Initial version, hacked out of ide.c,
+ *			and #include'd rather than compiled separately.
+ *			This will get cleaned up in a subsequent release.
+ */
+
+/*
+ * VLB Controller Support from 
+ * Wolfram Podien
+ * Rohoefe 3
+ * D28832 Achim
+ * Germany
+ *
+ * To enable UMC8672 support there must a lilo line like
+ * append="hd=umc8672"...
+ * To set the speed according to the abilities of the hardware there must be a
+ * line like
+ * #define UMC_DRIVE0 11
+ * in the beginning of the driver, which sets the speed of drive 0 to 11 (there
+ * are some lines present). 0 - 11 are allowed speed values. These values are
+ * the results from the DOS speed test programm supplied from UMC. 11 is the 
+ * highest speed (about PIO mode 3)
+ */
+
+/*
+ * The speeds will eventually become selectable using hdparm via ioctl's,
+ * but for now they are coded here:
+ */
+#define UMC_DRIVE0      11              /* DOS messured drive Speeds */
+#define UMC_DRIVE1      11              /* 0 - 11 allowed */
+#define UMC_DRIVE2      11              /* 11 = Highest Speed */
+#define UMC_DRIVE3      11              /* In case of crash reduce speed */
+
+void out_umc (char port,char wert)
+{
+	outb_p (port,0x108);
+	outb_p (wert,0x109);
+}
+
+byte in_umc (char port)
+{
+	outb_p (port,0x108);
+	return inb_p (0x109);
+}
+
+void init_umc8672(void)
+{
+	int i,tmp;
+	int speed [4];
+/*      0    1    2    3    4    5    6    7    8    9    10   11      */
+	char speedtab [3][12] = {
+	{0xf ,0xb ,0x2 ,0x2 ,0x2 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 },
+	{0x3 ,0x2 ,0x2 ,0x2 ,0x2 ,0x2 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 ,0x1 },
+	{0xff,0xcb,0xc0,0x58,0x36,0x33,0x23,0x22,0x21,0x11,0x10,0x0}};
+
+	cli ();
+	outb_p (0x5A,0x108); /* enable umc */
+	if (in_umc (0xd5) != 0xa0)
+	{
+		sti ();
+		printk ("UMC8672 not found\n");
+		return;  
+	}
+	speed[0] = UMC_DRIVE0;
+	speed[1] = UMC_DRIVE1;
+	speed[2] = UMC_DRIVE2;
+	speed[3] = UMC_DRIVE3;
+	for (i = 0;i < 4;i++)
+	{
+		if ((speed[i] < 0) || (speed[i] > 11))
+		{
+			sti ();
+			printk ("UMC 8672 drive speed out of range. Drive %d Speed %d\n",
+				i, speed[i]);
+			printk ("UMC support aborted\n");
+			return; 
+		}
+	}
+	out_umc (0xd7,(speedtab[0][speed[2]] | (speedtab[0][speed[3]]<<4)));
+	out_umc (0xd6,(speedtab[0][speed[0]] | (speedtab[0][speed[1]]<<4)));
+	tmp = 0;
+	for (i = 3; i >= 0; i--)
+	{
+		tmp = (tmp << 2) | speedtab[1][speed[i]];
+	}
+	out_umc (0xdc,tmp);
+	for (i = 0;i < 4; i++)
+	{
+		out_umc (0xd0+i,speedtab[2][speed[i]]);
+		out_umc (0xd8+i,speedtab[2][speed[i]]);
+	}
+	outb_p (0xa5,0x108); /* disable umc */
+	sti ();
+	printk ("Speeds for UMC8672 \n");
+	for (i = 0;i < 4;i++)
+		 printk ("Drive %d speed %d\n",i,speed[i]);
+}
diff -u --recursive --new-file v1.3.44/linux/drivers/cdrom/aztcd.c linux/drivers/cdrom/aztcd.c
--- v1.3.44/linux/drivers/cdrom/aztcd.c	Sat Nov 25 19:04:39 1995
+++ linux/drivers/cdrom/aztcd.c	Sun Nov 26 19:23:09 1995
@@ -1005,7 +1005,7 @@
   azt_transfer_is_active = 1;
   while (CURRENT_VALID) {
     if (CURRENT->bh) {
-      if (!CURRENT->bh->b_lock)
+      if (!buffer_locked(CURRENT->bh))
 	panic(DEVICE_NAME ": block not locked");
     }
     azt_transfer();
diff -u --recursive --new-file v1.3.44/linux/drivers/cdrom/cdu31a.c linux/drivers/cdrom/cdu31a.c
--- v1.3.44/linux/drivers/cdrom/cdu31a.c	Thu Nov  9 11:23:47 1995
+++ linux/drivers/cdrom/cdu31a.c	Sun Nov 26 19:23:09 1995
@@ -1551,7 +1551,7 @@
       }
       if (CURRENT->bh)
       {
-	 if (!CURRENT->bh->b_lock)
+	 if (!buffer_locked(CURRENT->bh))
          {
 	    panic(DEVICE_NAME ": block not locked");
          }
diff -u --recursive --new-file v1.3.44/linux/drivers/cdrom/mcd.c linux/drivers/cdrom/mcd.c
--- v1.3.44/linux/drivers/cdrom/mcd.c	Tue Nov 21 13:22:08 1995
+++ linux/drivers/cdrom/mcd.c	Sun Nov 26 19:23:09 1995
@@ -657,7 +657,7 @@
   mcd_transfer_is_active = 1;
   while (CURRENT_VALID) {
     if (CURRENT->bh) {
-      if (!CURRENT->bh->b_lock)
+      if (!buffer_locked(CURRENT->bh))
 	panic(DEVICE_NAME ": block not locked");
     }
     mcd_transfer();
diff -u --recursive --new-file v1.3.44/linux/drivers/cdrom/optcd.c linux/drivers/cdrom/optcd.c
--- v1.3.44/linux/drivers/cdrom/optcd.c	Thu Nov  9 11:23:47 1995
+++ linux/drivers/cdrom/optcd.c	Sun Nov 26 19:23:10 1995
@@ -998,7 +998,7 @@
 	opt_transfer_is_active = 1;
 	while (CURRENT_VALID) {
 		if (CURRENT->bh) {
-			if (!CURRENT->bh->b_lock)
+			if (!buffer_locked(CURRENT->bh))
 				panic(DEVICE_NAME ": block not locked");
 		}
 		opt_transfer();	/* First try to transfer block from buffers */
diff -u --recursive --new-file v1.3.44/linux/drivers/cdrom/sjcd.c linux/drivers/cdrom/sjcd.c
--- v1.3.44/linux/drivers/cdrom/sjcd.c	Thu Nov  9 11:23:48 1995
+++ linux/drivers/cdrom/sjcd.c	Sun Nov 26 19:23:10 1995
@@ -1334,7 +1334,7 @@
     /*
      * Who of us are paranoic?
      */
-    if( CURRENT->bh && !( CURRENT->bh->b_lock ) )
+    if( CURRENT->bh && !buffer_locked(CURRENT->bh) )
       panic( DEVICE_NAME ": block not locked" );
 
     sjcd_transfer();
diff -u --recursive --new-file v1.3.44/linux/drivers/char/console.c linux/drivers/char/console.c
--- v1.3.44/linux/drivers/char/console.c	Tue Nov 21 13:22:09 1995
+++ linux/drivers/char/console.c	Sun Nov 26 10:52:28 1995
@@ -134,6 +134,7 @@
 extern void register_console(void (*proc)(const char *));
 extern void vesa_blank(void);
 extern void vesa_unblank(void);
+extern void vesa_powerdown(void);
 extern void compute_shiftstate(void);
 extern void reset_palette(int currcons);
 extern void set_palette(void);
@@ -169,6 +170,7 @@
 
        int console_blanked = 0;
 static int blankinterval = 10*60*HZ;
+static int vesa_off_interval = 0;
 static long blank_origin, blank__origin, unblank_origin;
 
 struct vc vc_cons [MAX_NR_CONSOLES];
@@ -1150,6 +1152,9 @@
 		case 13: /* unblank the screen */
 			unblank_screen();
 			break;
+		case 14: /* set vesa powerdown interval */
+			vesa_off_interval = ((par[1] < 60) ? par[1] : 60) * 60 * HZ;
+			break;
 	}
 }
 
@@ -1826,6 +1831,7 @@
 	if (vt_cons[fg_console]->vc_mode == KD_GRAPHICS)
 		return;
 	if (console_blanked) {
+		timer_table[BLANK_TIMER].fn = unblank_screen;
 		timer_table[BLANK_TIMER].expires = 0;
 		timer_active |= 1<<BLANK_TIMER;
 	} else if (blankinterval) {
@@ -2058,6 +2064,14 @@
 	return kmem_start;
 }
 
+void vesa_powerdown_screen(void)
+{
+	timer_active &= ~(1<<BLANK_TIMER);
+	timer_table[BLANK_TIMER].fn = unblank_screen;
+
+	vesa_powerdown();
+}
+
 void do_blank_screen(int nopowersave)
 {
 	int currcons;
@@ -2065,8 +2079,14 @@
 	if (console_blanked)
 		return;
 
-	timer_active &= ~(1<<BLANK_TIMER);
-	timer_table[BLANK_TIMER].fn = unblank_screen;
+	if(vesa_off_interval && !nopowersave) {
+		timer_table[BLANK_TIMER].fn = vesa_powerdown_screen;
+		timer_table[BLANK_TIMER].expires = jiffies + vesa_off_interval;
+		timer_active |= (1<<BLANK_TIMER);
+	} else {
+		timer_active &= ~(1<<BLANK_TIMER);
+		timer_table[BLANK_TIMER].fn = unblank_screen;
+	}
 
 	/* try not to lose information by blanking, and not to waste memory */
 	currcons = fg_console;
diff -u --recursive --new-file v1.3.44/linux/drivers/char/vesa_blank.c linux/drivers/char/vesa_blank.c
--- v1.3.44/linux/drivers/char/vesa_blank.c	Tue Jun 27 14:11:35 1995
+++ linux/drivers/char/vesa_blank.c	Sun Nov 26 10:52:28 1995
@@ -4,6 +4,7 @@
  * Exported functions:
  *	void vesa_blank(void);
  *	void vesa_unblank(void);
+ *	void vesa_powerdown(void);
  *	void set_vesa_blanking(const unsigned long arg);
  *
  * Not all hardware reacts well to this code - activate at your own risk.
@@ -18,7 +19,7 @@
 |    struct { char ten, onoff; } arg;
 |
 |    if (argc != 2) {
-|	fprintf(stderr, "usage: setvesablank ON|on|off\n");
+|	fprintf(stderr, "usage: setvesablank on|vsync|hsync|powerdown|off\n");
 |	exit(1);
 |    }
 |    if ((fd = open("/dev/console", 0)) < 0)
@@ -27,8 +28,12 @@
 |    arg.onoff = 0;
 |    if (!strcmp(argv[1], "on"))
 |      arg.onoff = 1;
-|    else if (!strcmp(argv[1], "ON"))
+|    else if (!strcmp(argv[1], "vsync"))
+|      arg.onoff = 1;
+|    else if (!strcmp(argv[1], "hsync"))
 |      arg.onoff = 2;
+|    else if (!strcmp(argv[1], "powerdown"))
+|      arg.onoff = 3;
 |    if (ioctl(fd, TIOCLINUX, &arg)) {
 |	perror("setvesablank: TIOCLINUX");
 |	exit(1);
@@ -53,8 +58,8 @@
  *  -------------------------------------------
  *  "On"		on	on	active  (mode 0)
  *  "Suspend" {either}	on	off	blank   (mode 1)
- *            {  or  }	off	on	blank   
- *  "Off"               off	off	blank	(mode 2)
+ *            {  or  }	off	on	blank   (mode 2)
+ *  "Off"               off	off	blank	(mode 3)
  *
  * Original code taken from the Power Management Utility (PMU) of
  * Huang shi chao, delivered together with many new monitor models
@@ -63,6 +68,8 @@
  * Adapted to Linux by Christoph Rimek (chrimek@toppoint.de)  15-may-94.
  * A slightly adapted fragment of his README follows.
  *
+ * Two-stage blanking by todd j. derr (tjd@barefoot.org)      10-oct-95.
+
 Patch (based on Linux Kernel revision 1.0) for handling the Power Saving
 feature of the new monitor generation. The code works on all these monitors
 (mine is a Smile 1506) and should run on *all* video adapter cards (change
@@ -71,12 +78,21 @@
 
 You can choose from two options:
 
-(1) Setting vesa_blanking_mode to 1.
+(1) Setting vesa_blanking_mode to 1 or 2.
     The code will save the current setting of your video adapters'
     register settings and then program the controller to turn off
-    the vertical synchronisation pulse.
+    the vertical synchronization pulse (mode 1) or horizontal
+    synchronization pulse (mode 2).  Mode 1 should work with most
+    monitors, but the VESA spec allows mode 2, so it's included for
+    completeness.
+
+    If you use one of these modes, you can also set a second interval
+    by echoing the escape sequence ESC[10;interval] to the terminal.
+    The monitor will be turned off completely (mode 3) after being in
+    suspend mode for the specified interval.  The interval defaults to
+    60 minutes. An interval of 0 disables this feature.
 
-(2) Setting vesa_blanking_mode to 2.
+(2) Setting vesa_blanking_mode to 3.
     If your monitor locally has an Off_Mode timer then you should not
     force your video card to send the OFF-signal - your monitor will
     power down by itself.
@@ -92,9 +108,6 @@
 before the monitor powers down. Do not set a too short period, if you love
 your hardware :-)) .
 
-If requested, in the future it may be possible to install another timer
-to provide a configurable delay between the two stages Standby and Off
-similar to the "setterm -blank"-feature.
 */
 
 #define seq_port_reg	(0x3c4)		/* Sequencer register select port */
@@ -118,7 +131,15 @@
 	unsigned char	ClockingMode;		/* Seq-Controller:01h */
 } vga;
 
-static int vesa_blanking_mode = 0;
+#define VESA_NO_BLANKING	0
+#define VESA_VSYNC_SUSPEND	1
+#define VESA_HSYNC_SUSPEND	2
+#define VESA_POWERDOWN		(VESA_HSYNC_SUSPEND | VESA_VSYNC_SUSPEND)
+
+#define DEFAULT_VESA_BLANKING_MODE	VESA_NO_BLANKING
+
+static int vesa_blanking_mode = DEFAULT_VESA_BLANKING_MODE;
+static int suspend_vesa_blanking_mode = DEFAULT_VESA_BLANKING_MODE;
 static int vesa_blanked = 0;
 
 /* routine to blank a vesa screen */
@@ -130,13 +151,13 @@
 	  return;
 
 	/* save original values of VGA controller registers */
-	cli();
-	vga.SeqCtrlIndex = inb_p(seq_port_reg);
-	vga.CrtCtrlIndex = inb_p(video_port_reg);
-	vga.CrtMiscIO = inb_p(video_misc_rd);
-	sti();
+	if(!vesa_blanked) {
+	    cli();
+	    vga.SeqCtrlIndex = inb_p(seq_port_reg);
+	    vga.CrtCtrlIndex = inb_p(video_port_reg);
+	    vga.CrtMiscIO = inb_p(video_misc_rd);
+	    sti();
 
-	if(mode == 2) {
 	    outb_p(0x00,video_port_reg);		/* HorizontalTotal */
 	    vga.HorizontalTotal = inb_p(video_port_val);
 	    outb_p(0x01,video_port_reg);		/* HorizDisplayEnd */
@@ -145,17 +166,17 @@
 	    vga.StartHorizRetrace = inb_p(video_port_val);
 	    outb_p(0x05,video_port_reg);		/* EndHorizRetrace */
 	    vga.EndHorizRetrace = inb_p(video_port_val);
+	    outb_p(0x07,video_port_reg);		/* Overflow */
+	    vga.Overflow = inb_p(video_port_val);
+	    outb_p(0x10,video_port_reg);		/* StartVertRetrace */
+	    vga.StartVertRetrace = inb_p(video_port_val);
+	    outb_p(0x11,video_port_reg);		/* EndVertRetrace */
+	    vga.EndVertRetrace = inb_p(video_port_val);
+	    outb_p(0x17,video_port_reg);		/* ModeControl */
+	    vga.ModeControl = inb_p(video_port_val);
+	    outb_p(0x01,seq_port_reg);			/* ClockingMode */
+	    vga.ClockingMode = inb_p(seq_port_val);
 	}
-	outb_p(0x07,video_port_reg);			/* Overflow */
-	vga.Overflow = inb_p(video_port_val);
-	outb_p(0x10,video_port_reg);			/* StartVertRetrace */
-	vga.StartVertRetrace = inb_p(video_port_val);
-	outb_p(0x11,video_port_reg);			/* EndVertRetrace */
-	vga.EndVertRetrace = inb_p(video_port_val);
-	outb_p(0x17,video_port_reg);			/* ModeControl */
-	vga.ModeControl = inb_p(video_port_val);
-	outb_p(0x01,seq_port_reg);			/* ClockingMode */
-	vga.ClockingMode = inb_p(seq_port_val);
 
 	/* assure that video is enabled */
 	/* "0x20" is VIDEO_ENABLE_bit in register 01 of sequencer */
@@ -172,14 +193,17 @@
 	 * <Start of vertical Retrace> to maximum (incl. overflow)
 	 * Result: turn off vertical sync (VSync) pulse.
 	 */
-	outb_p(0x10,video_port_reg);		/* StartVertRetrace */
-	outb_p(0xff,video_port_val);		/* maximum value */
-	outb_p(0x11,video_port_reg);		/* EndVertRetrace */
-	outb_p(0x40,video_port_val);            /* minimum (bits 0..3)  */
-	outb_p(0x07,video_port_reg);		/* Overflow */
-	outb_p(vga.Overflow | 0x84,video_port_val);	/* bits 9,10 of  */
+	if (mode & VESA_VSYNC_SUSPEND) {
+	    outb_p(0x10,video_port_reg);	/* StartVertRetrace */
+	    outb_p(0xff,video_port_val); 	/* maximum value */
+	    outb_p(0x11,video_port_reg);	/* EndVertRetrace */
+	    outb_p(0x40,video_port_val);	/* minimum (bits 0..3)  */
+	    outb_p(0x07,video_port_reg);		/* Overflow */
+	    outb_p(vga.Overflow | 0x84,video_port_val);	/* bits 9,10 of  */
 							/* vert. retrace */
-	if (mode == 2) {
+	}
+
+	if (mode & VESA_HSYNC_SUSPEND) {
 	    /*
 	     * Set <End of horizontal retrace> to minimum (0) and
 	     *  <Start of horizontal Retrace> to maximum
@@ -209,16 +233,14 @@
 	cli();
 	outb_p(vga.CrtMiscIO,video_misc_wr);
 
-	if (vesa_blanked == 2) {
-	    outb_p(0x00,video_port_reg);	/* HorizontalTotal */
-	    outb_p(vga.HorizontalTotal,video_port_val);
-	    outb_p(0x01,video_port_reg);	/* HorizDisplayEnd */
-	    outb_p(vga.HorizDisplayEnd,video_port_val);
-	    outb_p(0x04,video_port_reg);	/* StartHorizRetrace */
-	    outb_p(vga.StartHorizRetrace,video_port_val);
-	    outb_p(0x05,video_port_reg);	/* EndHorizRetrace */
-	    outb_p(vga.EndHorizRetrace,video_port_val);
-	}
+	outb_p(0x00,video_port_reg);		/* HorizontalTotal */
+	outb_p(vga.HorizontalTotal,video_port_val);
+	outb_p(0x01,video_port_reg);		/* HorizDisplayEnd */
+	outb_p(vga.HorizDisplayEnd,video_port_val);
+	outb_p(0x04,video_port_reg);		/* StartHorizRetrace */
+	outb_p(vga.StartHorizRetrace,video_port_val);
+	outb_p(0x05,video_port_reg);		/* EndHorizRetrace */
+	outb_p(vga.EndHorizRetrace,video_port_val);
 	outb_p(0x07,video_port_reg);		/* Overflow */
 	outb_p(vga.Overflow,video_port_val);
 	outb_p(0x10,video_port_reg);		/* StartVertRetrace */
@@ -242,5 +264,17 @@
 {
 	unsigned char *argp = (unsigned char *)(arg + 1);
 	unsigned int mode = get_user(argp);
-	vesa_blanking_mode = ((mode < 3) ? mode : 0);
+	vesa_blanking_mode = suspend_vesa_blanking_mode =
+		((mode <= VESA_POWERDOWN) ? mode : DEFAULT_VESA_BLANKING_MODE);
+}
+
+void vesa_powerdown(void)
+{
+	if(vesa_blanking_mode == VESA_VSYNC_SUSPEND
+		|| vesa_blanking_mode == VESA_HSYNC_SUSPEND)
+	{
+		vesa_blanking_mode = VESA_POWERDOWN;
+		vesa_blank();
+		vesa_blanking_mode = suspend_vesa_blanking_mode;
+	}
 }
diff -u --recursive --new-file v1.3.44/linux/drivers/net/8390.c linux/drivers/net/8390.c
--- v1.3.44/linux/drivers/net/8390.c	Sat Nov 25 19:04:40 1995
+++ linux/drivers/net/8390.c	Sun Nov 26 19:37:32 1995
@@ -576,7 +576,7 @@
  *	Set or clear the multicast filter for this adaptor.
  */
  
-static void set_multicast_list(struct device *dev, int num_addrs, void *addrs)
+static void set_multicast_list(struct device *dev)
 {
 	short ioaddr = dev->base_addr;
     
diff -u --recursive --new-file v1.3.44/linux/drivers/net/arcnet.c linux/drivers/net/arcnet.c
--- v1.3.44/linux/drivers/net/arcnet.c	Mon Nov 13 12:36:44 1995
+++ linux/drivers/net/arcnet.c	Sun Nov 26 19:37:32 1995
@@ -575,7 +575,7 @@
 	int length,u_char saddr, u_char daddr);
 
 static struct enet_statistics *arcnet_get_stats(struct device *dev);
-static void set_multicast_list(struct device *dev, int num_addrs, void *addrs);
+static void set_multicast_list(struct device *dev);
 
 	/* functions for header/arp/etc building */
 #ifdef LINUX12
@@ -2690,7 +2690,7 @@
  *			best-effort filtering.
  */
 static void
-set_multicast_list(struct device *dev, int num_addrs, void *addrs)
+set_multicast_list(struct device *dev)
 {
 #if 0	  /* no promiscuous mode at all on most (all?) ARCnet models */
 	struct arcnet_local *lp=(struct arcnet_local *)(dev->priv);
diff -u --recursive --new-file v1.3.44/linux/drivers/net/lance.c linux/drivers/net/lance.c
--- v1.3.44/linux/drivers/net/lance.c	Sat Nov 25 19:04:46 1995
+++ linux/drivers/net/lance.c	Sun Nov 26 19:37:32 1995
@@ -1076,7 +1076,7 @@
 /* Set or clear the multicast filter for this adaptor.
  */
 
-static void set_multicast_list(struct device *dev, int num_addrs, void *addrs)
+static void set_multicast_list(struct device *dev)
 {
 	short ioaddr = dev->base_addr;
 
diff -u --recursive --new-file v1.3.44/linux/drivers/net/sk_g16.c linux/drivers/net/sk_g16.c
--- v1.3.44/linux/drivers/net/sk_g16.c	Sat Nov 25 19:04:46 1995
+++ linux/drivers/net/sk_g16.c	Sun Nov 26 19:37:32 1995
@@ -1730,7 +1730,7 @@
 /* Set or clear the multicast filter for SK_G16.
  */
 
-static void set_multicast_list(struct device *dev, int num_addrs, void *addrs)
+static void set_multicast_list(struct device *dev)
 {
 
     if (dev->flags&IFF_PROMISC)
diff -u --recursive --new-file v1.3.44/linux/drivers/net/tulip.c linux/drivers/net/tulip.c
--- v1.3.44/linux/drivers/net/tulip.c	Sat Nov 25 19:04:47 1995
+++ linux/drivers/net/tulip.c	Sun Nov 26 19:38:17 1995
@@ -673,7 +673,7 @@
  *	Set or clear the multicast filter for this adaptor.
  */
 
-static void set_multicast_list(struct device *dev, int num_addrs, void *addrs)
+static void set_multicast_list(struct device *dev)
 {
 	short ioaddr = dev->base_addr;
 	int csr6 = inl(ioaddr + CSR6) & ~0x00D5;
diff -u --recursive --new-file v1.3.44/linux/drivers/scsi/scsi.h linux/drivers/scsi/scsi.h
--- v1.3.44/linux/drivers/scsi/scsi.h	Mon Nov 13 12:36:45 1995
+++ linux/drivers/scsi/scsi.h	Mon Nov 27 09:47:00 1995
@@ -472,7 +472,7 @@
 	    req->nr_sectors -= bh->b_size >> 9;
 	    req->sector += bh->b_size >> 9;
 	    bh->b_reqnext = NULL;
-	    bh->b_uptodate = uptodate;
+	    mark_buffer_uptodate(bh, uptodate);
 	    unlock_buffer(bh);
 	    sectors -= bh->b_size >> 9;
 	    if ((bh = req->bh) != NULL) {
@@ -521,7 +521,7 @@
     if (MAJOR(CURRENT->rq_dev) != MAJOR_NR)           \
 	panic(DEVICE_NAME ": request list destroyed");\
     if (CURRENT->bh) {                                \
-	if (!CURRENT->bh->b_lock)                     \
+	if (!buffer_locked(CURRENT->bh))              \
 	    panic(DEVICE_NAME ": block not locked");  \
     }
 #endif
diff -u --recursive --new-file v1.3.44/linux/drivers/sound/Makefile linux/drivers/sound/Makefile
--- v1.3.44/linux/drivers/sound/Makefile	Wed Nov  8 07:11:35 1995
+++ linux/drivers/sound/Makefile	Sun Nov 26 11:47:44 1995
@@ -118,4 +118,4 @@
 	$(LD) -r -o sound.o $(FIXEDOBJS) sound.a
 
 modules: local.h sound.o
-	ln -fs `pwd`/sound.o /usr/src/linux/modules/sound.o
+	ln -fs `pwd`/sound.o $(TOPDIR)/modules/sound.o
diff -u --recursive --new-file v1.3.44/linux/fs/binfmt_elf.c linux/fs/binfmt_elf.c
--- v1.3.44/linux/fs/binfmt_elf.c	Tue Nov 21 13:22:11 1995
+++ linux/fs/binfmt_elf.c	Sun Nov 26 11:13:38 1995
@@ -75,7 +75,13 @@
 	nbyte = elf_bss & (PAGE_SIZE-1);
 	if (nbyte) {
 		nbyte = PAGE_SIZE - nbyte;
-		verify_area(VERIFY_WRITE, (void *) elf_bss, nbyte);
+		/* FIXME: someone should investigate, why a bad binary
+		   is allowed to bring a wrong elf_bss until here,
+		   and how to react. Suffice the plain return?
+		   rossius@hrz.tu-chemnitz.de */
+		if (verify_area(VERIFY_WRITE, (void *) elf_bss, nbyte)) {
+			return;
+		}
 		fpnt = (char *) elf_bss;
 		do {
 			put_user(0, fpnt++);
diff -u --recursive --new-file v1.3.44/linux/fs/block_dev.c linux/fs/block_dev.c
--- v1.3.44/linux/fs/block_dev.c	Mon Sep 18 14:54:05 1995
+++ linux/fs/block_dev.c	Sun Nov 26 19:23:10 1995
@@ -79,7 +79,7 @@
 		  generate_cluster(dev, cluster_list, blocksize);
 		bh = getblk(dev, block, blocksize);
 
-		if (chars != blocksize && !bh->b_uptodate) {
+		if (chars != blocksize && !buffer_uptodate(bh)) {
 		  if(!filp->f_reada ||
 		     !read_ahead[MAJOR(dev)]) {
 		    /* We do this to force the read of a single buffer */
@@ -123,7 +123,7 @@
 		memcpy_fromfs(p,buf,chars);
 		p += chars;
 		buf += chars;
-		bh->b_uptodate = 1;
+		mark_buffer_uptodate(bh, 1);
 		mark_buffer_dirty(bh, 0);
 		if (filp->f_flags & O_SYNC)
 			bufferlist[buffercount++] = bh;
@@ -133,7 +133,7 @@
 			ll_rw_block(WRITE, buffercount, bufferlist);
 			for(i=0; i<buffercount; i++){
 				wait_on_buffer(bufferlist[i]);
-				if (!bufferlist[i]->b_uptodate)
+				if (!buffer_uptodate(bufferlist[i]))
 					write_error=1;
 				brelse(bufferlist[i]);
 			}
@@ -146,7 +146,7 @@
 		ll_rw_block(WRITE, buffercount, bufferlist);
 		for(i=0; i<buffercount; i++){
 			wait_on_buffer(bufferlist[i]);
-			if (!bufferlist[i]->b_uptodate)
+			if (!buffer_uptodate(bufferlist[i]))
 				write_error=1;
 			brelse(bufferlist[i]);
 		}
@@ -247,7 +247,7 @@
 			}
 #endif
 			*bhb = getblk(dev, block++, blocksize);
-			if (*bhb && !(*bhb)->b_uptodate) {
+			if (*bhb && !buffer_uptodate(*bhb)) {
 				uptodate = 0;
 				bhreq[bhrequest++] = *bhb;
 			}
@@ -272,7 +272,7 @@
 		do { /* Finish off all I/O that has actually completed */
 			if (*bhe) {
 				wait_on_buffer(*bhe);
-				if (!(*bhe)->b_uptodate) {	/* read error? */
+				if (!buffer_uptodate(*bhe)) {	/* read error? */
 				        brelse(*bhe);
 					if (++bhe == &buflist[NBUF])
 					  bhe = buflist;
@@ -298,7 +298,7 @@
 			offset = 0;
 			if (++bhe == &buflist[NBUF])
 				bhe = buflist;
-		} while (left > 0 && bhe != bhb && (!*bhe || !(*bhe)->b_lock));
+		} while (left > 0 && bhe != bhb && (!*bhe || !buffer_locked(*bhe)));
 	} while (left > 0);
 
 /* Release the read-ahead blocks */
diff -u --recursive --new-file v1.3.44/linux/fs/buffer.c linux/fs/buffer.c
--- v1.3.44/linux/fs/buffer.c	Fri Nov 17 08:42:27 1995
+++ linux/fs/buffer.c	Mon Nov 27 09:49:50 1995
@@ -120,7 +120,7 @@
 	add_wait_queue(&bh->b_wait, &wait);
 repeat:
 	current->state = TASK_UNINTERRUPTIBLE;
-	if (bh->b_lock) {
+	if (buffer_locked(bh)) {
 		schedule();
 		goto repeat;
 	}
@@ -166,7 +166,7 @@
 			 if(!lru_list[nlist]) break;
 			 if (dev && bh->b_dev != dev)
 				  continue;
-			 if (bh->b_lock)
+			 if (buffer_locked(bh))
 			  {
 				  /* Buffer is locked; skip it unless wait is
 				     requested AND pass > 0. */
@@ -179,17 +179,17 @@
 			  }
 			 /* If an unlocked buffer is not uptodate, there has
 			     been an IO error. Skip it. */
-			 if (wait && bh->b_req && !bh->b_lock &&
-			     !bh->b_dirt && !bh->b_uptodate) {
+			 if (wait && buffer_req(bh) && !buffer_locked(bh) &&
+			     !buffer_dirty(bh) && !buffer_uptodate(bh)) {
 				  err = 1;
 				  continue;
 			  }
 			 /* Don't write clean buffers.  Don't write ANY buffers
 			    on the third pass. */
-			 if (!bh->b_dirt || pass>=2)
+			 if (!buffer_dirty(bh) || pass>=2)
 				  continue;
 			 /* don't bother about locked buffers */
-			 if (bh->b_lock)
+			 if (buffer_locked(bh))
 				 continue;
 			 bh->b_count++;
 			 bh->b_flushtime = 0;
@@ -273,8 +273,10 @@
 				continue;
 			if (bh->b_count)
 				continue;
-			bh->b_flushtime = bh->b_uptodate = 
-				bh->b_dirt = bh->b_req = 0;
+			bh->b_flushtime = 0;
+			clear_bit(BH_Uptodate, &bh->b_state);
+			clear_bit(BH_Dirty, &bh->b_state);
+			clear_bit(BH_Req, &bh->b_state);
 		}
 	}
 }
@@ -458,7 +460,6 @@
 	for (;;) {
 		if (!(bh=find_buffer(dev,block,size)))
 			return NULL;
-		bh->b_reuse=0;
 		bh->b_count++;
 		wait_on_buffer(bh);
 		if (bh->b_dev == dev && bh->b_blocknr == block
@@ -505,15 +506,17 @@
 			
 			wait_on_buffer(bh);
 			if (bh->b_dev == dev && bh->b_size != size) {
-				bh->b_uptodate = bh->b_dirt = bh->b_req =
-					 bh->b_flushtime = 0;
-			};
+				clear_bit(BH_Dirty, &bh->b_state);
+				clear_bit(BH_Uptodate, &bh->b_state);
+				clear_bit(BH_Req, &bh->b_state);
+				bh->b_flushtime = 0;
+			}
 			remove_from_hash_queue(bh);
 		}
 	}
 }
 
-#define BADNESS(bh) (((bh)->b_dirt<<1)+(bh)->b_lock)
+#define BADNESS(bh) (buffer_dirty(bh) || buffer_locked(bh))
 
 void refill_freelist(int size)
 {
@@ -578,10 +581,10 @@
 			 if (!bh) break;
 			 
 			 if (mem_map[MAP_NR((unsigned long) bh->b_data)].count != 1 ||
-			     bh->b_dirt) {
+			     buffer_dirty(bh)) {
 				 refile_buffer(bh);
 				 continue;
-			 };
+			 }
 			 
 			 if (bh->b_count || bh->b_size != size)
 				  continue;
@@ -590,7 +593,7 @@
 			    on the locked list. If we encounter a locked
 			    buffer here, this means that the rest of them
 			    are also locked */
-			 if(bh->b_lock && (i == BUF_LOCKED || i == BUF_LOCKED1)) {
+			 if (buffer_locked(bh) && (i == BUF_LOCKED || i == BUF_LOCKED1)) {
 				 buffers[i] = 0;
 				 break;
 			 }
@@ -650,7 +653,7 @@
 				if (!bh) break;
 				
 				if (mem_map[MAP_NR((unsigned long) bh->b_data)].count != 1 ||
-				    bh->b_dirt) {
+				    buffer_dirty(bh)) {
 					refile_buffer(bh);
 					continue;
 				};
@@ -662,7 +665,7 @@
 				   placed on the locked list.  If we encounter
 				   a locked buffer here, this means that the
 				   rest of them are also locked */
-				if(bh->b_lock && (i == BUF_LOCKED || i == BUF_LOCKED1)) {
+				if (buffer_locked(bh) && (i == BUF_LOCKED || i == BUF_LOCKED1)) {
 					buffers[i] = 0;
 					break;
 				}
@@ -721,10 +724,12 @@
 repeat:
 	bh = get_hash_table(dev, block, size);
 	if (bh) {
-		if (bh->b_uptodate && !bh->b_dirt)
-			 put_last_lru(bh);
-		if(!bh->b_dirt) bh->b_flushtime = 0;
-		bh->b_touched = 1;
+		if (!buffer_dirty(bh)) {
+			if (buffer_uptodate(bh))
+				 put_last_lru(bh);
+			bh->b_flushtime = 0;
+		}
+		set_bit(BH_Touched, &bh->b_state);
 		return bh;
 	}
 
@@ -737,16 +742,10 @@
 	remove_from_free_list(bh);
 
 /* OK, FINALLY we know that this buffer is the only one of its kind, */
-/* and that it's unused (b_count=0), unlocked (b_lock=0), and clean */
+/* and that it's unused (b_count=0), unlocked (buffer_locked=0), and clean */
 	bh->b_count=1;
-	bh->b_dirt=0;
-	bh->b_lock=0;
-	bh->b_uptodate=0;
 	bh->b_flushtime=0;
-	bh->b_req=0;
-	bh->b_reuse=0;
-	bh->b_touched = 1;
-	bh->b_has_aged = 0;
+	bh->b_state=(1<<BH_Touched);
 	bh->b_dev=dev;
 	bh->b_blocknr=block;
 	insert_into_queues(bh);
@@ -757,7 +756,7 @@
 {
         int newtime;
 
-	if (buf->b_dirt){
+	if (buffer_dirty(buf)) {
 		/* Move buffer to dirty list if jiffies is clear */
 		newtime = jiffies + (flag ? bdf_prm.b_un.age_super : 
 				     bdf_prm.b_un.age_buffer);
@@ -777,11 +776,11 @@
 		printk("Attempt to refile free buffer\n");
 		return;
 	}
-	if (buf->b_dirt)
+	if (buffer_dirty(buf))
 		dispose = BUF_DIRTY;
 	else if (mem_map[MAP_NR((unsigned long) buf->b_data)].count > 1)
 		dispose = BUF_SHARED;
-	else if (buf->b_lock)
+	else if (buffer_locked(buf))
 		dispose = BUF_LOCKED;
 	else if (buf->b_list == BUF_SHARED)
 		dispose = BUF_UNSHARED;
@@ -858,11 +857,11 @@
 			kdevname(dev));
 		return NULL;
 	}
-	if (bh->b_uptodate)
+	if (buffer_uptodate(bh))
 		return bh;
 	ll_rw_block(READ, 1, &bh);
 	wait_on_buffer(bh);
-	if (bh->b_uptodate)
+	if (buffer_uptodate(bh))
 		return bh;
 	brelse(bh);
 	return NULL;
@@ -893,7 +892,7 @@
 
 	index = BUFSIZE_INDEX(bh->b_size);
 
-	if (bh->b_uptodate)
+	if (buffer_uptodate(bh))
 		return bh;
 
 	blocks = ((filesize & (bufsize - 1)) - (pos & (bufsize - 1))) >> (9+index);
@@ -907,7 +906,7 @@
 	j = 1;
 	for(i=1; i<blocks; i++) {
 		bh = getblk(dev,block+i,bufsize);
-		if (bh->b_uptodate) {
+		if (buffer_uptodate(bh)) {
 			brelse(bh);
 			break;
 		}
@@ -923,7 +922,7 @@
 	/* Wait for this buffer, and then continue on */
 	bh = bhlist[0];
 	wait_on_buffer(bh);
-	if (bh->b_uptodate)
+	if (buffer_uptodate(bh))
 		return bh;
 	brelse(bh);
 	return NULL;
@@ -972,7 +971,7 @@
 	bh->b_next_free = NULL;
 	bh->b_data = NULL;
 	bh->b_size = 0;
-	bh->b_req = 0;
+	bh->b_state = 0;
 	return bh;
 }
 
@@ -1020,7 +1019,7 @@
 	struct buffer_head * bhr[MAX_BUF_PER_PAGE];
 
 	for (i = 0 ; i < nrbuf ; i++) {
-		if (bh[i] && !bh[i]->b_uptodate)
+		if (bh[i] && !buffer_uptodate(bh[i]))
 			bhr[bhnum++] = bh[i];
 	}
 	if (bhnum)
@@ -1116,11 +1115,10 @@
 	while (1) {
 		arr[block++] = bh;
 		bh->b_count = 1;
-		bh->b_dirt = 0;
-		bh->b_reuse = 0;
 		bh->b_flushtime = 0;
-		bh->b_uptodate = 0;
-		bh->b_req = 0;
+		clear_bit(BH_Dirty, &bh->b_state);
+		clear_bit(BH_Uptodate, &bh->b_state);
+		clear_bit(BH_Req, &bh->b_state);
 		bh->b_dev = dev;
 		bh->b_blocknr = *(p++);
 		bh->b_list = BUF_CLEAN;
@@ -1203,7 +1201,7 @@
 	where = address;
  	for (i=0, j=0; j<PAGE_SIZE ; i++, j += size, where += size) {
 		if (bh[i]) {
-			if (bh[i]->b_uptodate)
+			if (buffer_uptodate(bh[i]))
 				memcpy((void *) where, bh[i]->b_data, size);
 			brelse(bh[i]);
 		} else
@@ -1230,7 +1228,7 @@
  	for (i=0, j=0; j<PAGE_SIZE ; i++, j += size, address += size) {
 		if (bh[i]) {
 			memcpy(bh[i]->b_data, (void *) address, size);
-			bh[i]->b_uptodate = 1;
+			mark_buffer_uptodate(bh[i], 1);
 			mark_buffer_dirty(bh[i], 0);
 			brelse(bh[i]);
 		} else
@@ -1315,9 +1313,9 @@
 	do {
 		if (!tmp)
 			return 0;
-		if (tmp->b_count || tmp->b_dirt || tmp->b_lock || tmp->b_wait)
+		if (tmp->b_count || buffer_dirty(tmp) || buffer_locked(tmp) || tmp->b_wait)
 			return 0;
-		if (priority && tmp->b_touched)
+		if (priority && buffer_touched(tmp))
 			return 0;
 		tmp = tmp->b_this_page;
 	} while (tmp != bh);
@@ -1356,18 +1354,15 @@
 	 * ensures that a page full of multiple buffers only gets aged
 	 * once per pass through the lru lists. 
 	 */
-	if (bh->b_has_aged) {
-		bh->b_has_aged = 0;
+	if (clear_bit(BH_Has_aged, &bh->b_state))
 		return;
-	}
 	
 	do {
-		touched |= tmp->b_touched;
-		tmp->b_touched = 0;
+		touched |= clear_bit(BH_Touched, &tmp->b_state);
 		tmp = tmp->b_this_page;
-		tmp->b_has_aged = 1;
+		set_bit(BH_Has_aged, &tmp->b_state);
 	} while (tmp != bh);
-	bh->b_has_aged = 0;
+	clear_bit(BH_Has_aged, &bh->b_state);
 
 	if (touched) 
 		touch_page((unsigned long) bh->b_data);
@@ -1500,12 +1495,12 @@
 			if (bh->b_count || !bh->b_this_page)
 				 continue;
 			if(size && bh->b_size != size) continue;
-			if (bh->b_lock)
+			if (buffer_locked(bh))
 				 if (priority)
 					  continue;
 				 else
 					  wait_on_buffer(bh);
-			if (bh->b_dirt) {
+			if (buffer_dirty(bh)) {
 				bh->b_count++;
 				bh->b_flushtime = 0;
 				ll_rw_block(WRITEA, 1, &bh);
@@ -1546,9 +1541,9 @@
 	  if(!bh) continue;
 	  do {
 		found++;
-		if (bh->b_lock)
+		if (buffer_locked(bh))
 			locked++;
-		if (bh->b_dirt)
+		if (buffer_dirty(bh))
 			dirty++;
 		if(mem_map[MAP_NR(((unsigned long) bh->b_data))].count !=1) shared++;
 		if (bh->b_count)
@@ -1590,7 +1585,7 @@
 		if (!tmp)
 			 return 0;
 		
-		if (tmp->b_count || tmp->b_dirt || tmp->b_lock)
+		if (tmp->b_count || buffer_dirty(tmp) || buffer_locked(tmp))
 			 return 0;
 		tmp = tmp->b_this_page;
 	} while (tmp != bh);
@@ -1606,8 +1601,8 @@
 		tmp = tmp->b_this_page;
 		remove_from_queues(p);
 		p->b_dev = dev;
-		p->b_uptodate = 0;
-		p->b_req = 0;
+		mark_buffer_uptodate(p, 0);
+		clear_bit(BH_Req, &p->b_state);
 		p->b_blocknr = starting_block++;
 		insert_into_queues(p);
 	} while (tmp != bh);
@@ -1681,11 +1676,8 @@
 	while (1) {
 		arr[nblock++] = bh;
 		bh->b_count = 1;
-		bh->b_dirt = 0;
 		bh->b_flushtime = 0;
-		bh->b_lock = 0;
-		bh->b_uptodate = 0;
-		bh->b_req = 0;
+		bh->b_state = 0;
 		bh->b_dev = dev;
 		bh->b_list = BUF_CLEAN;
 		bh->b_blocknr = block++;
@@ -1850,13 +1842,13 @@
 				 }
 				 
 				 /* Clean buffer on dirty list?  Refile it */
-				 if (nlist == BUF_DIRTY && !bh->b_dirt && !bh->b_lock)
+				 if (nlist == BUF_DIRTY && !buffer_dirty(bh) && !buffer_locked(bh))
 				  {
 					  refile_buffer(bh);
 					  continue;
 				  }
 				 
-				 if (bh->b_lock || !bh->b_dirt)
+				 if (buffer_locked(bh) || !buffer_dirty(bh))
 					  continue;
 				 ndirty++;
 				 if(bh->b_flushtime > jiffies) continue;
@@ -1957,13 +1949,13 @@
 					  }
 					  
 					  /* Clean buffer on dirty list?  Refile it */
-					  if (nlist == BUF_DIRTY && !bh->b_dirt && !bh->b_lock)
+					  if (nlist == BUF_DIRTY && !buffer_dirty(bh) && !buffer_locked(bh))
 					   {
 						   refile_buffer(bh);
 						   continue;
 					   }
 					  
-					  if (bh->b_lock || !bh->b_dirt)
+					  if (buffer_locked(bh) || !buffer_dirty(bh))
 						   continue;
 					  /* Should we write back buffers that are shared or not??
 					     currently dirty buffers are not shared, so it does not matter */
diff -u --recursive --new-file v1.3.44/linux/fs/ext/file.c linux/fs/ext/file.c
--- v1.3.44/linux/fs/ext/file.c	Wed Aug  2 13:21:15 1995
+++ linux/fs/ext/file.c	Sun Nov 26 19:23:10 1995
@@ -126,7 +126,7 @@
 		while (blocks) {
 			--blocks;
 			*bhb = ext_getblk(inode, block++, 0);
-			if (*bhb && !(*bhb)->b_uptodate) {
+			if (*bhb && !buffer_uptodate(*bhb)) {
 				uptodate = 0;
 				bhreq[bhrequest++] = *bhb;
 			}
@@ -149,7 +149,7 @@
 		do { /* Finish off all I/O that has actually completed */
 			if (*bhe) {
 				wait_on_buffer(*bhe);
-				if (!(*bhe)->b_uptodate) {	/* read error? */
+				if (!buffer_uptodate(*bhe)) {	/* read error? */
 				        brelse(*bhe);
 					if (++bhe == &buflist[NBUF])
 					  bhe = buflist;
@@ -175,7 +175,7 @@
 			offset = 0;
 			if (++bhe == &buflist[NBUF])
 				bhe = buflist;
-		} while (left > 0 && bhe != bhb && (!*bhe || !(*bhe)->b_lock));
+		} while (left > 0 && bhe != bhb && (!*bhe || !buffer_locked(*bhe)));
 	} while (left > 0);
 
 /* Release the read-ahead blocks */
@@ -228,10 +228,10 @@
 		c = BLOCK_SIZE - (pos % BLOCK_SIZE);
 		if (c > count-written)
 			c = count-written;
-		if (c != BLOCK_SIZE && !bh->b_uptodate) {
+		if (c != BLOCK_SIZE && !buffer_uptodate(bh)) {
 			ll_rw_block(READ, 1, &bh);
 			wait_on_buffer(bh);
-			if (!bh->b_uptodate) {
+			if (!buffer_uptodate(bh)) {
 				brelse(bh);
 				if (!written)
 					written = -EIO;
@@ -247,7 +247,7 @@
 		written += c;
 		memcpy_fromfs(p,buf,c);
 		buf += c;
-		bh->b_uptodate = 1;
+		mark_buffer_uptodate(bh, 1);
 		mark_buffer_dirty(bh, 0);
 		brelse(bh);
 	}
diff -u --recursive --new-file v1.3.44/linux/fs/ext/freelists.c linux/fs/ext/freelists.c
--- v1.3.44/linux/fs/ext/freelists.c	Mon Sep 18 14:54:05 1995
+++ linux/fs/ext/freelists.c	Sun Nov 26 19:23:10 1995
@@ -54,7 +54,7 @@
 	}
 	bh = get_hash_table(sb->s_dev, block, sb->s_blocksize);
 	if (bh)
-		bh->b_dirt=0;
+		mark_buffer_clean(bh);
 	brelse(bh);
 	if (sb->u.ext_sb.s_firstfreeblock)
 		efb = (struct ext_free_block *) sb->u.ext_sb.s_firstfreeblock->b_data;
@@ -127,7 +127,7 @@
 		return 0;
 	}
 	memset(bh->b_data, 0, BLOCK_SIZE);
-	bh->b_uptodate = 1;
+	mark_buffer_uptodate(bh, 1);
 	mark_buffer_dirty(bh, 1);
 	brelse(bh);
 #ifdef EXTFS_DEBUG
diff -u --recursive --new-file v1.3.44/linux/fs/ext/fsync.c linux/fs/ext/fsync.c
--- v1.3.44/linux/fs/ext/fsync.c	Mon Dec 27 07:35:59 1993
+++ linux/fs/ext/fsync.c	Sun Nov 26 19:23:10 1995
@@ -42,11 +42,11 @@
 		brelse (bh);
 		return 1;
 	}
-	if (wait && bh->b_req && !bh->b_uptodate) {
+	if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
 		brelse(bh);
 		return -1;
 	}
-	if (wait || !bh->b_uptodate || !bh->b_dirt)
+	if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh))
 	{
 		brelse(bh);
 		return 0;
diff -u --recursive --new-file v1.3.44/linux/fs/ext/inode.c linux/fs/ext/inode.c
--- v1.3.44/linux/fs/ext/inode.c	Fri Nov 17 08:42:27 1995
+++ linux/fs/ext/inode.c	Sun Nov 26 19:23:10 1995
@@ -268,10 +268,10 @@
 
 	if (!bh)
 		return NULL;
-	if (!bh->b_uptodate) {
+	if (!buffer_uptodate(bh)) {
 		ll_rw_block(READ, 1, &bh);
 		wait_on_buffer(bh);
-		if (!bh->b_uptodate) {
+		if (!buffer_uptodate(bh)) {
 			brelse(bh);
 			return NULL;
 		}
@@ -346,11 +346,11 @@
 	struct buffer_head * bh;
 
 	bh = ext_getblk(inode,block,create);
-	if (!bh || bh->b_uptodate) 
+	if (!bh || buffer_uptodate(bh)) 
 		return bh;
 	ll_rw_block(READ, 1, &bh);
 	wait_on_buffer(bh);
-	if (bh->b_uptodate)
+	if (buffer_uptodate(bh))
 		return bh;
 	brelse(bh);
 	return NULL;
@@ -433,11 +433,11 @@
 	struct buffer_head *bh;
 
 	bh = ext_update_inode(inode);
-	if (bh && bh->b_dirt)
+	if (bh && buffer_dirty(bh))
 	{
 		ll_rw_block(WRITE, 1, &bh);
 		wait_on_buffer(bh);
-		if (bh->b_req && !bh->b_uptodate)
+		if (buffer_req(bh) && !buffer_uptodate(bh))
 		{
 			printk ("IO error syncing ext inode ["
 				"%s:%08lx]\n",
diff -u --recursive --new-file v1.3.44/linux/fs/ext2/balloc.c linux/fs/ext2/balloc.c
--- v1.3.44/linux/fs/ext2/balloc.c	Fri Jun 16 22:02:55 1995
+++ linux/fs/ext2/balloc.c	Sun Nov 26 19:23:10 1995
@@ -453,7 +453,7 @@
 		return 0;
 	}
 	memset(bh->b_data, 0, sb->s_blocksize);
-	bh->b_uptodate = 1;
+	mark_buffer_uptodate(bh, 1);
 	mark_buffer_dirty(bh, 1);
 	brelse (bh);
 
diff -u --recursive --new-file v1.3.44/linux/fs/ext2/dir.c linux/fs/ext2/dir.c
--- v1.3.44/linux/fs/ext2/dir.c	Tue Aug 15 20:39:04 1995
+++ linux/fs/ext2/dir.c	Sun Nov 26 19:23:10 1995
@@ -132,7 +132,7 @@
 			for (i = 16 >> (EXT2_BLOCK_SIZE_BITS(sb) - 9), num = 0;
 			     i > 0; i--) {
 				tmp = ext2_getblk (inode, ++blk, 0, &err);
-				if (tmp && !tmp->b_uptodate && !tmp->b_lock)
+				if (tmp && !buffer_uptodate(tmp) && !buffer_locked(tmp))
 					bha[num++] = tmp;
 				else
 					brelse (tmp);
diff -u --recursive --new-file v1.3.44/linux/fs/ext2/file.c linux/fs/ext2/file.c
--- v1.3.44/linux/fs/ext2/file.c	Wed Aug  2 13:21:15 1995
+++ linux/fs/ext2/file.c	Mon Nov 27 09:15:16 1995
@@ -150,7 +150,7 @@
 #endif
 
 			*bhb = ext2_getblk (inode, block++, 0, &err);
-			if (*bhb && !(*bhb)->b_uptodate) {
+			if (*bhb && !buffer_uptodate(*bhb)) {
 				uptodate = 0;
 				bhreq[bhrequest++] = *bhb;
 			}
@@ -181,7 +181,7 @@
 			 */
 			if (*bhe) {
 				wait_on_buffer (*bhe);
-				if (!(*bhe)->b_uptodate) { /* read error? */
+				if (!buffer_uptodate(*bhe)) { /* read error? */
 				        brelse(*bhe);
 					if (++bhe == &buflist[NBUF])
 					  bhe = buflist;
@@ -207,7 +207,7 @@
 			chars = sb->s_blocksize;
 			if (++bhe == &buflist[NBUF])
 				bhe = buflist;
-		} while (left > 0 && bhe != bhb && (!*bhe || !(*bhe)->b_lock));
+		} while (left > 0 && bhe != bhb && (!*bhe || !buffer_locked(*bhe)));
 	} while (left > 0);
 
 	/*
@@ -259,7 +259,6 @@
 			      inode->i_mode);
 		return -EINVAL;
 	}
-	down(&inode->i_sem);
 	if (filp->f_flags & O_APPEND)
 		pos = inode->i_size;
 	else
@@ -292,10 +291,10 @@
 		count -= c;
 		if (count < 0)
 			c += count;
-		if (c != sb->s_blocksize && !bh->b_uptodate) {
+		if (c != sb->s_blocksize && !buffer_uptodate(bh)) {
 			ll_rw_block (READ, 1, &bh);
 			wait_on_buffer (bh);
-			if (!bh->b_uptodate) {
+			if (!buffer_uptodate(bh)) {
 				brelse (bh);
 				if (!written)
 					written = -EIO;
@@ -307,7 +306,7 @@
 		written += c;
 		memcpy_fromfs (bh->b_data + offset, buf, c);
 		buf += c;
-		bh->b_uptodate = 1;
+		mark_buffer_uptodate(bh, 1);
 		mark_buffer_dirty(bh, 0);
 		if (filp->f_flags & O_SYNC)
 			bufferlist[buffercount++] = bh;
@@ -317,7 +316,7 @@
 			ll_rw_block(WRITE, buffercount, bufferlist);
 			for(i=0; i<buffercount; i++){
 				wait_on_buffer(bufferlist[i]);
-				if (!bufferlist[i]->b_uptodate)
+				if (!buffer_uptodate(bufferlist[i]))
 					write_error=1;
 				brelse(bufferlist[i]);
 			}
@@ -333,7 +332,7 @@
 		ll_rw_block(WRITE, buffercount, bufferlist);
 		for(i=0; i<buffercount; i++){
 			wait_on_buffer(bufferlist[i]);
-			if (!bufferlist[i]->b_uptodate)
+			if (!buffer_uptodate(bufferlist[i]))
 				write_error=1;
 			brelse(bufferlist[i]);
 		}
@@ -342,7 +341,6 @@
 		inode->i_size = pos;
 	if (filp->f_flags & O_SYNC)
 		inode->u.ext2_i.i_osync--;
-	up(&inode->i_sem);
 	inode->i_ctime = inode->i_mtime = CURRENT_TIME;
 	filp->f_pos = pos;
 	inode->i_dirt = 1;
diff -u --recursive --new-file v1.3.44/linux/fs/ext2/fsync.c linux/fs/ext2/fsync.c
--- v1.3.44/linux/fs/ext2/fsync.c	Sun Feb 26 18:52:02 1995
+++ linux/fs/ext2/fsync.c	Sun Nov 26 19:23:10 1995
@@ -42,11 +42,11 @@
 		brelse (bh);
 		return 1;
 	}
-	if (wait && bh->b_req && !bh->b_uptodate) {
+	if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
 		brelse (bh);
 		return -1;
 	}
-	if (wait || !bh->b_uptodate || !bh->b_dirt) {
+	if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) {
 		brelse (bh);
 		return 0;
 	}
diff -u --recursive --new-file v1.3.44/linux/fs/ext2/inode.c linux/fs/ext2/inode.c
--- v1.3.44/linux/fs/ext2/inode.c	Mon Sep 18 14:54:05 1995
+++ linux/fs/ext2/inode.c	Sun Nov 26 19:23:10 1995
@@ -102,7 +102,7 @@
 			return 0;
 		}
 		memset(bh->b_data, 0, inode->i_sb->s_blocksize);
-		bh->b_uptodate = 1;
+		mark_buffer_uptodate(bh, 1);
 		mark_buffer_dirty(bh, 1);
 		brelse (bh);
 	} else {
@@ -258,10 +258,10 @@
 
 	if (!bh)
 		return NULL;
-	if (!bh->b_uptodate) {
+	if (!buffer_uptodate(bh)) {
 		ll_rw_block (READ, 1, &bh);
 		wait_on_buffer (bh);
-		if (!bh->b_uptodate) {
+		if (!buffer_uptodate(bh)) {
 			brelse (bh);
 			return NULL;
 		}
@@ -477,11 +477,11 @@
 	struct buffer_head * bh;
 
 	bh = ext2_getblk (inode, block, create, err);
-	if (!bh || bh->b_uptodate)
+	if (!bh || buffer_uptodate(bh))
 		return bh;
 	ll_rw_block (READ, 1, &bh);
 	wait_on_buffer (bh);
-	if (bh->b_uptodate)
+	if (buffer_uptodate(bh))
 		return bh;
 	brelse (bh);
 	*err = -EIO;
@@ -655,11 +655,11 @@
 	struct buffer_head *bh;
 
 	bh = ext2_update_inode (inode);
-	if (bh && bh->b_dirt)
+	if (bh && buffer_dirty(bh))
 	{
 		ll_rw_block (WRITE, 1, &bh);
 		wait_on_buffer (bh);
-		if (bh->b_req && !bh->b_uptodate)
+		if (buffer_req(bh) && !buffer_uptodate(bh))
 		{
 			printk ("IO error syncing ext2 inode ["
 				"%s:%08lx]\n",
diff -u --recursive --new-file v1.3.44/linux/fs/ext2/namei.c linux/fs/ext2/namei.c
--- v1.3.44/linux/fs/ext2/namei.c	Mon Sep 18 14:54:05 1995
+++ linux/fs/ext2/namei.c	Sun Nov 26 19:23:10 1995
@@ -97,7 +97,7 @@
 			break;
 		bh = ext2_getblk (dir, block, 0, &err);
 		bh_use[block] = bh;
-		if (bh && !bh->b_uptodate)
+		if (bh && !buffer_uptodate(bh))
 			bh_read[toread++] = bh;
 	}
 
@@ -119,7 +119,7 @@
 			continue;
 		}
 		wait_on_buffer (bh);
-		if (!bh->b_uptodate) {
+		if (!buffer_uptodate(bh)) {
 			/*
 			 * read error: all bets are off
 			 */
@@ -152,7 +152,7 @@
 		else
 			bh = ext2_getblk (dir, block + NAMEI_RA_SIZE, 0, &err);
 		bh_use[block % NAMEI_RA_SIZE] = bh;
-		if (bh && !bh->b_uptodate)
+		if (bh && !buffer_uptodate(bh))
 			bh_read[toread++] = bh;
 	}
 
diff -u --recursive --new-file v1.3.44/linux/fs/ext2/truncate.c linux/fs/ext2/truncate.c
--- v1.3.44/linux/fs/ext2/truncate.c	Mon Oct 23 18:02:17 1995
+++ linux/fs/ext2/truncate.c	Mon Nov 27 09:16:59 1995
@@ -181,14 +181,13 @@
 		if (ind_bh->b_count != 1)
 			retry = 1;
 		else {
-			ind_bh->b_reuse = 1;
 			tmp = *p;
 			*p = 0;
 			inode->i_blocks -= blocks;
 			inode->i_dirt = 1;
 			ext2_free_blocks (inode->i_sb, tmp, 1);
 		}
-	if (IS_SYNC(inode) && ind_bh->b_dirt) {
+	if (IS_SYNC(inode) && buffer_dirty(ind_bh)) {
 		ll_rw_block (WRITE, 1, &ind_bh);
 		wait_on_buffer (ind_bh);
 	}
@@ -242,14 +241,13 @@
 		if (dind_bh->b_count != 1)
 			retry = 1;
 		else {
-			dind_bh->b_reuse = 1;
 			tmp = *p;
 			*p = 0;
 			inode->i_blocks -= blocks;
 			inode->i_dirt = 1;
 			ext2_free_blocks (inode->i_sb, tmp, 1);
 		}
-	if (IS_SYNC(inode) && dind_bh->b_dirt) {
+	if (IS_SYNC(inode) && buffer_dirty(dind_bh)) {
 		ll_rw_block (WRITE, 1, &dind_bh);
 		wait_on_buffer (dind_bh);
 	}
@@ -302,14 +300,13 @@
 		if (tind_bh->b_count != 1)
 			retry = 1;
 		else {
-			tind_bh->b_reuse = 1;
 			tmp = *p;
 			*p = 0;
 			inode->i_blocks -= blocks;
 			inode->i_dirt = 1;
 			ext2_free_blocks (inode->i_sb, tmp, 1);
 		}
-	if (IS_SYNC(inode) && tind_bh->b_dirt) {
+	if (IS_SYNC(inode) && buffer_dirty(tind_bh)) {
 		ll_rw_block (WRITE, 1, &tind_bh);
 		wait_on_buffer (tind_bh);
 	}
@@ -331,7 +328,6 @@
 		return;
 	ext2_discard_prealloc(inode);
 	while (1) {
-		down(&inode->i_sem);
 		retry = trunc_direct(inode);
 		retry |= trunc_indirect (inode, EXT2_IND_BLOCK,
 			(u32 *) &inode->u.ext2_i.i_data[EXT2_IND_BLOCK]);
@@ -339,7 +335,6 @@
 			EXT2_ADDR_PER_BLOCK(inode->i_sb),
 			(u32 *) &inode->u.ext2_i.i_data[EXT2_DIND_BLOCK]);
 		retry |= trunc_tindirect (inode);
-		up(&inode->i_sem);
 		if (!retry)
 			break;
 		if (IS_SYNC(inode) && inode->i_dirt)
diff -u --recursive --new-file v1.3.44/linux/fs/filesystems.c linux/fs/filesystems.c
--- v1.3.44/linux/fs/filesystems.c	Tue Nov 21 13:22:12 1995
+++ linux/fs/filesystems.c	Mon Nov 27 09:24:50 1995
@@ -26,8 +26,9 @@
 extern void device_setup(void);
 
 #ifdef CONFIG_ROOT_NFS
-extern int nfs_root_init(char *nfsname);
+extern int nfs_root_init(char *nfsname, char *nfsaddrs);
 extern char nfs_root_name [];
+extern char nfs_root_addrs [];
 #endif
 
 /* This may be used only once, enforced by 'static int callable' */
@@ -108,13 +109,14 @@
 #endif
 
 #ifdef CONFIG_ROOT_NFS
-	if (nfs_root_name [0]){
-		if (nfs_root_init(nfs_root_name) < 0) {
-			printk(KERN_ERR "Root-NFS: Unable to mount NFS filesystem as /, using /dev/fd0 instead\n");
+	if (ROOT_DEV == MKDEV(UNNAMED_MAJOR, 255)) {
+		if (nfs_root_init(nfs_root_name, nfs_root_addrs) < 0) {
+			printk(KERN_ERR "Root-NFS: Unable to contact NFS server for root fs, using /dev/fd0 instead\n");
 			ROOT_DEV = MKDEV(FLOPPY_MAJOR, 0);
 		}
 	}
 #endif
+
 	mount_root();
 	return 0;
 }
diff -u --recursive --new-file v1.3.44/linux/fs/isofs/file.c linux/fs/isofs/file.c
--- v1.3.44/linux/fs/isofs/file.c	Thu Nov  9 11:23:51 1995
+++ linux/fs/isofs/file.c	Sun Nov 26 19:23:10 1995
@@ -184,7 +184,7 @@
 			--blocks;
 			*bhb = getblk(inode->i_dev,isofs_bmap(inode, block++), ISOFS_BUFFER_SIZE(inode));
 			uptodate = 1;
-			if (*bhb && !(*bhb)->b_uptodate) {
+			if (*bhb && !buffer_uptodate(*bhb)) {
 			        uptodate = 0;
 			        bhreq[bhrequest++] = *bhb;
 			      };
@@ -207,7 +207,7 @@
 		do{ /* Finish off all I/O that has actually completed */
 		  if (*bhe) {/* test for valid buffer */
 		    wait_on_buffer(*bhe);
-		    if (!(*bhe)->b_uptodate) {
+		    if (!buffer_uptodate(*bhe)) {
 		      brelse(*bhe);
 		      if (++bhe == &buflist[NBUF])
 			bhe = buflist;
@@ -239,7 +239,7 @@
 		  offset = 0;
 		  if (++bhe == &buflist[NBUF])
 		    bhe = buflist;
-		} while( bhe != bhb && (*bhe == 0 || !(*bhe)->b_lock) && 
+		} while( bhe != bhb && (*bhe == 0 || !buffer_locked(*bhe)) && 
 			(left > 0));
 	} while (left > 0);
 
diff -u --recursive --new-file v1.3.44/linux/fs/minix/bitmap.c linux/fs/minix/bitmap.c
--- v1.3.44/linux/fs/minix/bitmap.c	Thu Nov  9 11:23:51 1995
+++ linux/fs/minix/bitmap.c	Sun Nov 26 23:45:33 1995
@@ -59,7 +59,7 @@
 	}
 	bh = get_hash_table(sb->s_dev,block,BLOCK_SIZE);
 	if (bh)
-		bh->b_dirt=0;
+		clear_bit(BH_Dirty, &bh->b_state);
 	brelse(bh);
 	zone = block - sb->u.minix_sb.s_firstdatazone + 1;
 	bit = zone & 8191;
@@ -107,7 +107,7 @@
 		return 0;
 	}
 	memset(bh->b_data, 0, BLOCK_SIZE);
-	bh->b_uptodate = 1;
+	mark_buffer_uptodate(bh, 1);
 	mark_buffer_dirty(bh, 1);
 	brelse(bh);
 	return j;
diff -u --recursive --new-file v1.3.44/linux/fs/minix/file.c linux/fs/minix/file.c
--- v1.3.44/linux/fs/minix/file.c	Thu Nov  9 11:23:51 1995
+++ linux/fs/minix/file.c	Mon Nov 27 09:20:18 1995
@@ -120,7 +120,7 @@
 		while (blocks) {
 			--blocks;
 			*bhb = minix_getblk(inode, block++, 0);
-			if (*bhb && !(*bhb)->b_uptodate) {
+			if (*bhb && !buffer_uptodate(*bhb)) {
 				uptodate = 0;
 				bhreq[bhrequest++] = *bhb;
 			}
@@ -143,7 +143,7 @@
 		do { /* Finish off all I/O that has actually completed */
 			if (*bhe) {
 				wait_on_buffer(*bhe);
-				if (!(*bhe)->b_uptodate) {	/* read error? */
+				if (!buffer_uptodate(*bhe)) {	/* read error? */
 				        brelse(*bhe);
 					if (++bhe == &buflist[NBUF])
 					  bhe = buflist;
@@ -169,7 +169,7 @@
 			offset = 0;
 			if (++bhe == &buflist[NBUF])
 				bhe = buflist;
-		} while (left > 0 && bhe != bhb && (!*bhe || !(*bhe)->b_lock));
+		} while (left > 0 && bhe != bhb && (!*bhe || !buffer_locked(*bhe)));
 	} while (left > 0);
 
 /* Release the read-ahead blocks */
@@ -201,7 +201,6 @@
 		printk("minix_file_write: mode = %07o\n",inode->i_mode);
 		return -EINVAL;
 	}
-	down(&inode->i_sem);
 	if (filp->f_flags & O_APPEND)
 		pos = inode->i_size;
 	else
@@ -217,10 +216,10 @@
 		c = BLOCK_SIZE - (pos % BLOCK_SIZE);
 		if (c > count-written)
 			c = count-written;
-		if (c != BLOCK_SIZE && !bh->b_uptodate) {
+		if (c != BLOCK_SIZE && !buffer_uptodate(bh)) {
 			ll_rw_block(READ, 1, &bh);
 			wait_on_buffer(bh);
-			if (!bh->b_uptodate) {
+			if (!buffer_uptodate(bh)) {
 				brelse(bh);
 				if (!written)
 					written = -EIO;
@@ -232,13 +231,12 @@
 		written += c;
 		memcpy_fromfs(p,buf,c);
 		buf += c;
-		bh->b_uptodate = 1;
+		mark_buffer_uptodate(bh, 1);
 		mark_buffer_dirty(bh, 0);
 		brelse(bh);
 	}
 	if (pos > inode->i_size)
 		inode->i_size = pos;
-	up(&inode->i_sem);
 	inode->i_mtime = inode->i_ctime = CURRENT_TIME;
 	filp->f_pos = pos;
 	inode->i_dirt = 1;
diff -u --recursive --new-file v1.3.44/linux/fs/minix/fsync.c linux/fs/minix/fsync.c
--- v1.3.44/linux/fs/minix/fsync.c	Thu Nov  9 11:23:51 1995
+++ linux/fs/minix/fsync.c	Sun Nov 26 19:23:10 1995
@@ -38,11 +38,11 @@
 		brelse (bh);
 		return 1;
 	}
-	if (wait && bh->b_req && !bh->b_uptodate) {
+	if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
 		brelse(bh);
 		return -1;
 	}
-	if (wait || !bh->b_uptodate || !bh->b_dirt)
+	if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh))
 	{
 		brelse(bh);
 		return 0;
diff -u --recursive --new-file v1.3.44/linux/fs/minix/inode.c linux/fs/minix/inode.c
--- v1.3.44/linux/fs/minix/inode.c	Thu Nov  9 11:23:51 1995
+++ linux/fs/minix/inode.c	Sun Nov 26 19:23:10 1995
@@ -321,10 +321,10 @@
 
 	if (!bh)
 		return NULL;
-	if (!bh->b_uptodate) {
+	if (!buffer_uptodate(bh)) {
 		ll_rw_block(READ, 1, &bh);
 		wait_on_buffer(bh);
-		if (!bh->b_uptodate) {
+		if (!buffer_uptodate(bh)) {
 			brelse(bh);
 			return NULL;
 		}
@@ -392,11 +392,11 @@
 	struct buffer_head * bh;
 
 	bh = minix_getblk(inode,block,create);
-	if (!bh || bh->b_uptodate)
+	if (!bh || buffer_uptodate(bh))
 		return bh;
 	ll_rw_block(READ, 1, &bh);
 	wait_on_buffer(bh);
-	if (bh->b_uptodate)
+	if (buffer_uptodate(bh))
 		return bh;
 	brelse(bh);
 	return NULL;
@@ -504,11 +504,11 @@
 	struct buffer_head *bh;
 
 	bh = minix_update_inode(inode);
-	if (bh && bh->b_dirt)
+	if (bh && buffer_dirty(bh))
 	{
 		ll_rw_block(WRITE, 1, &bh);
 		wait_on_buffer(bh);
-		if (bh->b_req && !bh->b_uptodate)
+		if (buffer_req(bh) && !buffer_uptodate(bh))
 		{
 			printk ("IO error syncing minix inode ["
 				"%s:%08lx]\n",
diff -u --recursive --new-file v1.3.44/linux/fs/msdos/buffer.c linux/fs/msdos/buffer.c
--- v1.3.44/linux/fs/msdos/buffer.c	Thu Nov  9 11:23:51 1995
+++ linux/fs/msdos/buffer.c	Sun Nov 26 19:23:10 1995
@@ -118,7 +118,7 @@
 	if (sb->s_blocksize != 512){
 		bh = bh->b_next;
 	}
-	bh->b_uptodate = val;
+	mark_buffer_uptodate(bh, val);
 }
 int msdos_is_uptodate (
 	struct super_block *sb,
@@ -127,7 +127,7 @@
 	if (sb->s_blocksize != 512){
 		bh = bh->b_next;
 	}
-	return bh->b_uptodate;
+	return buffer_uptodate(bh);
 }
 
 void msdos_ll_rw_block (
diff -u --recursive --new-file v1.3.44/linux/fs/msdos/namei.c linux/fs/msdos/namei.c
--- v1.3.44/linux/fs/msdos/namei.c	Sat Nov 11 17:41:34 1995
+++ linux/fs/msdos/namei.c	Sun Nov 26 11:13:00 1995
@@ -177,6 +177,12 @@
 		return -EACCES;
 	}
 	PRINTK (("msdos_lookup 5\n"));
+	if (!(*result)->i_sb ||
+	    ((*result)->i_sb->s_magic != MSDOS_SUPER_MAGIC)) {
+		/* crossed a mount point into a non-msdos fs */
+		iput(dir);
+		return 0;
+	}
 	if (MSDOS_I(*result)->i_busy) { /* mkdir in progress */
 		iput(*result);
 		iput(dir);
diff -u --recursive --new-file v1.3.44/linux/fs/namei.c linux/fs/namei.c
--- v1.3.44/linux/fs/namei.c	Mon Sep 18 14:54:07 1995
+++ linux/fs/namei.c	Mon Nov 27 09:18:29 1995
@@ -427,9 +427,11 @@
 			iput(inode);
 			return error;
 		}
+		down(&inode->i_sem);
 		inode->i_size = 0;
 		if (inode->i_op && inode->i_op->truncate)
 			inode->i_op->truncate(inode);
+		up(&inode->i_sem);
 		inode->i_dirt = 1;
 		put_write_access(inode);
 	}
diff -u --recursive --new-file v1.3.44/linux/fs/nfs/nfsroot.c linux/fs/nfs/nfsroot.c
--- v1.3.44/linux/fs/nfs/nfsroot.c	Sat Nov 25 19:04:47 1995
+++ linux/fs/nfs/nfsroot.c	Mon Nov 27 09:24:50 1995
@@ -6,20 +6,21 @@
  *  Allow an NFS filesystem to be mounted as root. The way this works
  *  is to first determine the local IP address via RARP. Then handle
  *  the RPC negotiation with the system which replied to the RARP. The
- *  actual mounting is done later, when init() is running.
+ *  actual mounting is done later, when init() is running. In addition
+ *  it's possible to avoid using RARP if the necessary addresses are
+ *  provided on the kernel command line. This is necessary to use boot-
+ *  roms which use bootp instead of RARP.
  *
- * 	Changes:
+ *	Changes:
  *
  *	Alan Cox	:	Removed get_address name clash with FPU.
  *	Alan Cox	:	Reformatted a bit.
  *
- *	TODO:
- *		Support bootp and dhcp as well as rarp.
  */
 
 
 /* Define this to allow debugging output */
-#define NFSROOT_DEBUG 1
+#undef NFSROOT_DEBUG 1
 
 /* Define the timeout for waiting for a RARP reply */
 #define RARP_TIMEOUT	30	/* 30 seconds */
@@ -46,12 +47,12 @@
 #include <linux/skbuff.h>
 #include <linux/socket.h>
 #include <linux/route.h>
-#include <net/route.h>
 #include <linux/nfs.h>
 #include <linux/nfs_fs.h>
 #include <linux/nfs_mount.h>
+#include <netinet/in.h>
+#include <net/route.h>
 
-#define IPPORT_RESERVED 1024
 
 /* Range of privileged ports */
 #define STARTPORT 600
@@ -60,8 +61,7 @@
 
 
 
-struct open_dev
-{
+struct open_dev {
 	struct device *dev;
 	unsigned short old_flags;
 	struct open_dev *next;
@@ -71,6 +71,8 @@
 static struct device *root_dev = NULL;
 static struct sockaddr_in myaddr;	/* My IP address */
 static struct sockaddr_in server;	/* Server IP address */
+static struct sockaddr_in gateway;	/* Gateway IP address */
+static struct sockaddr_in netmask;	/* Netmask for local subnet */
 static struct nfs_mount_data nfs_data;	/* NFS mount info */
 static char nfs_path[NFS_MAXPATHLEN];	/* Name of directory to mount */
 static int nfs_port;			/* Port to connect to for NFS service */
@@ -79,63 +81,28 @@
 
 /***************************************************************************
 
-			RARP Subroutines
+			Device Handling Subroutines
 
  ***************************************************************************/
 
-extern void arp_send(int type, int ptype, unsigned long target_ip, 
-			struct device *dev, unsigned long src_ip, 
-			unsigned char *dest_hw, unsigned char *src_hw,
-			unsigned char *target_hw);
-
-static int root_rarp_recv(struct sk_buff *skb, struct device *dev,
-			struct packet_type *pt);
-
-
-static struct packet_type rarp_packet_type =
-{
-	0,  	/* Should be: __constant_htons(ETH_P_RARP) - but this _doesn't_ come out constant! */
-	NULL,	/* Listen to all devices */
-	root_rarp_recv,
-	NULL,
-	NULL
-};
-
-
 /*
- *  For receiving rarp packets a packet type has to be registered. Also
- *  initialize all devices for usage by RARP.
+ * Setup and initialize all network devices
  */
-
-static int root_rarp_open(void)
+static int root_dev_open(void)
 {
 	struct open_dev *openp;
 	struct device *dev;
 	unsigned short old_flags;
-	int num;
+	int num = 0;
 
-	/*
-	 *	Register the packet type 
-	 */
-	 
-	rarp_packet_type.type=htons(ETH_P_RARP);
-	dev_add_pack(&rarp_packet_type);
-
-	/*
-	 *	Open all devices which allow RARP 
-	 */
-	 
-	for (dev = dev_base, num = 0; dev != NULL; dev = dev->next) 
-	{
+	for (dev = dev_base; dev != NULL; dev = dev->next) {
 		if (dev->type < ARPHRD_SLIP &&
-			dev->family == AF_INET &&
-			!(dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT | IFF_NOARP))) 
-		{
+		    dev->family == AF_INET &&
+		    !(dev->flags & (IFF_LOOPBACK | IFF_POINTOPOINT))) {
 			/* First up the interface */
 			old_flags = dev->flags;
 			dev->flags = IFF_UP | IFF_BROADCAST | IFF_RUNNING;
-			if (!(old_flags & IFF_UP) && dev_open(dev)) 
-			{
+			if (!(old_flags & IFF_UP) && dev_open(dev)) {
 				dev->flags = old_flags;
 				continue;
 			}
@@ -150,40 +117,32 @@
 			num++;
 		}
 	}
-	return num;
+
+	if (num == 0) {
+		printk(KERN_ERR "NFS: Unable to open at least one network device\n");
+		return -1;
+	}
+#ifdef NFSROOT_DEBUG
+	printk(KERN_NOTICE "NFS: Opened %d network interfaces\n", num);
+#endif
+	return 0;
 }
 
 
 /*
- *  Remove the packet type again when all rarp packets have been received
- *  and restore the state of the device. However, keep the root device
- *  open for the upcoming mount.
+ *  Restore the state of all devices. However, keep the root device open
+ *  for the upcoming mount.
  */
-
-static void root_rarp_close(void)
+static void root_dev_close(void)
 {
 	struct open_dev *openp;
 	struct open_dev *nextp;
 
-	/*
-	 *	Deregister the packet type 
-	 */
-	 
-	rarp_packet_type.type=htons(ETH_P_RARP);
-	dev_remove_pack(&rarp_packet_type);
-
-	/*
-	 *	Deactivate all previously opened devices except that one which is
-	 *	able to connect to a suitable server
-	 */
-
 	openp = open_base;
-	while (openp != NULL) 
-	{
+	while (openp != NULL) {
 		nextp = openp->next;
 		openp->next = NULL;
-		if (openp->dev != root_dev) 
-		{
+		if (openp->dev != root_dev) {
 			if (!(openp->old_flags & IFF_UP))
 				dev_close(openp->dev);
 			openp->dev->flags = openp->old_flags;
@@ -194,55 +153,86 @@
 }
 
 
+
+
+/***************************************************************************
+
+			RARP Subroutines
+
+ ***************************************************************************/
+
+extern void arp_send(int type, int ptype, unsigned long target_ip,
+		     struct device *dev, unsigned long src_ip,
+		     unsigned char *dest_hw, unsigned char *src_hw,
+		     unsigned char *target_hw);
+
+static int root_rarp_recv(struct sk_buff *skb, struct device *dev,
+			  struct packet_type *pt);
+
+
+static struct packet_type rarp_packet_type = {
+	0,			/* Should be: __constant_htons(ETH_P_RARP)
+				 * - but this _doesn't_ come out constant! */
+	NULL,			/* Listen to all devices */
+	root_rarp_recv,
+	NULL,
+	NULL
+};
+
+
+/*
+ *  Register the packet type for RARP
+ */
+static void root_rarp_open(void)
+{
+	rarp_packet_type.type = htons(ETH_P_RARP);
+	dev_add_pack(&rarp_packet_type);
+}
+
+
 /*
- *	Receive RARP packets.
+ *  Deregister the RARP packet type
+ */
+static void root_rarp_close(void)
+{
+	rarp_packet_type.type = htons(ETH_P_RARP);
+	dev_remove_pack(&rarp_packet_type);
+}
+
+
+/*
+ *  Receive RARP packets.
  */
- 
 static int root_rarp_recv(struct sk_buff *skb, struct device *dev, struct packet_type *pt)
 {
 	struct arphdr *rarp = (struct arphdr *)skb->h.raw;
-	unsigned char *rarp_ptr = (unsigned char *)(rarp+1);
+	unsigned char *rarp_ptr = (unsigned char *) (rarp + 1);
 	unsigned long sip, tip;
 	unsigned char *sha, *tha;		/* s for "source", t for "target" */
-  
-	/*
-	 *	If this test doesn't pass, its not IP, or we should ignore it anyway 
-	 */
-	 
-	if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)) 
-	{
+
+	/* If this test doesn't pass, its not IP, or we should ignore it anyway */
+	if (rarp->ar_hln != dev->addr_len || dev->type != ntohs(rarp->ar_hrd)) {
 		kfree_skb(skb, FREE_READ);
 		return 0;
 	}
 
-	/*
-	 *	If it's not a RARP reply, delete it. 
-	 */
-	 
-	if (rarp->ar_op != htons(ARPOP_RREPLY)) 
-	{
+	/* If it's not a RARP reply, delete it. */
+	if (rarp->ar_op != htons(ARPOP_RREPLY)) {
 		kfree_skb(skb, FREE_READ);
 		return 0;
 	}
 
-	/*
-	 *	If it's not ethernet or AX25, delete it. 
-	 */
-	 
-	if ((rarp->ar_pro != htons(ETH_P_IP) && dev->type != ARPHRD_AX25) || 
+	/* If it's not ethernet or AX25, delete it. */
+	if ((rarp->ar_pro != htons(ETH_P_IP) && dev->type != ARPHRD_AX25) ||
 #ifdef CONFIG_AX25
-		(rarp->ar_pro != htons(AX25_P_IP) && dev->type == ARPHRD_AX25) ||
+	   (rarp->ar_pro != htons(AX25_P_IP) && dev->type == ARPHRD_AX25) ||
 #endif
-		rarp->ar_pln != 4) 
-	{
+	    rarp->ar_pln != 4) {
 		kfree_skb(skb, FREE_READ);
 		return 0;
 	}
-  
-	/*
-	 *	Extract variable width fields 
-	 */
-	 
+
+	/* Extract variable width fields */
 	sha = rarp_ptr;
 	rarp_ptr += dev->addr_len;
 	memcpy(&sip, rarp_ptr, 4);
@@ -251,23 +241,24 @@
 	rarp_ptr += dev->addr_len;
 	memcpy(&tip, rarp_ptr, 4);
 
-	/*
-	 *	Discard packets which are not meant for us. 
-	 */
-	 
-	if (memcmp(tha, dev->dev_addr, dev->addr_len)) 
-	{
+	/* Discard packets which are not meant for us. */
+	if (memcmp(tha, dev->dev_addr, dev->addr_len)) {
+		kfree_skb(skb, FREE_READ);
+		return 0;
+	}
+	/* Discard packets which are not from specified server. */
+	if (server.sin_addr.s_addr != INADDR_NONE &&
+	    server.sin_addr.s_addr != sip) {
 		kfree_skb(skb, FREE_READ);
 		return 0;
 	}
 
 	/*
-	 *	The packet is what we were looking for. Setup the global variables. 
+	 * The packet is what we were looking for. Setup the global
+	 * variables.
 	 */
-
 	cli();
-	if (root_dev != NULL) 
-	{
+	if (root_dev != NULL) {
 		sti();
 		kfree_skb(skb, FREE_READ);
 		return 0;
@@ -275,83 +266,82 @@
 	root_dev = dev;
 	sti();
 
-	myaddr.sin_family = dev->family;
-	myaddr.sin_addr.s_addr = tip;
-	server.sin_family = dev->family;
-	if (!server.sin_addr.s_addr)
+	if (myaddr.sin_addr.s_addr == INADDR_NONE) {
+		myaddr.sin_family = dev->family;
+		myaddr.sin_addr.s_addr = tip;
+	}
+	if (server.sin_addr.s_addr == INADDR_NONE) {
+		server.sin_family = dev->family;
 		server.sin_addr.s_addr = sip;
-
+	}
 	kfree_skb(skb, FREE_READ);
 	return 0;
 }
 
 
 /*
- *	Send RARP request packet over all devices which allow RARP.
+ *  Send RARP request packet over all devices which allow RARP.
  */
-
-static void root_rarp_send(void)
+static int root_rarp_send(void)
 {
 	struct open_dev *openp;
 	struct device *dev;
+	int num = 0;
 
 #ifdef NFSROOT_DEBUG
 	printk(KERN_NOTICE "NFS: Sending RARP request...\n");
 #endif
 
-	for (openp = open_base; openp != NULL; openp = openp->next) 
-	{
+	for (openp = open_base; openp != NULL; openp = openp->next) {
 		dev = openp->dev;
-		arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
-			dev->dev_addr, dev->dev_addr);
+		if (!(dev->flags & IFF_NOARP)) {
+			arp_send(ARPOP_RREQUEST, ETH_P_RARP, 0, dev, 0, NULL,
+				 dev->dev_addr, dev->dev_addr);
+			num++;
+		}
 	}
+
+	if (num == 0) {
+		printk(KERN_ERR "NFS: Couldn't find device to send RARP request to\n");
+		return -1;
+	}
+	return 0;
 }
 
 
 /*
- *	Determine client and server IP numbers and appropriate device by using
- *	the RARP protocol.
+ *  Determine client and server IP numbers and appropriate device by using
+ *  the RARP protocol.
  */
-
 static int do_rarp(void)
 {
 	int retries = 0;
-	unsigned long timeout;
+	unsigned long timeout = 0;
 
-	/* 
-	 *	Open all devices and setup RARP protocol 
-	 */
-	 
-	if (!root_rarp_open()) 
-	{
-		printk(KERN_ERR "NFS: No network device found to send RARP request to\n");
-		return -1;
-	}
+	/* Setup RARP protocol */
+	root_rarp_open();
 
 	/*
-	 *	Send RARP request and wait, until we get an answer. This loop seems
-	 *	to be a terrible waste of cpu time, but actually there is no process
-	 *	running at all, so we don't need to use any scheduler functions.
-	 *	[Actually we could now, but the nothing else running note still 
-	 *	 applies.. - AC]
-	 */
-
-	for (retries = 0; retries < RARP_RETRIES && root_dev == NULL; retries++) 
-	{
-		root_rarp_send();
+	 * Send RARP request and wait, until we get an answer. This loop
+	 * seems to be a terrible waste of cpu time, but actually there is
+	 * no process running at all, so we don't need to use any
+	 * scheduler functions.
+	 * [Actually we could now, but the nothing else running note still 
+	 *  applies.. - AC]
+	 */
+	for (retries = 0; retries < RARP_RETRIES && root_dev == NULL; retries++) {
+		if (root_rarp_send() < 0)
+			break;
 		timeout = jiffies + (RARP_TIMEOUT * HZ);
 		while (jiffies < timeout && root_dev == NULL)
 			;;
 	}
 
-	if (root_dev == NULL) 
-	{
+	root_rarp_close();
+	if (root_dev == NULL && timeout > 0) {
 		printk(KERN_ERR "NFS: Timed out while waiting for RARP answer\n");
 		return -1;
 	}
-
-	root_rarp_close();
-
 	printk(KERN_NOTICE "NFS: ");
 	printk("Got RARP answer from %s, ", in_ntoa(server.sin_addr.s_addr));
 	printk("my address is %s\n", in_ntoa(myaddr.sin_addr.s_addr));
@@ -368,17 +358,12 @@
 
  ***************************************************************************/
 
-extern void ip_rt_add(short flags, unsigned long addr, unsigned long mask,
-			unsigned long gw, struct device *dev,
-			unsigned short mss, unsigned long window);
 
 
 /*
- *	The following integer options are recognized
+ *  The following integer options are recognized
  */
- 
-static struct nfs_int_opts
-{
+static struct nfs_int_opts {
 	char *name;
 	int  *val;
 } root_int_opts[] = {
@@ -391,15 +376,14 @@
 	{ "acregmax",	&nfs_data.acregmax },
 	{ "acdirmin",	&nfs_data.acdirmin },
 	{ "acdirmax",	&nfs_data.acdirmax },
-	{ NULL,		NULL }};
+	{ NULL,		NULL }
+};
 
 
 /*
- *	And now the flag options 
+ *  And now the flag options
  */
- 
-static struct nfs_bool_opts
-{
+static struct nfs_bool_opts {
 	char *name;
 	int  and_mask;
 	int  or_mask;
@@ -418,78 +402,42 @@
 };
 
 
-static unsigned long nfs_get_address (char **str)
-{
-	unsigned long l;
-	unsigned int val;
-	int i;
-   
-	l = 0;
-	for (i = 0; i < 4; i++) 
-	{
-		l <<= 8;
-		if (**str != '\0')
-		{
-	     		val = 0;
-	     		while (**str != '\0' && **str != '.' && **str != ':')
-	       		{
-		  		val *= 10;
-		  		val += **str - '0';
-				(*str)++;
-			}
-			l |= val;
-			if (**str != '\0') 
-				(*str)++;
-		}
-	}
-   	return(htonl(l));
-}
-
 /*
- *	Prepare the NFS data structure and parse any options
+ *  Prepare the NFS data structure and parse any options
  */
- 
 static int root_nfs_parse(char *name)
 {
 	char buf[NFS_MAXPATHLEN];
 	char *cp, *options, *val;
 
-	/*
-	 *	Get the host ip number 
-	 */
-	 
-	if (*name >= '0' && *name <= '9')
-	{
-		server.sin_addr.s_addr = nfs_get_address (&name);
+	/* Set the default system name in case none was previously found */
+	if (!system_utsname.nodename[0]) {
+		strncpy(system_utsname.nodename, in_ntoa(myaddr.sin_addr.s_addr), __NEW_UTS_LEN);
+		system_utsname.nodename[__NEW_UTS_LEN] = '\0';
+	}
+	/* It is possible to override the host IP number here */
+	if (*name >= '0' && *name <= '9' && (cp = strchr(name, ':')) != NULL) {
+		*cp++ = '\0';
+		server.sin_addr.s_addr = in_aton(name);
+		name = cp;
 	}
 
-	/*
-	 *	Setup the server hostname 
-	 */
-	 
+	/* Setup the server hostname */
 	cp = in_ntoa(server.sin_addr.s_addr);
 	strncpy(nfs_data.hostname, cp, 255);
-	nfs_data.addr = server;
 
-	/*
-	 *	Set the name of the directory to mount 
-	 */
-	 
+	/* Set the name of the directory to mount */
 	cp = in_ntoa(myaddr.sin_addr.s_addr);
 	strncpy(buf, name, 255);
 	if ((options = strchr(buf, ',')))
 		*options++ = '\0';
-	if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) 
-	{
+	if (strlen(buf) + strlen(cp) > NFS_MAXPATHLEN) {
 		printk(KERN_ERR "NFS: Pathname for remote directory too long\n");
 		return -1;
 	}
 	sprintf(nfs_path, buf, cp);
 
-	/*
-	 *	Set some default values 
-	 */
-	 
+	/* Set some default values */
 	nfs_port          = -1;
 	nfs_data.version  = NFS_MOUNT_VERSION;
 	nfs_data.flags    = 0;
@@ -502,31 +450,22 @@
 	nfs_data.acdirmin = 30;
 	nfs_data.acdirmax = 60;
 
-	/*
-	 *	Process any options
-	 */
-
-	if (options) 
-	{
+	/* Process any options */
+	if (options) {
 		cp = strtok(options, ",");
-		while (cp) 
-		{
-			if ((val = strchr(cp, '='))) 
-			{
+		while (cp) {
+			if ((val = strchr(cp, '='))) {
 				struct nfs_int_opts *opts = root_int_opts;
 				*val++ = '\0';
 				while (opts->name && strcmp(opts->name, cp))
 					opts++;
 				if (opts->name)
 					*(opts->val) = (int) simple_strtoul(val, NULL, 10);
-			}
-			else
-			{
+			} else {
 				struct nfs_bool_opts *opts = root_bool_opts;
 				while (opts->name && strcmp(opts->name, cp))
 					opts++;
-				if (opts->name) 
-				{
+				if (opts->name) {
 					nfs_data.flags &= opts->and_mask;
 					nfs_data.flags |= opts->or_mask;
 				}
@@ -539,9 +478,8 @@
 
 
 /*
- *	Tell the user what's going on.
+ *  Tell the user what's going on.
  */
-
 static void root_nfs_print(void)
 {
 #ifdef NFSROOT_DEBUG
@@ -559,59 +497,164 @@
 
 
 /*
- * Set the interface address and configure a route to the server.
+ *  Parse any IP addresses
+ */
+static void root_nfs_addrs(char *addrs)
+{
+	char *cp, *ip, *dp;
+	int num = 0;
+
+	/* Clear all addresses and strings */
+	myaddr.sin_family = server.sin_family =
+	    gateway.sin_family = netmask.sin_family = AF_INET;
+	myaddr.sin_addr.s_addr = server.sin_addr.s_addr =
+	    gateway.sin_addr.s_addr = netmask.sin_addr.s_addr = INADDR_NONE;
+	system_utsname.nodename[0] = '\0';
+	system_utsname.domainname[0] = '\0';
+
+	/*
+	 * Parse the address field. It contains 4 IP addresses which are
+	 * separated by colons: Field 0 = my own address Field 1 = server
+	 * address Field 2 = gateway address Field 3 = netmask address
+	 * Field 4 = client host name
+	 */
+	ip = addrs;
+	while (ip && *ip) {
+		if ((cp = strchr(ip, ':')))
+			*cp++ = '\0';
+		if (strlen(ip) > 0) {
+#ifdef NFSROOT_DEBUG
+			printk(KERN_NOTICE "NFS: IP address num %d is \"%s\"\n", num, ip);
+#endif
+			switch (num) {
+			case 0:
+				myaddr.sin_addr.s_addr = in_aton(ip);
+				break;
+			case 1:
+				server.sin_addr.s_addr = in_aton(ip);
+				break;
+			case 2:
+				gateway.sin_addr.s_addr = in_aton(ip);
+				break;
+			case 3:
+				netmask.sin_addr.s_addr = in_aton(ip);
+				break;
+			case 4:
+				if ((dp = strchr(ip, '.'))) {
+					*dp++ = '\0';
+					strncpy(system_utsname.domainname, dp, __NEW_UTS_LEN);
+					system_utsname.domainname[__NEW_UTS_LEN] = '\0';
+				}
+				strncpy(system_utsname.nodename, ip, __NEW_UTS_LEN);
+				system_utsname.nodename[__NEW_UTS_LEN] = '\0';
+				break;
+			default:
+				break;
+			}
+		}
+		ip = cp;
+		num++;
+	}
+}
+
+
+/*
+ *  Set the interface address and configure a route to the server.
  */
 static void root_nfs_setup(void)
 {
-	struct rtentry server_route;
-	struct sockaddr_in *sin;
+	struct rtentry route;
 
-	/* 
-	 *	Setup the device correctly
-	 */
-	 
+	/* Set the correct netmask */
+	if (netmask.sin_addr.s_addr == INADDR_NONE)
+		netmask.sin_addr.s_addr = ip_get_mask(myaddr.sin_addr.s_addr);
+
+	/* Setup the device correctly */
 	root_dev->family     = myaddr.sin_family;
 	root_dev->pa_addr    = myaddr.sin_addr.s_addr;
-	root_dev->pa_mask    = ip_get_mask(myaddr.sin_addr.s_addr);
+	root_dev->pa_mask    = netmask.sin_addr.s_addr;
 	root_dev->pa_brdaddr = root_dev->pa_addr | ~root_dev->pa_mask;
 	root_dev->pa_dstaddr = 0;
 
-	sin=(struct sockaddr_in *)&server_route.rt_dst;
-	*sin=server;
-	sin=(struct sockaddr_in *)&server_route.rt_genmask;
-	sin->sin_family=AF_INET;
-	sin->sin_addr.s_addr= root_dev->pa_mask;
-	server_route.rt_dev=NULL;
-	server_route.rt_flags=RTF_HOST|RTF_UP;
-  
 	/*
-	 *	Now add a route to the server
-	 */
- 
-	if(ip_rt_new(&server_route)==-1)
-	  	printk("Unable to add NFS server route.\n");
+	 * Now add a route to the server. If there is no gateway given,
+	 * the server is on our own local network, so a host route is
+	 * sufficient. Otherwise we first have to create a host route to
+	 * the gateway, and then setup a gatewayed host route to the
+	 * server. Note that it's not possible to setup a network route
+	 * because we don't know the network mask of the server network.
+	 */
+	memset(&route, 0, sizeof(route));
+	route.rt_dev = root_dev->name;
+	route.rt_mss = root_dev->mtu;
+	route.rt_flags = RTF_HOST | RTF_UP;
+	*((struct sockaddr_in *) &(route.rt_genmask)) = netmask;
+
+	if (gateway.sin_addr.s_addr == INADDR_NONE ||
+	    gateway.sin_addr.s_addr == server.sin_addr.s_addr ||
+	    !((server.sin_addr.s_addr ^ root_dev->pa_addr) & root_dev->pa_mask)) {
+		*((struct sockaddr_in *) &(route.rt_dst)) = server;
+		ip_rt_new(&route);
+	} else {
+		*((struct sockaddr_in *) &(route.rt_dst)) = gateway;
+		ip_rt_new(&route);
+		route.rt_flags |= RTF_GATEWAY;
+		*((struct sockaddr_in *) &(route.rt_gateway)) = gateway;
+		*((struct sockaddr_in *) &(route.rt_dst)) = server;
+		ip_rt_new(&route);
+	}
 }
 
 
 /*
- *	Get the necessary IP addresses and prepare for mounting the required
- *	NFS filesystem.
- */
-
-int nfs_root_init(char *nfsname)
-{
+ *  Get the necessary IP addresses and prepare for mounting the required
+ *  NFS filesystem.
+ */
+int nfs_root_init(char *nfsname, char *nfsaddrs)
+{
+	/* Setup all network devices */
+	if (root_dev_open() < 0)
+		return -1;
+
+	/*
+	 * Get local and server IP address. First check for addresses in
+	 * command line parameter. If one of the IP addresses is missing,
+	 * or there's more than one network interface in the system, use
+	 * RARP to get the missing values and routing information. If all
+	 * addresses are given, the best way to find a proper routing is
+	 * to use icmp echo requests ("ping"), but that would add a lot of
+	 * code to this module, which is only really necessary in the rare
+	 * case of multiple ethernet devices in the (diskless) system and
+	 * if the server is on another subnet (otherwise RARP can serve as
+	 * a ping substitute). If only one device is installed the routing
+	 * is obvious.
+	 */
+	root_nfs_addrs(nfsaddrs);
+	if ((myaddr.sin_addr.s_addr == INADDR_NONE ||
+	     server.sin_addr.s_addr == INADDR_NONE ||
+	     (open_base != NULL && open_base->next != NULL)) && do_rarp() < 0) {
+		root_dev_close();
+		return -1;
+	}
+	if (root_dev == NULL) {
+		if (open_base != NULL && open_base->next == NULL) {
+			root_dev = open_base->dev;
+		} else {
+			printk(KERN_ERR "NFS: Unable to find routing to server\n");
+			root_dev_close();
+			return -1;
+		}
+	}
 	/*
-	 *	Initialize network device and get local and server IP address 
+	 * Close all network devices except the device which connects to
+	 * server
 	 */
-
-	if (do_rarp() < 0)
-		return -1;
+	root_dev_close();
 
 	/*
-	 *	Initialize the global variables necessary for NFS. The server
-	 *	directory is actually mounted after init() has been started.
+	 * Initialize the global variables necessary for NFS. The server
+	 * directory is actually mounted after init() has been started.
 	 */
-
 	if (root_nfs_parse(nfsname) < 0)
 		return -1;
 	root_nfs_print();
@@ -619,6 +662,9 @@
 	return 0;
 }
 
+
+
+
 /***************************************************************************
 
 		Routines to actually mount the root directory
@@ -630,35 +676,27 @@
 static int *rpc_packet = NULL;		/* RPC packet */
 
 extern asmlinkage int sys_socketcall(int call, unsigned long *args);
-extern struct socket *socki_lookup(struct inode *inode);
 
 
 /*
- *	Open a UDP socket.
+ *  Open a UDP socket.
  */
-
 static int root_nfs_open(void)
 {
 	struct file *filp;
 	unsigned long opt[] = { AF_INET, SOCK_DGRAM, IPPROTO_UDP };
 
-	/*
-	 *	Open the socket 
-	 */
-
-	if ((nfs_data.fd = sys_socketcall(SYS_SOCKET, opt)) < 0) 
-	{
+	/* Open the socket */
+	if ((nfs_data.fd = sys_socketcall(SYS_SOCKET, opt)) < 0) {
 		printk(KERN_ERR "NFS: Cannot open UDP socket\n");
 		return -1;
 	}
-
-	/*	
-	 *	Copy the file and inode data area so that we can remove the
-	 *	file lateron without killing the socket. After all this the
-	 *	closing routine just needs to remove the file pointer from
-	 *	the init-task descriptor.
+	/*
+	 * Copy the file and inode data area so that we can remove the
+	 * file lateron without killing the socket. After all this the
+	 * closing routine just needs to remove the file pointer from the
+	 * init-task descriptor.
 	 */
-
 	filp = current->files->fd[nfs_data.fd];
 	memcpy(&nfs_file, filp, sizeof(struct file));
 	nfs_file.f_next = nfs_file.f_prev = NULL;
@@ -678,35 +716,28 @@
 
 
 /*
- *	Close the UDP file descriptor. The main part of preserving the socket
- *	has already been done after opening it. Now we have to remove the
- *	file descriptor from the init task.
+ *  Close the UDP file descriptor. The main part of preserving the socket
+ *  has already been done after opening it. Now we have to remove the file
+ *  descriptor from the init task.
  */
-
 static void root_nfs_close(int close_all)
 {
-	/*
-	 *	Remove the file from the list of open files 
-	 */
-
+	/* Remove the file from the list of open files */
 	current->files->fd[nfs_data.fd] = NULL;
 	if (current->files->count > 0)
 		current->files->count--;
 
-	/*
-	 *	Clear memory use by the RPC packet 
-	 */
-	 
+	/* Clear memory used by the RPC packet */
 	if (rpc_packet != NULL)
 		kfree_s(rpc_packet, nfs_data.wsize + 1024);
 
 	/*
-	 *	In case of an error we also have to close the socket again (sigh)
+	 * In case of an error we also have to close the socket again
+	 * (sigh)
 	 */
-	 
-	if (close_all) 
-	{
-		nfs_inode.u.socket_i.inode = NULL;	/* The inode is already cleared */
+	if (close_all) {
+		nfs_inode.u.socket_i.inode = NULL;	/* The inode is already
+							 * cleared */
 		if (nfs_file.f_op->release)
 			nfs_file.f_op->release(&nfs_inode, &nfs_file);
 	}
@@ -714,9 +745,8 @@
 
 
 /*
- *	Find a suitable listening port and bind to it
+ *  Find a suitable listening port and bind to it
  */
-
 static int root_nfs_bind(void)
 {
 	int res = -1;
@@ -724,21 +754,17 @@
 	struct sockaddr_in *sin = &myaddr;
 	int i;
 
-	if (nfs_inode.u.socket_i.ops->bind) 
-	{
-		for (i = 0; i < NPORTS && res < 0; i++) 
-		{
+	if (nfs_inode.u.socket_i.ops->bind) {
+		for (i = 0; i < NPORTS && res < 0; i++) {
 			sin->sin_port = htons(port++);
-			if (port > ENDPORT) 
-			{
+			if (port > ENDPORT) {
 				port = STARTPORT;
 			}
 			res = nfs_inode.u.socket_i.ops->bind(&nfs_inode.u.socket_i,
-				(struct sockaddr *) sin, sizeof(struct sockaddr_in));
+							     (struct sockaddr *)sin, sizeof(struct sockaddr_in));
 		}
 	}
-	if (res < 0) 
-	{
+	if (res < 0) {
 		printk(KERN_ERR "NFS: Cannot find a suitable listening port\n");
 		root_nfs_close(1);
 		return -1;
@@ -751,42 +777,38 @@
 
 
 /*
- *	Send an RPC request and wait for the answer
+ *  Send an RPC request and wait for the answer
  */
-
 static int *root_nfs_call(int *end)
 {
 	struct file *filp;
 	struct socket *sock;
 	int dummylen;
 	static struct nfs_server s = {
-		&nfs_file, /* struct file * */
-		0,         /* struct rsock * */
+		&nfs_file,		/* struct file *	 */
+		0,			/* struct rsock *	 */
 		{
-			0, "",
-		},         /* toaddr */
-		0,         /* lock */
-		NULL,      /* wait queue */
-		NFS_MOUNT_SOFT, /* flags - this seems a ___BAD___ default - AC */
-		0, 0,           /* rsize, wsize */
-		0,              /* timeo */
-		0,              /* retrans */
-		3*HZ, 60*HZ, 30*HZ, 60*HZ, "\0" 
+		    0, "",
+		},			/* toaddr		 */
+		0,			/* lock			 */
+		NULL,			/* wait queue		 */
+		NFS_MOUNT_SOFT,		/* flags		 */
+		0, 0,			/* rsize, wsize		 */
+		0,			/* timeo		 */
+		0,			/* retrans		 */
+		3 * HZ, 60 * HZ, 30 * HZ, 60 * HZ, "\0"
 	};
 
 	filp = &nfs_file;
 	sock = &((filp->f_inode)->u.socket_i);
-    
-	/*
-	 *	extract the other end of the socket into server->toaddr 
-	 */
-	 
-	sock->ops->getname(sock, &(s.toaddr), &dummylen, 1) ;
+
+	/* extract the other end of the socket into s->toaddr */
+	sock->ops->getname(sock, &(s.toaddr), &dummylen, 1);
 	((struct sockaddr_in *) &s.toaddr)->sin_port   = server.sin_port;
 	((struct sockaddr_in *) &s.toaddr)->sin_family = server.sin_family;
 	((struct sockaddr_in *) &s.toaddr)->sin_addr.s_addr = server.sin_addr.s_addr;
-  
-	s.rsock	= rpc_makesock(filp);
+
+	s.rsock = rpc_makesock(filp);
 	s.flags = nfs_data.flags;
 	s.rsize = nfs_data.rsize;
 	s.wsize = nfs_data.wsize;
@@ -795,18 +817,15 @@
 	strcpy(s.hostname, nfs_data.hostname);
 
 	/*
-	 *	First connect the UDP socket to a server port, then send the packet
-	 *	out, and finally check wether the answer is OK.
+	 * First connect the UDP socket to a server port, then send the
+	 * packet out, and finally check wether the answer is OK.
 	 */
-	 
 	if (nfs_inode.u.socket_i.ops->connect &&
-		nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
-		(struct sockaddr *) &server, sizeof(struct sockaddr_in),
-		nfs_file.f_flags) < 0)
-	{
-		return NULL;
-	}
-
+	    nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
+						(struct sockaddr *) &server,
+						sizeof(struct sockaddr_in),
+						nfs_file.f_flags) < 0)
+		            return NULL;
 	if (nfs_rpc_call(&s, rpc_packet, end, nfs_data.wsize) < 0)
 		return NULL;
 	return rpc_verify(rpc_packet);
@@ -814,56 +833,42 @@
 
 
 /*
- *	Create an RPC packet header
+ *  Create an RPC packet header
  */
- 
 static int *root_nfs_header(int proc, int program, int version)
 {
 	int groups[] = { 0, NOGROUP };
 
-	if (rpc_packet == NULL) 
-	{
-		if (!(rpc_packet = kmalloc(nfs_data.wsize + 1024, GFP_NFS))) 
-		{
+	if (rpc_packet == NULL) {
+		if (!(rpc_packet = kmalloc(nfs_data.wsize + 1024, GFP_NFS))) {
 			printk(KERN_ERR "NFS: Cannot allocate UDP buffer\n");
 			return NULL;
 		}
 	}
-	strcpy(system_utsname.nodename, in_ntoa(myaddr.sin_addr.s_addr));
 	return rpc_header(rpc_packet, proc, program, version, 0, 0, groups);
 }
 
 
 /*
- *	Query server portmapper for the port of a daemon program
+ *  Query server portmapper for the port of a daemon program
  */
-
 static int root_nfs_get_port(int program, int version)
 {
 	int *p;
 
-	/*
-	 *	Prepare header for portmap request
-	 */
-	 
+	/* Prepare header for portmap request */
 	server.sin_port = htons(NFS_PMAP_PORT);
 	p = root_nfs_header(NFS_PMAP_PROC, NFS_PMAP_PROGRAM, NFS_PMAP_VERSION);
 	if (!p)
 		return -1;
 
-	/*
-	 *	Set arguments for portmapper
-	 */
-	 
+	/* Set arguments for portmapper */
 	*p++ = htonl(program);
 	*p++ = htonl(version);
 	*p++ = htonl(IPPROTO_UDP);
 	*p++ = 0;
 
-	/*
-	 *	Send request to server portmapper
-	 */
-	 
+	/* Send request to server portmapper */
 	if ((p = root_nfs_call(p)) == NULL)
 		return -1;
 
@@ -872,17 +877,14 @@
 
 
 /*
- *	Get portnumbers for mountd and nfsd from server
+ *  Get portnumbers for mountd and nfsd from server
  */
- 
 static int root_nfs_ports(void)
 {
 	int port;
 
-	if (nfs_port < 0) 
-	{
-		if ((port = root_nfs_get_port(NFS_NFS_PROGRAM, NFS_NFS_VERSION)) < 0) 
-		{
+	if (nfs_port < 0) {
+		if ((port = root_nfs_get_port(NFS_NFS_PROGRAM, NFS_NFS_VERSION)) < 0) {
 			printk(KERN_ERR "NFS: Unable to get nfsd port number from server, using default\n");
 			port = NFS_NFS_PORT;
 		}
@@ -891,9 +893,7 @@
 		printk(KERN_NOTICE "NFS: Portmapper on server returned %d as nfsd port\n", port);
 #endif
 	}
-
-	if ((port = root_nfs_get_port(NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION)) < 0) 
-	{
+	if ((port = root_nfs_get_port(NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION)) < 0) {
 		printk(KERN_ERR "NFS: Unable to get mountd port number from server, using default\n");
 		port = NFS_MOUNT_PORT;
 	}
@@ -901,33 +901,26 @@
 #ifdef NFSROOT_DEBUG
 	printk(KERN_NOTICE "NFS: Portmapper on server returned %d as mountd port\n", port);
 #endif
+
 	return 0;
 }
 
 
 /*
- *	Get a file handle from the server for the directory which is to be mounted
+ *  Get a file handle from the server for the directory which is to be
+ *  mounted
  */
- 
 static int root_nfs_get_handle(void)
 {
 	int len, status, *p;
 
-	/*
-	 *	Prepare header for mountd request 
-	 */
-	 
+	/* Prepare header for mountd request */
 	p = root_nfs_header(NFS_MOUNT_PROC, NFS_MOUNT_PROGRAM, NFS_MOUNT_VERSION);
-	if (!p) 
-	{
+	if (!p) {
 		root_nfs_close(1);
 		return -1;
 	}
-
-	/*
-	 *	Set arguments for mountd
-	 */
-
+	/* Set arguments for mountd */
 	len = strlen(nfs_path);
 	*p++ = htonl(len);
 	memcpy(p, nfs_path, len);
@@ -935,72 +928,56 @@
 	p[len] = 0;
 	p += len;
 
-	/*
-	 *	Send request to server portmapper 
-	 */
-
-	if ((p = root_nfs_call(p)) == NULL)
-	{
+	/* Send request to server mountd */
+	if ((p = root_nfs_call(p)) == NULL) {
 		root_nfs_close(1);
 		return -1;
 	}
-
 	status = ntohl(*p++);
-	if (status == 0) 
-	{
+	if (status == 0) {
 		nfs_data.root = *((struct nfs_fh *) p);
-	} 
-	else
-	{
+		printk(KERN_NOTICE "NFS: ");
+		printk("Got file handle for %s via RPC\n", nfs_path);
+	} else {
 		printk(KERN_ERR "NFS: Server returned error %d while mounting %s\n",
 			status, nfs_path);
 		root_nfs_close(1);
 		return -1;
 	}
+
 	return 0;
 }
 
 
 /*
- *	Now actually mount the given directory
+ *  Now actually mount the given directory
  */
-
 static int root_nfs_do_mount(struct super_block *sb)
 {
-	/*
-	 *	First connect to the nfsd port on the server 
-	 */
-
+	/* First connect to the nfsd port on the server */
 	server.sin_port = htons(nfs_port);
 	nfs_data.addr = server;
 	if (nfs_inode.u.socket_i.ops->connect &&
-		nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
-		(struct sockaddr *) &server, sizeof(struct sockaddr_in),
-		nfs_file.f_flags) < 0) 
-	{
+	    nfs_inode.u.socket_i.ops->connect(&nfs_inode.u.socket_i,
+						(struct sockaddr *) &server,
+						sizeof(struct sockaddr_in),
+						nfs_file.f_flags) < 0) {
 		root_nfs_close(1);
 		return -1;
 	}
-
-	/*
-	 *	Now (finally ;-)) read the super block for mounting
-	 */
-
-	if (nfs_read_super(sb, &nfs_data, 1) == NULL) 
-	{
+	/* Now (finally ;-)) read the super block for mounting */
+	if (nfs_read_super(sb, &nfs_data, 1) == NULL) {
 		root_nfs_close(1);
 		return -1;
 	}
-
 	return 0;
 }
 
 
 /*
- *	Get the NFS port numbers and file handle, and then read the super-
- *	block for mounting.
+ *  Get the NFS port numbers and file handle, and then read the super-
+ *  block for mounting.
  */
-
 int nfs_root_mount(struct super_block *sb)
 {
 	if (root_nfs_open() < 0)
diff -u --recursive --new-file v1.3.44/linux/fs/open.c linux/fs/open.c
--- v1.3.44/linux/fs/open.c	Mon Oct 23 18:02:17 1995
+++ linux/fs/open.c	Mon Nov 27 09:19:56 1995
@@ -66,10 +66,12 @@
 	struct iattr newattrs;
 
 	/* truncate virtual mappings of this file */
+	down(&inode->i_sem);
 	vmtruncate(inode, length);
 	inode->i_size = newattrs.ia_size = length;
 	if (inode->i_op && inode->i_op->truncate)
 		inode->i_op->truncate(inode);
+	up(&inode->i_sem);
 	newattrs.ia_ctime = newattrs.ia_mtime = CURRENT_TIME;
 	newattrs.ia_valid = ATTR_SIZE | ATTR_CTIME | ATTR_MTIME;
 	inode->i_dirt = 1;
diff -u --recursive --new-file v1.3.44/linux/fs/read_write.c linux/fs/read_write.c
--- v1.3.44/linux/fs/read_write.c	Mon Oct 23 18:02:18 1995
+++ linux/fs/read_write.c	Mon Nov 27 09:14:46 1995
@@ -138,7 +138,9 @@
 	error = verify_area(VERIFY_READ,buf,count);
 	if (error)
 		return error;
+	down(&inode->i_sem);
 	written = file->f_op->write(inode,file,buf,count);
+	up(&inode->i_sem);
 	/*
 	 * If data has been written to the file, remove the setuid and
 	 * the setgid bits
diff -u --recursive --new-file v1.3.44/linux/fs/sysv/balloc.c linux/fs/sysv/balloc.c
--- v1.3.44/linux/fs/sysv/balloc.c	Thu Nov  9 11:23:51 1995
+++ linux/fs/sysv/balloc.c	Sun Nov 26 19:23:10 1995
@@ -84,7 +84,7 @@
 		*flc_count = *sb->sv_sb_flc_count; /* = sb->sv_flc_size */
 		memcpy(flc_blocks, sb->sv_sb_flc_blocks, *flc_count * sizeof(sysv_zone_t));
 		mark_buffer_dirty(bh, 1);
-		bh->b_uptodate = 1;
+		mark_buffer_uptodate(bh, 1);
 		brelse(bh);
 		*sb->sv_sb_flc_count = 0;
 	} else
@@ -101,14 +101,14 @@
 		memset(bh->b_data, 0, sb->sv_block_size);
 		/* this implies ((struct ..._freelist_chunk *) bh->b_data)->flc_count = 0; */
 		mark_buffer_dirty(bh, 1);
-		bh->b_uptodate = 1;
+		mark_buffer_uptodate(bh, 1);
 		brelse(bh);
 		/* still *sb->sv_sb_flc_count = 0 */
 	} else {
 		/* Throw away block's contents */
 		bh = sv_get_hash_table(sb, sb->s_dev, block);
 		if (bh)
-			bh->b_dirt = 0;
+			mark_buffer_clean(bh);
 		brelse(bh);
 	}
 	if (sb->sv_convert)
@@ -208,7 +208,7 @@
 	}
 	memset(bh->b_data, 0, sb->sv_block_size);
 	mark_buffer_dirty(bh, 1);
-	bh->b_uptodate = 1;
+	mark_buffer_uptodate(bh, 1);
 	brelse(bh);
 	if (sb->sv_convert)
 		*sb->sv_sb_total_free_blocks =
diff -u --recursive --new-file v1.3.44/linux/fs/sysv/file.c linux/fs/sysv/file.c
--- v1.3.44/linux/fs/sysv/file.c	Thu Nov  9 11:23:51 1995
+++ linux/fs/sysv/file.c	Sun Nov 26 19:23:10 1995
@@ -128,7 +128,7 @@
 		while (blocks) {
 			--blocks;
 			*bhb = sysv_getblk(inode, block++, 0);
-			if (*bhb && !(*bhb)->b_uptodate) {
+			if (*bhb && !buffer_uptodate(*bhb)) {
 				uptodate = 0;
 				bhreq[bhrequest++] = *bhb;
 			}
@@ -151,7 +151,7 @@
 		do { /* Finish off all I/O that has actually completed */
 			if (*bhe) {
 				wait_on_buffer(*bhe);
-				if (!(*bhe)->b_uptodate) {	/* read error? */
+				if (!buffer_uptodate(*bhe)) {	/* read error? */
 					brelse(*bhe);
 					if (++bhe == &buflist[NBUF])
 						bhe = buflist;
@@ -177,7 +177,7 @@
 			offset = 0;
 			if (++bhe == &buflist[NBUF])
 				bhe = buflist;
-		} while (left > 0 && bhe != bhb && (!*bhe || !(*bhe)->b_lock));
+		} while (left > 0 && bhe != bhb && (!*bhe || !buffer_locked(*bhe)));
 	} while (left > 0);
 
 /* Release the read-ahead blocks */
@@ -234,17 +234,17 @@
 		c = sb->sv_block_size - (pos & sb->sv_block_size_1);
 		if (c > count-written)
 			c = count-written;
-		if (c != sb->sv_block_size && !bh->b_uptodate) {
+		if (c != sb->sv_block_size && !buffer_uptodate(bh)) {
 			ll_rw_block(READ, 1, &bh);
 			wait_on_buffer(bh);
-			if (!bh->b_uptodate) {
+			if (!buffer_uptodate(bh)) {
 				brelse(bh);
 				if (!written)
 					written = -EIO;
 				break;
 			}
 		}
-		/* now either c==sb->sv_block_size or bh->b_uptodate */
+		/* now either c==sb->sv_block_size or buffer_uptodate(bh) */
 		p = (pos & sb->sv_block_size_1) + bh->b_data;
 		pos += c;
 		if (pos > inode->i_size) {
@@ -254,7 +254,7 @@
 		written += c;
 		memcpy_fromfs(p,buf,c);
 		buf += c;
-		bh->b_uptodate = 1;
+		mark_buffer_uptodate(bh, 1);
 		mark_buffer_dirty(bh, 0);
 		brelse(bh);
 	}
diff -u --recursive --new-file v1.3.44/linux/fs/sysv/fsync.c linux/fs/sysv/fsync.c
--- v1.3.44/linux/fs/sysv/fsync.c	Thu Nov  9 11:23:51 1995
+++ linux/fs/sysv/fsync.c	Sun Nov 26 19:23:10 1995
@@ -45,11 +45,11 @@
 		brelse (bh);
 		return 1;
 	}
-	if (wait && bh->b_req && !bh->b_uptodate) {
+	if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
 		brelse(bh);
 		return -1;
 	}
-	if (wait || !bh->b_uptodate || !bh->b_dirt) {
+	if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh)) {
 		brelse(bh);
 		return 0;
 	}
diff -u --recursive --new-file v1.3.44/linux/fs/sysv/inode.c linux/fs/sysv/inode.c
--- v1.3.44/linux/fs/sysv/inode.c	Thu Nov  9 11:23:52 1995
+++ linux/fs/sysv/inode.c	Sun Nov 26 19:23:10 1995
@@ -498,7 +498,7 @@
 void sysv_write_super (struct super_block *sb)
 {
 	lock_super(sb);
-	if (sb->sv_bh1->b_dirt || sb->sv_bh2->b_dirt) {
+	if (buffer_dirty(sb->sv_bh1) || buffer_dirty(sb->sv_bh2)) {
 		/* If we are going to write out the super block,
 		   then attach current time stamp.
 		   But if the filesystem was marked clean, keep it clean. */
@@ -678,10 +678,10 @@
 
 	if (!bh)
 		return NULL;
-	if (!bh->b_uptodate) {
+	if (!buffer_uptodate(bh)) {
 		ll_rw_block(READ, 1, &bh);
 		wait_on_buffer(bh);
-		if (!bh->b_uptodate) {
+		if (!buffer_uptodate(bh)) {
 			brelse(bh);
 			return NULL;
 		}
@@ -760,11 +760,11 @@
 	struct buffer_head * bh;
 
 	bh = sysv_getblk(inode,block,create);
-	if (!bh || bh->b_uptodate)
+	if (!bh || buffer_uptodate(bh))
 		return bh;
 	ll_rw_block(READ, 1, &bh);
 	wait_on_buffer(bh);
-	if (bh->b_uptodate)
+	if (buffer_uptodate(bh))
 		return bh;
 	brelse(bh);
 	return NULL;
@@ -952,10 +952,10 @@
         struct buffer_head *bh;
 
         bh = sysv_update_inode(inode);
-        if (bh && bh->b_dirt) {
+        if (bh && buffer_dirty(bh)) {
                 ll_rw_block(WRITE, 1, &bh);
                 wait_on_buffer(bh);
-                if (bh->b_req && !bh->b_uptodate)
+                if (buffer_req(bh) && !buffer_uptodate(bh))
                 {
                         printk ("IO error syncing sysv inode ["
 				"%s:%08lx]\n",
diff -u --recursive --new-file v1.3.44/linux/fs/sysv/truncate.c linux/fs/sysv/truncate.c
--- v1.3.44/linux/fs/sysv/truncate.c	Thu Nov  9 11:23:52 1995
+++ linux/fs/sysv/truncate.c	Sun Nov 26 19:23:10 1995
@@ -171,13 +171,16 @@
 	else
 		i = (inode->i_size - offset + sb->sv_ind_per_block_block_size_1) >> sb->sv_ind_per_block_block_size_bits;
 	for (; i < sb->sv_ind_per_block; i++) {
+		unsigned char dirty = 0;
 		ind = ((sysv_zone_t *) indbh->b_data) + i;
 		block = tmp = *ind;
 		if (sb->sv_convert)
 			block = from_coh_ulong(block);
 		if (!block)
 			continue;
-		retry |= trunc_indirect(inode,offset+(i<<sb->sv_ind_per_block_bits),ind,sb->sv_convert,&indbh->b_dirt);
+		retry |= trunc_indirect(inode,offset+(i<<sb->sv_ind_per_block_bits),ind,sb->sv_convert,&dirty);
+		if (dirty)
+			mark_buffer_dirty(indbh, 1);
 	}
 	for (i = 0; i < sb->sv_ind_per_block; i++)
 		if (((sysv_zone_t *) indbh->b_data)[i])
@@ -225,13 +228,16 @@
 	else
 		i = (inode->i_size - offset + sb->sv_ind_per_block_2_block_size_1) >> sb->sv_ind_per_block_2_block_size_bits;
 	for (; i < sb->sv_ind_per_block; i++) {
+		unsigned char dirty = 0;
 		ind = ((sysv_zone_t *) indbh->b_data) + i;
 		block = tmp = *ind;
 		if (sb->sv_convert)
 			block = from_coh_ulong(block);
 		if (!block)
 			continue;
-		retry |= trunc_dindirect(inode,offset+(i<<sb->sv_ind_per_block_2_bits),ind,sb->sv_convert,&indbh->b_dirt);
+		retry |= trunc_dindirect(inode,offset+(i<<sb->sv_ind_per_block_2_bits),ind,sb->sv_convert,&dirty);
+		if (dirty)
+			mark_buffer_dirty(indbh, 1);
 	}
 	for (i = 0; i < sb->sv_ind_per_block; i++)
 		if (((sysv_zone_t *) indbh->b_data)[i])
diff -u --recursive --new-file v1.3.44/linux/fs/xiafs/bitmap.c linux/fs/xiafs/bitmap.c
--- v1.3.44/linux/fs/xiafs/bitmap.c	Thu Nov  9 11:23:52 1995
+++ linux/fs/xiafs/bitmap.c	Sun Nov 26 19:23:10 1995
@@ -227,7 +227,7 @@
     }
     bh = get_hash_table(sb->s_dev, d_addr, XIAFS_ZSIZE(sb));
     if (bh)
-        bh->b_dirt=0;
+        mark_buffer_clean(bh);
     brelse(bh);
     bit=d_addr - sb->u.xiafs_sb.s_firstdatazone + 1;
     bh = get_zmap_zone(sb, bit, NULL);
@@ -269,7 +269,7 @@
 	return 0;
     }
     clear_buf(bh);
-    bh->b_uptodate = 1;
+    mark_buffer_uptodate(bh, 1);
     mark_buffer_dirty(bh, 1);
     brelse(bh);
     return tmp;
diff -u --recursive --new-file v1.3.44/linux/fs/xiafs/file.c linux/fs/xiafs/file.c
--- v1.3.44/linux/fs/xiafs/file.c	Thu Nov  9 11:23:52 1995
+++ linux/fs/xiafs/file.c	Sun Nov 26 19:23:10 1995
@@ -118,7 +118,7 @@
 	uptodate = 1;
 	while (zones--) {
 	    *bhb = xiafs_getblk(inode, zone_nr++, 0);
-	    if (*bhb && !(*bhb)->b_uptodate) {
+	    if (*bhb && !buffer_uptodate(*bhb)) {
 	        uptodate = 0;
 		bhreq[bhrequest++] = *bhb;
 	    }
@@ -141,7 +141,7 @@
 	do { /* Finish off all I/O that has actually completed */
 	    if (*bhe) {
 	        wait_on_buffer(*bhe);
-		if (!(*bhe)->b_uptodate) {	/* read error? */
+		if (!buffer_uptodate(*bhe)) {	/* read error? */
 		    brelse(*bhe);
 		    if (++bhe == &buflist[NBUF])
 		      bhe = buflist;
@@ -167,7 +167,7 @@
 	    offset = 0;
 	    if (++bhe == &buflist[NBUF])
 	        bhe = buflist;
-	} while (left > 0 && bhe != bhb && (!*bhe || !(*bhe)->b_lock));
+	} while (left > 0 && bhe != bhb && (!*bhe || !buffer_locked(*bhe)));
     } while (left > 0);
 
 /* Release the read-ahead blocks */
@@ -221,10 +221,10 @@
 	c = XIAFS_ZSIZE(inode->i_sb) - (pos & (XIAFS_ZSIZE(inode->i_sb) - 1));
 	if (c > count-written)
 	    c = count-written;
-	if (c != XIAFS_ZSIZE(inode->i_sb) && !bh->b_uptodate) {
+	if (c != XIAFS_ZSIZE(inode->i_sb) && !buffer_uptodate(bh)) {
 	    ll_rw_block(READ, 1, &bh);
 	    wait_on_buffer(bh);
-	    if (!bh->b_uptodate) {
+	    if (!buffer_uptodate(bh)) {
 	        brelse(bh);
 		if (!written)
 		    written = -EIO;
@@ -240,7 +240,7 @@
 	written += c;
 	memcpy_fromfs(cp,buf,c);
 	buf += c;
-	bh->b_uptodate = 1;
+	mark_buffer_uptodate(bh, 1);
 	mark_buffer_dirty(bh, 0);
 	brelse(bh);
     }
diff -u --recursive --new-file v1.3.44/linux/fs/xiafs/fsync.c linux/fs/xiafs/fsync.c
--- v1.3.44/linux/fs/xiafs/fsync.c	Thu Nov  9 11:23:52 1995
+++ linux/fs/xiafs/fsync.c	Sun Nov 26 19:23:10 1995
@@ -41,11 +41,11 @@
 		brelse (bh);
 		return 1;
 	}
-	if (wait && bh->b_req && !bh->b_uptodate) {
+	if (wait && buffer_req(bh) && !buffer_uptodate(bh)) {
 		brelse(bh);
 		return -1;
 	}
-	if (wait || !bh->b_uptodate || !bh->b_dirt)
+	if (wait || !buffer_uptodate(bh) || !buffer_dirty(bh))
 	{
 		brelse(bh);
 		return 0;
diff -u --recursive --new-file v1.3.44/linux/fs/xiafs/inode.c linux/fs/xiafs/inode.c
--- v1.3.44/linux/fs/xiafs/inode.c	Thu Nov  9 11:23:52 1995
+++ linux/fs/xiafs/inode.c	Sun Nov 26 19:23:10 1995
@@ -280,10 +280,10 @@
 
     if (!bh)
         return NULL;
-    if (!bh->b_uptodate) {
+    if (!buffer_uptodate(bh)) {
         ll_rw_block(READ, 1, &bh);
 	wait_on_buffer(bh);
-	if (!bh->b_uptodate) {
+	if (!buffer_uptodate(bh)) {
 	    brelse(bh);
 	    return NULL;
 	}
@@ -359,11 +359,11 @@
     struct buffer_head * bh;
 
     bh = xiafs_getblk(inode, zone, create);
-    if (!bh || bh->b_uptodate)
+    if (!bh || buffer_uptodate(bh))
         return bh;
     ll_rw_block(READ, 1, &bh);
     wait_on_buffer(bh);
-    if (bh->b_uptodate)
+    if (buffer_uptodate(bh))
         return bh;
     brelse(bh);
     return NULL;
@@ -494,11 +494,11 @@
     struct buffer_head *bh;
 
     bh = xiafs_update_inode(inode);
-    if (bh && bh->b_dirt)
+    if (bh && buffer_dirty(bh))
     {
     	ll_rw_block(WRITE, 1, &bh);
     	wait_on_buffer(bh);
-    	if (bh->b_req && !bh->b_uptodate)
+    	if (buffer_req(bh) && !buffer_uptodate(bh))
     	{
     	    printk ("IO error syncing xiafs inode [%s:%lu]\n",
 		    kdevname(inode->i_dev), inode->i_ino);
diff -u --recursive --new-file v1.3.44/linux/include/asm-alpha/bitops.h linux/include/asm-alpha/bitops.h
--- v1.3.44/linux/include/asm-alpha/bitops.h	Sun Oct 29 11:38:49 1995
+++ linux/include/asm-alpha/bitops.h	Sun Nov 26 23:45:33 1995
@@ -17,6 +17,7 @@
 {
 	unsigned long oldbit;
 	unsigned long temp;
+	unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
 
 	__asm__ __volatile__(
 		"\n1:\t"
@@ -28,10 +29,10 @@
 		"beq %0,1b\n"
 		"2:"
 		:"=&r" (temp),
-		 "=m" (((int *) addr)[nr >> 5]),
+		 "=m" (*m),
 		 "=&r" (oldbit)
 		:"r" (1UL << (nr & 31)),
-		 "m" (((int *) addr)[nr >> 5]));
+		 "m" (*m));
 	return oldbit != 0;
 }
 
@@ -39,6 +40,7 @@
 {
 	unsigned long oldbit;
 	unsigned long temp;
+	unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
 
 	__asm__ __volatile__(
 		"\n1:\t"
@@ -50,10 +52,10 @@
 		"beq %0,1b\n"
 		"2:"
 		:"=&r" (temp),
-		 "=m" (((int *) addr)[nr >> 5]),
+		 "=m" (*m),
 		 "=&r" (oldbit)
 		:"r" (1UL << (nr & 31)),
-		 "m" (((int *) addr)[nr >> 5]));
+		 "m" (*m));
 	return oldbit != 0;
 }
 
@@ -61,6 +63,7 @@
 {
 	unsigned long oldbit;
 	unsigned long temp;
+	unsigned int * m = ((unsigned int *) addr) + (nr >> 5);
 
 	__asm__ __volatile__(
 		"\n1:\t"
@@ -70,10 +73,10 @@
 		"stl_c %0,%1\n\t"
 		"beq %0,1b\n"
 		:"=&r" (temp),
-		 "=m" (((int *) addr)[nr >> 5]),
+		 "=m" (*m),
 		 "=&r" (oldbit)
 		:"r" (1UL << (nr & 31)),
-		 "m" (((int *) addr)[nr >> 5]));
+		 "m" (*m));
 	return oldbit != 0;
 }
 
diff -u --recursive --new-file v1.3.44/linux/include/asm-i386/bitops.h linux/include/asm-i386/bitops.h
--- v1.3.44/linux/include/asm-i386/bitops.h	Thu Nov  9 11:23:52 1995
+++ linux/include/asm-i386/bitops.h	Sun Nov 26 19:29:00 1995
@@ -60,17 +60,11 @@
 }
 
 /*
- * This routine doesn't need to be atomic, but it's faster to code it
- * this way.
+ * This routine doesn't need to be atomic.
  */
 extern __inline__ int test_bit(int nr, const void * addr)
 {
-	int oldbit;
-
-	__asm__ __volatile__("btl %2,%1\n\tsbbl %0,%0"
-		:"=r" (oldbit)
-		:"m" (CONST_ADDR),"ir" (nr));
-	return oldbit;
+	return 1UL & (((unsigned int *) addr)[nr >> 5] >> (nr & 31));
 }
 
 /*
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/a.out.h linux/include/asm-ppc/a.out.h
--- v1.3.44/linux/include/asm-ppc/a.out.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/a.out.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,26 @@
+#ifndef __PPC_A_OUT_H__
+#define __PPC_A_OUT_H__
+
+/* grabbed from the intel stuff  */   
+#define STACK_TOP TASK_SIZE
+
+
+struct exec
+{
+  unsigned long a_info;		/* Use macros N_MAGIC, etc for access */
+  unsigned a_text;		/* length of text, in bytes */
+  unsigned a_data;		/* length of data, in bytes */
+  unsigned a_bss;		/* length of uninitialized data area for file, in bytes */
+  unsigned a_syms;		/* length of symbol table data in file, in bytes */
+  unsigned a_entry;		/* start address */
+  unsigned a_trsize;		/* length of relocation info for text, in bytes */
+  unsigned a_drsize;		/* length of relocation info for data, in bytes */
+};
+
+
+#define N_TRSIZE(a)	((a).a_trsize)
+#define N_DRSIZE(a)	((a).a_drsize)
+#define N_SYMSIZE(a)	((a).a_syms)
+
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/bitops.h linux/include/asm-ppc/bitops.h
--- v1.3.44/linux/include/asm-ppc/bitops.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/bitops.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,84 @@
+#ifndef _ASM_PPC_BITOPS_H_
+#define _ASM_PPC_BITOPS_H_
+
+/*
+ * For the benefit of those who are trying to port Linux to another
+ * architecture, here are some C-language equivalents.  You should
+ * recode these in the native assembly language, if at all possible.
+ * To guarantee atomicity, these routines call cli() and sti() to
+ * disable interrupts while they operate.  (You have to provide inline
+ * routines to cli() and sti().)
+ *
+ * Also note, these routines assume that you have 32 bit integers.
+ * You will have to change this if you are trying to port Linux to the
+ * Alpha architecture or to a Cray.  :-)
+ * 
+ * C language equivalents written by Theodore Ts'o, 9/26/92
+ */
+
+#include "asm/system.h"  /* For cli/sti declaration */
+
+#define BIT(n) 1<<(n&0x1F)
+typedef unsigned long BITFIELD;
+
+extern __inline__ int set_bit(int nr, void * add)
+/*extern __inline__ int set_bit(int nr, BITFIELD * addr)*/
+{
+       int	mask, oldbit;
+  BITFIELD *addr = add;
+       
+	int s = _disable_interrupts();
+	addr += nr >> 5;
+	mask = BIT(nr);
+	oldbit = (mask & *addr) != 0;
+	*addr |= mask;
+	_enable_interrupts(s);
+
+	
+	return oldbit;
+}
+
+
+/*extern __inline__ int change_bit(int nr, BITFIELD *addr)*/
+extern __inline__ int change_bit(int nr, void *add)
+{
+  	BITFIELD *addr = add;
+	int	mask, retval;
+	int s = _disable_interrupts();
+	addr += nr >> 5;
+	mask = BIT(nr);
+	retval = (mask & *addr) != 0;
+	*addr ^= mask;
+	_enable_interrupts(s);
+	return retval;
+}
+
+
+/*extern __inline__ int clear_bit(int nr, BITFIELD *addr2)*/
+extern __inline__ int clear_bit(int nr, void *add)
+{
+        BITFIELD *addr = add;
+	int	mask, retval;
+	int s = _disable_interrupts();
+	addr += nr >> 5;
+	mask = BIT(nr);
+	retval = (mask & *addr) != 0;
+	*addr &= ~mask;
+	_enable_interrupts(s);
+	return retval;
+}
+
+extern __inline__ int test_bit(int nr, void *add)
+/*extern __inline__ int test_bit(int nr, BITFIELD *addr)*/
+{
+	int	mask;
+	BITFIELD *addr = add;
+
+	addr += nr >> 5;
+	mask = BIT(nr);
+	return ((mask & *addr) != 0);
+}
+
+#endif /* _ASM_PPC_BITOPS_H */
+
+
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/bugs.h linux/include/asm-ppc/bugs.h
--- v1.3.44/linux/include/asm-ppc/bugs.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/bugs.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,8 @@
+/*
+ * This file is included by 'init/main.c'
+ */
+
+void
+check_bugs(void)
+{
+} 
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/byteorder.h linux/include/asm-ppc/byteorder.h
--- v1.3.44/linux/include/asm-ppc/byteorder.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/byteorder.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,93 @@
+#ifndef _PPC_BYTEORDER_H
+#define _PPC_BYTEORDER_H
+
+#ifndef __BIG_ENDIAN
+#define __BIG_ENDIAN
+#endif
+
+#ifndef __BIG_ENDIAN_BITFIELD
+#define __BIG_ENDIAN_BITFIELD
+#endif
+
+#if 0 /* Assume PowerPC is Big-Endian! */
+#undef ntohl
+#undef ntohs
+#undef htonl
+#undef htons
+
+extern unsigned long int	ntohl(unsigned long int);
+extern unsigned short int	ntohs(unsigned short int);
+extern unsigned long int	htonl(unsigned long int);
+extern unsigned short int	htons(unsigned short int);
+
+extern unsigned long int	__ntohl(unsigned long int);
+extern unsigned short int	__ntohs(unsigned short int);
+extern unsigned long int	__constant_ntohl(unsigned long int);
+extern unsigned short int	__constant_ntohs(unsigned short int);
+
+extern __inline__ unsigned long int
+__ntohl(unsigned long int x)
+{
+	return (((x & 0x000000ffU) << 24) |
+		((x & 0x0000ff00U) <<  8) |
+		((x & 0x00ff0000U) >>  8) |
+		((x & 0xff000000U) >> 24));
+}
+
+extern __inline__ unsigned long int
+__constant_ntohl(unsigned long int x)
+{
+	return (((x & 0x000000ffU) << 24) |
+		((x & 0x0000ff00U) <<  8) |
+		((x & 0x00ff0000U) >>  8) |
+		((x & 0xff000000U) >> 24));
+}
+
+extern __inline__ unsigned short int
+__ntohs(unsigned short int x)
+{
+	return (((x & 0x00ff) << 8) |
+		((x & 0xff00) >> 8));
+}
+
+extern __inline__ unsigned short int
+__constant_ntohs(unsigned short int x)
+{
+	return (((x & 0x00ff) << 8) |
+		((x & 0xff00) >> 8));
+}
+
+#define __htonl(x) __ntohl(x)
+#define __htons(x) __ntohs(x)
+#define __constant_htonl(x) __constant_ntohl(x)
+#define __constant_htons(x) __constant_ntohs(x)
+
+#ifdef  __OPTIMIZE__
+#  define ntohl(x) \
+(__builtin_constant_p((long)(x)) ? \
+ __constant_ntohl((x)) : \
+ __ntohl((x)))
+#  define ntohs(x) \
+(__builtin_constant_p((short)(x)) ? \
+ __constant_ntohs((x)) : \
+ __ntohs((x)))
+#  define htonl(x) \
+(__builtin_constant_p((long)(x)) ? \
+ __constant_htonl((x)) : \
+ __htonl((x)))
+#  define htons(x) \
+(__builtin_constant_p((short)(x)) ? \
+ __constant_htons((x)) : \
+ __htons((x)))
+#endif
+
+#else
+
+#define ntohl(x) (x)
+#define ntohs(x) (x)
+#define htonl(x) (x)
+#define htons(x) (x)
+
+#endif
+
+#endif /* !(_PPC_BYTEORDER_H) */
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/checksum.h linux/include/asm-ppc/checksum.h
--- v1.3.44/linux/include/asm-ppc/checksum.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/checksum.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,58 @@
+#ifndef _PPC_CHECKSUM_H
+#define _PPC_CHECKSUM_H
+
+
+/*
+ *	This is a version of ip_compute_csum() optimized for IP headers,
+ *	which always checksum on 4 octet boundaries.
+ */
+extern unsigned short ip_fast_csum(unsigned char * iph, unsigned int ihl);
+
+/*
+ * computes the checksum of the TCP/UDP pseudo-header
+ * returns a 16-bit checksum, already complemented
+ */
+extern unsigned short int csum_tcpudp_magic(unsigned long saddr,
+					   unsigned long daddr,
+					   unsigned short len,
+					   unsigned short proto,
+					   unsigned int sum);
+
+/*
+ * computes the checksum of a memory block at buff, length len,
+ * and adds in "sum" (32-bit)
+ *
+ * returns a 32-bit number suitable for feeding into itself
+ * or csum_tcpudp_magic
+ *
+ * this function must be called with even lengths, except
+ * for the last fragment, which may be odd
+ *
+ * it's best to have buff aligned on a 32-bit boundary
+ */
+extern unsigned int csum_partial(const unsigned char * buff, int len, unsigned int sum);
+
+/*
+ * the same as csum_partial, but copies from src while it
+ * checksums
+ *
+ * here even more important to align src and dst on a 32-bit (or even
+ * better 64-bit) boundary
+ */
+unsigned int csum_partial_copy( const char *src, char *dst, int len, int sum);
+
+/*
+ * the same as csum_partial, but copies from user space (but on the alpha
+ * we have just one address space, so this is identical to the above)
+ */
+#define csum_partial_copy_fromuser csum_partial_copy
+
+
+/*
+ * this routine is used for miscellaneous IP-like checksums, mainly
+ * in icmp.c
+A */
+
+extern unsigned short ip_compute_csum(unsigned char * buff, int len);
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/delay.h linux/include/asm-ppc/delay.h
--- v1.3.44/linux/include/asm-ppc/delay.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/delay.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,15 @@
+#ifndef _PPC_DELAY_H
+#define _PPC_DELAY_H
+
+
+extern __inline__ void __delay(unsigned long );
+extern __inline__ void __udelay(unsigned long );
+
+
+extern __inline__ unsigned long muldiv(unsigned long a, unsigned long b, unsigned long c)
+{
+	return (a*b)/c;
+}
+
+#endif /* defined(_PPC_DELAY_H) */
+
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/dma.h linux/include/asm-ppc/dma.h
--- v1.3.44/linux/include/asm-ppc/dma.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/dma.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,271 @@
+/* $Id: dma.h,v 1.7 1992/12/14 00:29:34 root Exp root $
+ * linux/include/asm/dma.h: Defines for using and allocating dma channels.
+ * Written by Hennus Bergman, 1992.
+ * High DMA channel support & info by Hannu Savolainen
+ * and John Boyd, Nov. 1992.
+ */
+
+#ifndef _ASM_DMA_H
+#define _ASM_DMA_H
+
+#include <asm/io.h>		/* need byte IO */
+
+
+#ifdef HAVE_REALLY_SLOW_DMA_CONTROLLER
+#define dma_outb	outb_p
+#else
+#define dma_outb	outb
+#endif
+
+#define dma_inb		inb
+
+/*
+ * NOTES about DMA transfers:
+ *
+ *  controller 1: channels 0-3, byte operations, ports 00-1F
+ *  controller 2: channels 4-7, word operations, ports C0-DF
+ *
+ *  - ALL registers are 8 bits only, regardless of transfer size
+ *  - channel 4 is not used - cascades 1 into 2.
+ *  - channels 0-3 are byte - addresses/counts are for physical bytes
+ *  - channels 5-7 are word - addresses/counts are for physical words
+ *  - transfers must not cross physical 64K (0-3) or 128K (5-7) boundaries
+ *  - transfer count loaded to registers is 1 less than actual count
+ *  - controller 2 offsets are all even (2x offsets for controller 1)
+ *  - page registers for 5-7 don't use data bit 0, represent 128K pages
+ *  - page registers for 0-3 use bit 0, represent 64K pages
+ *
+ * DMA transfers are limited to the lower 16MB of _physical_ memory.  
+ * Note that addresses loaded into registers must be _physical_ addresses,
+ * not logical addresses (which may differ if paging is active).
+ *
+ *  Address mapping for channels 0-3:
+ *
+ *   A23 ... A16 A15 ... A8  A7 ... A0    (Physical addresses)
+ *    |  ...  |   |  ... |   |  ... |
+ *    |  ...  |   |  ... |   |  ... |
+ *    |  ...  |   |  ... |   |  ... |
+ *   P7  ...  P0  A7 ... A0  A7 ... A0   
+ * |    Page    | Addr MSB | Addr LSB |   (DMA registers)
+ *
+ *  Address mapping for channels 5-7:
+ *
+ *   A23 ... A17 A16 A15 ... A9 A8 A7 ... A1 A0    (Physical addresses)
+ *    |  ...  |   \   \   ... \  \  \  ... \  \
+ *    |  ...  |    \   \   ... \  \  \  ... \  (not used)
+ *    |  ...  |     \   \   ... \  \  \  ... \
+ *   P7  ...  P1 (0) A7 A6  ... A0 A7 A6 ... A0   
+ * |      Page      |  Addr MSB   |  Addr LSB  |   (DMA registers)
+ *
+ * Again, channels 5-7 transfer _physical_ words (16 bits), so addresses
+ * and counts _must_ be word-aligned (the lowest address bit is _ignored_ at
+ * the hardware level, so odd-byte transfers aren't possible).
+ *
+ * Transfer count (_not # bytes_) is limited to 64K, represented as actual
+ * count - 1 : 64K => 0xFFFF, 1 => 0x0000.  Thus, count is always 1 or more,
+ * and up to 128K bytes may be transferred on channels 5-7 in one operation. 
+ *
+ */
+
+#define MAX_DMA_CHANNELS	8
+
+/* The maximum address that we can perform a DMA transfer to on this platform */
+#define MAX_DMA_ADDRESS      0x1000000
+
+/* 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 */
+
+/* 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) */
+
+#define DMA_ADDR_0              0x00    /* DMA address registers */
+#define DMA_ADDR_1              0x02
+#define DMA_ADDR_2              0x04
+#define DMA_ADDR_3              0x06
+#define DMA_ADDR_4              0xC0
+#define DMA_ADDR_5              0xC4
+#define DMA_ADDR_6              0xC8
+#define DMA_ADDR_7              0xCC
+
+#define DMA_CNT_0               0x01    /* DMA count registers */
+#define DMA_CNT_1               0x03
+#define DMA_CNT_2               0x05
+#define DMA_CNT_3               0x07
+#define DMA_CNT_4               0xC2
+#define DMA_CNT_5               0xC6
+#define DMA_CNT_6               0xCA
+#define DMA_CNT_7               0xCE
+
+#define DMA_PAGE_0              0x87    /* DMA page registers */
+#define DMA_PAGE_1              0x83
+#define DMA_PAGE_2              0x81
+#define DMA_PAGE_3              0x82
+#define DMA_PAGE_5              0x8B
+#define DMA_PAGE_6              0x89
+#define DMA_PAGE_7              0x8A
+
+#define DMA_MODE_READ	0x44	/* I/O to memory, no autoinit, increment, single mode */
+#define DMA_MODE_WRITE	0x48	/* memory to I/O, no autoinit, increment, single mode */
+#define DMA_MODE_CASCADE 0xC0   /* pass thru DREQ->HRQ, DACK<-HLDA only */
+
+/* enable/disable a specific DMA channel */
+static __inline__ void enable_dma(unsigned int dmanr)
+{
+	if (dmanr<=3)
+		dma_outb(dmanr,  DMA1_MASK_REG);
+	else
+		dma_outb(dmanr & 3,  DMA2_MASK_REG);
+}
+
+static __inline__ void disable_dma(unsigned int dmanr)
+{
+	if (dmanr<=3)
+		dma_outb(dmanr | 4,  DMA1_MASK_REG);
+	else
+		dma_outb((dmanr & 3) | 4,  DMA2_MASK_REG);
+}
+
+/* Clear the 'DMA Pointer Flip Flop'.
+ * Write 0 for LSB/MSB, 1 for MSB/LSB access.
+ * Use this once to initialize the FF to a known state.
+ * After that, keep track of it. :-)
+ * --- In order to do that, the DMA routines below should ---
+ * --- only be used while interrupts are disabled! ---
+ */
+static __inline__ void clear_dma_ff(unsigned int dmanr)
+{
+	if (dmanr<=3)
+		dma_outb(0,  DMA1_CLEAR_FF_REG);
+	else
+		dma_outb(0,  DMA2_CLEAR_FF_REG);
+}
+
+/* set mode (above) for a specific DMA channel */
+static __inline__ void set_dma_mode(unsigned int dmanr, char mode)
+{
+	if (dmanr<=3)
+		dma_outb(mode | dmanr,  DMA1_MODE_REG);
+	else
+		dma_outb(mode | (dmanr&3),  DMA2_MODE_REG);
+}
+
+/* Set only the page register bits of the transfer address.
+ * This is used for successive transfers when we know the contents of
+ * the lower 16 bits of the DMA current address register, but a 64k boundary
+ * may have been crossed.
+ */
+static __inline__ void set_dma_page(unsigned int dmanr, char pagenr)
+{
+	switch(dmanr) {
+		case 0:
+			dma_outb(pagenr, DMA_PAGE_0);
+			break;
+		case 1:
+			dma_outb(pagenr, DMA_PAGE_1);
+			break;
+		case 2:
+			dma_outb(pagenr, DMA_PAGE_2);
+			break;
+		case 3:
+			dma_outb(pagenr, DMA_PAGE_3);
+			break;
+		case 5:
+			dma_outb(pagenr & 0xfe, DMA_PAGE_5);
+			break;
+		case 6:
+			dma_outb(pagenr & 0xfe, DMA_PAGE_6);
+			break;
+		case 7:
+			dma_outb(pagenr & 0xfe, DMA_PAGE_7);
+			break;
+	}
+}
+
+
+/* Set transfer address & page bits for specific DMA channel.
+ * Assumes dma flipflop is clear.
+ */
+static __inline__ void set_dma_addr(unsigned int dmanr, unsigned int a)
+{
+	set_dma_page(dmanr, a>>16);
+	if (dmanr <= 3)  {
+	    dma_outb( a & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+            dma_outb( (a>>8) & 0xff, ((dmanr&3)<<1) + IO_DMA1_BASE );
+	}  else  {
+	    dma_outb( (a>>1) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+	    dma_outb( (a>>9) & 0xff, ((dmanr&3)<<2) + IO_DMA2_BASE );
+	}
+}
+
+
+/* Set transfer size (max 64k for DMA1..3, 128k for DMA5..7) for
+ * a specific DMA channel.
+ * You must ensure the parameters are valid.
+ * NOTE: from a manual: "the number of transfers is one more
+ * than the initial word count"! This is taken into account.
+ * Assumes dma flip-flop is clear.
+ * NOTE 2: "count" represents _bytes_ and must be even for channels 5-7.
+ */
+static __inline__ void set_dma_count(unsigned int dmanr, unsigned int count)
+{
+        count--;
+	if (dmanr <= 3)  {
+	    dma_outb( count & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+	    dma_outb( (count>>8) & 0xff, ((dmanr&3)<<1) + 1 + IO_DMA1_BASE );
+        } else {
+	    dma_outb( (count>>1) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+	    dma_outb( (count>>9) & 0xff, ((dmanr&3)<<2) + 2 + IO_DMA2_BASE );
+        }
+}
+
+
+/* Get DMA residue count. After a DMA transfer, this
+ * should return zero. Reading this while a DMA transfer is
+ * still in progress will return unpredictable results.
+ * If called before the channel has been used, it may return 1.
+ * Otherwise, it returns the number of _bytes_ left to transfer.
+ *
+ * Assumes DMA flip-flop is clear.
+ */
+static __inline__ int get_dma_residue(unsigned int dmanr)
+{
+	unsigned int io_port = (dmanr<=3)? ((dmanr&3)<<1) + 1 + IO_DMA1_BASE
+					 : ((dmanr&3)<<2) + 2 + IO_DMA2_BASE;
+
+	/* using short to get 16-bit wrap around */
+	unsigned short count;
+
+	count = 1 + dma_inb(io_port);
+	count += dma_inb(io_port) << 8;
+	
+	return (dmanr<=3)? count : (count<<1);
+}
+
+
+/* These are in kernel/dma.c: */
+/*extern int request_dma(unsigned int dmanr, char * device_id);*/	/* reserve a DMA channel */
+extern void free_dma(unsigned int dmanr);	/* release it again */
+
+
+#endif /* _ASM_DMA_H */
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/elf.h linux/include/asm-ppc/elf.h
--- v1.3.44/linux/include/asm-ppc/elf.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/elf.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,17 @@
+#ifndef __PPC_ELF_H
+#define __PPC_ELF_H
+
+/*
+ * ELF register definitions..
+ */
+
+#define ELF_NGREG	32
+#define ELF_NFPREG	32
+
+typedef unsigned long elf_greg_t;
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef double elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/errno.h linux/include/asm-ppc/errno.h
--- v1.3.44/linux/include/asm-ppc/errno.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/errno.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,134 @@
+#ifndef _PPC_ERRNO_H
+#define _PPC_ERRNO_H
+
+#define	EPERM		 1	/* Operation not permitted */
+#define	ENOENT		 2	/* No such file or directory */
+#define	ESRCH		 3	/* No such process */
+#define	EINTR		 4	/* Interrupted system call */
+#define	EIO		 5	/* I/O error */
+#define	ENXIO		 6	/* No such device or address */
+#define	E2BIG		 7	/* Arg list too long */
+#define	ENOEXEC		 8	/* Exec format error */
+#define	EBADF		 9	/* Bad file number */
+#define	ECHILD		10	/* No child processes */
+#define	EDEADLK		11	/* Resource deadlock would occur */
+#define	ENOMEM		12	/* Out of memory */
+#define	EACCES		13	/* Permission denied */
+#define	EFAULT		14	/* Bad address */
+#define	ENOTBLK		15	/* Block device required */
+#define	EBUSY		16	/* Device or resource busy */
+#define	EEXIST		17	/* File exists */
+#define	EXDEV		18	/* Cross-device link */
+#define	ENODEV		19	/* No such device */
+#define	ENOTDIR		20	/* Not a directory */
+#define	EISDIR		21	/* Is a directory */
+#define	EINVAL		22	/* Invalid argument */
+#define	ENFILE		23	/* File table overflow */
+#define	EMFILE		24	/* Too many open files */
+#define	ENOTTY		25	/* Not a typewriter */
+#define	ETXTBSY		26	/* Text file busy */
+#define	EFBIG		27	/* File too large */
+#define	ENOSPC		28	/* No space left on device */
+#define	ESPIPE		29	/* Illegal seek */
+#define	EROFS		30	/* Read-only file system */
+#define	EMLINK		31	/* Too many links */
+#define	EPIPE		32	/* Broken pipe */
+#define	EDOM		33	/* Math argument out of domain of func */
+#define	ERANGE		34	/* Math result not representable */
+#define	EAGAIN		35	/* Try again */
+#define	EWOULDBLOCK	EAGAIN	/* Operation would block */
+#define	EINPROGRESS	36	/* Operation now in progress */
+#define	EALREADY	37	/* Operation already in progress */
+#define	ENOTSOCK	38	/* Socket operation on non-socket */
+#define	EDESTADDRREQ	39	/* Destination address required */
+#define	EMSGSIZE	40	/* Message too long */
+#define	EPROTOTYPE	41	/* Protocol wrong type for socket */
+#define	ENOPROTOOPT	42	/* Protocol not available */
+#define	EPROTONOSUPPORT	43	/* Protocol not supported */
+#define	ESOCKTNOSUPPORT	44	/* Socket type not supported */
+#define	EOPNOTSUPP	45	/* Operation not supported on transport endpoint */
+#define	EPFNOSUPPORT	46	/* Protocol family not supported */
+#define	EAFNOSUPPORT	47	/* Address family not supported by protocol */
+#define	EADDRINUSE	48	/* Address already in use */
+#define	EADDRNOTAVAIL	49	/* Cannot assign requested address */
+#define	ENETDOWN	50	/* Network is down */
+#define	ENETUNREACH	51	/* Network is unreachable */
+#define	ENETRESET	52	/* Network dropped connection because of reset */
+#define	ECONNABORTED	53	/* Software caused connection abort */
+#define	ECONNRESET	54	/* Connection reset by peer */
+#define	ENOBUFS		55	/* No buffer space available */
+#define	EISCONN		56	/* Transport endpoint is already connected */
+#define	ENOTCONN	57	/* Transport endpoint is not connected */
+#define	ESHUTDOWN	58	/* Cannot send after transport endpoint shutdown */
+#define	ETOOMANYREFS	59	/* Too many references: cannot splice */
+#define	ETIMEDOUT	60	/* Connection timed out */
+#define	ECONNREFUSED	61	/* Connection refused */
+#define	ELOOP		62	/* Too many symbolic links encountered */
+#define	ENAMETOOLONG	63	/* File name too long */
+#define	EHOSTDOWN	64	/* Host is down */
+#define	EHOSTUNREACH	65	/* No route to host */
+#define	ENOTEMPTY	66	/* Directory not empty */
+
+#define	EUSERS		68	/* Too many users */
+#define	EDQUOT		69	/* Quota exceeded */
+#define	ESTALE		70	/* Stale NFS file handle */
+#define	EREMOTE		71	/* Object is remote */
+
+#define	ENOLCK		77	/* No record locks available */
+#define	ENOSYS		78	/* Function not implemented */
+
+#define	ENOMSG		80	/* No message of desired type */
+#define	EIDRM		81	/* Identifier removed */
+#define	ENOSR		82	/* Out of streams resources */
+#define	ETIME		83	/* Timer expired */
+#define	EBADMSG		84	/* Not a data message */
+#define	EPROTO		85	/* Protocol error */
+#define	ENODATA		86	/* No data available */
+#define	ENOSTR		87	/* Device not a stream */
+
+#define	ENOPKG		92	/* Package not installed */
+
+#define	EILSEQ		116	/* Illegal byte sequence */
+
+/* The following are just random noise.. */
+#define	ECHRNG		44	/* Channel number out of range */
+#define	EL2NSYNC	45	/* Level 2 not synchronized */
+#define	EL3HLT		46	/* Level 3 halted */
+#define	EL3RST		47	/* Level 3 reset */
+#define	ELNRNG		48	/* Link number out of range */
+#define	EUNATCH		49	/* Protocol driver not attached */
+#define	ENOCSI		50	/* No CSI structure available */
+#define	EL2HLT		51	/* Level 2 halted */
+#define	EBADE		52	/* Invalid exchange */
+#define	EBADR		53	/* Invalid request descriptor */
+#define	EXFULL		54	/* Exchange full */
+#define	ENOANO		55	/* No anode */
+#define	EBADRQC		56	/* Invalid request code */
+#define	EBADSLT		57	/* Invalid slot */
+#define	EDEADLOCK	58	/* File locking deadlock error */
+#define	EBFONT		59	/* Bad font file format */
+#define	ENONET		64	/* Machine is not on the network */
+#define	ENOLINK		67	/* Link has been severed */
+#define	EADV		68	/* Advertise error */
+#define	ESRMNT		69	/* Srmount error */
+#define	ECOMM		70	/* Communication error on send */
+#define	EMULTIHOP	72	/* Multihop attempted */
+#define	EDOTDOT		73	/* RFS specific error */
+#define	EOVERFLOW	75	/* Value too large for defined data type */
+#define	ENOTUNIQ	76	/* Name not unique on network */
+#define	EBADFD		77	/* File descriptor in bad state */
+#define	EREMCHG		78	/* Remote address changed */
+#define	ELIBACC		79	/* Can not access a needed shared library */
+#define	ELIBBAD		80	/* Accessing a corrupted shared library */
+#define	ELIBSCN		81	/* .lib section in a.out corrupted */
+#define	ELIBMAX		82	/* Attempting to link in too many shared libraries */
+#define	ELIBEXEC	83	/* Cannot exec a shared library directly */
+#define	ERESTART	85	/* Interrupted system call should be restarted */
+#define	ESTRPIPE	86	/* Streams pipe error */
+#define	EUCLEAN		117	/* Structure needs cleaning */
+#define	ENOTNAM		118	/* Not a XENIX named type file */
+#define	ENAVAIL		119	/* No XENIX semaphores available */
+#define	EISNAM		120	/* Is a named type file */
+#define	EREMOTEIO	121	/* Remote I/O error */
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/fcntl.h linux/include/asm-ppc/fcntl.h
--- v1.3.44/linux/include/asm-ppc/fcntl.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/fcntl.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,64 @@
+#ifndef _PPC_FCNTL_H
+#define _PPC_FCNTL_H
+
+/* open/fcntl - O_SYNC is only implemented on blocks devices and on files
+   located on an ext2 file system */
+#define O_ACCMODE	  0003
+#define O_RDONLY	    00
+#define O_WRONLY	    01
+#define O_RDWR		    02
+#define O_CREAT		  0100	/* not fcntl */
+#define O_EXCL		  0200	/* not fcntl */
+#define O_NOCTTY	  0400	/* not fcntl */
+#define O_TRUNC		 01000	/* not fcntl */
+#define O_APPEND	 02000
+#define O_NONBLOCK	 04000
+#define O_NDELAY	O_NONBLOCK
+#define O_SYNC		010000
+#define FASYNC		020000	/* fcntl, for BSD compatibility */
+
+#define F_DUPFD		0	/* dup */
+#define F_GETFD		1	/* get f_flags */
+#define F_SETFD		2	/* set f_flags */
+#define F_GETFL		3	/* more flags (cloexec) */
+#define F_SETFL		4
+#define F_GETLK		5
+#define F_SETLK		6
+#define F_SETLKW	7
+
+#define F_SETOWN	8	/*  for sockets. */
+#define F_GETOWN	9	/*  for sockets. */
+
+/* for F_[GET|SET]FL */
+#define FD_CLOEXEC	1	/* actually anything with low bit set goes */
+
+/* for posix fcntl() and lockf() */
+#define F_RDLCK		0
+#define F_WRLCK		1
+#define F_UNLCK		2
+
+/* for old implementation of bsd flock () */
+#define F_EXLCK		4	/* or 3 */
+#define F_SHLCK		8	/* or 4 */
+
+/* operations for bsd flock(), also used by the kernel implementation */
+#define LOCK_SH		1	/* shared lock */
+#define LOCK_EX		2	/* exclusive lock */
+#define LOCK_NB		4	/* or'd with one of the above to prevent
+				   blocking */
+#define LOCK_UN		8	/* remove lock */
+
+#ifdef __KERNEL__
+#define F_POSIX		1
+#define F_FLOCK		2
+#endif /* __KERNEL__ */
+
+struct flock {
+	short l_type;
+	short l_whence;
+	off_t l_start;
+	off_t l_len;
+	pid_t l_pid;
+};
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/io.h linux/include/asm-ppc/io.h
--- v1.3.44/linux/include/asm-ppc/io.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/io.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,86 @@
+#ifndef _PPC_IO_H
+#define _PPC_IO_H
+
+/* Define the particulars of outb/outw/outl "instructions" */
+
+#define SLOW_DOWN_IO
+
+#ifndef PCI_DRAM_OFFSET
+#define PCI_DRAM_OFFSET  0x80000000
+#endif
+#ifndef KERNELBASE
+#define KERNELBASE 0x90000000
+#endif
+
+/*
+ * The PCI bus is inherently Little-Endian.  The PowerPC is being
+ * run Big-Endian.  Thus all values which cross the [PCI] barrier
+ * must be endian-adjusted.  Also, the local DRAM has a different
+ * address from the PCI point of view, thus buffer addresses also
+ * have to be modified [mapped] appropriately.
+ */
+extern inline unsigned long virt_to_bus(volatile void * address)
+{
+        if (address == (void *)0) return 0;
+        return ((unsigned long)((long)address - KERNELBASE + PCI_DRAM_OFFSET));
+}
+
+extern inline void * bus_to_virt(unsigned long address)
+{
+        if (address == 0) return 0;
+        return ((void *)(address - PCI_DRAM_OFFSET + KERNELBASE));
+}
+/* #define virt_to_bus(a) ((unsigned long)(((char *)a==(char *) 0) ? ((char *)0) \
+			: ((char *)((long)a - KERNELBASE + PCI_DRAM_OFFSET))))
+#define bus_to_virt(a) ((void *) (((char *)a==(char *)0) ? ((char *)0) \
+			: ((char *)((long)a - PCI_DRAM_OFFSET + KERNELBASE))))
+*/
+
+#define readb(addr) (*(volatile unsigned char *) (addr))
+#define readw(addr) (*(volatile unsigned short *) (addr))
+#define readl(addr) (*(volatile unsigned int *) (addr))
+
+#define writeb(b,addr) ((*(volatile unsigned char *) (addr)) = (b))
+#define writew(b,addr) ((*(volatile unsigned short *) (addr)) = (b))
+#define writel(b,addr) ((*(volatile unsigned int *) (addr)) = (b))
+
+/*
+ * Change virtual addresses to physical addresses and vv.
+ * These are trivial on the 1:1 Linux/i386 mapping (but if we ever
+ * make the kernel segment mapped at 0, we need to do translation
+ * on the i386 as well)
+ */
+extern inline unsigned long virt_to_phys(volatile void * address)
+{
+	return (unsigned long) address;
+}
+
+extern inline void * phys_to_virt(unsigned long address)
+{
+	return (void *) address;
+}
+
+/* from arch/ppc/kernel/port_io.c
+ *               -- Cort
+ */
+unsigned char inb(int port);
+unsigned short inw(int port);
+unsigned long inl(int port);
+unsigned char outb(unsigned char val,int port);
+unsigned short outw(unsigned short val,int port);
+unsigned long outl(unsigned long val,int port);
+void outsl(int port, long *ptr, int len);
+
+static inline unsigned char  inb_p(int port) {return (inb(port)); }
+static inline unsigned short inw_p(int port) {return (inw(port)); }
+static inline unsigned long  inl_p(int port) {return (inl(port)); }
+
+
+
+static inline unsigned char  outb_p(unsigned char val,int port) { return (outb(val,port)); }
+static inline unsigned short outw_p(unsigned short val,int port) { return (outw(val,port)); }
+static inline unsigned long  outl_p(unsigned long val,int port) { return (outl(val,port)); }
+
+
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/ioctl.h linux/include/asm-ppc/ioctl.h
--- v1.3.44/linux/include/asm-ppc/ioctl.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/ioctl.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,52 @@
+#ifndef _PPC_IOCTL_H
+#define _PPC_IOCTL_H
+
+
+/*
+ * this was copied from the alpha as it's a bit cleaner there.
+ *                         -- Cort
+ */
+
+#define _IOC_NRBITS	8
+#define _IOC_TYPEBITS	8
+#define _IOC_SIZEBITS	13
+#define _IOC_DIRBITS	3
+
+#define _IOC_NRMASK	((1 << _IOC_NRBITS)-1)
+#define _IOC_TYPEMASK	((1 << _IOC_TYPEBITS)-1)
+#define _IOC_SIZEMASK	((1 << _IOC_SIZEBITS)-1)
+#define _IOC_DIRMASK	((1 << _IOC_DIRBITS)-1)
+
+#define _IOC_NRSHIFT	0
+#define _IOC_TYPESHIFT	(_IOC_NRSHIFT+_IOC_NRBITS)
+#define _IOC_SIZESHIFT	(_IOC_TYPESHIFT+_IOC_TYPEBITS)
+#define _IOC_DIRSHIFT	(_IOC_SIZESHIFT+_IOC_SIZEBITS)
+
+/*
+ * Direction bits _IOC_NONE could be 0, but OSF/1 gives it a bit.
+ * And this turns out useful to catch old ioctl numbers in header
+ * files for us.
+ */
+#define _IOC_NONE	1U
+#define _IOC_READ	2U
+#define _IOC_WRITE	4U
+
+#define _IOC(dir,type,nr,size) \
+	(((dir)  << _IOC_DIRSHIFT) | \
+	 ((type) << _IOC_TYPESHIFT) | \
+	 ((nr)   << _IOC_NRSHIFT) | \
+	 ((size) << _IOC_SIZESHIFT))
+
+/* used to create numbers */
+#define _IO(type,nr)		_IOC(_IOC_NONE,(type),(nr),0)
+#define _IOR(type,nr,size)	_IOC(_IOC_READ,(type),(nr),sizeof(size))
+#define _IOW(type,nr,size)	_IOC(_IOC_WRITE,(type),(nr),sizeof(size))
+#define _IOWR(type,nr,size)	_IOC(_IOC_READ|_IOC_WRITE,(type),(nr),sizeof(size))
+
+/* used to decode them.. */
+#define _IOC_DIR(nr)		(((nr) >> _IOC_DIRSHIFT) & _IOC_DIRMASK)
+#define _IOC_TYPE(nr)		(((nr) >> _IOC_TYPESHIFT) & _IOC_TYPEMASK)
+#define _IOC_NR(nr)		(((nr) >> _IOC_NRSHIFT) & _IOC_NRMASK)
+#define _IOC_SIZE(nr)		(((nr) >> _IOC_SIZESHIFT) & _IOC_SIZEMASK)
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/irq.h linux/include/asm-ppc/irq.h
--- v1.3.44/linux/include/asm-ppc/irq.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/irq.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,15 @@
+#ifndef _ASM_IRQ_H
+#define _ASM_IRQ_H
+
+
+/*
+ * wild guess here.  someone should go look and put
+ * the right number in.
+ *                      -- Cort
+ */
+# define NR_IRQS	16
+
+extern void disable_irq(unsigned int);
+extern void enable_irq(unsigned int);
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/mman.h linux/include/asm-ppc/mman.h
--- v1.3.44/linux/include/asm-ppc/mman.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/mman.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,23 @@
+#ifndef __PPC_MMAN_H__
+#define __PPC_MMAN_H__
+
+#define PROT_READ	0x1		/* page can be read */
+#define PROT_WRITE	0x2		/* page can be written */
+#define PROT_EXEC	0x4		/* page can be executed */
+#define PROT_NONE	0x0		/* page can not be accessed */
+
+#define MAP_SHARED	0x01		/* Share changes */
+#define MAP_PRIVATE	0x02		/* Changes are private */
+#define MAP_TYPE	0x0f		/* Mask for type of mapping */
+#define MAP_FIXED	0x10		/* Interpret addr exactly */
+#define MAP_ANONYMOUS	0x20		/* don't use a file */
+
+#define MAP_GROWSDOWN	0x0100		/* stack-like segment */
+#define MAP_DENYWRITE	0x0800		/* ETXTBSY */
+#define MAP_EXECUTABLE	0x1000		/* mark it as a executable */
+
+#define MS_ASYNC	1		/* sync memory asynchronously */
+#define MS_INVALIDATE	2		/* invalidate the caches */
+#define MS_SYNC		4		/* synchronous memory sync */
+
+#endif /* __I386_MMAN_H__ */
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/mmu.h linux/include/asm-ppc/mmu.h
--- v1.3.44/linux/include/asm-ppc/mmu.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/mmu.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,152 @@
+/*
+ * PowerPC memory management structures
+ */
+
+#ifndef _PPC_MMU_H_
+#define _PPC_MMU_H_
+
+/* Hardware Page Table Entry */
+ 
+typedef struct _PTE
+   {
+      unsigned long v:1;	/* Entry is valid */
+      unsigned long vsid:24;	/* Virtual segment identifier */
+      unsigned long h:1;	/* Hash algorithm indicator */
+      unsigned long api:6;	/* Abbreviated page index */
+      unsigned long rpn:20;	/* Real (physical) page number */
+      unsigned long    :3;	/* Unused */
+      unsigned long r:1;	/* Referenced */
+      unsigned long c:1;	/* Changed */
+      unsigned long w:1;	/* Write-thru cache mode */
+      unsigned long i:1;	/* Cache inhibited */
+      unsigned long m:1;	/* Memory coherence */
+      unsigned long g:1;	/* Guarded */
+      unsigned long    :1;	/* Unused */
+      unsigned long pp:2;	/* Page protection */
+   } PTE; 
+
+/* Values for PP (assumes Ks=0, Kp=1) */
+#define PP_RWXX	0	/* Supervisor read/write, User none */
+#define PP_RWRX 1	/* Supervisor read/write, User read */
+#define PP_RWRW 2	/* Supervisor read/write, User read/write */
+
+/* Segment Register */
+
+typedef struct _SEGREG
+   {
+      unsigned long t:1;	/* Normal or I/O  type */
+      unsigned long ks:1;	/* Supervisor 'key' (normally 0) */
+      unsigned long kp:1;	/* User 'key' (normally 1) */
+      unsigned long n:1;	/* No-execute */
+      unsigned long :4;		/* Unused */
+      unsigned long vsid:24;	/* Virtual Segment Identifier */
+   } SEGREG;
+
+/* Block Address Translation (BAT) Registers */
+
+typedef struct _BATU		/* Upper part of BAT */
+   {
+      unsigned long bepi:15;	/* Effective page index (virtual address) */
+      unsigned long :4;		/* Unused */
+      unsigned long bl:11;	/* Block size mask */
+      unsigned long vs:1;	/* Supervisor valid */
+      unsigned long vp:1;	/* User valid */
+   } BATU;   
+
+typedef struct _BATL		/* Lower part of BAT */
+   {
+      unsigned long brpn:15;	/* Real page index (physical address) */
+      unsigned long :10;	/* Unused */
+      unsigned long w:1;	/* Write-thru cache */
+      unsigned long i:1;	/* Cache inhibit */
+      unsigned long m:1;	/* Memory coherence */
+      unsigned long g:1;	/* Guarded (MBZ) */
+      unsigned long :1;		/* Unused */
+      unsigned long pp:2;	/* Page access protections */
+   } BATL;
+
+typedef struct _BAT
+   {
+      BATU batu;		/* Upper register */
+      BATL batl;		/* Lower register */
+   } BAT;
+
+/* Block size masks */
+#define BL_128K	0x000
+#define BL_256K 0x001
+#define BL_512K 0x003
+#define BL_1M   0x007
+#define BL_2M   0x00F
+#define BL_4M   0x01F
+#define BL_8M   0x03F
+#define BL_16M  0x07F
+#define BL_32M  0x0FF
+#define BL_64M  0x1FF
+#define BL_128M 0x3FF
+#define BL_256M 0x7FF
+
+/* BAT Access Protection */
+#define BPP_XX	0x00		/* No access */
+#define BPP_RX	0x01		/* Read only */
+#define BPP_RW	0x02		/* Read/write */
+
+/*
+ * Simulated two-level MMU.  This structure is used by the kernel
+ * to keep track of MMU mappings and is used to update/maintain
+ * the hardware HASH table which is really a cache of mappings.
+ *
+ * The simulated structures mimic the hardware available on other
+ * platforms, notably the 80x86 and 680x0.
+ */
+
+typedef struct _pte
+   {
+   	unsigned long page_num:20;
+   	unsigned long flags:12;		/* Page flags (with some unused bits) */
+   } pte;
+
+#define PD_SHIFT (10+12)		/* Page directory */
+#define PD_MASK  0x02FF
+#define PT_SHIFT (12)			/* Page Table */
+#define PT_MASK  0x02FF
+#define PG_SHIFT (12)			/* Page Entry */
+ 
+
+/* MMU context */
+
+typedef struct _MMU_context
+   {
+      SEGREG	segs[16];	/* Segment registers */
+      pte	**pmap;		/* Two-level page-map structure */
+   } MMU_context;
+
+#if 0
+BAT	ibat[4];	/* Instruction BAT images */
+BAT	dbat[4];	/* Data BAT images */
+PTE	*hash_table;	/* Hardware hashed page table */
+int	hash_table_size;
+int	hash_table_mask;
+unsigned long sdr;	/* Hardware image of SDR */
+#endif   
+
+/* Used to set up SDR register */
+#define HASH_TABLE_SIZE_64K	0x00010000
+#define HASH_TABLE_SIZE_128K	0x00020000
+#define HASH_TABLE_SIZE_256K	0x00040000
+#define HASH_TABLE_SIZE_512K	0x00080000
+#define HASH_TABLE_SIZE_1M	0x00100000
+#define HASH_TABLE_SIZE_2M	0x00200000
+#define HASH_TABLE_SIZE_4M	0x00400000
+#define HASH_TABLE_MASK_64K	0x000   
+#define HASH_TABLE_MASK_128K	0x001   
+#define HASH_TABLE_MASK_256K	0x003   
+#define HASH_TABLE_MASK_512K	0x007
+#define HASH_TABLE_MASK_1M	0x00F   
+#define HASH_TABLE_MASK_2M	0x01F   
+#define HASH_TABLE_MASK_4M	0x03F   
+
+#define MMU_PAGE_SIZE	4096
+
+extern int MMU_hash_page(struct thread_struct *tss, unsigned long va, pte *pg);
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/page.h linux/include/asm-ppc/page.h
--- v1.3.44/linux/include/asm-ppc/page.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/page.h	Sun Nov 26 10:48:54 1995
@@ -0,0 +1,88 @@
+#ifndef _PPC_PAGE_H
+#define _PPC_PAGE_H
+
+/* PAGE_SHIFT determines the page size */
+#define PAGE_SHIFT	12
+#define PAGE_SIZE	(1UL << PAGE_SHIFT)
+#define PAGE_MASK	(~(PAGE_SIZE-1))
+
+void invalidate(void);
+
+#ifdef __KERNEL__
+
+#define STRICT_MM_TYPECHECKS
+
+#ifdef STRICT_MM_TYPECHECKS
+/*
+ * These are used to make use of C type-checking..
+ */
+typedef struct { unsigned long pte; } pte_t;
+typedef struct { unsigned long pmd; } pmd_t;
+typedef struct { unsigned long pgd; } pgd_t;
+typedef struct { unsigned long pgprot; } pgprot_t;
+
+#define pte_val(x)	((x).pte)
+#define pmd_val(x)	((x).pmd)
+#define pgd_val(x)	((x).pgd)
+#define pgprot_val(x)	((x).pgprot)
+
+#define __pte(x)	((pte_t) { (x) } )
+#define __pmd(x)	((pmd_t) { (x) } )
+#define __pgd(x)	((pgd_t) { (x) } )
+#define __pgprot(x)	((pgprot_t) { (x) } )
+
+#else
+/*
+ * .. while these make it easier on the compiler
+ */
+typedef unsigned long pte_t;
+typedef unsigned long pmd_t;
+typedef unsigned long pgd_t;
+typedef unsigned long pgprot_t;
+
+#define pte_val(x)	(x)
+#define pmd_val(x)	(x)
+#define pgd_val(x)	(x)
+#define pgprot_val(x)	(x)
+
+#define __pte(x)	(x)
+#define __pmd(x)	(x)
+#define __pgd(x)	(x)
+#define __pgprot(x)	(x)
+
+#endif
+
+/* to align the pointer to the (next) page boundary */
+#define PAGE_ALIGN(addr)	(((addr)+PAGE_SIZE-1)&PAGE_MASK)
+
+/* This handles the memory map.. */
+
+#define KERNELBASE	0x90000000
+#define PAGE_OFFSET	KERNELBASE
+#define MAP_NR(addr)	((((unsigned long)addr) - PAGE_OFFSET) >> PAGE_SHIFT)
+#define MAP_PAGE_RESERVED	(1<<15)
+
+
+/*
+ * This used to be an unsigned short...
+ * 
+ *                         -- Cort
+ */
+/*typedef unsigned short mem_map_t;*/
+
+typedef struct {
+	unsigned count:30,
+		 dirty:1,
+		 reserved:1;
+} mem_map_t;
+
+/* Certain architectures need to do special things when pte's
+ * within a page table are directly modified.  Thus, the following
+ * hook is made available.
+ */
+#define set_pte(pteptr, pteval) ((*(pteptr)) = (pteval))
+
+
+#endif /* __KERNEL__ */
+
+#endif /* _PPC_PAGE_H */
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/param.h linux/include/asm-ppc/param.h
--- v1.3.44/linux/include/asm-ppc/param.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/param.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,20 @@
+#ifndef _ASM_PPC_PARAM_H
+#define _ASM_PPC_PARAM_H
+
+#ifndef HZ
+#define HZ 100
+#endif
+
+#define EXEC_PAGESIZE	4096
+
+#ifndef NGROUPS
+#define NGROUPS		32
+#endif
+
+#ifndef NOGROUP
+#define NOGROUP		(-1)
+#endif
+
+#define MAXHOSTNAMELEN	64	/* max length of hostname */
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/pgtable.h linux/include/asm-ppc/pgtable.h
--- v1.3.44/linux/include/asm-ppc/pgtable.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/pgtable.h	Sat Nov 25 19:52:45 1995
@@ -0,0 +1,505 @@
+/* * Last edited: Nov  7 23:44 1995 (cort) */
+#ifndef _PPC_PGTABLE_H
+#define _PPC_PGTABLE_H
+
+#include <asm/page.h>
+#include <asm/mmu.h>
+
+/*
+ * Memory management on the PowerPC is a software emulation of the i386
+ * MMU folded onto the PowerPC hardware MMU.  The emulated version looks
+ * and behaves like the two-level i386 MMU.  Entries from these tables
+ * are merged into the PowerPC hashed MMU tables, on demand, treating the
+ * hashed tables like a special cache.
+ *
+ * Since the PowerPC does not have separate kernel and user address spaces,
+ * the user virtual address space must be a [proper] subset of the kernel
+ * space.  Thus, all tasks will have a specific virtual mapping for the
+ * user virtual space and a common mapping for the kernel space.  The
+ * simplest way to split this was literally in half.  Also, life is so
+ * much simpler for the kernel if the machine hardware resources are
+ * always mapped in.  Thus, some additional space is given up to the
+ * kernel space to accomodate this.
+ *
+ * CAUTION! Some of the trade-offs make sense for the PreP platform on
+ * which this code was originally developed.  When it migrates to other
+ * PowerPC environments, some of the assumptions may fail and the whole
+ * setup may need to be reevaluated.
+ *
+ * On the PowerPC, page translations are kept in a hashed table.  There
+ * is exactly one of these tables [although the architecture supports
+ * an arbitrary number].  Page table entries move in/out of this hashed
+ * structure on demand, with the kernel filling in entries as they are
+ * needed.  Just where a page table entry hits in the hashed table is a
+ * function of the hashing which is in turn based on the upper 4 bits
+ * of the logical address.  These 4 bits address a "virtual segment id"
+ * which is unique per task/page combination for user addresses and
+ * fixed for the kernel addresses.  Thus, the kernel space can be simply
+ * shared [indeed at low overhead] amoung all tasks.
+ *
+ * The basic virtual address space is thus:
+ *
+ * 0x0XXXXXX  --+
+ * 0x1XXXXXX    |
+ * 0x2XXXXXX    |  User address space. 
+ * 0x3XXXXXX    |
+ * 0x4XXXXXX    |
+ * 0x5XXXXXX    |
+ * 0x6XXXXXX    |
+ * 0x7XXXXXX  --+
+ * 0x8XXXXXX       PCI/ISA I/O space
+ * 0x9XXXXXX  --+
+ * 0xAXXXXXX    |  Kernel virtual memory
+ * 0xBXXXXXX  --+
+ * 0xCXXXXXX       PCI/ISA Memory space
+ * 0xDXXXXXX
+ * 0xEXXXXXX
+ * 0xFXXXXXX       Board I/O space
+ *
+ * CAUTION!  One of the real problems here is keeping the software
+ * managed tables coherent with the hardware hashed tables.  When
+ * the software decides to update the table, it's normally easy to
+ * update the hardware table.  But when the hardware tables need
+ * changed, e.g. as the result of a page fault, it's more difficult
+ * to reflect those changes back into the software entries.  Currently,
+ * this process is quite crude, with updates causing the entire set
+ * of tables to become invalidated.  Some performance could certainly
+ * be regained by improving this.
+ *
+ * The Linux memory management assumes a three-level page table setup. On
+ * the i386, we use that, but "fold" the mid level into the top-level page
+ * table, so that we physically have the same two-level page table as the
+ * i386 mmu expects.
+ *
+ * This file contains the functions and defines necessary to modify and use
+ * the i386 page table tree.
+ */
+
+/* PMD_SHIFT determines the size of the area a second-level page table can map */
+#define PMD_SHIFT	22
+#define PMD_SIZE	(1UL << PMD_SHIFT)
+#define PMD_MASK	(~(PMD_SIZE-1))
+
+/* PGDIR_SHIFT determines what a third-level page table entry can map */
+#define PGDIR_SHIFT	22
+#define PGDIR_SIZE	(1UL << PGDIR_SHIFT)
+#define PGDIR_MASK	(~(PGDIR_SIZE-1))
+
+/*
+ * entries per page directory level: the i386 is two-level, so
+ * we don't really have any PMD directory physically.
+ */
+#define PTRS_PER_PTE	1024
+#define PTRS_PER_PMD	1
+#define PTRS_PER_PGD	1024
+
+/* Just any arbitrary offset to the start of the vmalloc VM area: the
+ * current 8MB value just means that there will be a 8MB "hole" after the
+ * physical memory until the kernel virtual memory starts.  That means that
+ * any out-of-bounds memory accesses will hopefully be caught.
+ * The vmalloc() routines leaves a hole of 4kB between each vmalloced
+ * area for the same reason. ;)
+ */
+#define VMALLOC_OFFSET	(8*1024*1024)
+#define VMALLOC_START ((high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1))
+#define VMALLOC_VMADDR(x) ((unsigned long)(x))
+
+#define _PAGE_PRESENT	0x001
+#define _PAGE_RW	0x002
+#define _PAGE_USER	0x004
+#define _PAGE_PCD	0x010
+#define _PAGE_ACCESSED	0x020
+#define _PAGE_DIRTY	0x040
+#define _PAGE_COW	0x200	/* implemented in software (one of the AVL bits) */
+
+#define _PAGE_TABLE	(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED | _PAGE_DIRTY)
+#define _PAGE_CHG_MASK	(PAGE_MASK | _PAGE_ACCESSED | _PAGE_DIRTY)
+
+#define PAGE_NONE	__pgprot(_PAGE_PRESENT | _PAGE_ACCESSED)
+#define PAGE_SHARED	__pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_USER | _PAGE_ACCESSED)
+#define PAGE_COPY	__pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED | _PAGE_COW)
+#define PAGE_READONLY	__pgprot(_PAGE_PRESENT | _PAGE_USER | _PAGE_ACCESSED)
+#define PAGE_KERNEL	__pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY | _PAGE_ACCESSED)
+
+/*
+ * The i386 can't do page protection for execute, and considers that the same are read.
+ * Also, write permissions imply read permissions. This is the closest we can get..
+ */
+#define __P000	PAGE_NONE
+#define __P001	PAGE_READONLY
+#define __P010	PAGE_COPY
+#define __P011	PAGE_COPY
+#define __P100	PAGE_READONLY
+#define __P101	PAGE_READONLY
+#define __P110	PAGE_COPY
+#define __P111	PAGE_COPY
+
+#define __S000	PAGE_NONE
+#define __S001	PAGE_READONLY
+#define __S010	PAGE_SHARED
+#define __S011	PAGE_SHARED
+#define __S100	PAGE_READONLY
+#define __S101	PAGE_READONLY
+#define __S110	PAGE_SHARED
+#define __S111	PAGE_SHARED
+
+/*
+ * Define this if things work differently on a i386 and a i486:
+ * it will (on a i486) warn about kernel memory accesses that are
+ * done without a 'verify_area(VERIFY_WRITE,..)'
+ */
+#undef CONFIG_TEST_VERIFY_AREA
+
+/* page table for 0-4MB for everybody */
+extern unsigned long pg0[1024];
+
+/*
+ * BAD_PAGETABLE is used when we need a bogus page-table, while
+ * BAD_PAGE is used for a bogus page.
+ *
+ * ZERO_PAGE is a global shared page that is always zero: used
+ * for zero-mapped memory areas etc..
+ */
+extern pte_t __bad_page(void);
+extern pte_t * __bad_pagetable(void);
+
+extern unsigned long __zero_page(void);
+
+#define BAD_PAGETABLE __bad_pagetable()
+#define BAD_PAGE __bad_page()
+#define ZERO_PAGE __zero_page()
+
+/* number of bits that fit into a memory pointer */
+#define BITS_PER_PTR			(8*sizeof(unsigned long))
+
+/* to align the pointer to a pointer address */
+#define PTR_MASK			(~(sizeof(void*)-1))
+
+/* sizeof(void*)==1<<SIZEOF_PTR_LOG2 */
+/* 64-bit machines, beware!  SRB. */
+#define SIZEOF_PTR_LOG2			2
+
+/* to find an entry in a page-table */
+#define PAGE_PTR(address) \
+((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK)
+
+/* to set the page-dir */
+/* tsk is a task_struct and pgdir is a pte_t */
+#define SET_PAGE_DIR(tsk,pgdir) \
+do { \
+	(tsk)->tss.pg_tables = (unsigned long *)(pgdir); \
+	if ((tsk) == current) \
+	{ \
+/*_printk("Change page tables = %x\n", pgdir);*/ \
+	} \
+} while (0)
+
+extern unsigned long high_memory;
+
+extern inline int pte_none(pte_t pte)		{ return !pte_val(pte); }
+extern inline int pte_present(pte_t pte)	{ return pte_val(pte) & _PAGE_PRESENT; }
+extern inline int pte_inuse(pte_t *ptep)	{ return mem_map[MAP_NR(ptep)].reserved; }
+/*extern inline int pte_inuse(pte_t *ptep)	{ return mem_map[MAP_NR(ptep)] != 1; }*/
+extern inline void pte_clear(pte_t *ptep)	{ pte_val(*ptep) = 0; }
+extern inline void pte_reuse(pte_t * ptep)
+{
+	if (!mem_map[MAP_NR(ptep)].reserved)
+		mem_map[MAP_NR(ptep)].count++;
+}
+/*
+   extern inline void pte_reuse(pte_t * ptep)
+{
+	if (!(mem_map[MAP_NR(ptep)] & MAP_PAGE_RESERVED))
+		mem_map[MAP_NR(ptep)]++;
+}
+*/
+extern inline int pmd_none(pmd_t pmd)		{ return !pmd_val(pmd); }
+extern inline int pmd_bad(pmd_t pmd)		{ return (pmd_val(pmd) & ~PAGE_MASK) != _PAGE_TABLE; }
+extern inline int pmd_present(pmd_t pmd)	{ return pmd_val(pmd) & _PAGE_PRESENT; }
+extern inline int pmd_inuse(pmd_t *pmdp)	{ return 0; }
+extern inline void pmd_clear(pmd_t * pmdp)	{ pmd_val(*pmdp) = 0; }
+extern inline void pmd_reuse(pmd_t * pmdp)	{ }
+
+/*
+ * The "pgd_xxx()" functions here are trivial for a folded two-level
+ * setup: the pgd is never bad, and a pmd always exists (as it's folded
+ * into the pgd entry)
+ */
+extern inline int pgd_none(pgd_t pgd)		{ return 0; }
+extern inline int pgd_bad(pgd_t pgd)		{ return 0; }
+extern inline int pgd_present(pgd_t pgd)	{ return 1; }
+/*extern inline int pgd_inuse(pgd_t * pgdp)	{ return mem_map[MAP_NR(pgdp)] != 1; }*/
+extern inline int pgd_inuse(pgd_t *pgdp)	{ return mem_map[MAP_NR(pgdp)].reserved;  }
+extern inline void pgd_clear(pgd_t * pgdp)	{ }
+
+/*
+extern inline void pgd_reuse(pgd_t * pgdp)
+{
+	if (!mem_map[MAP_NR(pgdp)].reserved)
+		mem_map[MAP_NR(pgdp)].count++;
+}
+*/
+
+/*
+ * The following only work if pte_present() is true.
+ * Undefined behaviour if not..
+ */
+extern inline int pte_read(pte_t pte)		{ return pte_val(pte) & _PAGE_USER; }
+extern inline int pte_write(pte_t pte)		{ return pte_val(pte) & _PAGE_RW; }
+extern inline int pte_exec(pte_t pte)		{ return pte_val(pte) & _PAGE_USER; }
+extern inline int pte_dirty(pte_t pte)		{ return pte_val(pte) & _PAGE_DIRTY; }
+extern inline int pte_young(pte_t pte)		{ return pte_val(pte) & _PAGE_ACCESSED; }
+extern inline int pte_cow(pte_t pte)		{ return pte_val(pte) & _PAGE_COW; }
+
+extern inline pte_t pte_wrprotect(pte_t pte)	{ pte_val(pte) &= ~_PAGE_RW; return pte; }
+extern inline pte_t pte_rdprotect(pte_t pte)	{ pte_val(pte) &= ~_PAGE_USER; return pte; }
+extern inline pte_t pte_exprotect(pte_t pte)	{ pte_val(pte) &= ~_PAGE_USER; return pte; }
+extern inline pte_t pte_mkclean(pte_t pte)	{ pte_val(pte) &= ~_PAGE_DIRTY; return pte; }
+extern inline pte_t pte_mkold(pte_t pte)	{ pte_val(pte) &= ~_PAGE_ACCESSED; return pte; }
+extern inline pte_t pte_uncow(pte_t pte)	{ pte_val(pte) &= ~_PAGE_COW; return pte; }
+extern inline pte_t pte_mkwrite(pte_t pte)	{ pte_val(pte) |= _PAGE_RW; return pte; }
+extern inline pte_t pte_mkread(pte_t pte)	{ pte_val(pte) |= _PAGE_USER; return pte; }
+extern inline pte_t pte_mkexec(pte_t pte)	{ pte_val(pte) |= _PAGE_USER; return pte; }
+extern inline pte_t pte_mkdirty(pte_t pte)	{ pte_val(pte) |= _PAGE_DIRTY; return pte; }
+extern inline pte_t pte_mkyoung(pte_t pte)	{ pte_val(pte) |= _PAGE_ACCESSED; return pte; }
+extern inline pte_t pte_mkcow(pte_t pte)	{ pte_val(pte) |= _PAGE_COW; return pte; }
+
+/*
+ * Conversion functions: convert a page and protection to a page entry,
+ * and a page entry and page directory to the page they refer to.
+ */
+extern inline pte_t mk_pte(unsigned long page, pgprot_t pgprot)
+{ pte_t pte; pte_val(pte) = page | 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; }
+
+/*extern inline void pmd_set(pmd_t * pmdp, pte_t * ptep)
+{ pmd_val(*pmdp) = _PAGE_TABLE | ((((unsigned long) ptep) - PAGE_OFFSET) << (32-PAGE_SHIFT)); }
+*/
+extern inline unsigned long pte_page(pte_t pte)
+{ return pte_val(pte) & PAGE_MASK; }
+
+extern inline unsigned long pmd_page(pmd_t pmd)
+{ return pmd_val(pmd) & PAGE_MASK; }
+
+
+/* to find an entry in a page-table-directory */
+extern inline pgd_t * pgd_offset(struct mm_struct * mm, unsigned long address)
+{
+	return mm->pgd + (address >> PGDIR_SHIFT);
+}
+
+/* Find an entry in the second-level page table.. */
+extern inline pmd_t * pmd_offset(pgd_t * dir, unsigned long address)
+{
+	return (pmd_t *) dir;
+}
+
+/* Find an entry in the third-level page table.. */ 
+extern inline pte_t * pte_offset(pmd_t * dir, unsigned long address)
+{
+	return (pte_t *) pmd_page(*dir) + ((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1));
+}
+
+
+/*
+ * Allocate and free page tables. The xxx_kernel() versions are
+ * used to allocate a kernel page table - this turns on ASN bits
+ * if any, and marks the page tables reserved.
+ */
+extern inline void pte_free_kernel(pte_t * pte)
+{
+	mem_map[MAP_NR(pte)].reserved = 1;
+	free_page((unsigned long) pte);
+}
+/*extern inline void pte_free_kernel(pte_t * pte)
+{
+	mem_map[MAP_NR(pte)] = 1;
+	free_page((unsigned long) pte);
+}
+*/
+
+/*
+extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
+{
+	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+	if (pmd_none(*pmd)) {
+		pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
+		if (pmd_none(*pmd)) {
+			if (page) {
+				pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
+				mem_map[MAP_NR(page)] = MAP_PAGE_RESERVED;
+				return page + address;
+			}
+			pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
+			return NULL;
+		}
+		free_page((unsigned long) page);
+	}
+	if (pmd_bad(*pmd)) {
+		printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
+		pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
+		return NULL;
+	}
+	return (pte_t *) pmd_page(*pmd) + address;
+}*/
+/*
+extern inline pte_t * pte_alloc_kernel(pmd_t *pmd, unsigned long address)
+{
+printk("pte_alloc_kernel pmd = %08X, address = %08X\n", pmd, address);
+	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+printk("address now = %08X\n", address);
+	if (pmd_none(*pmd)) {
+		pte_t *page;
+printk("pmd_none(*pmd) true\n");
+		page = (pte_t *) get_free_page(GFP_KERNEL);
+printk("page = %08X after get_free_page(%08X)\n",page,GFP_KERNEL);
+		if (pmd_none(*pmd)) {
+printk("pmd_none(*pmd=%08X) still\n",*pmd);		  
+			if (page) {
+printk("page true = %08X\n",page);			  
+				pmd_set(pmd, page);
+printk("pmd_set(%08X,%08X)\n",pmd,page);			  
+				mem_map[MAP_NR(page)].reserved = 1;
+printk("did mem_map\n",pmd,page);			  
+				return page + address;
+			}
+printk("did pmd_set(%08X, %08X\n",pmd,BAD_PAGETABLE);			  
+			pmd_set(pmd, (pte_t *) BAD_PAGETABLE);
+			return NULL;
+		}
+printk("did free_page(%08X)\n",page);			  		
+		free_page((unsigned long) page);
+	}
+	if (pmd_bad(*pmd)) {
+		printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
+		pmd_set(pmd, (pte_t *) BAD_PAGETABLE);
+		return NULL;
+	}
+printk("returning pmd_page(%08X) + %08X\n",pmd_page(*pmd) , address);	  
+
+	return (pte_t *) pmd_page(*pmd) + address;
+}
+*/
+extern inline pte_t * pte_alloc_kernel(pmd_t * pmd, unsigned long address)
+{
+	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+	if (pmd_none(*pmd)) {
+		pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
+		if (pmd_none(*pmd)) {
+			if (page) {
+/*                                pmd_set(pmd,page);*/
+			pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
+				mem_map[MAP_NR(page)].reserved = 1;
+				return page + address;
+			}
+/*			pmd_set(pmd, BAD_PAGETABLE);*/
+			pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
+			return NULL;
+		}
+		free_page((unsigned long) page);
+	}
+	if (pmd_bad(*pmd)) {
+		printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
+/*		pmd_set(pmd, (pte_t *) BAD_PAGETABLE);		*/
+		pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
+		return NULL;
+	}
+	return (pte_t *) pmd_page(*pmd) + address;
+}
+
+/*
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
+ */
+extern inline void pmd_free_kernel(pmd_t * pmd)
+{
+}
+
+extern inline pmd_t * pmd_alloc_kernel(pgd_t * pgd, unsigned long address)
+{
+	return (pmd_t *) pgd;
+}
+
+extern inline void pte_free(pte_t * pte)
+{
+	free_page((unsigned long) pte);
+}
+
+extern inline pte_t * pte_alloc(pmd_t * pmd, unsigned long address)
+{
+	address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1);
+	if (pmd_none(*pmd)) {
+		pte_t * page = (pte_t *) get_free_page(GFP_KERNEL);
+		if (pmd_none(*pmd)) {
+			if (page) {
+				pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) page;
+				return page + address;
+			}
+			pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
+			return NULL;
+		}
+		free_page((unsigned long) page);
+	}
+	if (pmd_bad(*pmd)) {
+		printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd));
+		pmd_val(*pmd) = _PAGE_TABLE | (unsigned long) BAD_PAGETABLE;
+		return NULL;
+	}
+	return (pte_t *) pmd_page(*pmd) + address;
+}
+
+/*
+ * allocating and freeing a pmd is trivial: the 1-entry pmd is
+ * inside the pgd, so has no extra memory associated with it.
+ */
+extern inline void pmd_free(pmd_t * pmd)
+{
+}
+
+extern inline pmd_t * pmd_alloc(pgd_t * pgd, unsigned long address)
+{
+	return (pmd_t *) pgd;
+}
+
+extern inline void pgd_free(pgd_t * pgd)
+{
+	free_page((unsigned long) pgd);
+}
+
+extern inline pgd_t * pgd_alloc(void)
+{
+	return (pgd_t *) get_free_page(GFP_KERNEL);
+}
+
+extern pgd_t swapper_pg_dir[1024*8];
+/*extern pgd_t *swapper_pg_dir;*/
+
+/*
+ * Software maintained MMU tables may have changed -- update the
+ * hardware [aka cache]
+ */
+extern inline void update_mmu_cache(struct vm_area_struct * vma,
+	unsigned long address, pte_t _pte)
+{
+#if 0
+	printk("Update MMU cache - VMA: %x, Addr: %x, PTE: %x\n", vma, address, *(long *)&_pte);
+	_printk("Update MMU cache - VMA: %x, Addr: %x, PTE: %x\n", vma, address, *(long *)&_pte);
+/*	MMU_hash_page(&(vma->vm_task)->tss, address & PAGE_MASK, (pte *)&_pte);*/
+#endif	
+	MMU_hash_page(&(current)->tss, address & PAGE_MASK, (pte *)&_pte);
+
+}
+
+
+#ifdef _SCHED_INIT_
+#define INIT_MMAP { &init_task, 0, 0x40000000, PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC }
+
+#endif	
+
+#define SWP_TYPE(entry) (((entry) >> 1) & 0x7f)
+#define SWP_OFFSET(entry) ((entry) >> 8)
+#define SWP_ENTRY(type,offset) (((type) << 1) | ((offset) << 8))
+
+#endif /* _PPC_PAGE_H */
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/processor.h linux/include/asm-ppc/processor.h
--- v1.3.44/linux/include/asm-ppc/processor.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/processor.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,120 @@
+#ifndef __ASM_PPC_PROCESSOR_H
+#define __ASM_PPC_PROCESSOR_H
+
+/*
+ * PowerPC machine specifics
+ */
+
+#ifndef _PPC_MACHINE_H_
+#define _PPC_MACHINE_H_ 
+
+/* Bit encodings for Machine State Register (MSR) */
+#define MSR_POW		(1<<18)		/* Enable Power Management */
+#define MSR_TGPR	(1<<17)		/* TLB Update registers in use */
+#define MSR_ILE		(1<<16)		/* Interrupt Little-Endian enable */
+#define MSR_EE		(1<<15)		/* External Interrupt enable */
+#define MSR_PR		(1<<14)		/* Supervisor/User privelege */
+#define MSR_FP		(1<<13)		/* Floating Point enable */
+#define MSR_ME		(1<<12)		/* Machine Check enable */
+#define MSR_FE0		(1<<11)		/* Floating Exception mode 0 */
+#define MSR_SE		(1<<10)		/* Single Step */
+#define MSR_BE		(1<<9)		/* Branch Trace */
+#define MSR_FE1		(1<<8)		/* Floating Exception mode 1 */
+#define MSR_IP		(1<<6)		/* Exception prefix 0x000/0xFFF */
+#define MSR_IR		(1<<5)		/* Instruction MMU enable */
+#define MSR_DR		(1<<4)		/* Data MMU enable */
+#define MSR_RI		(1<<1)		/* Recoverable Exception */
+#define MSR_LE		(1<<0)		/* Little-Endian enable */
+
+#define MSR_		MSR_FP|MSR_FE0|MSR_FE1|MSR_ME
+#define MSR_USER	MSR_|MSR_PR|MSR_EE|MSR_IR|MSR_DR
+
+/* Bit encodings for Hardware Implementation Register (HID0) */
+#define HID0_EMCP	(1<<31)		/* Enable Machine Check pin */
+#define HID0_EBA	(1<<29)		/* Enable Bus Address Parity */
+#define HID0_EBD	(1<<28)		/* Enable Bus Data Parity */
+#define HID0_SBCLK	(1<<27)
+#define HID0_EICE	(1<<26)
+#define HID0_ECLK	(1<<25)
+#define HID0_PAR	(1<<24)
+#define HID0_DOZE	(1<<23)
+#define HID0_NAP	(1<<22)
+#define HID0_SLEEP	(1<<21)
+#define HID0_DPM	(1<<20)
+#define HID0_ICE	(1<<15)		/* Instruction Cache Enable */
+#define HID0_DCE	(1<<14)		/* Data Cache Enable */
+#define HID0_ILOCK	(1<<13)		/* Instruction Cache Lock */
+#define HID0_DLOCK	(1<<12)		/* Data Cache Lock */
+#define HID0_ICFI	(1<<11)		/* Instruction Cache Flash Invalidate */
+#define HID0_DCI	(1<<10)		/* Data Cache Invalidate */
+ 
+#endif
+
+static inline void start_thread(struct pt_regs * regs, unsigned long eip, unsigned long esp)
+{
+  regs->nip = eip;
+  regs->gpr[1] = esp;
+  regs->msr = MSR_USER;
+}
+
+
+/*
+ * Bus types
+ */
+#define EISA_bus 0
+#define EISA_bus__is_a_macro /* for versions in ksyms.c */
+#define MCA_bus 0
+#define MCA_bus__is_a_macro /* for versions in ksyms.c */
+
+/*
+ * Write Protection works right in supervisor mode on the PowerPC
+ */
+
+#define wp_works_ok 1
+#define wp_works_ok__is_a_macro /* for versions in ksyms.c */
+
+/*
+ * User space process size: 2GB. This is hardcoded into a few places,
+ * so don't change it unless you know what you are doing.
+ *
+ * "this is gonna have to change to 1gig for the sparc" - David S. Miller
+ */
+#define TASK_SIZE	(0x80000000UL)
+
+struct thread_struct 
+   {
+   	unsigned long	ksp;		/* Kernel stack pointer */
+	unsigned long	*pg_tables;	/* MMU information */
+	unsigned long	segs[16];	/* MMU Segment registers */
+	unsigned long	last_pc;	/* PC when last entered system */
+	double		fpr[32];	/* Complete floating point set */
+   };
+
+#define INIT_TSS  { \
+	0, 0, 0, \
+	0, 0, 0, \
+	0, 0, 0, \
+}
+
+#define INIT_MMAP { &init_mm, 0, 0x40000000, \
+		      PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC }
+
+
+
+
+/*
+ * Return saved PC of a blocked thread.  This assumes the frame pointer
+ * is the 6th saved long on the kernel stack and that the saved return
+ * address is the first long in the frame.  This all holds provided the
+ * thread blocked through a call to schedule().
+ */
+static inline unsigned long thread_saved_pc(struct thread_struct *t)
+{
+	unsigned long fp;
+
+	fp = ((unsigned long*)t->ksp)[6];
+	return *(unsigned long*)fp;
+}
+
+#endif
+
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/ptrace.h linux/include/asm-ppc/ptrace.h
--- v1.3.44/linux/include/asm-ppc/ptrace.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/ptrace.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,52 @@
+#ifndef _PPC_PTRACE_H
+#define _PPC_PTRACE_H
+
+
+/*
+ * This struct defines the way the registers are stored on the
+ * kernel stack during a system call or other kernel entry.
+ * Note: the "_overhead" and "_underhead" spaces are stack locations
+ * used by called routines.  Because of the way the PowerPC ABI
+ * specifies the function prologue/epilogue, registers can be
+ * saved in stack locations which are below the current stack
+ * pointer (_underhead).  If an interrupt occurs during this
+ * [albeit] small time interval, registers which were saved on
+ * the stack could be trashed by the interrupt save code.  The
+ * "_underhead" leaves a hole just in case this happens.  It also
+ * wastes 80 bytes of stack if it doesn't!  Similarly, the called
+ * routine stores some information "above" the stack pointer before
+ * if gets adjusted.  This is covered by the "_overhead" field
+ * and [thankfully] is not totally wasted.
+ *
+ */
+
+struct pt_regs {
+	unsigned long _overhead[14]; /* Callee's SP,LR,params */
+	unsigned long gpr[32];
+	unsigned long nip;
+	unsigned long msr;
+	unsigned long ctr;
+	unsigned long link;
+	unsigned long ccr;
+	unsigned long xer;
+	unsigned long dar;	/* Fault registers */
+	unsigned long dsisr;
+	unsigned long hash1, hash2;
+	unsigned long imiss, dmiss;
+	unsigned long icmp, dcmp;
+	unsigned long orig_gpr3; /* Used for restarting system calls */
+	unsigned long result;    /* Result of a system call */
+	double        fpr[4];    /* Caution! Only FP0-FP3 save on interrupts */
+	double        fpcsr;
+	unsigned long trap;	/* Reason for being here */
+	unsigned long marker;	/* Should have DEADDEAD */
+	unsigned long _underhead[20]; /* Callee's register save area */
+	unsigned long edx;	/* for binfmt_elf.c which wants edx */
+};
+
+#define instruction_pointer(regs) ((regs)->nip)
+#define user_mode(regs) ((regs)->msr & 0x4000)
+extern void show_regs(struct pt_regs *);
+
+#endif
+
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/resource.h linux/include/asm-ppc/resource.h
--- v1.3.44/linux/include/asm-ppc/resource.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/resource.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,30 @@
+#ifndef _PPC_RESOURCE_H
+#define _PPC_RESOURCE_H
+
+/*
+ * These were swiped from asm-i386 so they don't fit well with the
+ * powerstack very well at all.  Anyone want to go through them and
+ * correct them?
+ *                              -- Cort
+ */
+
+/*
+ * Resource limits
+ */
+
+#define RLIMIT_CPU	0		/* CPU time in ms */
+#define RLIMIT_FSIZE	1		/* Maximum filesize */
+#define RLIMIT_DATA	2		/* max data size */
+#define RLIMIT_STACK	3		/* max stack size */
+#define RLIMIT_CORE	4		/* max core file size */
+#define RLIMIT_RSS	5		/* max resident set size */
+#define RLIMIT_NPROC	6		/* max number of processes */
+#define RLIMIT_NOFILE	7		/* max number of open files */
+
+#ifdef notdef
+#define RLIMIT_MEMLOCK	8		/* max locked-in-memory address space*/
+#endif
+
+#define RLIM_NLIMITS	8
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/segment.h linux/include/asm-ppc/segment.h
--- v1.3.44/linux/include/asm-ppc/segment.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/segment.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,131 @@
+#ifndef _ASM_PPC_SEGMENT_H
+#define _ASM_PPC_SEGMENT_H
+
+#include <linux/string.h>
+
+#define put_user(x,ptr) __put_user((unsigned long)(x),(ptr),sizeof(*(ptr)))
+#define get_user(ptr) ((__typeof__(*(ptr)))__get_user((ptr),sizeof(*(ptr))))
+
+extern int bad_user_access_length(void);
+
+static inline void __put_user(unsigned long x, void * y, int size)
+{
+	switch (size) {
+		case 1:
+			*(char *) y = x;
+			break;
+		case 2:
+			*(short *) y = x;
+			break;
+		case 4:
+			*(int *) y = x;
+			break;
+		case 8:
+			*(long *) y = x;
+			break;
+		default:
+			bad_user_access_length();
+	}
+}
+
+static inline unsigned long __get_user(const void * y, int size)
+{
+	switch (size) {
+		case 1:
+			return *(unsigned char *) y;
+		case 2:
+			return *(unsigned short *) y;
+		case 4:
+			return *(unsigned int *) y;
+		case 8:
+			return *(unsigned long *) y;
+		default:
+			return bad_user_access_length();
+	}
+}
+
+static inline unsigned char get_user_byte(const char * addr)
+{
+	return *addr;
+}
+
+#define get_fs_byte(addr) get_user_byte((char *)(addr))
+
+static inline unsigned short get_user_word(const short *addr)
+{
+	return *addr;
+}
+
+#define get_fs_word(addr) get_user_word((short *)(addr))
+
+static inline unsigned long get_user_long(const int *addr)
+{
+	return *addr;
+}
+
+#define get_fs_long(addr) get_user_long((int *)(addr))
+
+static inline unsigned long get_user_quad(const long *addr)
+{
+	return *addr;
+}
+
+#define get_fs_quad(addr) get_user_quad((long *)(addr))
+
+static inline void put_user_byte(char val,char *addr)
+{
+	*addr = val;
+}
+
+#define put_fs_byte(x,addr) put_user_byte((x),(char *)(addr))
+
+static inline void put_user_word(short val,short * addr)
+{
+	*addr = val;
+}
+
+#define put_fs_word(x,addr) put_user_word((x),(short *)(addr))
+
+static inline void put_user_long(unsigned long val,int * addr)
+{
+	*addr = val;
+}
+
+#define put_fs_long(x,addr) put_user_long((x),(int *)(addr))
+
+static inline void put_user_quad(unsigned long val,long * addr)
+{
+	*addr = val;
+}
+
+#define put_fs_quad(x,addr) put_user_quad((x),(long *)(addr))
+
+#define memcpy_fromfs(to, from, n) memcpy((to),(from),(n))
+
+#define memcpy_tofs(to, from, n) memcpy((to),(from),(n))
+
+/*
+ * For segmented architectures, these are used to specify which segment
+ * to use for the above functions.
+ *
+ * The powerpc is not segmented, so these are just dummies.
+ */
+
+#define KERNEL_DS 0
+#define USER_DS 1
+
+static inline unsigned long get_fs(void)
+{
+	return 0;
+}
+
+static inline unsigned long get_ds(void)
+{
+	return 0;
+}
+
+static inline void set_fs(unsigned long val)
+{
+}
+
+#endif /* _ASM_SEGMENT_H */
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/shmparam.h linux/include/asm-ppc/shmparam.h
--- v1.3.44/linux/include/asm-ppc/shmparam.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/shmparam.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,44 @@
+#ifndef _PPC_SHMPARAM_H
+#define _PPC_SHMPARAM_H
+
+/* address range for shared memory attaches if no address passed to shmat() */
+#define SHM_RANGE_START	0x50000000
+#define SHM_RANGE_END	0x60000000
+
+/*
+ * Format of a swap-entry for shared memory pages currently out in
+ * swap space (see also mm/swap.c).
+ *
+ * SWP_TYPE = SHM_SWP_TYPE
+ * SWP_OFFSET is used as follows:
+ *
+ *  bits 0..6 : id of shared memory segment page belongs to (SHM_ID)
+ *  bits 7..21: index of page within shared memory segment (SHM_IDX)
+ *		(actually fewer bits get used since SHMMAX is so low)
+ */
+
+/*
+ * Keep _SHM_ID_BITS as low as possible since SHMMNI depends on it and
+ * there is a static array of size SHMMNI.
+ */
+#define _SHM_ID_BITS	7
+#define SHM_ID_MASK	((1<<_SHM_ID_BITS)-1)
+
+#define SHM_IDX_SHIFT	(_SHM_ID_BITS)
+#define _SHM_IDX_BITS	15
+#define SHM_IDX_MASK	((1<<_SHM_IDX_BITS)-1)
+
+/*
+ * _SHM_ID_BITS + _SHM_IDX_BITS must be <= 24 on the i386 and
+ * SHMMAX <= (PAGE_SIZE << _SHM_IDX_BITS).
+ */
+
+#define SHMMAX 0x3fa000			/* max shared seg size (bytes) */
+#define SHMMIN 1 /* really PAGE_SIZE */	/* min shared seg size (bytes) */
+#define SHMMNI (1<<_SHM_ID_BITS)	/* max num of segs system wide */
+#define SHMALL				/* max shm system wide (pages) */ \
+	(1<<(_SHM_IDX_BITS+_SHM_ID_BITS))
+#define	SHMLBA PAGE_SIZE		/* attach addr a multiple of this */
+#define SHMSEG SHMMNI			/* max shared segs per process */
+
+#endif /* _PPC_SHMPARAM_H */
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/sigcontext.h linux/include/asm-ppc/sigcontext.h
--- v1.3.44/linux/include/asm-ppc/sigcontext.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/sigcontext.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,15 @@
+#ifndef _ASM_PPC_SIGCONTEXT_H
+#define _ASM_PPC_SIGCONTEXT_H
+
+#include <asm/ptrace.h>
+
+
+struct sigcontext_struct {
+	unsigned long	_unused[4];
+	int		signal;
+	unsigned long	handler;
+	unsigned long	oldmask;
+	struct pt_regs 	*regs;
+};
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/signal.h linux/include/asm-ppc/signal.h
--- v1.3.44/linux/include/asm-ppc/signal.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/signal.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,85 @@
+#ifndef _ASMPPC_SIGNAL_H
+#define _ASMPPC_SIGNAL_H
+
+typedef unsigned long sigset_t;		/* at least 32 bits */
+
+#define _NSIG             32
+#define NSIG		_NSIG
+
+#define SIGHUP		 1
+#define SIGINT		 2
+#define SIGQUIT		 3
+#define SIGILL		 4
+#define SIGTRAP		 5
+#define SIGABRT		 6
+#define SIGIOT		 6
+#define SIGBUS		 7
+#define SIGFPE		 8
+#define SIGKILL		 9
+#define SIGUSR1		10
+#define SIGSEGV		11
+#define SIGUSR2		12
+#define SIGPIPE		13
+#define SIGALRM		14
+#define SIGTERM		15
+#define SIGSTKFLT	16
+#define SIGCHLD		17
+#define SIGCONT		18
+#define SIGSTOP		19
+#define SIGTSTP		20
+#define SIGTTIN		21
+#define SIGTTOU		22
+#define SIGURG		23
+#define SIGXCPU		24
+#define SIGXFSZ		25
+#define SIGVTALRM	26
+#define SIGPROF		27
+#define SIGWINCH	28
+#define SIGIO		29
+#define SIGPOLL		SIGIO
+/*
+#define SIGLOST		29
+*/
+#define SIGPWR		30
+#define	SIGUNUSED	31
+
+/*
+ * sa_flags values: SA_STACK is not currently supported, but will allow the
+ * usage of signal stacks by using the (now obsolete) sa_restorer field in
+ * the sigaction structure as a stack pointer. This is now possible due to
+ * the changes in signal handling. LBT 010493.
+ * SA_INTERRUPT is a no-op, but left due to historical reasons. Use the
+ * SA_RESTART flag to get restarting signals (which were the default long ago)
+ */
+#define SA_NOCLDSTOP	1
+#define SA_STACK	0x08000000
+#define SA_RESTART	0x10000000
+#define SA_INTERRUPT	0x20000000
+#define SA_NOMASK	0x40000000
+#define SA_ONESHOT	0x80000000
+
+#define SIG_BLOCK          0	/* for blocking signals */
+#define SIG_UNBLOCK        1	/* for unblocking signals */
+#define SIG_SETMASK        2	/* for setting the signal mask */
+
+/* Type of a signal handler.  */
+typedef void (*__sighandler_t)(int);
+
+#define SIG_DFL	((__sighandler_t)0)	/* default signal handling */
+#define SIG_IGN	((__sighandler_t)1)	/* ignore signal */
+#define SIG_ERR	((__sighandler_t)-1)	/* error return from signal */
+
+struct sigaction {
+	__sighandler_t sa_handler;
+	sigset_t sa_mask;
+	unsigned long sa_flags;
+	void (*sa_restorer)(void);
+};
+
+#ifdef __KERNEL__
+#include <asm/sigcontext.h>
+#endif
+
+#endif
+
+
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/socket.h linux/include/asm-ppc/socket.h
--- v1.3.44/linux/include/asm-ppc/socket.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/socket.h	Sat Nov 25 19:49:06 1995
@@ -0,0 +1,30 @@
+#ifndef _ASM_SOCKET_H
+#define _ASM_SOCKET_H
+
+/* Socket-level I/O control calls. */
+#define FIOSETOWN 	0x8901
+#define SIOCSPGRP	0x8902
+#define FIOGETOWN	0x8903
+#define SIOCGPGRP	0x8904
+#define SIOCATMARK	0x8905
+#define SIOCGSTAMP	0x8906		/* Get stamp */
+
+/* For setsockoptions(2) */
+#define SOL_SOCKET	1
+
+#define SO_DEBUG	1
+#define SO_REUSEADDR	2
+#define SO_TYPE		3
+#define SO_ERROR	4
+#define SO_DONTROUTE	5
+#define SO_BROADCAST	6
+#define SO_SNDBUF	7
+#define SO_RCVBUF	8
+#define SO_KEEPALIVE	9
+#define SO_OOBINLINE	10
+#define SO_NO_CHECK	11
+#define SO_PRIORITY	12
+#define SO_LINGER	13
+/* To add :#define SO_REUSEPORT 14 */
+
+#endif /* _ASM_SOCKET_H */
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/stat.h linux/include/asm-ppc/stat.h
--- v1.3.44/linux/include/asm-ppc/stat.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/stat.h	Sat Nov 25 19:49:07 1995
@@ -0,0 +1,41 @@
+#ifndef _PPC_STAT_H
+#define _PPC_STAT_H
+
+struct old_stat {
+	unsigned short st_dev;
+	unsigned short st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned long  st_size;
+	unsigned long  st_atime;
+	unsigned long  st_mtime;
+	unsigned long  st_ctime;
+};
+
+struct new_stat {
+	unsigned short st_dev;
+	unsigned short __pad1;
+	unsigned long st_ino;
+	unsigned short st_mode;
+	unsigned short st_nlink;
+	unsigned short st_uid;
+	unsigned short st_gid;
+	unsigned short st_rdev;
+	unsigned short __pad2;
+	unsigned long  st_size;
+	unsigned long  st_blksize;
+	unsigned long  st_blocks;
+	unsigned long  st_atime;
+	unsigned long  __unused1;
+	unsigned long  st_mtime;
+	unsigned long  __unused2;
+	unsigned long  st_ctime;
+	unsigned long  __unused3;
+	unsigned long  __unused4;
+	unsigned long  __unused5;
+};
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/statfs.h linux/include/asm-ppc/statfs.h
--- v1.3.44/linux/include/asm-ppc/statfs.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/statfs.h	Sat Nov 25 19:49:07 1995
@@ -0,0 +1,24 @@
+#ifndef _PPC_STATFS_H
+#define _PPC_STATFS_H
+
+typedef struct {
+	long    val[2];
+} fsid_t;
+
+struct statfs {
+	long f_type;
+	long f_bsize;
+	long f_blocks;
+	long f_bfree;
+	long f_bavail;
+	long f_files;
+	long f_ffree;
+	fsid_t f_fsid;
+	long f_namelen;
+	long f_spare[6];
+};
+
+#endif
+
+
+
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/string.h linux/include/asm-ppc/string.h
--- v1.3.44/linux/include/asm-ppc/string.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/string.h	Sat Nov 25 19:49:07 1995
@@ -0,0 +1,62 @@
+#ifndef _PPC_STRING_H_
+#define _PPC_STRING_H_
+
+
+
+/*
+ * keep things happy, the compile became unhappy since memset is
+ * in include/string.h and lib/string.c with different args
+ *                          -- Cort
+ */
+
+#define  __HAVE_ARCH_MEMSET
+extern inline void * memset(void * s,int c,size_t count)
+{
+	char *xs = (char *) s;
+
+	while (count--)
+		*xs++ = c;
+
+	return s;
+}
+#define __HAVE_ARCH_STRSTR
+/* Return the first ocurrence of NEEDLE in HAYSTACK.  */
+extern inline char *
+strstr(const char *haystack, const char *needle)
+{
+  const char *const needle_end = strchr(needle, '\0');
+  const char *const haystack_end = strchr(haystack, '\0');
+  const size_t needle_len = needle_end - needle;
+  const size_t needle_last = needle_len - 1;
+  const char *begin;
+
+  if (needle_len == 0)
+#ifdef __linux__
+    return (char *) haystack;
+#else
+    return (char *) haystack_end;
+#endif
+  if ((size_t) (haystack_end - haystack) < needle_len)
+    return NULL;
+
+  for (begin = &haystack[needle_last]; begin < haystack_end; ++begin)
+    {
+      register const char *n = &needle[needle_last];
+      register const char *h = begin;
+
+      do
+	if (*h != *n)
+	  goto loop;		/* continue for loop */
+      while (--n >= needle && --h >= haystack);
+
+      return (char *) h;
+
+    loop:;
+    }
+
+  return NULL;
+}
+
+
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/system.h linux/include/asm-ppc/system.h
--- v1.3.44/linux/include/asm-ppc/system.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/system.h	Sat Nov 25 19:49:07 1995
@@ -0,0 +1,76 @@
+#ifndef __PPC_SYSTEM_H
+#define __PPC_SYSTEM_H
+
+#if 0
+#define mb() \
+__asm__ __volatile__("mb": : :"memory")
+#endif
+#define mb()  __asm__ __volatile__ (""   : : :"memory")
+
+
+extern void __save_flags(long *flags);
+extern void __restore_flags(long flags);
+extern void sti(void);
+extern void cli(void);
+extern int _disable_interrupts(void);
+extern void _enable_interrupts(int);
+
+/*extern void memcpy(void *, void *, int);*/
+extern void bzero(void *, int);
+
+struct task_struct;
+extern void switch_to(struct task_struct *);
+
+#define save_flags(flags) __save_flags(&(flags))
+#define restore_flags(flags) __restore_flags(flags)
+
+#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr))))
+
+/* this guy lives in arch/ppc/kernel */
+extern inline unsigned long *xchg_u32(void *m, unsigned long val);
+
+/*
+ *  these guys don't exist.
+ *  someone should create them.
+ *              -- Cort
+ */
+extern void *xchg_u64(void *ptr, unsigned long val);
+extern int xchg_u8(char *m, char val);
+
+/*
+ * This function doesn't exist, so you'll get a linker error
+ * if something tries to do an invalid xchg().
+ *
+ * This only works if the compiler isn't horribly bad at optimizing.
+ * gcc-2.5.8 reportedly can't handle this, but as that doesn't work
+ * too well on the alpha anyway..
+ */
+extern void __xchg_called_with_bad_pointer(void);
+
+static inline unsigned long __xchg(unsigned long x, void * ptr, int size)
+{
+	switch (size) {
+		case 4:
+			return (unsigned long )xchg_u32(ptr, x);
+		case 8:
+			return (unsigned long )xchg_u64(ptr, x);
+	}
+	__xchg_called_with_bad_pointer();
+	return x;
+
+
+}
+
+
+
+extern inline int tas(char * m)
+{
+	return xchg_u8(m,1);
+}
+
+extern inline void * xchg_ptr(void * m, void * val)
+{
+	return (void *) xchg_u32(m, (unsigned long) val);
+}
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/termios.h linux/include/asm-ppc/termios.h
--- v1.3.44/linux/include/asm-ppc/termios.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/termios.h	Sat Nov 25 19:49:07 1995
@@ -0,0 +1,398 @@
+#ifndef _PPC_TERMIOS_H
+#define _PPC_TERMIOS_H
+
+
+/*
+ * These were swiped from the alpha termios.h.  These probably aren't
+ * correct but we can fix them as we come across problems.
+ *                                -- Cort
+ */
+
+#include <linux/types.h>
+
+#include <asm/ioctl.h>
+
+struct sgttyb {
+	char	sg_ispeed;
+	char	sg_ospeed;
+	char	sg_erase;
+	char	sg_kill;
+	short	sg_flags;
+};
+
+struct tchars {
+	char	t_intrc;
+	char	t_quitc;
+	char	t_startc;
+	char	t_stopc;
+	char	t_eofc;
+	char	t_brkc;
+};
+
+struct ltchars {
+	char	t_suspc;
+	char	t_dsuspc;
+	char	t_rprntc;
+	char	t_flushc;
+	char	t_werasc;
+	char	t_lnextc;
+};
+
+#define FIOCLEX		_IO('f', 1)
+#define FIONCLEX	_IO('f', 2)
+#define FIOASYNC	_IOW('f', 125, int)
+#define FIONBIO		_IOW('f', 126, int)
+#define FIONREAD	_IOR('f', 127, int)
+#define TIOCINQ		FIONREAD
+
+#define TIOCGETP	_IOR('t', 8, struct sgttyb)
+#define TIOCSETP	_IOW('t', 9, struct sgttyb)
+#define TIOCSETN	_IOW('t', 10, struct sgttyb)	/* TIOCSETP wo flush */
+
+#define TIOCSETC	_IOW('t', 17, struct tchars)
+#define TIOCGETC	_IOR('t', 18, struct tchars)
+#define TCGETS		_IOR('t', 19, struct termios)
+#define TCSETS		_IOW('t', 20, struct termios)
+#define TCSETSW		_IOW('t', 21, struct termios)
+#define TCSETSF		_IOW('t', 22, struct termios)
+
+#define TCGETA		_IOR('t', 23, struct termio)
+#define TCSETA		_IOW('t', 24, struct termio)
+#define TCSETAW		_IOW('t', 25, struct termio)
+#define TCSETAF		_IOW('t', 28, struct termio)
+
+#define TCSBRK		_IO('t', 29)
+#define TCXONC		_IO('t', 30)
+#define TCFLSH		_IO('t', 31)
+
+#define TIOCSWINSZ	_IOW('t', 103, struct winsize)
+#define TIOCGWINSZ	_IOR('t', 104, struct winsize)
+#define	TIOCSTART	_IO('t', 110)		/* start output, like ^Q */
+#define	TIOCSTOP	_IO('t', 111)		/* stop output, like ^S */
+#define TIOCOUTQ        _IOR('t', 115, int)     /* output queue size */
+
+#define TIOCGLTC	_IOR('t', 116, struct ltchars)
+#define TIOCSLTC	_IOW('t', 117, struct ltchars)
+#define TIOCSPGRP	_IOW('t', 118, int)
+#define TIOCGPGRP	_IOR('t', 119, int)
+
+#define TIOCEXCL	0x540C
+#define TIOCNXCL	0x540D
+#define TIOCSCTTY	0x540E
+
+#define TIOCSTI		0x5412
+#define TIOCMGET	0x5415
+#define TIOCMBIS	0x5416
+#define TIOCMBIC	0x5417
+#define TIOCMSET	0x5418
+#define TIOCGSOFTCAR	0x5419
+#define TIOCSSOFTCAR	0x541A
+#define TIOCLINUX	0x541C
+#define TIOCCONS	0x541D
+#define TIOCGSERIAL	0x541E
+#define TIOCSSERIAL	0x541F
+#define TIOCPKT		0x5420
+
+#define TIOCNOTTY	0x5422
+#define TIOCSETD	0x5423
+#define TIOCGETD	0x5424
+#define TCSBRKP		0x5425	/* Needed for POSIX tcsendbreak() */
+#define TIOCTTYGSTRUCT	0x5426  /* For debugging only */
+
+#define TIOCSERCONFIG	0x5453
+#define TIOCSERGWILD	0x5454
+#define TIOCSERSWILD	0x5455
+#define TIOCGLCKTRMIOS	0x5456
+#define TIOCSLCKTRMIOS	0x5457
+#define TIOCSERGSTRUCT	0x5458 /* For debugging only */
+#define TIOCSERGETLSR   0x5459 /* Get line status register */
+#define TIOCSERGETMULTI 0x545A /* Get multiport config  */
+#define TIOCSERSETMULTI 0x545B /* Set multiport config */
+
+/* Used for packet mode */
+#define TIOCPKT_DATA		 0
+#define TIOCPKT_FLUSHREAD	 1
+#define TIOCPKT_FLUSHWRITE	 2
+#define TIOCPKT_STOP		 4
+#define TIOCPKT_START		 8
+#define TIOCPKT_NOSTOP		16
+#define TIOCPKT_DOSTOP		32
+
+struct winsize {
+	unsigned short ws_row;
+	unsigned short ws_col;
+	unsigned short ws_xpixel;
+	unsigned short ws_ypixel;
+};
+
+#define NCC 8
+struct termio {
+	unsigned short c_iflag;		/* input mode flags */
+	unsigned short c_oflag;		/* output mode flags */
+	unsigned short c_cflag;		/* control mode flags */
+	unsigned short c_lflag;		/* local mode flags */
+	unsigned char c_line;		/* line discipline */
+	unsigned char c_cc[NCC];	/* control characters */
+};
+
+#define NCCS 19
+struct termios {
+	tcflag_t c_iflag;		/* input mode flags */
+	tcflag_t c_oflag;		/* output mode flags */
+	tcflag_t c_cflag;		/* control mode flags */
+	tcflag_t c_lflag;		/* local mode flags */
+	cc_t c_cc[NCCS];		/* control characters */
+	cc_t c_line;			/* line discipline (== c_cc[19]) */
+	int c_ispeed;			/* input speed */
+	int c_ospeed;			/* output speed */
+};
+
+/* c_cc characters */
+#define VEOF 0
+#define VEOL 1
+#define VEOL2 2
+#define VERASE 3
+#define VWERASE 4
+#define VKILL 5
+#define VREPRINT 6
+#define VSWTC 7
+#define VINTR 8
+#define VQUIT 9
+#define VSUSP 10
+#define VSTART 12
+#define VSTOP 13
+#define VLNEXT 14
+#define VDISCARD 15
+#define VMIN 16
+#define VTIME 17
+
+/*
+ * ..and the same for c_cc in the termio structure.. 
+ * Oh, how I love being backwardly compatible.
+ */
+#define _VINTR	0
+#define _VQUIT	1
+#define _VERASE	2
+#define _VKILL	3
+#define _VEOF	4
+#define _VMIN	4
+#define _VEOL	5
+#define _VTIME	5
+#define _VEOL2	6
+#define _VSWTC	7
+
+#ifdef __KERNEL__
+/*	eof=^D		eol=\0		eol2=\0		erase=del
+	werase=^W	kill=^U		reprint=^R	sxtc=\0
+	intr=^C		quit=^\		susp=^Z		<OSF/1 VDSUSP>
+	start=^Q	stop=^S		lnext=^V	discard=^U
+	vmin=\1		vtime=\0
+*/
+#define INIT_C_CC "\004\000\000\177\027\025\022\000\003\034\032\000\021\023\026\025\001\000"
+#endif
+
+/* c_iflag bits */
+#define IGNBRK	0000001
+#define BRKINT	0000002
+#define IGNPAR	0000004
+#define PARMRK	0000010
+#define INPCK	0000020
+#define ISTRIP	0000040
+#define INLCR	0000100
+#define IGNCR	0000200
+#define ICRNL	0000400
+#define IXON	0001000
+#define IXOFF	0002000
+#define IXANY	0004000
+#define IUCLC	0010000
+#define IMAXBEL	0020000
+
+/* c_oflag bits */
+#define OPOST	0000001
+#define ONLCR	0000002
+#define OLCUC	0000004
+
+#define OCRNL	0000010
+#define ONOCR	0000020
+#define ONLRET	0000040
+
+#define OFILL	00000100
+#define OFDEL	00000200
+#define NLDLY	00001400
+#define   NL0	00000000
+#define   NL1	00000400
+#define   NL2	00001000
+#define   NL3	00001400
+#define TABDLY	00006000
+#define   TAB0	00000000
+#define   TAB1	00002000
+#define   TAB2	00004000
+#define   TAB3	00006000
+#define CRDLY	00030000
+#define   CR0	00000000
+#define   CR1	00010000
+#define   CR2	00020000
+#define   CR3	00030000
+#define FFDLY	00040000
+#define   FF0	00000000
+#define   FF1	00040000
+#define BSDLY	00100000
+#define   BS0	00000000
+#define   BS1	00100000
+#define VTDLY	00200000
+#define   VT0	00000000
+#define   VT1	00200000
+#define XTABS	01000000 /* Hmm.. Linux/i386 considers this part of TABDLY.. */
+
+/* c_cflag bit meaning */
+#define CBAUD	0000377
+#define  B0	0000000		/* hang up */
+#define  B50	0000001
+#define  B75	0000002
+#define  B110	0000003
+#define  B134	0000004
+#define  B150	0000005
+#define  B200	0000006
+#define  B300	0000007
+#define  B600	0000010
+#define  B1200	0000011
+#define  B1800	0000012
+#define  B2400	0000013
+#define  B4800	0000014
+#define  B9600	0000015
+#define  B19200	0000016
+#define  B38400	0000017
+#define EXTA B19200
+#define EXTB B38400
+#define CBAUDEX 0000020
+#define  B57600   00020
+#define  B115200  00021
+#define  B230400  00022
+
+#define CSIZE	00001400
+#define   CS5	00000000
+#define   CS6	00000400
+#define   CS7	00001000
+#define   CS8	00001400
+
+#define CSTOPB	00002000
+#define CREAD	00004000
+#define PARENB	00010000
+#define PARODD	00020000
+#define HUPCL	00040000
+
+#define CLOCAL	00100000
+#define CRTSCTS	  020000000000		/* flow control */
+
+/* c_lflag bits */
+#define ISIG	0x00000080
+#define ICANON	0x00000100
+#define XCASE	0x00004000
+#define ECHO	0x00000008
+#define ECHOE	0x00000002
+#define ECHOK	0x00000004
+#define ECHONL	0x00000010
+#define NOFLSH	0x80000000
+#define TOSTOP	0x00400000
+#define ECHOCTL	0x00000040
+#define ECHOPRT	0x00000020
+#define ECHOKE	0x00000001
+#define FLUSHO	0x00800000
+#define PENDIN	0x20000000
+#define IEXTEN	0x00000400
+
+/* modem lines */
+#define TIOCM_LE	0x001
+#define TIOCM_DTR	0x002
+#define TIOCM_RTS	0x004
+#define TIOCM_ST	0x008
+#define TIOCM_SR	0x010
+#define TIOCM_CTS	0x020
+#define TIOCM_CAR	0x040
+#define TIOCM_RNG	0x080
+#define TIOCM_DSR	0x100
+#define TIOCM_CD	TIOCM_CAR
+#define TIOCM_RI	TIOCM_RNG
+
+/* ioctl (fd, TIOCSERGETLSR, &result) where result may be as below */
+#define TIOCSER_TEMT    0x01	/* Transmitter physically empty */
+
+
+/* tcflow() and TCXONC use these */
+#define	TCOOFF		0
+#define	TCOON		1
+#define	TCIOFF		2
+#define	TCION		3
+
+/* tcflush() and TCFLSH use these */
+#define	TCIFLUSH	0
+#define	TCOFLUSH	1
+#define	TCIOFLUSH	2
+
+/* tcsetattr uses these */
+#define	TCSANOW		0
+#define	TCSADRAIN	1
+#define	TCSAFLUSH	2
+
+/* line disciplines */
+#define N_TTY		0
+#define N_SLIP		1
+#define N_MOUSE		2
+#define N_PPP		3
+
+#ifdef __KERNEL__
+
+/*
+ * Translate a "termio" structure into a "termios". Ugh.
+ */
+extern inline void trans_from_termio(struct termio * termio,
+	struct termios * termios)
+{
+#define SET_LOW_BITS(x,y)	((x) = (0xffff0000 & (x)) | (y))
+	SET_LOW_BITS(termios->c_iflag, termio->c_iflag);
+	SET_LOW_BITS(termios->c_oflag, termio->c_oflag);
+	SET_LOW_BITS(termios->c_cflag, termio->c_cflag);
+	SET_LOW_BITS(termios->c_lflag, termio->c_lflag);
+#undef SET_LOW_BITS
+	termios->c_cc[VINTR] = termio->c_cc[_VINTR];
+	termios->c_cc[VQUIT] = termio->c_cc[_VQUIT];
+	termios->c_cc[VERASE]= termio->c_cc[_VERASE];
+	termios->c_cc[VKILL] = termio->c_cc[_VKILL];
+	termios->c_cc[VEOF]  = termio->c_cc[_VEOF];
+	termios->c_cc[VMIN]  = termio->c_cc[_VMIN];
+	termios->c_cc[VEOL]  = termio->c_cc[_VEOL];
+	termios->c_cc[VTIME] = termio->c_cc[_VTIME];
+	termios->c_cc[VEOL2] = termio->c_cc[_VEOL2];
+	termios->c_cc[VSWTC] = termio->c_cc[_VSWTC];
+}
+
+/*
+ * Translate a "termios" structure into a "termio". Ugh.
+ *
+ * Note the "fun" _VMIN overloading.
+ */
+extern inline void trans_to_termio(struct termios * termios,
+	struct termio * termio)
+{
+	termio->c_iflag = termios->c_iflag;
+	termio->c_oflag = termios->c_oflag;
+	termio->c_cflag = termios->c_cflag;
+	termio->c_lflag = termios->c_lflag;
+	termio->c_line	= termios->c_line;
+	termio->c_cc[_VINTR] = termios->c_cc[VINTR];
+	termio->c_cc[_VQUIT] = termios->c_cc[VQUIT];
+	termio->c_cc[_VERASE]= termios->c_cc[VERASE];
+	termio->c_cc[_VKILL] = termios->c_cc[VKILL];
+	termio->c_cc[_VEOF]  = termios->c_cc[VEOF];
+	termio->c_cc[_VEOL]  = termios->c_cc[VEOL];
+	termio->c_cc[_VEOL2] = termios->c_cc[VEOL2];
+	termio->c_cc[_VSWTC] = termios->c_cc[VSWTC];
+	if (!(termios->c_lflag & ICANON)) {
+		termio->c_cc[_VMIN]  = termios->c_cc[VMIN];
+		termio->c_cc[_VTIME] = termios->c_cc[VTIME];
+	}
+}
+
+#endif	/* __KERNEL__ */
+
+#endif	/* _ALPHA_TERMIOS_H */
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/types.h linux/include/asm-ppc/types.h
--- v1.3.44/linux/include/asm-ppc/types.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/types.h	Sat Nov 25 19:49:07 1995
@@ -0,0 +1,128 @@
+#ifndef _PPC_TYPES_H
+#define _PPC_TYPES_H
+
+#ifndef _SIZE_T
+#define _SIZE_T
+typedef unsigned int size_t;
+#endif
+
+#ifndef _SSIZE_T
+#define _SSIZE_T
+typedef int ssize_t;
+#endif
+
+#ifndef _PTRDIFF_T
+#define _PTRDIFF_T
+typedef int ptrdiff_t;
+#endif
+
+#ifndef _TIME_T
+#define _TIME_T
+typedef long time_t;
+#endif
+
+#ifndef _CLOCK_T
+#define _CLOCK_T
+typedef long clock_t;
+#endif
+
+typedef int pid_t;
+typedef unsigned int uid_t;
+typedef unsigned int gid_t;
+typedef unsigned int dev_t;
+typedef unsigned int ino_t;
+typedef unsigned int mode_t;
+typedef unsigned int umode_t;
+typedef unsigned short nlink_t;
+typedef int daddr_t;
+typedef long off_t;
+
+/*
+ * __xx is ok: it doesn't pollute the POSIX namespace. Use these in the
+ * header files exported to user space
+ */
+
+typedef __signed__ char __s8;
+typedef unsigned char __u8;
+
+typedef __signed__ short __s16;
+typedef unsigned short __u16;
+
+typedef __signed__ long __s32;
+typedef unsigned long __u32;
+
+#if defined(__GNUC__) && !defined(__STRICT_ANSI__)
+typedef __signed__ long long __s64;
+typedef unsigned long long __u64;
+#endif
+
+/*
+ * These aren't exported outside the kernel to avoid name space clashes
+ */
+#ifdef __KERNEL__
+
+typedef signed char s8;
+typedef unsigned char u8;
+
+typedef signed short s16;
+typedef unsigned short u16;
+
+typedef signed long s32;
+typedef unsigned long u32;
+
+typedef signed long long s64;
+typedef unsigned long long u64;
+
+#endif /* __KERNEL__ */
+
+#undef __FD_SET
+static __inline__ void __FD_SET(unsigned long fd, fd_set *fdsetp)
+{
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	fdsetp->fds_bits[_tmp] |= (1UL<<_rem);
+}
+
+#undef __FD_CLR
+static __inline__ void __FD_CLR(unsigned long fd, fd_set *fdsetp)
+{
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	fdsetp->fds_bits[_tmp] &= ~(1UL<<_rem);
+}
+
+#undef __FD_ISSET
+static __inline__ int __FD_ISSET(unsigned long fd, fd_set *p)
+{ 
+	unsigned long _tmp = fd / __NFDBITS;
+	unsigned long _rem = fd % __NFDBITS;
+	return (p->fds_bits[_tmp] & (1UL<<_rem)) != 0;
+}
+
+/*
+ * This will unroll the loop for the normal constant case (8 ints,
+ * for a 256-bit fd_set)
+ */
+#undef __FD_ZERO
+static __inline__ void __FD_ZERO(fd_set *p)
+{
+	unsigned int *tmp = p->fds_bits;
+	int i;
+
+	if (__builtin_constant_p(__FDSET_INTS)) {
+		switch (__FDSET_INTS) {
+			case 8:
+				tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0;
+				tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0;
+				return;
+		}
+	}
+	i = __FDSET_INTS;
+	while (i) {
+		i--;
+		*tmp = 0;
+		tmp++;
+	}
+}
+
+#endif
diff -u --recursive --new-file v1.3.44/linux/include/asm-ppc/unistd.h linux/include/asm-ppc/unistd.h
--- v1.3.44/linux/include/asm-ppc/unistd.h	Thu Jan  1 02:00:00 1970
+++ linux/include/asm-ppc/unistd.h	Sat Nov 25 19:49:07 1995
@@ -0,0 +1,332 @@
+/* * Last edited: Nov 17 16:28 1995 (cort) */
+#ifndef _ASM_PPC_UNISTD_H_
+#define _ASM_PPC_UNISTD_H_
+
+#define _NR(n) #n
+#define _lisc(n) "li 0," _NR(n)
+
+/*
+ * This file contains the system call numbers.
+ */
+
+#define __NR_setup		  0	/* used only by init, to get system going */
+#define __NR_exit		  1
+#define __NR_fork		  2
+#define __NR_read		  3
+#define __NR_write		  4
+#define __NR_open		  5
+#define __NR_close		  6
+#define __NR_waitpid		  7
+#define __NR_creat		  8
+#define __NR_link		  9
+#define __NR_unlink		 10
+#define __NR_execve		 11
+#define __NR_chdir		 12
+#define __NR_time		 13
+#define __NR_mknod		 14
+#define __NR_chmod		 15
+#define __NR_chown		 16
+#define __NR_break		 17
+#define __NR_oldstat		 18
+#define __NR_lseek		 19
+#define __NR_getpid		 20
+#define __NR_mount		 21
+#define __NR_umount		 22
+#define __NR_setuid		 23
+#define __NR_getuid		 24
+#define __NR_stime		 25
+#define __NR_ptrace		 26
+#define __NR_alarm		 27
+#define __NR_oldfstat		 28
+#define __NR_pause		 29
+#define __NR_utime		 30
+#define __NR_stty		 31
+#define __NR_gtty		 32
+#define __NR_access		 33
+#define __NR_nice		 34
+#define __NR_ftime		 35
+#define __NR_sync		 36
+#define __NR_kill		 37
+#define __NR_rename		 38
+#define __NR_mkdir		 39
+#define __NR_rmdir		 40
+#define __NR_dup		 41
+#define __NR_pipe		 42
+#define __NR_times		 43
+#define __NR_prof		 44
+#define __NR_brk		 45
+#define __NR_setgid		 46
+#define __NR_getgid		 47
+#define __NR_signal		 48
+#define __NR_geteuid		 49
+#define __NR_getegid		 50
+#define __NR_acct		 51
+#define __NR_phys		 52
+#define __NR_lock		 53
+#define __NR_ioctl		 54
+#define __NR_fcntl		 55
+#define __NR_mpx		 56
+#define __NR_setpgid		 57
+#define __NR_ulimit		 58
+#define __NR_oldolduname	 59
+#define __NR_umask		 60
+#define __NR_chroot		 61
+#define __NR_ustat		 62
+#define __NR_dup2		 63
+#define __NR_getppid		 64
+#define __NR_getpgrp		 65
+#define __NR_setsid		 66
+#define __NR_sigaction		 67
+#define __NR_sgetmask		 68
+#define __NR_ssetmask		 69
+#define __NR_setreuid		 70
+#define __NR_setregid		 71
+#define __NR_sigsuspend		 72
+#define __NR_sigpending		 73
+#define __NR_sethostname	 74
+#define __NR_setrlimit		 75
+#define __NR_getrlimit		 76
+#define __NR_getrusage		 77
+#define __NR_gettimeofday	 78
+#define __NR_settimeofday	 79
+#define __NR_getgroups		 80
+#define __NR_setgroups		 81
+#define __NR_select		 82
+#define __NR_symlink		 83
+#define __NR_oldlstat		 84
+#define __NR_readlink		 85
+#define __NR_uselib		 86
+#define __NR_swapon		 87
+#define __NR_reboot		 88
+#define __NR_readdir		 89
+#define __NR_mmap		 90
+#define __NR_munmap		 91
+#define __NR_truncate		 92
+#define __NR_ftruncate		 93
+#define __NR_fchmod		 94
+#define __NR_fchown		 95
+#define __NR_getpriority	 96
+#define __NR_setpriority	 97
+#define __NR_profil		 98
+#define __NR_statfs		 99
+#define __NR_fstatfs		100
+#define __NR_ioperm		101
+#define __NR_socketcall		102
+#define __NR_syslog		103
+#define __NR_setitimer		104
+#define __NR_getitimer		105
+#define __NR_stat		106
+#define __NR_lstat		107
+#define __NR_fstat		108
+#define __NR_olduname		109
+#define __NR_iopl		110
+#define __NR_vhangup		111
+#define __NR_idle		112
+#define __NR_vm86		113
+#define __NR_wait4		114
+#define __NR_swapoff		115
+#define __NR_sysinfo		116
+#define __NR_ipc		117
+#define __NR_fsync		118
+#define __NR_sigreturn		119
+#define __NR_clone		120
+#define __NR_setdomainname	121
+#define __NR_uname		122
+#define __NR_modify_ldt		123
+#define __NR_adjtimex		124
+#define __NR_mprotect		125
+#define __NR_sigprocmask	126
+#define __NR_create_module	127
+#define __NR_init_module	128
+#define __NR_delete_module	129
+#define __NR_get_kernel_syms	130
+#define __NR_quotactl		131
+#define __NR_getpgid		132
+#define __NR_fchdir		133
+#define __NR_bdflush		134
+#define __NR_sysfs		135
+#define __NR_personality	136
+#define __NR_afs_syscall	137 /* Syscall for Andrew File System */
+#define __NR_setfsuid		138
+#define __NR_setfsgid		139
+#define __NR__llseek		140
+#define __NR_getdents		141
+#define __NR__newselect		142
+#define __NR_flock		143
+#define __NR_msync		144
+/*#define __NR_kclone		145*/
+
+
+/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */
+#define _syscall0(type,name) \
+type name(void) \
+{ \
+ __asm__ (_lisc(__NR_##name)); \
+ __asm__ ("sc"); \
+ __asm__ ("mr 31,3"); \
+ __asm__ ("bns 10f"); \
+ __asm__ ("mr 0,3"); \
+ __asm__ ("lis 3,errno@ha"); \
+ __asm__ ("stw 0,errno@l(3)"); \
+ __asm__ ("li 3,-1"); \
+ __asm__ ("10:"); \
+}
+
+#define _syscall1(type,name,type1,arg1) \
+type name(type1 arg1) \
+{ \
+ __asm__ (_lisc(__NR_##name)); \
+ __asm__ ("sc"); \
+ __asm__ ("mr 31,3"); \
+ __asm__ ("bns 10f"); \
+ __asm__ ("mr 0,3"); \
+ __asm__ ("lis 3,errno@ha"); \
+ __asm__ ("stw 0,errno@l(3)"); \
+ __asm__ ("li 3,-1"); \
+ __asm__ ("10:"); \
+}
+
+#define _syscall2(type,name,type1,arg1,type2,arg2) \
+type name(type1 arg1,type2 arg2) \
+{ \
+ __asm__ (_lisc(__NR_##name)); \
+ __asm__ ("sc"); \
+ __asm__ ("mr 31,3"); \
+ __asm__ ("bns 10f"); \
+ __asm__ ("mr 0,3"); \
+ __asm__ ("lis 3,errno@ha"); \
+ __asm__ ("stw 0,errno@l(3)"); \
+ __asm__ ("li 3,-1"); \
+ __asm__ ("10:"); \
+}
+
+#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \
+type name(type1 arg1,type2 arg2,type3 arg3) \
+{ \
+ __asm__ (_lisc(__NR_##name)); \
+ __asm__ ("sc"); \
+ __asm__ ("mr 31,3"); \
+ __asm__ ("bns 10f"); \
+ __asm__ ("mr 0,3"); \
+ __asm__ ("lis 3,errno@ha"); \
+ __asm__ ("stw 0,errno@l(3)"); \
+ __asm__ ("li 3,-1"); \
+ __asm__ ("10:"); \
+}
+
+#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \
+type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \
+{ \
+ __asm__ (_lisc(__NR_##name)); \
+ __asm__ ("sc"); \
+ __asm__ ("mr 31,3"); \
+ __asm__ ("bns 10f"); \
+ __asm__ ("mr 0,3"); \
+ __asm__ ("lis 3,errno@ha"); \
+ __asm__ ("stw 0,errno@l(3)"); \
+ __asm__ ("li 3,-1"); \
+ __asm__ ("10:"); \
+} 
+
+#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \
+	  type5,arg5) \
+type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \
+{ \
+ __asm__ (_lisc(__NR_##name)); \
+ __asm__ ("sc"); \
+ __asm__ ("mr 31,3"); \
+ __asm__ ("bns 10f"); \
+ __asm__ ("mr 0,3"); \
+ __asm__ ("lis 3,errno@ha"); \
+ __asm__ ("stw 0,errno@l(3)"); \
+ __asm__ ("li 3,-1"); \
+ __asm__ ("10:"); \
+}
+
+#ifdef __KERNEL_SYSCALLS__
+
+/*
+ * we need this inline - forking from kernel space will result
+ * in NO COPY ON WRITE (!!!), until an execve is executed. This
+ * is no problem, but for the stack. This is handled by not letting
+ * main() use the stack at all after fork(). Thus, no function
+ * calls - which means inline code for fork too, as otherwise we
+ * would use the stack upon exit from 'fork()'.
+ *
+ * Actually only pause and fork are needed inline, so that there
+ * won't be any messing with the stack from main(), but we define
+ * some others too.
+ */
+/*
+   some of these had problems getting the right arguments (namely sys_clone())
+   when they were inline.
+             -- Cort
+ */
+#define __NR__exit __NR_exit
+static inline _syscall0(int,idle) /* made inline "just in case" -- Cort */
+static inline _syscall0(int,fork) /* needs to be inline */
+static inline _syscall0(int,pause) /* needs to be inline */
+static inline _syscall0(int,setup) /* called in init before execve */
+static inline _syscall0(int,sync)
+static inline _syscall0(pid_t,setsid)
+static /*inline*/ _syscall3(int,write,int,fd,const char *,buf,off_t,count)
+static /*inline*/ _syscall1(int,dup,int,fd)
+static /*inline*/ _syscall3(int,execve,const char *,file,char **,argv,char **,envp)
+static /*inline*/ _syscall3(int,open,const char *,file,int,flag,int,mode)
+static inline _syscall1(int,close,int,fd)
+static /*inline*/ _syscall1(int,_exit,int,exitcode)
+static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options)
+/*static inline _syscall2(int,clone,unsigned long,flags,char *,esp)*/
+
+/*
+   syscalls from kernel mode is a little strange and I can't get used to
+   the idea -- this makes me feel better.   -- Cort
+ */
+/*static inline int kclone (void)
+{
+ __asm__ (_lisc(__NR_kclone)); 
+ __asm__ ("sc"); 
+ __asm__ ("mr 31,3"); 
+ __asm__ ("bns 10f"); 
+ __asm__ ("mr 0,3"); 
+ __asm__ ("lis 3,errno@ha"); 
+ __asm__ ("stw 0,errno@l(3)"); 
+ __asm__ ("li 3,-1"); 
+ __asm__ ("10:");   
+}*/
+
+static inline int clone (unsigned long flags,char *esp)
+{
+/*  printk("unistd.h: clone(): flags = %x, esp = %x\n", flags, esp);*/
+ __asm__ (_lisc(__NR_clone)); 
+ __asm__ ("sc");
+ __asm__ ("mr 31,3"); 
+
+/* this is a hack to get the damned thing to return something even though inlined
+   -- Cort
+   */
+ __asm__ ("mr 0,3"); 
+ __asm__ ("lis 3,errno@ha"); 
+ __asm__ ("stw 0,errno@l(3)"); 
+ 
+ __asm__ ("bns 10f"); 
+ __asm__ ("mr 0,3"); 
+ __asm__ ("lis 3,errno@ha"); 
+ __asm__ ("stw 0,errno@l(3)"); 
+ __asm__ ("li 3,-1"); 
+ __asm__ ("10:");
+ return errno;
+}
+
+
+/* called from init before execve -- need to be inline? -- Cort */
+static inline pid_t wait(int * wait_stat) 
+{
+	return waitpid(-1,wait_stat,0);
+}
+
+#endif
+
+#endif /* _ASM_PPC_UNISTD_H_ */
+
+
diff -u --recursive --new-file v1.3.44/linux/include/asm-sparc/floppy.h linux/include/asm-sparc/floppy.h
--- v1.3.44/linux/include/asm-sparc/floppy.h	Sat Nov 25 19:04:49 1995
+++ linux/include/asm-sparc/floppy.h	Sun Nov 26 11:50:02 1995
@@ -1,5 +1,4 @@
-/* $Id: floppy.h,v 1.8 1995/11/25 02:31:45 davem Exp $
- * asm-sparc/floppy.h: Sparc specific parts of the Floppy driver.
+/* asm-sparc/floppy.h: Sparc specific parts of the Floppy driver.
  *
  * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu)
  */
@@ -130,12 +129,14 @@
 		 *               drive attached to a Sun controller
 		 *               and it will be at drive zero.
 		 */
+#if 0
 		if(value & 0xf0)
+#else
+		if(value & 0x10)
+#endif
 			set_auxio(AUXIO_FLPY_DSEL, 0);
-#if 0
 		else
 			set_auxio(0, AUXIO_FLPY_DSEL);
-#endif
 		break;
 	case 5: /* FD_DATA */
 		sun_fdc->data_82072 = value;
@@ -203,7 +204,6 @@
  * the transfer for debugging.  1=read 2=write
  */
 char *pdma_vaddr;
-char *pdma_vsave;
 unsigned long pdma_size;
 int doing_pdma = 0;
 
@@ -246,7 +246,7 @@
 static inline void sun_fd_enable_dma(void)
 {
 	/* We're about to let it rip, lock any tlb entries necessary. */
-	pdma_vaddr = pdma_vsave = mmu_lockarea(pdma_vaddr, pdma_size);
+	pdma_vaddr = mmu_lockarea(pdma_vaddr, pdma_size);
 }
 
 /* Our low-level entry point in arch/sparc/kernel/entry.S */
diff -u --recursive --new-file v1.3.44/linux/include/asm-sparc/processor.h linux/include/asm-sparc/processor.h
--- v1.3.44/linux/include/asm-sparc/processor.h	Sat Nov 25 19:04:51 1995
+++ linux/include/asm-sparc/processor.h	Sun Nov 26 11:50:02 1995
@@ -1,4 +1,4 @@
-/* $Id: processor.h,v 1.28 1995/11/25 02:32:30 davem Exp $
+/* $Id: processor.h,v 1.29 1995/11/26 05:01:29 davem Exp $
  * include/asm-sparc/processor.h
  *
  * Copyright (C) 1994 David S. Miller (davem@caip.rutgers.edu)
@@ -73,7 +73,7 @@
 	struct sigstack sstk_info;
 };
 
-#define INIT_MMAP { &init_mm, (0xf0000000UL), (0xffffffffUL), \
+#define INIT_MMAP { &init_mm, (0xf0000000UL), (0xfe100000UL), \
 		    __pgprot(0x0) , VM_READ | VM_WRITE | VM_EXEC }
 
 #define INIT_TSS  { \
diff -u --recursive --new-file v1.3.44/linux/include/asm-sparc/socket.h linux/include/asm-sparc/socket.h
--- v1.3.44/linux/include/asm-sparc/socket.h	Sat Nov 25 19:04:51 1995
+++ linux/include/asm-sparc/socket.h	Sun Nov 26 11:50:02 1995
@@ -1,4 +1,4 @@
-/* $Id: socket.h,v 1.4 1995/11/25 02:32:49 davem Exp $ */
+/* $Id: socket.h,v 1.5 1995/11/26 01:32:36 davem Exp $ */
 #ifndef _ASM_SOCKET_H
 #define _ASM_SOCKET_H
 
@@ -21,6 +21,7 @@
 #define SO_LINGER	0x0080
 #define SO_OOBINLINE	0x0100
 /* To add :#define SO_REUSEPORT 0x0200 */
+#define SO_BSDCOMPAT    0x0400
 
 /* wha!??? */
 #define SO_DONTLINGER   (~SO_LINGER)  /* Older SunOS compat. hack */
diff -u --recursive --new-file v1.3.44/linux/include/linux/blk.h linux/include/linux/blk.h
--- v1.3.44/linux/include/linux/blk.h	Mon Oct 23 18:02:18 1995
+++ linux/include/linux/blk.h	Mon Nov 27 11:21:50 1995
@@ -325,7 +325,7 @@
 	if (MAJOR(CURRENT->rq_dev) != MAJOR_NR) \
 		panic(DEVICE_NAME ": request list destroyed"); \
 	if (CURRENT->bh) { \
-		if (!CURRENT->bh->b_lock) \
+		if (!buffer_locked(CURRENT->bh)) \
 			panic(DEVICE_NAME ": block not locked"); \
 	}
 
@@ -362,7 +362,7 @@
 	if ((bh = req->bh) != NULL) {
 		req->bh = bh->b_reqnext;
 		bh->b_reqnext = NULL;
-		bh->b_uptodate = uptodate;		
+		mark_buffer_uptodate(bh, uptodate);
 		unlock_buffer(bh);
 		if ((bh = req->bh) != NULL) {
 			req->current_nr_sectors = bh->b_size >> 9;
diff -u --recursive --new-file v1.3.44/linux/include/linux/cdk.h linux/include/linux/cdk.h
--- v1.3.44/linux/include/linux/cdk.h	Fri Sep 15 11:13:02 1995
+++ linux/include/linux/cdk.h	Mon Nov 27 09:24:50 1995
@@ -461,12 +461,12 @@
  *	to the board. These include interrupting it, and initializeing
  *	the driver after board startup and shutdown.
  */
-#define	STLCMD		(((unsigned long) 's') << 8)
+#include <linux/ioctl.h>
 
-#define	STL_BINTR	(STLCMD | 20)
-#define	STL_BSTART	(STLCMD | 21)
-#define	STL_BSTOP	(STLCMD | 22)
-#define	STL_BRESET	(STLCMD | 23)
+#define	STL_BINTR	_IO('s',20)
+#define	STL_BSTART	_IO('s',21)
+#define	STL_BSTOP	_IO('s',22)
+#define	STL_BRESET	_IO('s',23)
 
 /*****************************************************************************/
 #endif
diff -u --recursive --new-file v1.3.44/linux/include/linux/fs.h linux/include/linux/fs.h
--- v1.3.44/linux/include/linux/fs.h	Fri Nov 17 08:42:28 1995
+++ linux/include/linux/fs.h	Mon Nov 27 09:24:50 1995
@@ -13,6 +13,9 @@
 #include <linux/vfs.h>
 #include <linux/net.h>
 #include <linux/kdev_t.h>
+#include <linux/ioctl.h>
+
+#include <asm/bitops.h>
 
 /*
  * It's silly to have NR_OPEN bigger than NR_FILE, but I'll fix
@@ -94,17 +97,17 @@
 /* the read-only stuff doesn't really belong here, but any other place is
    probably as bad and I don't want to create yet another include file. */
 
-#define BLKROSET 4701 /* set device read-only (0 = read-write) */
-#define BLKROGET 4702 /* get read-only status (0 = read_write) */
-#define BLKRRPART 4703 /* re-read partition table */
-#define BLKGETSIZE 4704 /* return device size */
-#define BLKFLSBUF 4705 /* flush buffer cache */
-#define BLKRASET 4706 /* Set read ahead for block device */
-#define BLKRAGET 4707 /* get current read ahead setting */
+#define BLKROSET   _IO(0x12,93)	/* set device read-only (0 = read-write) */
+#define BLKROGET   _IO(0x12,94)	/* get read-only status (0 = read_write) */
+#define BLKRRPART  _IO(0x12,95)	/* re-read partition table */
+#define BLKGETSIZE _IO(0x12,96)	/* return device size */
+#define BLKFLSBUF  _IO(0x12,97)	/* flush buffer cache */
+#define BLKRASET   _IO(0x12,98)	/* Set read ahead for block device */
+#define BLKRAGET   _IO(0x12,99)	/* get current read ahead setting */
 
 #define BMAP_IOCTL 1		/* obsolete - kept for compatibility */
-#define FIBMAP	   0x0001	/* bmap access */
-#define FIGETBSZ   0x0002	/* get the block size used for bmap */
+#define FIBMAP	   _IO(0x00,1)	/* bmap access */
+#define FIGETBSZ   _IO(0x00,2)	/* get the block size used for bmap */
 
 #ifdef __KERNEL__
 extern void buffer_init(void);
@@ -114,28 +117,22 @@
 
 typedef char buffer_block[BLOCK_SIZE];
 
+/* bh state bits */
+#define BH_Uptodate	0	/* 1 if the buffer contains valid data */
+#define BH_Dirty	1	/* 1 if the buffer is dirty */
+#define BH_Lock		2	/* 1 if the buffer is locked */
+#define BH_Req		3	/* 0 if the buffer has been invalidated */
+#define BH_Touched	4	/* 1 if the buffer has been touched (aging) */
+#define BH_Has_aged	5	/* 1 if the buffer has been aged (aging) */
+
 struct buffer_head {
 	char * b_data;			/* pointer to data block (1024 bytes) */
 	unsigned long b_size;		/* block size */
 	unsigned long b_blocknr;	/* block number */
 	kdev_t b_dev;			/* device (B_FREE = free) */
-
-	unsigned short b_count;		/* users using this block */
-	unsigned char b_uptodate;
-	unsigned char b_dirt;		/* 0-clean,1-dirty */
-	unsigned char b_lock;		/* 0 - ok, 1 -locked */
-	unsigned char b_req;		/* 0 if the buffer has been 
-					 * invalidated */
-	unsigned char b_list;		/* List that this buffer appears */
-	unsigned char b_reuse;		/* 0 - normal, 
-					 * 1 - better reused for something 
-					 *     else */
-	unsigned char b_touched:1;	/* True if the buffer has been
-					 * accessed since it was last aged */
-	unsigned char b_has_aged:1;	/* True if the buffer has aged
-					 * (by alias to another buffer
-					 * on the same page) since it
-					 * was last scanned for aging */
+	unsigned long b_state;		/* buffer state bitmap (see above) */
+	unsigned int b_count;		/* users using this block */
+	unsigned int b_list;		/* List that this buffer appears */
 	unsigned long b_flushtime;      /* Time when this (dirty) buffer
 					 * should be written */
 	unsigned long b_lru_time;       /* Time when this buffer was 
@@ -149,6 +146,36 @@
 	struct buffer_head * b_reqnext;		/* request queue */
 };
 
+static inline int buffer_uptodate(struct buffer_head * bh)
+{
+	return test_bit(BH_Uptodate, &bh->b_state);
+}	
+
+static inline int buffer_dirty(struct buffer_head * bh)
+{
+	return test_bit(BH_Dirty, &bh->b_state);
+}
+
+static inline int buffer_locked(struct buffer_head * bh)
+{
+	return test_bit(BH_Lock, &bh->b_state);
+}
+
+static inline int buffer_req(struct buffer_head * bh)
+{
+	return test_bit(BH_Req, &bh->b_state);
+}
+
+static inline int buffer_touched(struct buffer_head * bh)
+{
+	return test_bit(BH_Touched, &bh->b_state);
+}
+
+static inline int buffer_has_aged(struct buffer_head * bh)
+{
+	return test_bit(BH_Has_aged, &bh->b_state);
+}
+
 #include <linux/pipe_fs_i.h>
 #include <linux/minix_fs_i.h>
 #include <linux/ext_fs_i.h>
@@ -445,23 +472,30 @@
 #define BUF_SHARED 5   /* Buffers shared */
 #define NR_LIST 6
 
+extern inline void mark_buffer_uptodate(struct buffer_head * bh, int on)
+{
+	if (on)
+		set_bit(BH_Uptodate, &bh->b_state);
+	else
+		clear_bit(BH_Uptodate, &bh->b_state);
+}
+
 extern inline void mark_buffer_clean(struct buffer_head * bh)
 {
-  if(bh->b_dirt) {
-    bh->b_dirt = 0;
-    if(bh->b_list == BUF_DIRTY) refile_buffer(bh);
-  }
+	if (clear_bit(BH_Dirty, &bh->b_state)) {
+		if (bh->b_list == BUF_DIRTY)
+			refile_buffer(bh);
+	}
 }
 
 extern inline void mark_buffer_dirty(struct buffer_head * bh, int flag)
 {
-  if(!bh->b_dirt) {
-    bh->b_dirt = 1;
-    set_writetime(bh, flag);
-    if(bh->b_list != BUF_DIRTY) refile_buffer(bh);
-  }
+	if (!set_bit(BH_Dirty, &bh->b_state)) {
+		set_writetime(bh, flag);
+		if (bh->b_list != BUF_DIRTY)
+			refile_buffer(bh);
+	}
 }
-
 
 extern int check_disk_change(kdev_t dev);
 extern void invalidate_inodes(kdev_t dev);
diff -u --recursive --new-file v1.3.44/linux/include/linux/locks.h linux/include/linux/locks.h
--- v1.3.44/linux/include/linux/locks.h	Wed Dec  1 14:44:15 1993
+++ linux/include/linux/locks.h	Sun Nov 26 19:23:10 1995
@@ -9,20 +9,19 @@
 
 extern inline void wait_on_buffer(struct buffer_head * bh)
 {
-	if (bh->b_lock)
+	if (test_bit(BH_Lock, &bh->b_state))
 		__wait_on_buffer(bh);
 }
 
 extern inline void lock_buffer(struct buffer_head * bh)
 {
-	if (bh->b_lock)
+	if (set_bit(BH_Lock, &bh->b_state))
 		__wait_on_buffer(bh);
-	bh->b_lock = 1;
 }
 
 extern inline void unlock_buffer(struct buffer_head * bh)
 {
-	bh->b_lock = 0;
+	clear_bit(BH_Lock, &bh->b_state);
 	wake_up(&bh->b_wait);
 }
 
diff -u --recursive --new-file v1.3.44/linux/include/linux/timex.h linux/include/linux/timex.h
--- v1.3.44/linux/include/linux/timex.h	Sun Oct 29 11:38:49 1995
+++ linux/include/linux/timex.h	Sun Nov 26 10:52:28 1995
@@ -74,7 +74,7 @@
 #define FINEUSEC (1L << SHIFT_SCALE) /* 1 us in phase units */
 
 #define MAXPHASE 512000L        /* max phase error (us) */
-#define MAXFREQ (512000L << SHIFT_USEC)  /* max frequency error (ppm) */
+#define MAXFREQ (100L << SHIFT_USEC)  /* max frequency error (ppm) */
 #define MAXTIME (200L << PPS_AVG) /* max PPS error (jitter) (200 us) */
 #define MINSEC 16L              /* min interval between updates (s) */
 #define MAXSEC 1200L            /* max interval between updates (s) */
diff -u --recursive --new-file v1.3.44/linux/include/linux/umsdos_fs.h linux/include/linux/umsdos_fs.h
--- v1.3.44/linux/include/linux/umsdos_fs.h	Wed Mar 22 10:31:43 1995
+++ linux/include/linux/umsdos_fs.h	Mon Nov 27 09:24:50 1995
@@ -16,6 +16,9 @@
 #ifndef _LINUX_DIRENT_H
 #include <linux/dirent.h>
 #endif
+#ifndef _LINUX_IOCTL_H
+#include <linux/ioctl.h>
+#endif
 
 struct umsdos_fake_info {
 	char fname[13];
@@ -70,19 +73,19 @@
 /* The next ioctl commands operate only on the DOS directory */
 /* The file umsdos_progs/umsdosio.c contain a string table */
 /* based on the order of those definition. Keep it in sync */
-#define UMSDOS_READDIR_DOS	1234	/* Do a readdir of the DOS directory */
-#define UMSDOS_UNLINK_DOS	1235	/* Erase in the DOS directory only */
-#define UMSDOS_RMDIR_DOS	1236	/* rmdir in the DOS directory only */
-#define UMSDOS_STAT_DOS		1237	/* Get info about a file */
+#define UMSDOS_READDIR_DOS _IO(0x04,210) /* Do a readdir of the DOS directory */
+#define UMSDOS_UNLINK_DOS  _IO(0x04,211) /* Erase in the DOS directory only */
+#define UMSDOS_RMDIR_DOS   _IO(0x04,212) /* rmdir in the DOS directory only */
+#define UMSDOS_STAT_DOS    _IO(0x04,213) /* Get info about a file */
 /* The next ioctl commands operate only on the EMD file */
-#define UMSDOS_CREAT_EMD	1238	/* Create a file */
-#define UMSDOS_UNLINK_EMD	1239	/* unlink (rmdir) a file */
-#define UMSDOS_READDIR_EMD	1240	/* read the EMD file only. */
-#define UMSDOS_GETVERSION	1241	/* Get the release number of UMSDOS */
-#define UMSDOS_INIT_EMD		1242	/* Create the EMD file if not there */
-#define UMSDOS_DOS_SETUP	1243	/* Set the defaults of the MsDOS driver */
+#define UMSDOS_CREAT_EMD   _IO(0x04,214) /* Create a file */
+#define UMSDOS_UNLINK_EMD  _IO(0x04,215) /* unlink (rmdir) a file */
+#define UMSDOS_READDIR_EMD _IO(0x04,216) /* read the EMD file only. */
+#define UMSDOS_GETVERSION  _IO(0x04,217) /* Get the release number of UMSDOS */
+#define UMSDOS_INIT_EMD    _IO(0x04,218) /* Create the EMD file if not there */
+#define UMSDOS_DOS_SETUP   _IO(0x04,219) /* Set the defaults of the MsDOS driver */
 
-#define UMSDOS_RENAME_DOS	1244	/* rename a file/directory in the DOS */
+#define UMSDOS_RENAME_DOS  _IO(0x04,220) /* rename a file/directory in the DOS */
 									/* directory only */
 struct umsdos_ioctl{
 	struct dirent dos_dirent;
diff -u --recursive --new-file v1.3.44/linux/init/main.c linux/init/main.c
--- v1.3.44/linux/init/main.c	Tue Nov 21 13:22:13 1995
+++ linux/init/main.c	Mon Nov 27 09:24:50 1995
@@ -123,8 +123,8 @@
 char *execute_command = 0;
 
 #ifdef CONFIG_ROOT_NFS
-char nfs_root_name[256] = { 0, };
-extern int nfs_root_init(char *name);
+char nfs_root_name[256] = { NFS_ROOT };
+char nfs_root_addrs[128] = { "" };
 #endif
 
 static char * argv_init[MAX_INIT_ARGS+2] = { "init", NULL, };
@@ -397,16 +397,24 @@
 			continue;
 		}
 #ifdef CONFIG_ROOT_NFS
-		if (!strncmp(line,"nfsroot=",8)) {
-			int n = 255 - strlen (NFS_ROOT);
+		if (!strncmp(line, "nfsroot=", 8)) {
+			int n;
 			line += 8;
-			if (line [0] == '/' || (line [0] >= '0' && line [0] <= '9')){
-				strncpy (nfs_root_name, line, 255);
+			if (line[0] == '/' || (line[0] >= '0' && line[0] <= '9')) {
+				strncpy(nfs_root_name, line, sizeof(nfs_root_name));
+				nfs_root_name[sizeof(nfs_root_name)] = '\0';
 				continue;
 			}
-			if (strlen (line) >= n)
-			        line [n] = 0;
-			sprintf (nfs_root_name, NFS_ROOT, line);
+			n = strlen(line) + strlen(NFS_ROOT);
+			if (n >= sizeof(nfs_root_name))
+				line[sizeof(nfs_root_name) - strlen(NFS_ROOT) - 1] = '\0';
+			sprintf(nfs_root_name, NFS_ROOT, line);
+			continue;
+		}
+		if (!strncmp(line, "nfsaddrs=", 9)) {
+			line += 9;
+			strncpy(nfs_root_addrs, line, sizeof(nfs_root_addrs));
+			nfs_root_addrs[sizeof(nfs_root_addrs)] = '\0';
 			continue;
 		}
 #endif
diff -u --recursive --new-file v1.3.44/linux/kernel/sched.c linux/kernel/sched.c
--- v1.3.44/linux/kernel/sched.c	Tue Nov 21 13:22:14 1995
+++ linux/kernel/sched.c	Sun Nov 26 10:52:28 1995
@@ -49,9 +49,9 @@
  * phase-lock loop variables
  */
 int time_state = TIME_BAD;     /* clock synchronization status */
-int time_status = STA_UNSYNC;	/* clock status bits */
+int time_status = STA_UNSYNC | STA_PLL;	/* clock status bits */
 long time_offset = 0;           /* time adjustment (us) */
-long time_constant = 0;         /* pll time constant */
+long time_constant = 2;         /* pll time constant */
 long time_tolerance = MAXFREQ;  /* frequency tolerance (ppm) */
 long time_precision = 1; 	/* clock precision (us) */
 long time_maxerror = 0x70000000;/* maximum error */
diff -u --recursive --new-file v1.3.44/linux/mm/memory.c linux/mm/memory.c
--- v1.3.44/linux/mm/memory.c	Thu Nov  9 11:23:56 1995
+++ linux/mm/memory.c	Sun Nov 26 10:46:03 1995
@@ -663,7 +663,7 @@
 		goto good_area;
 	if (!(vma->vm_flags & VM_GROWSDOWN))
 		goto bad_area;
-	if (vma->vm_end - start > current->rlim[RLIMIT_STACK].rlim_cur)
+	if (expand_stack(vma, start))
 		goto bad_area;
 
 good_area:
diff -u --recursive --new-file v1.3.44/linux/net/ipv4/icmp.c linux/net/ipv4/icmp.c
--- v1.3.44/linux/net/ipv4/icmp.c	Fri Nov 17 08:42:33 1995
+++ linux/net/ipv4/icmp.c	Mon Nov 27 10:34:00 1995
@@ -356,14 +356,14 @@
 			case ICMP_HOST_UNREACH:
 				break;
 			case ICMP_PROT_UNREACH:
-				printk("ICMP: %s:%d: protocol unreachable.\n",
+				printk(KERN_INFO "ICMP: %s:%d: protocol unreachable.\n",
 					in_ntoa(iph->daddr), ntohs(iph->protocol));
 				break;
 			case ICMP_PORT_UNREACH:
 				break;
 			case ICMP_FRAG_NEEDED:
 #ifdef CONFIG_NO_PATH_MTU_DISCOVERY
-				printk("ICMP: %s: fragmentation needed and DF set.\n",
+				printk(KERN_INFO "ICMP: %s: fragmentation needed and DF set.\n",
 								in_ntoa(iph->daddr));
 				break;
 #else
@@ -408,7 +408,7 @@
 			}
 #endif
 			case ICMP_SR_FAILED:
-				printk("ICMP: %s: Source Route Failed.\n", in_ntoa(iph->daddr));
+				printk(KERN_INFO "ICMP: %s: Source Route Failed.\n", in_ntoa(iph->daddr));
 				break;
 			default:
 				break;
@@ -483,7 +483,7 @@
 	/*
 	 *	We are a router. Routers should not respond to ICMP_REDIRECT messages.
 	 */
-	printk("icmp: ICMP redirect from %s on %s ignored.\n", in_ntoa(source), dev->name);
+	printk(KERN_INFO "icmp: ICMP redirect from %s on %s ignored.\n", in_ntoa(source), dev->name);
 #else	
 	switch(icmph->code & 7) 
 	{
@@ -511,12 +511,12 @@
 			 *	(not some confused thing sending our
 			 *	address)
 			 */
-			printk("ICMP redirect from %s\n", in_ntoa(source));
+			printk(KERN_INFO "ICMP redirect from %s\n", in_ntoa(source));
 			ip_rt_redirect(source, ip, icmph->un.gateway, dev);
 			break;
 		case ICMP_REDIR_NETTOS:
 		case ICMP_REDIR_HOSTTOS:
-			printk("ICMP: cannot handle TOS redirects yet!\n");
+			printk(KERN_INFO "ICMP: cannot handle TOS redirects yet!\n");
 			break;
 		default:
 			break;
@@ -648,7 +648,7 @@
 	{
 		/* Failed checksum! */
 		icmp_statistics.IcmpInErrors++;
-		printk("ICMP: failed checksum from %s!\n", in_ntoa(saddr));
+		printk(KERN_INFO "ICMP: failed checksum from %s!\n", in_ntoa(saddr));
 		kfree_skb(skb, FREE_READ);
 		return(0);
 	}
