# This is a BitKeeper generated patch for the following project:
# Project Name: Linux kernel tree
# This patch format is intended for GNU patch command version 2.5 or higher.
# This patch includes the following deltas:
#	           ChangeSet	v2.5.72 -> 1.1348 
#	  arch/sparc/Kconfig	1.13.1.1 -> 1.16   
#	drivers/i2c/chips/w83781d.c	1.9     -> 1.12   
#	include/asm-ia64/sn/xtalk/xwidget.h	1.3     -> 1.4    
#	drivers/scsi/arm/oak.c	1.19    -> 1.20   
#	arch/ia64/sn/io/xbow.c	1.6     ->         (deleted)      
#	arch/ia64/kernel/efi_stub.S	1.4     -> 1.5    
#	drivers/pcmcia/cs_internal.h	1.19    -> 1.20   
#	drivers/i2c/chips/Makefile	1.6     -> 1.7    
#	drivers/scsi/megaraid.c	1.47    -> 1.49   
#	arch/ia64/kernel/fsys.S	1.10    -> 1.15   
#	arch/ia64/sn/io/sgi_io_init.c	1.4     -> 1.5     arch/ia64/sn/io/platform_init/sgi_io_init.c (moved)
#	include/asm-ia64/sn/pci/pcibr_private.h	1.6     -> 1.7    
#	arch/ia64/sn/fakeprom/klgraph_init.c	1.2     -> 1.3    
#	arch/ia64/sn/io/sn2/ml_iograph.c	1.1     -> 1.3    
#	drivers/usb/misc/usblcd.c	1.9     -> 1.10   
#	  drivers/scsi/ips.c	1.58    -> 1.59   
#	arch/ia64/sn/fakeprom/make_textsym	1.4     -> 1.5    
#	include/asm-ia64/sn/pci/pciio.h	1.4     -> 1.5    
#	drivers/usb/input/kbtab.c	1.3     -> 1.4    
#	drivers/scsi/scsi_error.c	1.54    -> 1.56   
#	include/asm-ia64/topology.h	1.7     -> 1.8    
#	drivers/usb/storage/protocol.c	1.10    -> 1.11   
#	arch/ia64/sn/io/sn2/xtalk.c	1.1     -> 1.2    
#	drivers/usb/misc/tiglusb.c	1.19    -> 1.20   
#	include/asm-arm/proc-armv/uaccess.h	1.9     -> 1.10   
#	include/asm-ia64/sigcontext.h	1.5     -> 1.6    
#	include/asm-ia64/sn/sn1/hubstat.h	1.1     ->         (deleted)      
#	drivers/scsi/pas16.c	1.10    -> 1.11   
#	arch/ia64/sn/io/sn2/ml_SN_init.c	1.1     -> 1.3    
#	include/asm-ia64/sn/sgi.h	1.4     -> 1.6    
#	      kernel/ksyms.c	1.203   -> 1.204  
#	drivers/usb/Makefile.lib	1.5     -> 1.6    
#	drivers/i2c/chips/adm1021.c	1.17    -> 1.18   
#	arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c	1.1     ->         (deleted)      
#	drivers/scsi/pci2220i.c	1.22    -> 1.23   
#	include/asm-ia64/pgalloc.h	1.16    -> 1.17   
#	arch/ia64/ia32/ia32_signal.c	1.17    -> 1.19   
#	drivers/usb/class/usb-midi.c	1.18    -> 1.19   
#	drivers/usb/net/Makefile	1.7     -> 1.8    
#	arch/ia64/sn/io/sn2/klconflib.c	1.1.1.1 -> 1.3    
#	include/asm-ia64/sn/sn_fru.h	1.3     -> 1.4    
#	  arch/ia64/Makefile	1.44    -> 1.53   
#	arch/ia64/sn/io/pciba.c	1.7.1.1 ->         (deleted)      
#	arch/ia64/sn/io/sn2/module.c	1.1     -> 1.2    
#	include/linux/nfsd/state.h	1.3     -> 1.4    
#	drivers/scsi/aha152x.c	1.31    -> 1.32   
#	arch/ia64/sn/io/sn2/pcibr/pcibr_error.c	1.4     -> 1.5    
#	arch/ia64/sn/io/eeprom.c	1.3     ->         (deleted)      
#	drivers/scsi/hosts.c	1.70    -> 1.77   
#	drivers/usb/input/wacom.c	1.28    -> 1.29   
#	include/asm-ia64/io.h	1.11    -> 1.13   
#	    fs/ext3/balloc.c	1.11    -> 1.15   
#	drivers/scsi/53c700.h	1.12    -> 1.13   
#	include/asm-ia64/sn/sn2/shub_mmr_t.h	1.1     -> 1.2    
#	  net/llc/llc_conn.c	1.29    -> 1.30   
#	drivers/scsi/atp870u.h	1.10    -> 1.11   
#	arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c	1.3     -> 1.4    
#	net/ipv6/ip6_tunnel.c	1.1     -> 1.2    
#	include/asm-ia64/sn/iograph.h	1.4     -> 1.5    
#	drivers/usb/gadget/net2280.c	1.10    -> 1.11   
#	drivers/scsi/scsi_proc.c	1.25    -> 1.28   
#	drivers/scsi/aic7xxx/aic7xxx_osm.c	1.42    -> 1.43   
#	  net/llc/llc_c_ev.c	1.8     -> 1.9    
#	arch/ia64/ia32/ia32_support.c	1.7     -> 1.9    
#	include/asm-ia64/sn/vector.h	1.3     -> 1.4    
#	include/asm-ia64/sn/hcl_util.h	1.2     -> 1.3    
#	arch/ia64/lib/idiv64.S	1.3     -> 1.4    
#	include/asm-ia64/spinlock.h	1.11    -> 1.13   
#	drivers/scsi/jazz_esp.c	1.6     -> 1.8    
#	include/asm-ia64/sn/sn2/addrs.h	1.2     -> 1.3    
#	arch/ia64/sn/kernel/iomv.c	1.1     ->         (deleted)      
#	include/linux/ext3_jbd.h	1.10    -> 1.13   
#	include/asm-ia64/sn/sn_private.h	1.3     -> 1.4    
#	arch/ia64/sn/io/sn2/pci_bus_cvlink.c	1.2.1.1 ->         (deleted)      
#	drivers/scsi/arm/cumana_1.c	1.18    -> 1.19   
#	include/asm-ia64/sn/io.h	1.4     -> 1.5    
#	     fs/jbd/revoke.c	1.12    -> 1.13   
#	drivers/scsi/lasi700.c	1.8     -> 1.11   
#	include/asm-ia64/sn/pci/pciba.h	1.3     ->         (deleted)      
#	net/sunrpc/svcsock.c	1.50    -> 1.53   
#	drivers/block/ll_rw_blk.c	1.173   -> 1.174  
#	drivers/scsi/ibmmca.c	1.19    -> 1.20   
#	include/asm-ia64/sn/leds.h	1.4     -> 1.5    
#	drivers/net/wireless/airo.c	1.40    -> 1.41   
#	drivers/scsi/bvme6000.c	1.5     -> 1.6    
#	include/asm-ia64/sn/pio.h	1.3     -> 1.4    
#	include/asm-ia64/unistd.h	1.25    -> 1.28   
#	include/linux/rmap-locking.h	1.2     -> 1.3    
#	   include/net/tcp.h	1.48    -> 1.49   
#	arch/ia64/sn/kernel/sn_asm.S	1.2     ->         (deleted)      
#	include/asm-v850/io.h	1.1     -> 1.2    
#	arch/ia64/sn/io/klgraph.c	1.3     ->         (deleted)      
#	include/asm-ia64/page.h	1.17    -> 1.19   
#	net/sctp/endpointola.c	1.25    -> 1.26   
#	drivers/ieee1394/sbp2.c	1.34    -> 1.35   
#	include/asm-ia64/sn/invent.h	1.3     -> 1.4    
#	arch/ia64/kernel/setup.c	1.41.1.1 -> 1.52   
#	drivers/scsi/NCR_D700.c	1.12    -> 1.14   
#	include/asm-ia64/sn/sn1/hublb_next.h	1.2     ->         (deleted)      
#	drivers/scsi/dc395x.c	1.6     -> 1.7    
#	include/asm-v850/hardirq.h	1.3     -> 1.4    
#	drivers/scsi/sym53c416.c	1.17    -> 1.18   
#	arch/ia64/sn/kernel/Makefile	1.11    -> 1.13   
#	include/asm-ia64/sn/sn_cpuid.h	1.5     -> 1.6    
#	arch/ia64/hp/common/sba_iommu.c	1.23    -> 1.25   
#	arch/ia64/sn/io/xtalk.c	1.6     ->         (deleted)      
#	include/asm-ia64/sn/sn2/sn_private.h	1.2     -> 1.3    
#	   arch/i386/Kconfig	1.60    -> 1.61   
#	arch/ia64/kernel/ivt.S	1.14    -> 1.22   
#	drivers/scsi/53c700.c	1.33    -> 1.35   
#	arch/ia64/sn/kernel/irq.c	1.5     -> 1.6    
#	include/asm-ia64/sn/sn1/arch.h	1.2     ->         (deleted)      
#	    drivers/atm/he.c	1.12    -> 1.15   
#	      net/ipv4/udp.c	1.43    -> 1.44   
#	    net/ipx/af_ipx.c	1.37    -> 1.39   
#	    fs/jbd/journal.c	1.33    -> 1.56   
#	    fs/nfsd/nfsctl.c	1.35    -> 1.36   
#	 drivers/scsi/eata.h	1.19    ->         (deleted)      
#	include/asm-ia64/sn/hack.h	1.4     ->         (deleted)      
#	drivers/usb/class/usblp.c	1.45    -> 1.49   
#	arch/ia64/sn/kernel/mca.c	1.4     -> 1.5    
#	include/asm-ia64/kregs.h	1.5     -> 1.6    
#	include/asm-ia64/sn/mca.h	1.1     ->         (deleted)      
#	include/asm-ia64/sn/sn1/hubmd_next.h	1.3     ->         (deleted)      
#	net/bluetooth/af_bluetooth.c	1.20    -> 1.21   
#	arch/ia64/sn/kernel/sv.c	1.5     -> 1.6    
#	  net/llc/llc_evnt.c	1.6     -> 1.7    
#	drivers/scsi/scsi_sysfs.c	1.21    -> 1.22   
#	include/asm-ia64/sn/pci/bridge.h	1.7     -> 1.8    
#	include/asm-ia64/sn/nodepda.h	1.4     -> 1.5    
#	arch/ia64/sn/io/sn1/huberror.c	1.3     ->         (deleted)      
#	include/asm-ia64/sn/sn1/synergy.h	1.5     ->         (deleted)      
#	arch/ia64/sn/io/xswitch.c	1.4     -> 1.6    
#	arch/ia64/kernel/time.c	1.21.1.1 -> 1.27   
#	  net/atm/atm_misc.c	1.4     -> 1.6    
#	include/asm-ia64/mca.h	1.7     -> 1.8    
#	include/asm-ia64/sn/arc/hinv.h	1.3     -> 1.4    
#	   drivers/atm/eni.c	1.14    -> 1.16   
#	net/ipv6/xfrm6_policy.c	1.8     -> 1.9    
#	arch/arm/mm/fault-armv.c	1.21    -> 1.22   
#	drivers/block/cciss_scsi.c	1.15    -> 1.16   
#	 fs/jbd/checkpoint.c	1.8     -> 1.21   
#	include/asm-ia64/sn/sv.h	1.3     -> 1.4    
#	include/asm-ia64/asmmacro.h	1.9     -> 1.12   
#	include/asm-ia64/sn/intr.h	1.4     -> 1.5    
#	drivers/usb/core/message.c	1.27    -> 1.28   
#	arch/ia64/kernel/smpboot.c	1.32    -> 1.35   
#	   drivers/scsi/sr.c	1.80.1.1 -> 1.82   
#	    net/key/af_key.c	1.42    -> 1.43   
#	drivers/net/bonding/bonding.h	1.1     -> 1.2    
#	drivers/scsi/aha1740.c	1.16    -> 1.19   
#	arch/ia64/sn/io/Makefile	1.11    -> 1.14   
#	 drivers/scsi/scsi.h	1.83    -> 1.87   
#	include/asm-ia64/sn/xtalk/xbow.h	1.4     -> 1.5    
#	arch/ia64/sn/kernel/probe.c	1.2     -> 1.3    
#	 drivers/pcmcia/cs.c	1.43    -> 1.45   
#	drivers/usb/storage/usb.c	1.64.1.2 -> 1.68   
#	drivers/net/wireless/atmel.c	1.1     -> 1.2    
#	arch/ia64/kernel/entry.S	1.40    -> 1.42   
#	drivers/scsi/ini9100u.c	1.15    -> 1.16   
#	arch/ia64/sn/kernel/setup.c	1.11    -> 1.14   
#	drivers/usb/misc/rio500_usb.h	1.2     -> 1.3    
#	arch/ia64/sn/fakeprom/fpromasm.S	1.3     -> 1.4    
#	drivers/net/wan/syncppp.c	1.12    -> 1.13   
#	include/asm-ia64/sn/sn1/hwcntrs.h	1.3     ->         (deleted)      
#	drivers/md/dm-ioctl.c	1.24    -> 1.25   
#	drivers/oprofile/buffer_sync.c	1.20    -> 1.21   
#	arch/ia64/sn/io/sn1/mem_refcnt.c	1.5     ->         (deleted)      
#	drivers/scsi/scsi_module.c	1.2     -> 1.4    
#	      net/ipv4/tcp.c	1.45    -> 1.46   
#	arch/ia64/sn/io/cdl.c	1.4     -> 1.5    
#	arch/ia64/sn/io/pci.c	1.5     -> 1.7     arch/ia64/sn/io/machvec/pci.c (moved)
#	include/net/syncppp.h	1.3     -> 1.4    
#	include/asm-ia64/sn/sn1/intr.h	1.2     ->         (deleted)      
#	 arch/mips64/Kconfig	1.13    -> 1.14   
#	      net/atm/proc.c	1.17    -> 1.19   
#	arch/ia64/sn/io/pci_dma.c	1.7     -> 1.9     arch/ia64/sn/io/machvec/pci_dma.c (moved)
#	include/asm-ia64/sn/pci/pci_defs.h	1.3     -> 1.4    
#	drivers/scsi/inia100.c	1.23    -> 1.24   
#	include/asm-ia64/sn/ifconfig_net.h	1.1     -> 1.2    
#	include/asm-ia64/pgtable.h	1.18.1.1 -> 1.28   
#	arch/ia64/sn/io/klconflib.c	1.4.1.1 ->         (deleted)      
#	       net/atm/pvc.c	1.8     -> 1.12   
#	fs/jbd/transaction.c	1.31    -> 1.67   
#	drivers/scsi/u14-34f.c	1.28    -> 1.29   
#	include/asm-ia64/sn/klconfig.h	1.5     -> 1.6    
#	include/asm-ia64/sn/router.h	1.4     -> 1.5    
#	include/asm-ia64/sn/sn1/hubxb_next.h	1.3     ->         (deleted)      
#	drivers/pcmcia/cistpl.c	1.16    -> 1.17   
#	include/asm-ia64/sn/ksys/l1.h	1.4     -> 1.5    
#	include/asm-ia64/sn/pio_flush.h	1.1     ->         (deleted)      
#	drivers/scsi/hosts.h	1.67    -> 1.73   
#	include/asm-ia64/sn/module.h	1.5     -> 1.6    
#	include/asm-ia64/sn/sn1/sn_private.h	1.2     ->         (deleted)      
#	 net/ipv4/tcp_ipv4.c	1.62    -> 1.64   
#	arch/ia64/sn/io/sgi_io_sim.c	1.4     -> 1.5    
#	include/asm-ia64/sn/mmtimer_private.h	1.1     -> 1.2    
#	drivers/pcmcia/yenta.h	1.3     -> 1.4     drivers/pcmcia/yenta_socket.h (moved)
#	   fs/nfsd/nfsproc.c	1.24    -> 1.25   
#	drivers/scsi/scsi_devinfo.c	1.2     -> 1.5    
#	       fs/ext3/acl.c	1.7     -> 1.8    
#	arch/ia64/sn/io/sn2/sgi_io_init.c	1.1     ->         (deleted)      
#	arch/ia64/sn/io/ifconfig_net.c	1.4     -> 1.6     arch/ia64/sn/io/drivers/ifconfig_net.c (moved)
#	include/asm-ia64/sn/ioc3.h	1.2     -> 1.3    
#	include/asm-ia64/sn/sn2/arch.h	1.2     -> 1.3    
#	          fs/namei.c	1.75    -> 1.76   
#	drivers/i2c/chips/lm85.c	1.1     -> 1.2    
#	arch/arm/vmlinux-armv.lds.in	1.25    -> 1.26   
#	arch/ia64/ia32/ia32_traps.c	1.5     -> 1.6    
#	include/asm-ia64/processor.h	1.36    -> 1.46   
#	include/asm-ia64/sn/sn1/hubpi.h	1.2     ->         (deleted)      
#	     fs/nfsd/nfsfh.c	1.40    -> 1.41   
#	arch/ia64/sn/io/sn2/l1_command.c	1.2     -> 1.3    
#	include/asm-ia64/sn/hcl.h	1.3     -> 1.4    
#	include/asm-ia64/sn/sn1/hubdev.h	1.2     ->         (deleted)      
#	drivers/scsi/fd_mcs.c	1.14    -> 1.15   
#	drivers/scsi/amiga7xx.c	1.5     -> 1.6    
#	include/asm-ia64/sn/uart16550.h	1.3     -> 1.4    
#	drivers/scsi/nsp32.c	1.13    -> 1.14   
#	drivers/usb/storage/transport.c	1.77    -> 1.78   
#	drivers/scsi/arm/fas216.c	1.19    -> 1.21   
#	arch/ia64/sn/fakeprom/fpmem.c	1.7     -> 1.8    
#	arch/ia64/kernel/perfmon_generic.h	1.3     -> 1.5    
#	       fs/nfsd/vfs.c	1.61    -> 1.63   
#	arch/ia64/kernel/entry.h	1.5     -> 1.8    
#	arch/ia64/sn/io/labelcl.c	1.4     ->         (deleted)      
#	arch/ia64/sn/io/module.c	1.4     ->         (deleted)      
#	      net/ipv6/raw.c	1.31    -> 1.32   
#	   arch/s390/Kconfig	1.10    -> 1.11   
#	     fs/ext3/ioctl.c	1.8     -> 1.9    
#	include/asm-ia64/sn/arch.h	1.4     -> 1.5    
#	include/asm-ia64/ptrace_offsets.h	1.2     -> 1.4    
#	drivers/usb/storage/transport.h	1.27    -> 1.28   
#	drivers/scsi/atp870u.c	1.22    -> 1.23   
#	drivers/usb/misc/auerswald.c	1.32    -> 1.33   
#	arch/ia64/sn/kernel/sn1/sn1_smp.c	1.6     ->         (deleted)      
#	       net/netsyms.c	1.81    -> 1.83   
#	include/asm-ia64/sn/sn1/slotnum.h	1.3     ->         (deleted)      
#	arch/ia64/sn/kernel/sn1/cache.c	1.1     ->         (deleted)      
#	include/asm-sparc64/xor.h	1.2     -> 1.3    
#	include/asm-ia64/system.h	1.35    -> 1.39   
#	arch/ia64/sn/io/sn2/xbow.c	1.1     -> 1.4    
#	include/asm-ia64/tlb.h	1.13    -> 1.14   
#	arch/ia64/kernel/module.c	1.5     -> 1.7    
#	 arch/ia64/mm/init.c	1.35.1.1 -> 1.44   
#	 include/linux/usb.h	1.79    -> 1.80   
#	arch/arm/common/Makefile	1.3     -> 1.5    
#	include/asm-ia64/sn/driver.h	1.2     -> 1.3    
#	drivers/usb/storage/protocol.h	1.5     -> 1.6    
#	arch/ia64/sn/io/ate_utils.c	1.2     -> 1.3    
#	arch/ia64/hp/sim/Kconfig	1.1     -> 1.3    
#	drivers/scsi/seagate.c	1.18    -> 1.19   
#	arch/ia64/sn/io/io.c	1.6     -> 1.7    
#	include/asm-ia64/sn/kldir.h	1.3     -> 1.4    
#	include/asm-ia64/sn/sn2/io.h	1.1     -> 1.2    
#	include/asm-ia64/sn/sn1/addrs.h	1.4     ->         (deleted)      
#	   arch/v850/Kconfig	1.12    -> 1.13   
#	arch/ia64/kernel/ia64_ksyms.c	1.23    -> 1.32   
#	include/asm-ia64/sn/sn2/shubio.h	1.2     -> 1.4    
#	include/asm-ia64/sn/nag.h	1.1     -> 1.2    
#	include/asm-ia64/sn/systeminfo.h	1.2     -> 1.3    
#	include/asm-ia64/sn/klclock.h	1.2     -> 1.3    
#	drivers/usb/net/catc.c	1.26    -> 1.27   
#	drivers/usb/core/hub.c	1.70    -> 1.71   
#	arch/ia64/sn/io/pciio.c	1.3     ->         (deleted)      
#	arch/ia64/kernel/mca.c	1.29    -> 1.33   
#	arch/i386/kernel/setup.c	1.83.1.1 -> 1.85   
#	 include/linux/tcp.h	1.11    -> 1.12   
#	arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c	1.5.1.1 -> 1.7    
#	arch/ia64/kernel/process.c	1.34    -> 1.44   
#	include/asm-ia64/sn/prio.h	1.2     -> 1.3    
#	   arch/mips/Kconfig	1.11    -> 1.12   
#	drivers/atm/idt77252.c	1.14    -> 1.16   
#	drivers/scsi/AM53C974.c	1.14    -> 1.15   
#	arch/arm/mach-integrator/cpu.c	1.16    -> 1.17   
#	drivers/scsi/NCR53c406a.c	1.20    -> 1.23   
#	arch/ia64/lib/memcpy_mck.S	1.3     -> 1.4    
#	include/asm-ia64/sn/snconfig.h	1.1     ->         (deleted)      
#	drivers/serial/Makefile	1.16    -> 1.17   
#	arch/ia64/hp/sim/simserial.c	1.21    -> 1.22   
#	arch/ia64/kernel/acpi.c	1.40    -> 1.42   
#	     arch/um/Kconfig	1.9     -> 1.10   
#	drivers/scsi/mac_esp.c	1.10    -> 1.12   
#	arch/ia64/sn/io/sgi_if.c	1.4     -> 1.5    
#	net/econet/af_econet.c	1.21    -> 1.22   
#	include/linux/spinlock.h	1.24    -> 1.25   
#	drivers/usb/storage/isd200.c	1.30    -> 1.31   
#	drivers/scsi/scsi_syms.c	1.38    -> 1.40   
#	drivers/i2c/busses/i2c-i801.c	1.9     -> 1.10   
#	arch/sparc64/kernel/time.c	1.40    -> 1.41   
#	drivers/usb/storage/scsiglue.c	1.45    -> 1.48   
#	drivers/scsi/scsi_lib.c	1.92    -> 1.95   
#	    fs/ext3/ialloc.c	1.27    -> 1.30   
#	arch/ia64/sn/kernel/sn1/iomv.c	1.4     -> 1.5     arch/ia64/sn/io/machvec/iomv.c (moved)
#	drivers/usb/input/xpad.c	1.15    -> 1.16   
#	arch/ia64/sn/io/l1_command.c	1.3.1.1 ->         (deleted)      
#	arch/ia64/sn/io/alenlist.c	1.4     ->         (deleted)      
#	arch/ia64/sn/io/invent.c	1.4     ->         (deleted)      
#	net/netlink/af_netlink.c	1.28    -> 1.29   
#	include/asm-ia64/sn/bte.h	1.2     -> 1.3    
#	      net/core/dev.c	1.86    -> 1.87   
#	     kernel/compat.c	1.16    -> 1.17   
#	arch/ia64/sn/io/sn2/shub_intr.c	1.2     -> 1.3    
#	drivers/usb/core/usb.c	1.125   -> 1.126  
#	 drivers/scsi/scsi.c	1.113   -> 1.118  
#	drivers/usb/misc/brlvger.c	1.18    -> 1.19   
#	drivers/i2c/busses/i2c-ali15x3.c	1.8     -> 1.9    
#	include/asm-ia64/sn/sn1/bedrock.h	1.3     ->         (deleted)      
#	include/asm-ia64/sn/sn1/hubni.h	1.2     ->         (deleted)      
#	include/asm-ia64/sn/sn2/slotnum.h	1.1     -> 1.2    
#	arch/ia64/mm/hugetlbpage.c	1.10.1.1 -> 1.13   
#	include/asm-ia64/sn/eeprom.h	1.5     ->         (deleted)      
#	arch/ia64/sn/fakeprom/main.c	1.3     -> 1.4    
#	drivers/scsi/arm/acornscsi.c	1.31    -> 1.32   
#	drivers/scsi/arm/arxescsi.c	1.20    -> 1.21   
#	drivers/scsi/aha1542.c	1.27    -> 1.29   
#	arch/ia64/tools/Makefile	1.12    ->         (deleted)      
#	include/asm-ia64/sn/alenlist.h	1.5     -> 1.6    
#	net/decnet/af_decnet.c	1.29    -> 1.30   
#	drivers/scsi/ultrastor.c	1.18    -> 1.19   
#	drivers/scsi/megaraid.h	1.19    -> 1.21   
#	include/linux/sunrpc/cache.h	1.11    -> 1.12   
#	arch/ia64/sn/kernel/sn1/Makefile	1.8     ->         (deleted)      
#	arch/ia64/tools/print_offsets.awk	1.6     ->         (deleted)      
#	include/asm-ia64/sn/ioerror_handling.h	1.3     -> 1.4    
#	arch/ia64/sn/kernel/machvec.c	1.5     -> 1.6    
#	arch/ia64/sn/io/sn2/shub.c	1.1     -> 1.2    
#	    arch/arm/Kconfig	1.20    -> 1.23   
#	include/asm-ia64/xor.h	1.1     -> 1.3    
#	drivers/usb/net/usbnet.c	1.54    -> 1.56   
#	include/asm-ia64/machvec.h	1.14    -> 1.15   
#	include/asm-ia64/unwind.h	1.5     -> 1.7    
#	drivers/usb/storage/scsiglue.h	1.5     -> 1.6    
#	include/asm-ia64/sn/pci/pciio_private.h	1.4     -> 1.5    
#	arch/i386/kernel/nmi.c	1.20    -> 1.21   
#	include/linux/sunrpc/svc.h	1.20    -> 1.23   
#	  arch/ppc64/Kconfig	1.20    -> 1.21   
#	arch/ia64/sn/kernel/bte.c	1.2     -> 1.3    
#	drivers/i2c/chips/Kconfig	1.11    -> 1.12   
#	include/asm-ia64/sn/sndrv.h	1.2     -> 1.3    
#	arch/ia64/ia32/ia32_entry.S	1.24    -> 1.26   
#	      net/ipv4/raw.c	1.34    -> 1.35   
#	    fs/nfsd/nfssvc.c	1.37    -> 1.38   
#	drivers/scsi/aic7xxx/aic79xx_osm.c	1.46    -> 1.47   
#	 net/ipv6/tcp_ipv6.c	1.61    -> 1.62   
#	arch/ia64/sn/fakeprom/fpmem.h	1.3     -> 1.4    
#	arch/ia64/sn/io/klgraph_hack.c	1.6     ->         (deleted)      
#	     fs/ext3/xattr.c	1.15    -> 1.16   
#	include/asm-ia64/perfmon.h	1.13    -> 1.15   
#	arch/ia64/sn/io/sn1/hub_intr.c	1.2     ->         (deleted)      
#	include/asm-ia64/sn/idle.h	1.2     ->         (deleted)      
#	include/asm-ia64/sn/sn1/hubxb.h	1.2     ->         (deleted)      
#	arch/sparc/kernel/time.c	1.17    -> 1.18   
#	  net/sunrpc/cache.c	1.14    -> 1.15   
#	arch/ia64/kernel/sys_ia64.c	1.21    -> 1.23   
#	arch/i386/oprofile/init.c	1.6     -> 1.7    
#	arch/ia64/kernel/signal.c	1.24    -> 1.32   
#	arch/ia64/sn/io/hubspc.c	1.5     ->         (deleted)      
#	drivers/usb/input/hid-core.c	1.60    -> 1.61   
#	drivers/usb/core/hcd.c	1.64    -> 1.66   
#	    fs/nfsd/export.c	1.80    -> 1.81   
#	include/asm-ia64/sn/bte_copy.h	1.3     ->         (deleted)      
#	     fs/ext3/namei.c	1.38    -> 1.40   
#	  drivers/scsi/ppa.c	1.23    -> 1.24   
#	include/linux/skbuff.h	1.24    -> 1.25   
#	include/linux/ext3_fs.h	1.24    -> 1.26   
#	   arch/m68k/Kconfig	1.12.1.1 -> 1.15   
#	drivers/usb/input/powermate.c	1.14    -> 1.15   
#	arch/ia64/sn/io/hcl_util.c	1.4     ->         (deleted)      
#	drivers/usb/core/urb.c	1.17    -> 1.18   
#	 arch/parisc/Kconfig	1.14    -> 1.15   
#	drivers/usb/net/rtl8150.c	1.27    -> 1.28   
#	include/asm-ia64/sn/sn1/hubio_next.h	1.3     ->         (deleted)      
#	drivers/pcmcia/yenta.c	1.26    -> 1.28    drivers/pcmcia/yenta_socket.c (moved)
#	drivers/pcmcia/rsrc_mgr.c	1.20    -> 1.22   
#	include/asm-ia64/sn/fetchop.h	1.2     -> 1.3    
#	drivers/scsi/scsi_debug.c	1.38    -> 1.39   
#	arch/ia64/ia32/sys_ia32.c	1.55    -> 1.64   
#	arch/ia64/sn/io/sn2/pic.c	1.1     -> 1.3    
#	       net/atm/lec.c	1.25    -> 1.28   
#	arch/ia64/sn/io/sn1/ml_SN_intr.c	1.7.1.1 ->         (deleted)      
#	arch/ia64/sn/io/sn2/klgraph.c	1.1     -> 1.3    
#	include/asm-ia64/sn/geo.h	1.1     -> 1.2    
#	include/asm-ia64/sn/xtalk/xtalk.h	1.4     -> 1.5    
#	arch/ia64/sn/kernel/llsc4.h	1.3     ->         (deleted)      
#	  net/unix/af_unix.c	1.48    -> 1.49   
#	net/sunrpc/svcauth_unix.c	1.15    -> 1.16   
#	include/asm-ia64/sn/cdl.h	1.3     -> 1.4    
#	arch/v850/vmlinux.lds.S	1.9     -> 1.11   
#	drivers/usb/class/cdc-acm.c	1.44    -> 1.46   
#	drivers/usb/misc/rio500.c	1.23    -> 1.24   
#	drivers/scsi/ide-scsi.c	1.25    -> 1.26   
#	   drivers/scsi/st.c	1.63    -> 1.64   
#	arch/arm/mm/mm-armv.c	1.19    -> 1.20   
#	include/asm-ia64/sn/xtalk/xbow_info.h	1.2     -> 1.3    
#	drivers/usb/storage/usb.h	1.28    -> 1.30   
#	arch/ia64/sn/kernel/sn2/iomv.c	1.3     ->         (deleted)      
#	arch/ia64/sn/io/ioconfig_bus.c	1.1     -> 1.3     arch/ia64/sn/io/drivers/ioconfig_bus.c (moved)
#	arch/ia64/hp/sim/Makefile	1.6     -> 1.7    
#	arch/ia64/hp/sim/hpsim_setup.c	1.5     -> 1.6    
#	include/asm-ia64/sn/sn1/mem_refcnt.h	1.2     ->         (deleted)      
#	       net/atm/svc.c	1.10    -> 1.14   
#	drivers/scsi/arm/powertec.c	1.26    -> 1.27   
#	drivers/atm/atmtcp.c	1.7     -> 1.9    
#	include/asm-ia64/ptrace.h	1.10.1.1 -> 1.15   
#	drivers/usb/host/ehci-hcd.c	1.49    -> 1.52   
#	 drivers/scsi/mesh.c	1.8     -> 1.9    
#	drivers/scsi/pci2000.c	1.17    -> 1.18   
#	drivers/input/serio/ambakmi.c	1.5     -> 1.6    
#	arch/ia64/sn/io/sn1/pcibr.c	1.14    ->         (deleted)      
#	arch/ia64/sn/io/ml_SN_init.c	1.3     ->         (deleted)      
#	arch/ia64/sn/io/efi-rtc.c	1.2     ->         (deleted)      
#	     fs/ext3/inode.c	1.68    -> 1.74   
#	arch/ia64/kernel/head.S	1.10    -> 1.12   
#	include/asm-ia64/sn/clksupport.h	1.3     -> 1.5    
#	net/packet/af_packet.c	1.30    -> 1.31   
#	drivers/scsi/blz1230.c	1.9     -> 1.10   
#	drivers/scsi/psi240i.c	1.10    -> 1.12   
#	arch/ia64/sn/io/sn2/bte_error.c	1.2     -> 1.3    
#	drivers/scsi/scsi_priv.h	1.13    -> 1.15   
#	include/asm-ia64/elf.h	1.8     -> 1.12   
#	arch/ia64/sn/kernel/sn_ksyms.c	1.2     -> 1.4    
#	arch/m68knommu/Kconfig	1.13    -> 1.14   
#	  net/llc/llc_s_ev.c	1.6     -> 1.7    
#	include/linux/page-flags.h	1.40    -> 1.41   
#	drivers/scsi/sun3x_esp.c	1.10    -> 1.11   
#	arch/arm/mach-integrator/core.c	1.10    -> 1.11   
#	  arch/ia64/mm/tlb.c	1.15    -> 1.18   
#	drivers/scsi/fdomain.c	1.22    -> 1.23   
#	drivers/scsi/dec_esp.c	1.6     -> 1.8    
#	 fs/nfsd/nfs4state.c	1.3     -> 1.5    
#	include/asm-ia64/sn/sn2/shub_mmr.h	1.2     -> 1.3    
#	drivers/scsi/constants.c	1.10    -> 1.11   
#	include/asm-ia64/sn/xtalk/xtalk_private.h	1.4     -> 1.5    
#	include/asm-ia64/sn/hires_clock.h	1.1     ->         (deleted)      
#	drivers/usb/net/kaweth.c	1.43    -> 1.45   
#	drivers/scsi/arm/cumana_2.c	1.28    -> 1.29   
#	  drivers/scsi/dtc.c	1.10    -> 1.11   
#	drivers/net/shaper.c	1.14    -> 1.15   
#	include/asm-ia64/nodedata.h	1.2     -> 1.3    
#	include/asm-ia64/sn/labelcl.h	1.2     -> 1.3    
#	   net/core/skbuff.c	1.27    -> 1.28   
#	  include/net/sock.h	1.44    -> 1.46   
#	arch/ia64/sn/io/ml_iograph.c	1.4     ->         (deleted)      
#	arch/ia64/sn/io/sn1/ip37.c	1.3     ->         (deleted)      
#	arch/ia64/kernel/perfmon_mckinley.h	1.6     -> 1.8    
#	arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c	1.3     -> 1.4    
#	include/asm-ia64/sn/gda.h	1.3     ->         (deleted)      
#	include/asm-ia64/sn/sn_pio_sync.h	1.1     ->         (deleted)      
#	    net/atm/common.h	1.4     -> 1.8    
#	drivers/usb/net/Kconfig	1.4     -> 1.6    
#	include/asm-ia64/sn/ate_utils.h	1.2     -> 1.3    
#	include/asm-ia64/sn/addrs.h	1.5     -> 1.6    
#	arch/ia64/sn/io/sn2/ml_SN_intr.c	1.2     -> 1.3    
#	net/atm/mpoa_caches.c	1.1     -> 1.2    
#	arch/ia64/ia32/ia32_ioctl.c	1.9     -> 1.12   
#	arch/ia64/sn/io/sn2/l1.c	1.1     -> 1.3    
#	arch/ia64/sn/io/hubdev.c	1.4     ->         (deleted)      
#	include/asm-ia64/sn/sn1/hubmd.h	1.3     ->         (deleted)      
#	drivers/usb/class/bluetty.c	1.45    -> 1.46   
#	   drivers/scsi/sd.c	1.117.1.1 -> 1.123  
#	arch/ia64/sn/fakeprom/fw-emu.c	1.8     -> 1.9    
#	include/net/llc_pdu.h	1.4     -> 1.5    
#	net/ipv4/tcp_minisocks.c	1.38    -> 1.40   
#	drivers/usb/input/aiptek.c	1.16    -> 1.17   
#	include/asm-ia64/resource.h	1.1     -> 1.2    
#	Documentation/usb/dma.txt	1.1     -> 1.2    
#	include/asm-ia64/sn/xtalk/xtalkaddrs.h	1.3     -> 1.4    
#	  arch/alpha/Kconfig	1.17    -> 1.18   
#	   net/llc/llc_sap.c	1.20    -> 1.21   
#	 net/atm/signaling.c	1.9     -> 1.12   
#	arch/ia64/sn/io/pci_bus_cvlink.c	1.6.1.1 -> 1.8     arch/ia64/sn/io/machvec/pci_bus_cvlink.c (moved)
#	drivers/usb/storage/unusual_devs.h	1.40    -> 1.42   
#	arch/ia64/sn/kernel/misctest.c	1.4     ->         (deleted)      
#	  arch/h8300/Kconfig	1.3     -> 1.4    
#	      fs/nfs/inode.c	1.79    -> 1.80   
#	include/asm-ia64/sn/sn1/hubio.h	1.2     ->         (deleted)      
#	drivers/pcmcia/Makefile	1.24    -> 1.25   
#	drivers/message/i2o/i2o_scsi.c	1.18    -> 1.19   
#	arch/ia64/sn/kernel/llsc4.c	1.9     ->         (deleted)      
#	drivers/scsi/scsi_scan.c	1.87.1.2 -> 1.93   
#	 arch/x86_64/Kconfig	1.22    -> 1.23   
#	include/asm-ia64/sn/sn1/ip27config.h	1.3     ->         (deleted)      
#	drivers/net/rcpci45.c	1.21    -> 1.23   
#	 net/atm/resources.h	1.3     -> 1.6    
#	include/asm-ia64/sn/nic.h	1.2     ->         (deleted)      
#	drivers/usb/host/ehci-q.c	1.47    -> 1.50   
#	drivers/usb/host/ehci-dbg.c	1.19    -> 1.20   
#	arch/ia64/sn/io/hcl.c	1.8     ->         (deleted)      
#	drivers/usb/net/Makefile.mii	1.1     -> 1.2    
#	arch/ia64/sn/io/sn2/pcibr/pcibr_config.c	1.2     -> 1.3    
#	 include/linux/jbd.h	1.21    -> 1.37   
#	arch/ia64/scripts/check-gas	1.2     -> 1.3    
#	include/asm-ia64/sn/xtalk/xswitch.h	1.2     -> 1.3    
#	drivers/scsi/sim710.c	1.13    -> 1.16   
#	arch/ia64/kernel/gate.S	1.15    -> 1.17   
#	include/asm-ia64/a.out.h	1.4     -> 1.5    
#	drivers/scsi/dpt_i2o.c	1.30.1.1 -> 1.32   
#	       net/atm/mpc.c	1.17    -> 1.19   
#	      net/ipv6/udp.c	1.41    -> 1.42   
#	include/linux/atmdev.h	1.14    -> 1.17   
#	arch/ia64/sn/io/sn2/shubio.c	1.1     -> 1.2    
#	drivers/scsi/mvme16x.c	1.5     -> 1.6    
#	include/asm-ia64/sn/pci/pcibr.h	1.5     -> 1.6    
#	arch/ia64/sn/kernel/sn1/error.c	1.2     ->         (deleted)      
#	   fs/nfsd/nfs4xdr.c	1.15    -> 1.17   
#	arch/ia64/sn/Makefile	1.1     -> 1.2    
#	include/asm-ia64/sn/ioerror.h	1.5     -> 1.6    
#	arch/ia64/sn/io/sn1/hubcounters.c	1.3     ->         (deleted)      
#	arch/ia64/sn/io/stubs.c	1.4     ->         (deleted)      
#	include/asm-ia64/sn/ksys/elsc.h	1.4     -> 1.5    
#	include/asm-ia64/sn/sn2/intr.h	1.2     -> 1.3    
#	include/asm-ia64/sn/sn1/hubpi_next.h	1.3     ->         (deleted)      
#	include/asm-sparc/xor.h	1.2     -> 1.3    
#	include/asm-ia64/timex.h	1.3.1.1 -> 1.7    
#	arch/ia64/vmlinux.lds.S	1.29.1.1 -> 1.34   
#	include/asm-ia64/sn/sn1/intr_public.h	1.2     ->         (deleted)      
#	include/asm-ia64/sn/sn1/hublb.h	1.2     ->         (deleted)      
#	drivers/usb/host/ehci.h	1.20    -> 1.21   
#	arch/ia64/kernel/minstate.h	1.10    -> 1.15   
#	    net/ipv6/mcast.c	1.22    -> 1.25   
#	 drivers/scsi/eata.c	1.33    -> 1.34   
#	arch/ia64/mm/discontig.c	1.3     -> 1.4    
#	include/asm-ia64/sn/arc/types.h	1.4     -> 1.5    
#	arch/sparc64/Kconfig	1.19.1.2 -> 1.23   
#	arch/ia64/kernel/mca_asm.S	1.8     -> 1.10   
#	arch/ia64/kernel/irq.c	1.24    -> 1.25   
#	arch/i386/oprofile/Makefile	1.5     -> 1.6    
#	     fs/jbd/commit.c	1.16    -> 1.34   
#	arch/ia64/sn/kernel/sn2/io.c	1.1     -> 1.2    
#	include/linux/journal-head.h	1.1     -> 1.3    
#	      fs/nfsd/auth.c	1.1     -> 1.2    
#	drivers/scsi/Kconfig	1.22    -> 1.23   
#	     fs/ext3/super.c	1.63    -> 1.68   
#	arch/ia64/tools/print_offsets.c	1.17    ->         (deleted)      
#	arch/ia64/kernel/unaligned.c	1.12    -> 1.13   
#	 drivers/scsi/t128.c	1.11    -> 1.12   
#	drivers/scsi/u14-34f.h	1.16    ->         (deleted)      
#	arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c	1.2     -> 1.3    
#	arch/ia64/sn/io/sn2/pcibr/Makefile	1.2     -> 1.5    
#	include/linux/ext3_fs_sb.h	1.5     -> 1.7    
#	   arch/cris/Kconfig	1.8     -> 1.9    
#	include/asm-ia64/siginfo.h	1.12    -> 1.13   
#	include/asm-ia64/sn/types.h	1.4     -> 1.5    
#	include/asm-ia64/pci.h	1.17    -> 1.18   
#	drivers/serial/Kconfig	1.9     -> 1.10   
#	include/asm-arm/memory.h	1.7     -> 1.8    
#	arch/ia64/boot/bootloader.c	1.5     -> 1.7    
#	arch/ia64/ia32/binfmt_elf32.c	1.12    -> 1.13   
#	include/asm-ia64/sn/pda.h	1.3     -> 1.4    
#	    net/sunrpc/svc.c	1.20    -> 1.21   
#	include/asm-ia64/mca_asm.h	1.6     -> 1.7    
#	drivers/net/bonding/bond_main.c	1.23    -> 1.25   
#	 drivers/char/moxa.c	1.23    -> 1.24   
#	drivers/usb/input/usbmouse.c	1.26    -> 1.27   
#	arch/ia64/kernel/perfmon.c	1.43    -> 1.50   
#	arch/ia64/sn/io/l1.c	1.7     ->         (deleted)      
#	arch/ia64/sn/kernel/sn2/sn2_smp.c	1.4     -> 1.5    
#	include/asm-ia64/sn/dmamap.h	1.3     -> 1.4    
#	arch/i386/oprofile/nmi_int.c	1.14    -> 1.15   
#	include/asm-ia64/compat.h	1.12    -> 1.13   
#	include/asm-ia64/sn/sn2/mmzone_sn2.h	1.3     ->         (deleted)      
#	arch/ia64/sn/kernel/sn1/synergy.c	1.6     ->         (deleted)      
#	 net/atm/resources.c	1.9     -> 1.12   
#	   arch/ia64/Kconfig	1.21.1.3 -> 1.31   
#	arch/ia64/sn/io/sn2/shuberror.c	1.2     -> 1.4    
#	    net/x25/af_x25.c	1.28    -> 1.29   
#	arch/ia64/lib/Makefile	1.16.1.1 -> 1.20   
#	include/asm-ia64/sal.h	1.16    -> 1.17   
#	include/asm-ia64/sn/sn2/shub_md.h	1.3     -> 1.4    
#	drivers/scsi/arm/ecoscsi.c	1.18    -> 1.19   
#	drivers/usb/misc/usbtest.c	1.15    -> 1.16   
#	drivers/usb/input/usbkbd.c	1.30    -> 1.31   
#	arch/arm/mach-sa1100/irq.c	1.14    -> 1.15   
#	arch/ia64/kernel/traps.c	1.29    -> 1.34   
#	drivers/scsi/scsi_ioctl.c	1.17    -> 1.18   
#	include/asm-ia64/sn/sn1/mmzone_sn1.h	1.5     ->         (deleted)      
#	arch/ia64/mm/fault.c	1.14    -> 1.15   
#	include/asm-ia64/sn/intr_public.h	1.3     ->         (deleted)      
#	include/asm-ia64/sn/sn2/shub.h	1.1     -> 1.2    
#	include/asm-ia64/sn/pci/pci_bus_cvlink.h	1.4     -> 1.5    
#	      net/atm/clip.c	1.13    -> 1.16   
#	include/linux/nfsd/nfsd.h	1.18    -> 1.20   
#	net/wanrouter/af_wanpipe.c	1.27    -> 1.28   
#	  net/llc/llc_c_ac.c	1.21    -> 1.22   
#	drivers/usb/class/audio.c	1.37    -> 1.38   
#	arch/ia64/ia32/ia32_ldt.c	1.2     -> 1.3    
#	    arch/ppc/Kconfig	1.24    -> 1.25   
#	drivers/usb/net/pegasus.c	1.49    -> 1.50   
#	  drivers/scsi/esp.c	1.27    -> 1.30   
#	     net/ipv4/igmp.c	1.24    -> 1.26   
#	drivers/scsi/pcmcia/nsp_cs.c	1.22    -> 1.23   
#	arch/ia64/kernel/ptrace.c	1.22    -> 1.28   
#	drivers/scsi/wd7000.c	1.25    -> 1.27   
#	arch/ia64/sn/kernel/sn2/Makefile	1.10    -> 1.12   
#	arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c	1.3     -> 1.4    
#	arch/ia64/kernel/pal.S	1.6     -> 1.7    
#	     arch/sh/Kconfig	1.12    -> 1.13   
#	include/asm-i386/apic.h	1.12    -> 1.13   
#	drivers/scsi/arm/eesox.c	1.28    -> 1.29   
#	include/asm-ia64/ia32.h	1.21    -> 1.23   
#	arch/ia64/kernel/init_task.c	1.8     -> 1.9    
#	drivers/usb/image/hpusbscsi.c	1.29.1.1 -> 1.31   
#	  drivers/scsi/imm.c	1.22    -> 1.23   
#	drivers/scsi/arm/fas216.h	1.7     -> 1.8    
#	arch/ia64/sn/kernel/sn2/sn_proc_fs.c	1.1     -> 1.2    
#	include/asm-ia64/sn/slotnum.h	1.3     -> 1.4    
#	include/net/sctp/structs.h	1.65    -> 1.66   
#	drivers/atm/fore200e.c	1.15    -> 1.17   
#	arch/ia64/kernel/Makefile	1.17    -> 1.24   
#	arch/ia64/sn/io/sn2/pciio.c	1.1     -> 1.2    
#	  fs/nfsd/nfs4proc.c	1.12    -> 1.13   
#	drivers/usb/misc/speedtch.c	1.93    -> 1.94   
#	drivers/scsi/qlogicfas.c	1.20    -> 1.22   
#	arch/ia64/sn/fakeprom/README	1.5     -> 1.6    
#	arch/ia64/sn/io/sn2/Makefile	1.2     -> 1.3    
#	include/asm-ia64/thread_info.h	1.8     -> 1.9    
#	include/asm-ia64/sn/sn_sal.h	1.3     -> 1.4    
#	include/asm-ia64/sn/sn1/hubspc.h	1.2     ->         (deleted)      
#	arch/ia64/kernel/acpi-ext.c	1.3     -> 1.4    
#	arch/ia64/kernel/perfmon_itanium.h	1.4     -> 1.5    
#	include/asm-ia64/sn/sn1/hubni_next.h	1.2     ->         (deleted)      
#	arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c	1.7     -> 1.10   
#	drivers/usb/image/microtek.c	1.31    -> 1.32   
#	include/asm-ia64/sn/simulator.h	1.1     -> 1.2    
#	arch/ia64/kernel/unwind.c	1.22    -> 1.29   
#	arch/ia64/sn/kernel/sn2/cache.c	1.1     -> 1.2    
#	   net/sctp/socket.c	1.76    -> 1.79   
#	    net/atm/common.c	1.27    -> 1.31   
#	               (new)	        -> 1.1     arch/ia64/sn/io/machvec/Makefile
#	               (new)	        -> 1.1     arch/ia64/sn/io/hwgfs/hcl_util.c
#	               (new)	        -> 1.1     arch/ia64/lib/xor.S
#	               (new)	        -> 1.1     arch/ia64/scripts/check-segrel.lds
#	               (new)	        -> 1.1     include/scsi/scsi_device.h
#	               (new)	        -> 1.2     include/asm-ia64/patch.h
#	               (new)	        -> 1.2     include/scsi/scsi_host.h
#	               (new)	        -> 1.2     include/asm-ia64/sn/hwgfs.h
#	               (new)	        -> 1.1     arch/ia64/sn/kernel/sn2/prominfo_proc.c
#	               (new)	        -> 1.2     drivers/usb/net/ax8817x.c
#	               (new)	        -> 1.1     include/asm-ia64/perfmon_default_smpl.h
#	               (new)	        -> 1.1     include/asm-ia64/sn/ioc4.h
#	               (new)	        -> 1.1     arch/i386/oprofile/nmi_timer_int.c
#	               (new)	        -> 1.3     arch/ia64/kernel/gate.lds.S
#	               (new)	        -> 1.1     arch/arm/common/amba.c
#	               (new)	        -> 1.1     arch/ia64/sn/io/sn2/kdba_io.c
#	               (new)	        -> 1.1     arch/ia64/sn/io/hwgfs/Makefile
#	               (new)	        -> 1.2     arch/ia64/sn/io/platform_init/irix_io_init.c
#	               (new)	        -> 1.1     include/asm-arm/hardware/icst525.h
#	               (new)	        -> 1.1     drivers/scsi/scsi_typedefs.h
#	               (new)	        -> 1.2     arch/ia64/sn/io/hwgfs/hcl.c
#	               (new)	        -> 1.1     arch/ia64/scripts/check-segrel.S
#	               (new)	        -> 1.4     arch/ia64/sn/kernel/sn2/timer.c
#	               (new)	        -> 1.1     arch/ia64/sn/io/hwgfs/labelcl.c
#	               (new)	        -> 1.1     arch/ia64/sn/io/platform_init/Makefile
#	               (new)	        -> 1.4     arch/ia64/kernel/patch.c
#	               (new)	        -> 1.1     include/scsi/scsi_cmnd.h
#	               (new)	        -> 1.1     arch/ia64/sn/io/hwgfs/ramfs.c
#	               (new)	        -> 1.1     arch/ia64/kernel/gate-data.S
#	               (new)	        -> 1.1     include/scsi/scsi_tcq.h
#	               (new)	        -> 1.1     arch/ia64/sn/io/hwgfs/invent_stub.c
#	               (new)	        -> 1.1     drivers/i2c/chips/lm78.c
#	               (new)	        -> 1.3     arch/ia64/sn/io/drivers/Makefile
#	               (new)	        -> 1.1     arch/ia64/kernel/perfmon_default_smpl.c
#	               (new)	        -> 1.1     include/asm-arm/hardware/amba.h
#	               (new)	        -> 1.1     arch/ia64/kernel/asm-offsets.c
#	               (new)	        -> 1.1     fs/Kconfig.binfmt
#	               (new)	        -> 1.1     include/scsi/scsi_eh.h
#	               (new)	        -> 1.1     arch/arm/common/icst525.c
#	               (new)	        -> 1.1     arch/ia64/scripts/toolchain-flags
#	               (new)	        -> 1.1     include/asm-ia64/ioctl32.h
#	               (new)	        -> 1.2     include/asm-ia64/ustack.h
#	               (new)	        -> 1.1     arch/ia64/ia32/ia32priv.h
#	               (new)	        -> 1.1     include/scsi/scsi_request.h
#	               (new)	        -> 1.1     arch/ia64/sn/io/hwgfs/interface.c
#	               (new)	        -> 1.1     arch/ia64/sn/kernel/idle.c
#
# The following is the BitKeeper ChangeSet Log
# --------------------------------------------
# 03/06/16	torvalds@home.transmeta.com	1.1327.4.1
# Linux 2.5.72
# --------------------------------------------
# 03/06/17	acme@conectiva.com.br	1.1329
# o ipx: fix var shadowing paramente with CONFIG_IPX_INTERN is enabled
# 
# Which is 0.1% of the times, I'll have to research usage and eventually
# kill this uglymoron that is responsible for 9 out of 10 "ipx is not
# working with mars_nwe, why?" answer "Disable the damn CONFIG_IPX_INTERN
# and be happy!" Thanks to Geert for reporting thisn in lkml.
# --------------------------------------------
# 03/06/17	david-b@pacbell.net	1.1318.5.9
# [PATCH] USB: ehci-hcd micro-patch
# 
# This is a handful of one-liners, significantly:
# 
#   - don't disable "park" feature (faster).
#   - cut'n'paste should have morphed "||" to "&&"
#   - initialize qh as "live" (as now expected)
# 
# The "&&" was the most troublesome bug.  It could make
# all kinds of things misbehave, not just those vt6202
# issues some folks report.
# 
# The interesting bit about the "park" feature (NForce2
# has it, maybe a few others) is that it made one disk
# run 18% faster (according to hdparm).
# --------------------------------------------
# 03/06/17	mikenc@us.ibm.com	1.1327.3.2
# [PATCH] fixes compile error in inia100.c
# 
# The attached patch fixes the compile errors in inia100.c described in
# Bugzilla bug #345 at http://bugme.osdl.org/show_bug.cgi?id=345. It was
# built against 2.5.71. I do not have the hardware, so I have only
# verified that it compiles correctly.
# --------------------------------------------
# 03/06/16	shemminger@osdl.org	1.1327.2.2
# [NET]: Fix module owner for bonding driver.
# --------------------------------------------
# 03/06/17	david-b@pacbell.net	1.1318.5.10
# [PATCH] USB: net2280, halt ep != 0
# 
# Fix from Al.Borchers@guidant.com, should fix a chapter 9
# test conformance issue.
# --------------------------------------------
# 03/06/17	davidm@tiger.hpl.hp.com	1.1327.4.2
# Merge tiger.hpl.hp.com:/data1/bk/vanilla/linux-2.5
# into tiger.hpl.hp.com:/data1/bk/lia64/to-linus-2.5
# --------------------------------------------
# 03/06/17	heiko.carstens@de.ibm.com	1.1327.3.3
# [PATCH] sd.c: set data direction to SCSI_DATA_NONE for START_STOP
# 
# while trying to access a disk drive via an FCP bridge we got an FCP_RSP IU
# with the RSP_CODE field set to "FCP_CMND Fields Invalid". This happened
# after sending a START_STOP command to the device. Reason for this was that
# the FCP_CMND IU incorrectly had the RDDATA field set to one, because of a
# bug in sd_spinup_disk(). There the data direction for START_STOP is set
# to SCSI_DATA_READ instead of SCSI_DATA_NONE.
# Please apply the patch below.
# 
# Thanks,
# Heiko
# --------------------------------------------
# 03/06/17	thornber@sistina.com	1.1327.5.1
# [PATCH] dm: dm-ioctl.c: Unregister with devfs before renaming the device
# 
# DM originally stored a devfs handle in the hash-cell, and performed the
# unregister based on that handle. These devfs handles have since been removed,
# and devices are registered and unregistered simply based on their names. So
# the device now needs to be unregistered before we lose the name.
# 
# See the following BK change for more details:
# http://linux.bkbits.net:8080/linux-2.5/diffs/drivers/md/dm-ioctl.c@1.6?nav=index.html|src/|src/drivers|src/drivers/md|hist/drivers/md/dm-ioctl.c
# [Kevin Corry]
# --------------------------------------------
# 03/06/17	davidm@tiger.hpl.hp.com	1.1327.4.3
# ia64: Sync with 2.5.71.
# --------------------------------------------
# 03/06/17	fcusack@fcusack.com	1.1327.5.2
# [PATCH] nfs_unlink() fix and trivial nfs_fhget cleanup
# 
# Don't remove sillyrenamed files: those will be removed (by
# nfs_async_unlink) when they are no longer used any more.
# 
# Remove double initialization of "i_mode" in __nfs_fhget().
# --------------------------------------------
# 03/06/17	hanno@gmx.de	1.1318.5.11
# [PATCH] USB: Patch for Vivicam 355
# --------------------------------------------
# 03/06/17	jejb@raven.il.steeleye.com	1.1327.3.4
# Fix SCSI ID setting for HP Cirrus-II card
# --------------------------------------------
# 03/06/17	davem@nuts.ninka.net	1.1327.2.3
# Merge nuts.ninka.net:/home/davem/src/BK/network-2.5
# into nuts.ninka.net:/home/davem/src/BK/net-2.5
# --------------------------------------------
# 03/06/17	greg@kroah.com	1.1318.5.12
# [PATCH] USB: fix up sparse warnings in drivers/usb/class/*
# --------------------------------------------
# 03/06/17	torvalds@home.transmeta.com	1.1327.5.3
# Merge bk://bk.arm.linux.org.uk/linux-2.5-pcmcia
# into home.transmeta.com:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/06/17	davem@nuts.ninka.net	1.1327.1.2
# Merge nuts.ninka.net:/home/davem/src/BK/sparcwork-2.5
# into nuts.ninka.net:/home/davem/src/BK/sparc-2.5
# --------------------------------------------
# 03/06/17	dlstevens@us.ibm.com	1.1327.2.4
# [IPV4/IPV6]: Make sure SKB has enough space while building IGMP/MLD packets.
# --------------------------------------------
# 03/06/17	greg@kroah.com	1.1318.5.13
# [PATCH] USB: fix up sparse warnings in drivers/usb/misc/*
# --------------------------------------------
# 03/06/17	davem@nuts.ninka.net	1.1328.1.1
# Merge bk://kernel.bkbits.net/acme/net-2.5
# into nuts.ninka.net:/home/davem/src/BK/net-2.5
# --------------------------------------------
# 03/06/18	davidm@tiger.hpl.hp.com	1.1327.4.4
# ia64: Initial sync with 2.5.72.
# --------------------------------------------
# 03/06/17	chas@cmf.nrl.navy.mil	1.1328.1.2
# [ATM]: Split atm_ioctl into vcc_ioctl and atm_dev_ioctl.
# --------------------------------------------
# 03/06/17	davem@nuts.ninka.net	1.1327.1.3
# [SPARC64]: Fix wal_to_monotonic initialization.
# --------------------------------------------
# 03/06/17	jejb@raven.il.steeleye.com	1.1327.3.5
# SCSI: tidy up io vs mem mapping in 53c700 driver
# 
# The parisc ports may use both the lasi700 and sim710 versions of this driver
# Unfortunately, one must be memory mapped, and one must be IO mapped, so
# add code to the driver for this case
# --------------------------------------------
# 03/06/17	bunk@fs.tum.de	1.1327.3.6
# [PATCH] aha1740.c doesn't compile.
# --------------------------------------------
# 03/06/17	chas@cmd.nrl.navy.mil	1.1328.1.3
# [ATM]: Remove recvmsg and rename atm_async_release_vcc.
# --------------------------------------------
# 03/06/17	davem@nuts.ninka.net	1.1327.1.4
# [SPARC]: Fix wall_to_monotonic initialization.
# --------------------------------------------
# 03/06/17	chas@cmf.nrl.navy.mil	1.1328.1.4
# [ATM]: Keep vcc's on global list instead of per device.
# --------------------------------------------
# 03/06/17	davem@nuts.ninka.net	1.1330
# Merge bk://kernel.bkbits.net/acme/net-2.5
# into nuts.ninka.net:/home/davem/src/BK/net-2.5
# --------------------------------------------
# 03/06/17	davem@nuts.ninka.net	1.1331
# [ATM]: Revert vcc global list changes, broke the build.
# --------------------------------------------
# 03/06/17	yoshfuji@linux-ipv6.org	1.1332
# [IPV6]: Fix warnings in ip6ip6 tunnel driver.
# --------------------------------------------
# 03/06/17	toml@us.ibm.com	1.1333
# [IPV6]: Fix xfrm bundle address setup and comparisons.
# --------------------------------------------
# 03/06/17	torvalds@home.transmeta.com	1.1332.1.1
# Merge bk://kernel.bkbits.net/davem/net-2.5
# into home.transmeta.com:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/06/18	acme@conectiva.com.br	1.1332.1.2
# o net: make sk_{add,del}_node functions take care of sock refcounting
# 
# With this we make it easier to write correct network families as less
# details need to be taken into account, as well in the current state we
# make the non-refcounting protocols (the ones still keeping deliver_to_old_ones
# in the tree) suck less. 8)
# 
# Left a WARN_ON in sk_del_node_init for a while, so that we can catch cases
# where we're using __sock_put on a struct sock that has refcnt == 1, which
# is not the case for all the ones I tested.
# --------------------------------------------
# 03/06/17	bunk@fs.tum.de	1.1334
# [NET]: Fix namespace pollution in two wireless drivers.
# --------------------------------------------
# 03/06/17	davem@kernel.bkbits.net	1.1332.2.1
# Merge davem@nuts.ninka.net:/home/davem/src/BK/sparc-2.5
# into kernel.bkbits.net:/home/davem/sparc-2.5
# --------------------------------------------
# 03/06/17	greg@kroah.com	1.1332.3.1
# Merge kroah.com:/home/greg/linux/BK/bleed-2.5
# into kroah.com:/home/greg/linux/BK/gregkh-2.5
# --------------------------------------------
# 03/06/17	torvalds@home.transmeta.com	1.1332.4.1
# Merge bk://linux-scsi.bkbits.net/scsi-for-linus-2.5
# into home.transmeta.com:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/06/17	Ballabio_Dario@emc.com	1.1332.4.2
# [PATCH] eata and u14-34f update
# 
# Here enclosed an update for the new IRQ and module_param APIs.
# eata.h and u14-34f.h are no longer used and will be deleted.
# --------------------------------------------
# 03/06/17	davem@kernel.bkbits.net	1.1332.2.2
# Merge davem@nuts.ninka.net:/home/davem/src/BK/sparc-2.5
# into kernel.bkbits.net:/home/davem/sparc-2.5
# --------------------------------------------
# 03/06/17	greg@kroah.com	1.1332.5.1
# Merge kroah.com:/home/greg/linux/BK/bleed-2.5
# into kroah.com:/home/greg/linux/BK/i2c-2.5
# --------------------------------------------
# 03/06/18	jgrimm2@us.ibm.com	1.1332.1.3
# o hlist change on sctp not quite right.
# --------------------------------------------
# 03/06/18	oliver@neukum.org	1.1332.3.2
# [PATCH] USB: convert kaweth to usb_buffer_alloc
# 
#   - switch to usb_buffer_alloc
# --------------------------------------------
# 03/06/17	yoshfuji@linux-ipv6.org	1.1335
# [IPV6]: Use in6_dev_hold/__in6_dev_put in net/ipv6/mcast.c
# --------------------------------------------
# 03/06/18	acme@conectiva.com.br	1.1332.1.4
# o llc: don't use inverted logic
# 
# I don't understand what was on the mind of Procom programmers,
# why do all this inverted logic? Its plain confusing, revert it.
# Thanks to DaveM for asking if the logic was inverted, I should
# have killed this weird stuff a long time ago :-\
# --------------------------------------------
# 03/06/18	david-b@pacbell.net	1.1332.3.3
# [PATCH] USB: usbnet talks to boot loader (blob)
# 
# Boot ROMs have talked TFTP forever.  Some do it over USB now.
# --------------------------------------------
# 03/06/17	torvalds@home.transmeta.com	1.1332.2.3
# Merge bk://kernel.bkbits.net/davem/sparc-2.5
# into home.transmeta.com:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/06/17	torvalds@home.transmeta.com	1.1332.2.4
# Fix moxa compile (at least for UP) and remove a few warnings.
# 
# From Adrian Bunk.
# --------------------------------------------
# 03/06/17	neilb@cse.unsw.edu.au	1.1332.2.5
# [PATCH] kNFSd: Fix bug in svc_pushback_unused_pages that occurs on zero byte NFS read
# 
# svc_pushback_unused_pages must be ready of the possibility that
# no pages were allocated or will need to be pushed back.
# --------------------------------------------
# 03/06/17	neilb@cse.unsw.edu.au	1.1332.2.6
# [PATCH] kNFSd: Assorted fixed for NFS export cache
# 
# The most significant fix is cleaning up properly when
# nfs service is stopped.
# 
# Also fix some refcounting problems and other little bits.
# --------------------------------------------
# 03/06/17	neilb@cse.unsw.edu.au	1.1332.2.7
# [PATCH] kNFSd: Make sure an early close on a nfs/tcp connection is handled properly.
# 
# From: Hirokazu Takahashi <taka@valinux.co.jp>
# 
# In svc_tcp_listen_data_ready we should be waiting for
# TCP_LISTEN, not TCP_ESTABLISHED.  The later only worked
# by accident.
# 
# Also, if a socket is closed as soon as we accept it, we
# must shut it down straight away as we will never get a 'close'
# event.
# --------------------------------------------
# 03/06/17	neilb@cse.unsw.edu.au	1.1332.2.8
# [PATCH] kNFSd: Allow nfsv4 readdir to return filehandle when a mountpoint is found is a directory
# 
# From: "William A.(Andy) Adamson" <andros@citi.umich.edu>
# 
# When readdir is enumerating a directory and finds a mountpoint,
# it needs to do a bit of extra work to find the filehandle to be
# returned in the readdir reply.
# 
# It is even possible that finding the filehandle requires an up-call,
# so the request might be dropped to be re-tried later.
# --------------------------------------------
# 03/06/17	neilb@cse.unsw.edu.au	1.1332.2.9
# [PATCH] kNFSd: Make sure unused bits of NFSv4 xfr buffered are zero..
# --------------------------------------------
# 03/06/17	neilb@cse.unsw.edu.au	1.1332.2.10
# [PATCH] kNFSd: RENEW and lease management for NFSv4 server
# 
# From: "William A.(Andy) Adamson" <andros@citi.umich.edu>
# 
# Put all clients in a LRU list and use a "work_queue" to
# expire old clients periodically.
# --------------------------------------------
# 03/06/17	neilb@cse.unsw.edu.au	1.1332.2.11
# [PATCH] kNFSd: Do NFSv4 server state initialisation when nfsd starts instead of when module loaded.
# 
# From: "William A.(Andy) Adamson" <andros@citi.umich.edu>
# --------------------------------------------
# 03/06/17	neilb@cse.unsw.edu.au	1.1332.2.12
# [PATCH] kNFSd: Set nfsd user every time a filehandle is verified.
# 
# request might traverse several export points which may
# have different uid squashing.
# --------------------------------------------
# 03/06/17	willy@debian.org	1.1332.2.13
# [PATCH] Consolidate Kconfigs for binfmts
# 
# This patch creates fs/Kconfig.binfmt and converts all architectures to
# use it.  I took the opportunity to spruce up the a.out help text for
# the new millennium.
# --------------------------------------------
# 03/06/17	paulkf@microgate.com	1.1332.2.14
# [PATCH] syncppp fixes
# 
#  - Fix 'badness in local_bh_enable' warning
# 
#    This involved moving dev_queue_xmit() calls
#    outside of sections with spinlock held.
# 
#  - Fix 'fix old protocol handler' warning
# 
#    This includes accounting for shared skbs,
#    setting protocol .data field to non-null,
#    and adding per device synchronization to
#    receive handler.
# 
# This has been tested in PPP and Cisco modes
# with and with out the keepalives enabled
# on a SMP machine.
# --------------------------------------------
# 03/06/17	levon@movementarian.org	1.1332.2.15
# [PATCH] OProfile: small NMI shutdown fix
# 
# Reduce the possibility of dazed-and-confuseds.
# --------------------------------------------
# 03/06/17	levon@movementarian.org	1.1332.2.16
# [PATCH] OProfile: IO-APIC based NMI delivery
# 
# Use the IO-APIC NMI delivery when the local APIC performance counter delivery is
# not available. By Zwane Mwaikambo.
# --------------------------------------------
# 03/06/17	levon@movementarian.org	1.1332.2.17
# [PATCH] OProfile: thread switching performance fix
# 
# Avoid the linear list walk of get_exec_dcookie() when we've switched to a task
# using the same mm.
# --------------------------------------------
# 03/06/17	anton@samba.org	1.1332.2.18
# [PATCH] Fix compat_sys_getrusage.  Again
# 
# I must not ignore compiler warnings.
# I must not ignore compiler warnings.
# I must not ignore compiler warnings.
# --------------------------------------------
# 03/06/17	miles@lsi.nec.co.jp	1.1332.2.19
# [PATCH] v850 whitespace tweaks
# --------------------------------------------
# 03/06/17	miles@lsi.nec.co.jp	1.1332.2.20
# [PATCH] Add .con_initcall.init section on v850
# --------------------------------------------
# 03/06/17	miles@lsi.nec.co.jp	1.1332.2.21
# [PATCH] Add linker script support for v850 "rte_nb85e_cb" platform
# --------------------------------------------
# 03/06/17	miles@lsi.nec.co.jp	1.1332.2.22
# [PATCH] Add __raw_ read/write ops to v850 io.h
# --------------------------------------------
# 03/06/18	rmk@flint.arm.linux.org.uk	1.1332.2.23
# Merge flint.arm.linux.org.uk:/usr/src/linux-bk-2.5/linux-2.5
# into flint.arm.linux.org.uk:/usr/src/linux-bk-2.5/linux-2.5-rmk
# --------------------------------------------
# 03/06/18	torvalds@home.transmeta.com	1.1332.6.1
# Merge http://lia64.bkbits.net/to-linus-2.5
# into home.transmeta.com:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.2
# [PATCH] ext3: move lock_kernel() down into the JBD layer.
# 
# This is the start of the ext3 scalability rework.  It basically comes in two
# halves:
# 
# - ext3 BKL/lock_super removal and scalable inode/block allocators
# 
# - JBD locking rework.
# 
# The ext3 scalability work was completed a couple of months ago.
# 
# The JBD rework has been stable for a couple of weeks now.  My gut feeling is
# that there should be one, maybe two bugs left in it, but no problems have
# been discovered...
# 
# 
# Performance-wise, throughput is increased by up to 2x on dual CPU.  10x on
# 16-way has been measured.  Given that current ext3 is able to chew two whole
# CPUs spinning on locks on a 4-way, that wasn't especially suprising.
# 
# These patches were prepared by Alex Tomas <bzzz@tmi.comex.ru> and myself.
# 
# 
# First patch: ext3 lock_kernel() removal.
# 
# The only reason why ext3 takes lock_kernel() is because it is requires by the
# JBD API.
# 
# The patch removes the lock_kernels() from ext3 and pushes them down into JBD
# itself.
# --------------------------------------------
# 03/06/18	rmk@flint.arm.linux.org.uk	1.1332.2.24
# [ARM] Separate ICS525 VCO calculation code.
# 
# The ICS525 clock chip is used in several different parts of the
# Integrator platform.  Rather than duplicate the code, separate it
# out so everyone can use it.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.3
# [PATCH] JBD: journal_get_write_access() speedup
# 
# Move some lock_kernel() calls from the caller to the callee, reducing
# holdtimes.
# --------------------------------------------
# 03/06/18	rmk@flint.arm.linux.org.uk	1.1332.2.25
# [ARM] Add AMBA bus type for ARM PrimeCells on Integrator.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.4
# [PATCH] ext3: concurrent block/inode allocation
# 
# From: Alex Tomas <bzzz@tmi.comex.ru>
# 
# 
# This patch weans ext3 off lock_super()-based protection for the inode and
# block allocators.
# 
# It's basically the same as the ext2 changes.
# 
# 
# 1) each group has own spinlock, which is used for group counter
#    modifications
# 
# 2) sb->s_free_blocks_count isn't used any more.  ext2_statfs() and
#    find_group_orlov() loop over groups to count free blocks
# 
# 3) sb->s_free_blocks_count is recalculated at mount/umount/sync_super time
#    in order to check consistency and to avoid fsck warnings
# 
# 4) reserved blocks are distributed over last groups
# 
# 5) ext3_new_block() tries to use non-reserved blocks and if it fails then
#    tries to use reserved blocks
# 
# 6) ext3_new_block() and ext3_free_blocks do not modify sb->s_free_blocks,
#    therefore they do not call mark_buffer_dirty() for superblock's
#    buffer_head. this should reduce I/O a bit
# 
# 
# Also fix orlov allocator boundary case:
# 
# In the interests of SMP scalability the ext2 free blocks and free inodes
# counters are "approximate".  But there is a piece of code in the Orlov
# allocator which fails due to boundary conditions on really small
# filesystems.
# 
# Fix that up via a final allocation pass which simply uses first-fit for
# allocatiopn of a directory inode.
# --------------------------------------------
# 03/06/18	rmk@flint.arm.linux.org.uk	1.1332.2.26
# [ARM] Convert ambakmi.c to AMBA device driver.
# 
# This cset makes use of our AMBA device model, thereby allowing the
# "KMI" PrimeCell driver to become ARM platform independent.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.5
# [PATCH] ext3: scalable counters and locks
# 
# From: Alex Tomas <bzzz@tmi.comex.ru>
# 
# This is a port from ext2 of the fuzzy counters (for Orlov allocator
# heuristics) and the hashed spinlocking (for the inode and bloock allocators).
# --------------------------------------------
# 03/06/19	rmk@flint.arm.linux.org.uk	1.1332.2.27
# [ARM] Tighten virt_addr_valid(), add comments for __pa and friends.
# 
# Ensure virt_addr_valid(x) works correctly for pointers.
# Add comments indicating that drivers should not use virt_to_phys
# and/or __pa to obtain an address for DMA.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.6
# [PATCH] JBD: fix race over access to b_committed_data
# 
# From: Alex Tomas <bzzz@tmi.comex.ru>
# 
# We have a race wherein the block allocator can decide that
# journal_head.b_committed_data is present and then will use it.  But kjournald
# can concurrently free it and set the pointer to NULL.  It goes oops.
# 
# We introduce per-buffer_head "spinlocking" based on a bit in b_state.  To do
# this we abstract out pte_chain_lock() and reuse the implementation.
# 
# The bit-based spinlocking is pretty inefficient CPU-wise (hence the warning
# in there) and we may move this to a hashed spinlock later.
# --------------------------------------------
# 03/06/19	rmk@flint.arm.linux.org.uk	1.1332.2.28
# [ARM] Fix sa1100 irq.c build errors.
# 
# Fix a couple of minor build errors caused by the recent system device
# changes.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.7
# [PATCH] JBD: plan JBD locking schema
# 
# This is the start of the JBD locking rework.
# 
# The aims of all this are to remove all lock_kernel() calls from JBD, to
# remove all lock_journal() calls (the context switch rate is astonishing when
# the lock_kernel()s are removed) and to remove all sleep_on() instances.
# 
# 
# 
# 
# The strategy which is taken is:
# 
# a) Define the lcoking schema (this patch)
# 
# b) Work through every JBD data structure and implement its locking fully,
#    according to the above schema.  We work from "innermost" data structures
#    and outwards.
# 
# It isn't guaranteed that the filesystem will work very well at all stages of
# this patch series.
# 
# 
# 
# In this patch:
# 
# 
# Add commentary and various locks to jbd.h describing the locking scheme which
# is about to be implemented.
# 
# Initialise the new locks.
# 
# Coding-style goodness in jbd.h
# --------------------------------------------
# 03/06/19	rmk@flint.arm.linux.org.uk	1.1332.2.29
# [ARM] Fix flush_cache_page address parameter.
# 
# Noticed by Jun Sun.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.8
# [PATCH] JBD: remove jh_splice_lock
# 
# This was a strange spinlock which was designed to prevent another CPU from
# ripping a buffer's journal_head away while this CPU was inspecting its state.
# 
# Really, we don't need it - we can inspect that state directly from bh->b_state.
# 
# So kill it off, along with a few things which used it which are themselves
# not actually used any more.
# --------------------------------------------
# 03/06/19	rmk@flint.arm.linux.org.uk	1.1332.2.30
# [ARM] Allow ECC and cache write allocations on ARMv5 and higher CPUs.
# 
# All current CPUs of ARMv5 or later can have ECC memory and can
# support write allocations.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.9
# [PATCH] JBD: fine-grain journal_add_journal_head locking
# 
# buffer_heads and journal_heads are joined at the hip.  We need a lock to
# protect the joint and its refcounts.
# 
# JBD is currently using a global spinlock for that.  Change it to use one bit
# in bh->b_state.
# --------------------------------------------
# 03/06/19	rmk@flint.arm.linux.org.uk	1.1332.2.31
# [ARM] Fix SECURITY_INIT in linker script.
# 
# SECURITY_INIT doesn't work when it is placed inside an output section.
# Use our own version instead.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.10
# [PATCH] JBD: rename journal_unlock_journal_head to
# 
# journal_unlock_journal_head() is misnamed: what it does is to drop a ref on
# the journal_head and free it if that ref fell to zero.  It doesn't actually
# unlock anything.
# 
# Rename it to journal_put_journal_head().
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.11
# [PATCH] JBD: Finish protection of journal_head.b_frozen_data
# 
# We now start to move across the JBD data structure's fields, from "innermost"
# and outwards.
# 
# Start with journal_head.b_frozen_data, because the locking for this field was
# partially implemented in jbd-010-b_committed_data-race-fix.patch.
# 
# It is protected by jbd_lock_bh_state().  We keep the lock_journal() and
# spin_lock(&journal_datalist_lock) calls in place.  Later,
# spin_lock(&journal_datalist_lock) is replaced by
# spin_lock(&journal->j_list_lock).
# 
# Of course, this completion of the locking around b_frozen_data also puts a
# lot of the locking for other fields in place.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.12
# [PATCH] JBD: implement b_committed_data locking
# 
# Implement the designed locking schema around the
# journal_head.b_committed_data field.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.13
# [PATCH] JBD: implement b_transaction locking rules
# 
# Go through all use of b_transaction and implement the rules.
# 
# Fairly straightforward.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.14
# [PATCH] JBD: Implement b_next_transaction locking rules
# 
# Go through all b_next_transaction instances, implement locking rules.
# (Nothing to do here - b_transaction locking covered it)
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.15
# [PATCH] JBD: b_tnext locking
# 
# Implement the designated b_tnext locking.
# 
# This also covers b_tprev locking.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.16
# [PATCH] JBD: remove journal_datalist_lock
# 
# This was a system-wide spinlock.
# 
# Simple transformation: make it a filesystem-wide spinlock, in the JBD
# journal.
# 
# That's a bit lame, and later it might be nice to make it per-transaction_t.
# But there are interesting ranking and ordering problems with that, especially
# around __journal_refile_buffer().
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.17
# [PATCH] JBD: t_nr_buffers locking
# 
# Now we move more into the locking of the transaction_t fields.
# 
# t_nr_buffers locking is just an audit-and-commentary job.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.18
# [PATCH] JBD: t_updates locking
# 
# Provide the designating locking for transaction_t.t_updates.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.19
# [PATCH] JBD: implement t_outstanding_credits locking
# 
# Implement the designed locking for t_outstanding_credits
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.20
# [PATCH] JBD: implement t_jcb locking
# 
# Provide the designed locking around the transaction's t_jcb callback list.
# 
# It turns out that this is wholly redundant at present.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.21
# [PATCH] JBD: implement j_barrier_count locking
# 
# We now start to move onto the fields of the topmost JBD data structure: the
# journal.
# 
# The patch implements the designed locking around the j_barrier_count member.
# And as a part of that, a lot of the new locking scheme is implemented.
# Several lock_kernel()s and sleep_on()s go away.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.22
# [PATCH] JBD: implement j_running_transaction locking
# 
# Implement the designed locking around journal->j_running_transaction.
# 
# A lot more of the new locking scheme falls into place.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.23
# [PATCH] JBD: implement j_committing_transaction locking
# 
# Go through all sites which use j_committing_transaction and ensure that the
# deisgned locking is correctly implemented there.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.24
# [PATCH] JBD: implement j_checkpoint_transactions locking
# 
# Implement the designed locking around j_checkpoint_transactions.  It was all
# pretty much there actually.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.25
# [PATCH] JBD: implement journal->j_head locking
# 
# Implement the designed locking around journal->j_head.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.26
# [PATCH] JBD: implement journal->j_tail locking
# 
# Implement the designed locking around journal->j_tail.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.27
# [PATCH] JBD: implement journal->j_free locking
# 
# Implement the designed locking around journal->j_free.
# 
# Things get a lot better here, too.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.28
# [PATCH] JBD: implement journal->j_commit_sequence locking
# 
# Implement the designed locking around journal->j_commit_sequence.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.29
# [PATCH] JBD: implement j_commit_request locking
# 
# Impement the designed locking around journal->j_commit_request.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.30
# [PATCH] JBD: implement dual revoke tables.
# 
# From: Alex Tomas <bzzz@tmi.comex.ru>
# 
# We're about to remove lock_journal(), and it is lock_journal which separates
# the running and committing transaction's revokes on the single revoke table.
# 
# So implement two revoke tables and rotate them at commit time.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.31
# [PATCH] JBD: remove remaining sleep_on()s
# 
# Remove the remaining sleep_on() calls from JBD.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.32
# [PATCH] JBD: remove lock_kernel()
# 
# lock_kernel() is no longer needed in JBD.  Remove all the lock_kernel() calls
# from fs/jbd/.
# 
# Here is where I get to say "ex-parrot".
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.33
# [PATCH] JBD: remove lock_journal()
# 
# This filesystem-wide sleeping lock is no longer needed.  Remove it.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.34
# [PATCH] JBD: journal_release_buffer: handle credits fix
# 
# There's a bug: a caller tries to journal a buffer and then decides he didn't
# want to after all.  He calls journal_release_buffer().
# 
# But journal_release_buffer() is only allowed to give the caller a buffer
# credit back if it was the caller who added the buffer in the first place.
# 
# journal_release_buffer() currently looks at the buffer state to work that
# out, but gets it wrong: if the buffer has been moved onto a different list by
# some other part of ext3 the credit is bogusly not returned to the caller and
# the fs can later go BUG due to handle credit exhaustion.
# 
# 
# The fix:
# 
# Change journal_get_undo_access() to return the number of buffers which the
# caller actually added to the journal.  (one or zero).
# 
# When the caller later calls journal_release_buffer(), he passes in that
# count, to tell journal_release_buffer() how many credits the caller should
# get back.
# 
# For API consistency this change should also be made to
# journal_get_create_access() and journal_get_write_access().  But there is no
# requirement for that in ext3 at this time.
# 
# 
# The remaining bug:
# 
# This logic effectively gives another transaction handle a free buffer credit.
# These could conceivably accumulate and cause a journal overflow.  This is a
# separate problem and needs changes to the t_outstanding_credits accounting
# and the logic in start_this_handle.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.35
# [PATCH] JBD: journal_unmap_buffer race fix
# 
# We need to check that buffer is still journalled _after_ taking the right
# locks.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.36
# [PATCH] ext3: ext3_writepage race fix
# 
# After ext3_writepage() has called block_write_full_page() it will walk the
# page's buffer ring dropping the buffer_head refcounts.
# 
# It does this wrong - on the final loop it will dereference the buffer_head
# which it just dropped the refcount on.  Poisoned oopses have been seen
# against bh->b_this_page.
# 
# Change it to take a local copy of b_this_page prior to dropping the bh's
# refcount.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.37
# [PATCH] JBD: buffer freeing non-race comment
# 
# Add a comment describing why a race isn't there.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.38
# [PATCH] JBD: add some locking assertions
# 
# Drop in a few assertions to ensure that the locking rules are being adhered
# to.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.39
# [PATCH] JBD: additional transaction shutdown locking
# 
# Plug a conceivable race with the freeing up of trasnactions, and add some
# more debug checks.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.40
# [PATCH] JBD: fix log_start_commit race
# 
# In start_this_handle() the caller does not have a handle ref pinning the
# transaction open, and so the call to log_start_commit() is racy because some
# other CPU could take the transaction into commit state independently.
# 
# Fix that by holding j_state_lock (which pins j_running_transaction) across
# the log_start_commit() call.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.41
# [PATCH] JBD: do_get_write_access() speedup
# 
# Avoid holding the journal's j_list_lock while copying the buffer_head's data.
# We hold jbd_lock_bh_state() during the copy, which is all that is needed.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.42
# [PATCH] ext3: fix data=journal mode
# 
# ext3's fully data-journalled mode has been broken for a year.  This patch
# fixes it up.
# 
# The prepare_write/commit_write/writepage implementations have been split up.
# Instead of having each function handle all three journalling mode we now have
# three separate sets of address_space_operations.
# 
# The problematic part of data=journal is MAP_SHARED writepage traffic: pages
# which don't have buffers.  In 2.4 these were cheatingly treated as
# data-ordered buffers and that caused several nasty problems.
# 
# Here we do it properly: writepage traffic is fully journalled.  This means
# that the various workarounds for the 2.4 scheme can be removed, when I
# remember where they all are.
# 
# The PG_checked flag has been borrowed: it it set in the atomic set_page_dirty
# a_op to tell the subsequent writepage() that this page needs to have buffers
# attached, dirtied and journalled.
# 
# This rather defines PG_checked as "fs-private info in page->flags" and it
# should be renamed sometime.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.43
# [PATCH] JBD: journal_try_to_free_buffers race fix
# 
# There is a race between transaction commit's attempt to free journal_heads
# and journal_try_to_free_buffers' attempt.
# 
# Fix that by taking a ref against the journal_head in
# journal_try_to_free_buffers().
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.44
# [PATCH] ext3: add a dump_stack()
# 
# add a dump_stack() to a can't-happen path which happened during development.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.45
# [PATCH] ext3: fix error-path handle leak
# 
# The ioctl handler can leave a transaction open on an error path.  That
# will wedge up the filesystem.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.46
# [PATCH] ext3: Fix leak in ext3_acl_chmod()
# 
# From: Andreas Gruenbacher <agruen@suse.de>
# 
# This function can leak a posix_acl on an error path.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.47
# [PATCH] ext3: remove mount-time diagnostic messages
# 
# ext3 no longer keeps the filesystem-wide free blocks counter and free inodes
# counter up to date all the time in the superblock.  Because that requires
# fs-wide locking.  These counters are only needed at runtime for the Orlov
# allocator heuristics, and we are now using a fuzzy per-cpu coutner for that.
# 
# These counters are rather unnecessary: the same info is present in the file
# allocation maps and inode tables, the group descriptor blocks and the
# bitmaps.
# 
# e2fsck will be changed to downgrade the seriousness of this inconsistency.
# 
# The filesystem _will_ write these numbers out in the superblock on a clean
# unmount, based on the sum of the free block and inode counts in the group
# descriptors.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.48
# [PATCH] JBD: journal_dirty_metadata() speedup
# 
# Before taking the highly-taken j_list_lock, take a peek to seem if this
# buffer is already journalled and in the appropriate state.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.49
# [PATCH] JBD: journal_dirty_metadata diagnostics
# 
# Try to trap some more state when an assertion which cannot happen happens.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.50
# [PATCH] JBD: fix race between journal_commit_transaction and
# 
# start_this_handle() can decide to add this handle to a transaction, but
# kjournald then moves the handle into commit phase.
# 
# Extend the coverage of j_state_lock so that start_this_transaction()'s
# examination of journal->j_state is atomic wrt journal_commit_transaction().
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.51
# [PATCH] ext3: fix data=journal for small blocksize
# 
# Fix various problems which cropped up due to MAP_SHARED traffic on
# data=journal with blocksize < PAGE_CACHE_SIZE.
# 
# All relate to handling the "pending truncate" buffers outside i_size.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.52
# [PATCH] JBD: remove j_commit_timer_active
# 
# This was a flag which said "the transaction's time is active".
# timer_pending() could have told us that, but in fact there is no need to
# query it at all.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.53
# [PATCH] ext3: explicitly free truncated pages
# 
# With data=ordered it is often the case that a quick write-and-truncate will
# leave large numbers of pages on the page LRU with no ->mapping, and attached
# buffers.  Because ext3 was not ready to let the pages go at the time of
# truncation.
# 
# These pages are trivially reclaimable, but their seeming absence makes the VM
# overcommit accounting confused (they don't count as "free", nor as
# pagecache).  And they make the /proc/meminfo stats look odd.
# 
# So what we do here is to try to strip the buffers from these pages as the
# buffers exit the journal commit.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.54
# [PATCH] JBD: log_do_checkpoint() locking fixes
# 
# log_do_checkpoint is playing around with a transaction pointer without enough
# locking to ensure that it is valid.  Fix that up by revalidating the
# transaction after acquiring the right locks.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.55
# [PATCH] JBD: fix locking around log_start_commit()
# 
# There are various places in which JBD is starting a commit against a
# transaction without sufficient locking in place to ensure that that
# transaction is still alive.
# 
# Change it so that log_start_commit() takes a transaction ID instead.  Make
# the caller take a copy of that ID inside the appropriate locks.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.56
# [PATCH] JBD: hold onto j_state_lock after
# 
# Minro tweak: once log_wait_for_space() has created sufficient space in the
# journal to start the new handle, hang onto the spinlock as
# start_this_handle() loops around to reevaluate the journal's state.
# 
# It prevents anyone else from zooming in and stealing the space we just made.
# --------------------------------------------
# 03/06/18	akpm@digeo.com	1.1332.6.57
# [PATCH] ext3: disable O_DIRECT in journalled-data mode
# 
# We cannot sensibly support O_DIRECT reads or writes when all writes are
# journalled.
# 
# This is because the VFS explicitly avoids syncing the file metadata during
# O_DIRECT reads and writes.  ext3 with journalled data will leave pending
# changes in memory and they will overwrite the results of O_DIRECT writes, and
# O_DIRECT reads will not return the latest data.
# 
# Setting the a_op to null will cause opens and fcntl(F_SETFL) to return
# -EINVAL if O_DIRECT is requested.
# --------------------------------------------
# 03/06/18	greg@kroah.com	1.1332.6.58
# merge
# --------------------------------------------
# 03/06/18	greg@kroah.com	1.1332.7.1
# Merge kroah.com:/home/greg/linux/BK/bleed-2.5
# into kroah.com:/home/greg/linux/BK/i2c-2.5
# --------------------------------------------
# 03/06/18	torvalds@home.transmeta.com	1.1332.6.59
# Merge bk://kernel.bkbits.net/gregkh/linux/i2c-2.5
# into home.transmeta.com:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/06/18	davem@nuts.ninka.net	1.1336
# Merge nuts.ninka.net:/home/davem/src/BK/network-2.5
# into nuts.ninka.net:/home/davem/src/BK/net-2.5
# --------------------------------------------
# 03/06/18	torvalds@home.transmeta.com	1.1332.2.32
# Merge bk://bk.arm.linux.org.uk/linux-2.5-rmk
# into home.transmeta.com:/home/torvalds/v2.5/linux
# --------------------------------------------
# 03/06/18	davem@nuts.ninka.net	1.1337
# [SPARC]: ESP scsi driver already has a release method, do not add a second one :-)
# --------------------------------------------
# 03/06/18	shemminger@osdl.org	1.1338
# [NET]: Use alloc_netdev in bonding driver.
# --------------------------------------------
# 03/06/18	shemminger@osdl.org	1.1339
# [NET]: Move Red Creek VPN drier to alloc_etherdev().
# --------------------------------------------
# 03/06/18	shemminger@osdl.org	1.1340
# [NET]: Kill unused function in Red Creek VPN driver.
# --------------------------------------------
# 03/06/18	davem@nuts.ninka.net	1.1341
# [NET]: Mark skb_linearize() as deprecated.
# --------------------------------------------
# 03/06/18	dlstevens@us.ibm.com	1.1342
# [IPV4/IPV6]: Fix IGMP device refcount leaks, with help from yoshfuji@linux-ipv6.org.
# --------------------------------------------
# 03/06/18	whydoubt@yahoo.com	1.1343
# [NET]: Export netdev_boot_setup_check.
# --------------------------------------------
# 03/06/18	chas@cmf.nrl.navy.mil	1.1344
# [ATM]: Fix possible unlock of a non-locked lock in HE driver.
# --------------------------------------------
# 03/06/18	davem@nuts.ninka.net	1.1345
# Merge bk://kernel.bkbits.net/acme/net-2.5
# into nuts.ninka.net:/home/davem/src/BK/net-2.5
# --------------------------------------------
# 03/06/18	davem@nuts.ninka.net	1.1346
# Merge bk://kernel.bkbits.net/acme/net-2.5
# into nuts.ninka.net:/home/davem/src/BK/net-2.5
# --------------------------------------------
# 03/06/18	davem@kernel.bkbits.net	1.1347
# Merge davem@nuts.ninka.net:/home/davem/src/BK/net-2.5
# into kernel.bkbits.net:/home/davem/net-2.5
# --------------------------------------------
# 03/06/18	davidm@napali.hpl.hp.com	1.1348
# [PATCH] re-enable the building of 8250_hcdp and 8250_acpi
# 
# This adds a separate SERIAL_8250_ACPI config option and makes the
# 8250_acpi.c code dependent on ACPI_BUS (since acpi_bus_register_driver()
# is a prerequisite).
# --------------------------------------------
#
diff -Nru a/Documentation/usb/dma.txt b/Documentation/usb/dma.txt
--- a/Documentation/usb/dma.txt	Wed Jun 18 23:42:08 2003
+++ b/Documentation/usb/dma.txt	Wed Jun 18 23:42:08 2003
@@ -15,10 +15,12 @@
   manage dma mappings for existing dma-ready buffers (see below).
 
 - URBs have an additional "transfer_dma" field, as well as a transfer_flags
-  bit saying if it's valid.  (Control requests also needed "setup_dma".) 
+  bit saying if it's valid.  (Control requests also have "setup_dma" and a
+  corresponding transfer_flags bit.)
 
-- "usbcore" will map those DMA addresses, if a DMA-aware driver didn't do it
-  first and set URB_NO_DMA_MAP.  HCDs don't manage dma mappings for urbs.
+- "usbcore" will map those DMA addresses, if a DMA-aware driver didn't do
+  it first and set URB_NO_TRANSFER_DMA_MAP or URB_NO_SETUP_DMA_MAP.  HCDs
+  don't manage dma mappings for URBs.
 
 - There's a new "generic DMA API", parts of which are usable by USB device
   drivers.  Never use dma_set_mask() on any USB interface or device; that
@@ -33,8 +35,9 @@
 - When you're allocating a buffer for DMA purposes anyway, use the buffer
   primitives.  Think of them as kmalloc and kfree that give you the right
   kind of addresses to store in urb->transfer_buffer and urb->transfer_dma,
-  while guaranteeing that hidden copies through DMA "bounce" buffers won't
-  slow things down.  You'd also set URB_NO_DMA_MAP in urb->transfer_flags:
+  while guaranteeing that no hidden copies through DMA "bounce" buffers will
+  slow things down.  You'd also set URB_NO_TRANSFER_DMA_MAP in
+  urb->transfer_flags:
 
 	void *usb_buffer_alloc (struct usb_device *dev, size_t size,
 		int mem_flags, dma_addr_t *dma);
@@ -42,10 +45,18 @@
 	void usb_buffer_free (struct usb_device *dev, size_t size,
 		void *addr, dma_addr_t dma);
 
+  For control transfers you can use the buffer primitives or not for each
+  of the transfer buffer and setup buffer independently.  Set the flag bits
+  URB_NO_TRANSFER_DMA_MAP and URB_NO_SETUP_DMA_MAP to indicate which
+  buffers you have prepared.  For non-control transfers URB_NO_SETUP_DMA_MAP
+  is ignored.
+
   The memory buffer returned is "dma-coherent"; sometimes you might need to
   force a consistent memory access ordering by using memory barriers.  It's
   not using a streaming DMA mapping, so it's good for small transfers on
-  systems where the I/O would otherwise tie up an IOMMU mapping.
+  systems where the I/O would otherwise tie up an IOMMU mapping.  (See
+  Documentation/DMA-mapping.txt for definitions of "coherent" and "streaming"
+  DMA mappings.)
 
   Asking for 1/Nth of a page (as well as asking for N pages) is reasonably
   space-efficient.
@@ -91,7 +102,8 @@
 
   These calls all work with initialized urbs:  urb->dev, urb->pipe,
   urb->transfer_buffer, and urb->transfer_buffer_length must all be
-  valid when these calls are used:
+  valid when these calls are used (urb->setup_packet must be valid too
+  if urb is a control request):
 
 	struct urb *usb_buffer_map (struct urb *urb);
 
@@ -99,6 +111,6 @@
 
 	void usb_buffer_unmap (struct urb *urb);
 
-  The calls manage urb->transfer_dma for you, and set URB_NO_DMA_MAP so that
-  usbcore won't map or unmap the buffer.
-
+  The calls manage urb->transfer_dma for you, and set URB_NO_TRANSFER_DMA_MAP
+  so that usbcore won't map or unmap the buffer.  The same goes for
+  urb->setup_dma and URB_NO_SETUP_DMA_MAP for control requests.
diff -Nru a/arch/alpha/Kconfig b/arch/alpha/Kconfig
--- a/arch/alpha/Kconfig	Wed Jun 18 23:42:08 2003
+++ b/arch/alpha/Kconfig	Wed Jun 18 23:42:08 2003
@@ -647,103 +647,7 @@
 	  This driver is also available as a module and will be called
 	  srm_env then.
 
-config BINFMT_AOUT
-	tristate "Kernel support for a.out (ECOFF) binaries"
-	---help---
-	  A.out (Assembler.OUTput) is a set of formats for libraries and
-	  executables used in the earliest versions of UNIX. Linux used the
-	  a.out formats QMAGIC and ZMAGIC until they were replaced with the
-	  ELF format.
-
-	  As more and more programs are converted to ELF, the use for a.out
-	  will gradually diminish. If you disable this option it will reduce
-	  your kernel by one page. This is not much and by itself does not
-	  warrant removing support. However its removal is a good idea if you
-	  wish to ensure that absolutely none of your programs will use this
-	  older executable format. If you don't know what to answer at this
-	  point then answer Y. If someone told you "You need a kernel with
-	  QMAGIC support" then you'll have to say Y here. You may answer M to
-	  compile a.out support as a module and later load the module when you
-	  want to use a program or library in a.out format. The module will be
-	  called binfmt_aout. Saying M or N here is dangerous though,
-	  because some crucial programs on your system might still be in A.OUT
-	  format.
-
-config OSF4_COMPAT
-	bool "OSF/1 v4 readv/writev compatibility"
-	depends on BINFMT_AOUT
-	help
-	  Say Y if you are using OSF/1 binaries (like Netscape and Acrobat)
-	  with v4 shared libraries freely available from Compaq. If you're
-	  going to use shared libraries from Tru64 version 5.0 or later, say N.
-
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  use this part of the kernel.
-
-	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc. If you
-	  don't know what to answer at this point, say Y.
-
-config BINFMT_EM86
-	tristate "Kernel support for Linux/Intel ELF binaries"
-	---help---
-	  Say Y here if you want to be able to execute Linux/Intel ELF
-	  binaries just like native Alpha binaries on your Alpha machine. For
-	  this to work, you need to have the emulator /usr/bin/em86 in place.
-
-	  You can get the same functionality by saying N here and saying Y to
-	  "Kernel support for MISC binaries".
-
-	  You may answer M to compile the emulation support as a module and
-	  later load the module when you want to use a Linux/Intel binary. The
-	  module will be called binfmt_em86. If unsure, say Y.
+source "fs/Kconfig.binfmt"
 
 source "drivers/parport/Kconfig"
 
diff -Nru a/arch/arm/Kconfig b/arch/arm/Kconfig
--- a/arch/arm/Kconfig	Wed Jun 18 23:42:07 2003
+++ b/arch/arm/Kconfig	Wed Jun 18 23:42:07 2003
@@ -483,6 +483,16 @@
 	depends on PCI && ARCH_SHARK
 	default y
 
+config ICST525
+	bool
+	depends on ARCH_INTEGRATOR
+	default y
+
+config ARM_AMBA
+	bool
+	depends on ARCH_INTEGRATOR
+	default y
+
 config ISA
 	bool
 	depends on FOOTBRIDGE_HOST || ARCH_SHARK || ARCH_CLPS7500 || ARCH_EBSA110 || ARCH_CDB89712 || ARCH_EDB7211 || ARCH_SA1100
@@ -582,7 +592,7 @@
 
 config CPU_FREQ_INTEGRATOR
 	tristate "CPUfreq driver for ARM Integrator CPUs"
-	depends on ARCH_INTEGRATOR && CPU_FREQ
+	depends on ARCH_INTEGRATOR && ICST525 && CPU_FREQ
 	default y
 	help
 	  This enables the CPUfreq driver for ARM Integrator CPUs.
@@ -691,81 +701,7 @@
 
 endchoice
 
-config BINFMT_AOUT
-	tristate "Kernel support for a.out binaries"
-	---help---
-	  A.out (Assembler.OUTput) is a set of formats for libraries and
-	  executables used in the earliest versions of UNIX. Linux used the
-	  a.out formats QMAGIC and ZMAGIC until they were replaced with the
-	  ELF format.
-
-	  As more and more programs are converted to ELF, the use for a.out
-	  will gradually diminish. If you disable this option it will reduce
-	  your kernel by one page. This is not much and by itself does not
-	  warrant removing support. However its removal is a good idea if you
-	  wish to ensure that absolutely none of your programs will use this
-	  older executable format. If you don't know what to answer at this
-	  point then answer Y. If someone told you "You need a kernel with
-	  QMAGIC support" then you'll have to say Y here. You may answer M to
-	  compile a.out support as a module and later load the module when you
-	  want to use a program or library in a.out format. The module will be
-	  called binfmt_aout. Saying M or N here is dangerous though,
-	  because some crucial programs on your system might still be in A.OUT
-	  format.
-
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  use this part of the kernel.
-
-	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 config PM
 	bool "Power Management support"
diff -Nru a/arch/arm/common/Makefile b/arch/arm/common/Makefile
--- a/arch/arm/common/Makefile	Wed Jun 18 23:42:07 2003
+++ b/arch/arm/common/Makefile	Wed Jun 18 23:42:07 2003
@@ -3,6 +3,8 @@
 #
 
 obj-y				+= platform.o
+obj-$(CONFIG_ARM_AMBA)		+= amba.o
+obj-$(CONFIG_ICST525)		+= icst525.o
 obj-$(CONFIG_SA1111)		+= sa1111.o sa1111-pcibuf.o sa1111-pcipool.o
 obj-$(CONFIG_PCI_HOST_PLX90X0)	+= plx90x0.o
 obj-$(CONFIG_PCI_HOST_VIA82C505) += via82c505.o
diff -Nru a/arch/arm/common/amba.c b/arch/arm/common/amba.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/common/amba.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,243 @@
+/*
+ *  linux/arch/arm/common/amba.c
+ *
+ *  Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/device.h>
+
+#include <asm/io.h>
+#include <asm/hardware/amba.h>
+#include <asm/sizes.h>
+
+#define to_amba_device(d)	container_of(d, struct amba_device, dev)
+#define to_amba_driver(d)	container_of(d, struct amba_driver, drv)
+
+static struct amba_id *
+amba_lookup(struct amba_id *table, struct amba_device *dev)
+{
+	int ret = 0;
+
+	while (table->mask) {
+		ret = (dev->periphid & table->mask) == table->id;
+		if (ret)
+			break;
+		table++;
+	}
+
+	return ret ? table : NULL;
+}
+
+static int amba_match(struct device *dev, struct device_driver *drv)
+{
+	struct amba_device *pcdev = to_amba_device(dev);
+	struct amba_driver *pcdrv = to_amba_driver(drv);
+
+	return amba_lookup(pcdrv->id_table, pcdev) != NULL;
+}
+
+/*
+ * Primecells are part of the Advanced Microcontroller Bus Architecture,
+ * so we call the bus "amba".
+ */
+struct bus_type amba_bustype = {
+	.name	= "amba",
+	.match	= amba_match,
+};
+
+static int __init amba_init(void)
+{
+	return bus_register(&amba_bustype);
+}
+
+postcore_initcall(amba_init);
+
+/*
+ * These are the device model conversion veneers; they convert the
+ * device model structures to our more specific structures.
+ */
+static int amba_probe(struct device *dev)
+{
+	struct amba_device *pcdev = to_amba_device(dev);
+	struct amba_driver *pcdrv = to_amba_driver(dev->driver);
+	struct amba_id *id;
+
+	id = amba_lookup(pcdrv->id_table, pcdev);
+
+	return pcdrv->probe(pcdev, id);
+}
+
+static int amba_remove(struct device *dev)
+{
+	struct amba_driver *drv = to_amba_driver(dev->driver);
+	return drv->remove(to_amba_device(dev));
+}
+
+static void amba_shutdown(struct device *dev)
+{
+	struct amba_driver *drv = to_amba_driver(dev->driver);
+	drv->shutdown(to_amba_device(dev));
+}
+
+static int amba_suspend(struct device *dev, u32 state, u32 level)
+{
+	struct amba_driver *drv = to_amba_driver(dev->driver);
+	return drv->suspend(to_amba_device(dev), state, level);
+}
+
+static int amba_resume(struct device *dev, u32 level)
+{
+	struct amba_driver *drv = to_amba_driver(dev->driver);
+	return drv->resume(to_amba_device(dev), level);
+}
+
+/**
+ *	amba_driver_register - register an AMBA device driver
+ *	@drv: amba device driver structure
+ *
+ *	Register an AMBA device driver with the Linux device model
+ *	core.  If devices pre-exist, the drivers probe function will
+ *	be called.
+ */
+int amba_driver_register(struct amba_driver *drv)
+{
+	drv->drv.bus = &amba_bustype;
+
+#define SETFN(fn)	if (drv->fn) drv->drv.fn = amba_##fn
+	SETFN(probe);
+	SETFN(remove);
+	SETFN(shutdown);
+	SETFN(suspend);
+	SETFN(resume);
+
+	return driver_register(&drv->drv);
+}
+
+/**
+ *	amba_driver_unregister - remove an AMBA device driver
+ *	@drv: AMBA device driver structure to remove
+ *
+ *	Unregister an AMBA device driver from the Linux device
+ *	model.  The device model will call the drivers remove function
+ *	for each device the device driver is currently handling.
+ */
+void amba_driver_unregister(struct amba_driver *drv)
+{
+	driver_unregister(&drv->drv);
+}
+
+
+static void amba_device_release(struct device *dev)
+{
+	struct amba_device *d = to_amba_device(dev);
+
+	if (d->res.parent)
+		release_resource(&d->res);
+	kfree(d);
+}
+
+static ssize_t show_id(struct device *_dev, char *buf)
+{
+	struct amba_device *dev = to_amba_device(_dev);
+	return sprintf(buf, "%08x\n", dev->periphid);
+}
+static DEVICE_ATTR(id, S_IRUGO, show_id, NULL);
+
+static ssize_t show_irq(struct device *_dev, char *buf)
+{
+	struct amba_device *dev = to_amba_device(_dev);
+	return sprintf(buf, "%u\n", dev->irq);
+}
+static DEVICE_ATTR(irq, S_IRUGO, show_irq, NULL);
+
+static ssize_t show_res(struct device *_dev, char *buf)
+{
+	struct amba_device *dev = to_amba_device(_dev);
+	return sprintf(buf, "\t%08lx\t%08lx\t%08lx\n",
+			dev->res.start, dev->res.end, dev->res.flags);
+}
+static DEVICE_ATTR(resource, S_IRUGO, show_res, NULL);
+
+/**
+ *	amba_device_register - register an AMBA device
+ *	@dev: AMBA device to register
+ *	@parent: parent memory resource
+ *
+ *	Setup the AMBA device, reading the cell ID if present.
+ *	Claim the resource, and register the AMBA device with
+ *	the Linux device manager.
+ */
+int amba_device_register(struct amba_device *dev, struct resource *parent)
+{
+	u32 pid, cid;
+	void *tmp;
+	int i, ret;
+
+	dev->dev.release = amba_device_release;
+	dev->dev.bus = &amba_bustype;
+	dev->res.name = dev->dev.name;
+
+	ret = request_resource(parent, &dev->res);
+	if (ret == 0) {
+		tmp = ioremap(dev->res.start, SZ_4K);
+		if (!tmp) {
+			ret = -ENOMEM;
+			goto out;
+		}
+
+		for (pid = 0, i = 0; i < 4; i++)
+			pid |= (readl(tmp + 0xfe0 + 4 * i) & 255) << (i * 8);
+		for (cid = 0, i = 0; i < 4; i++)
+			cid |= (readl(tmp + 0xff0 + 4 * i) & 255) << (i * 8);
+
+		iounmap(tmp);
+
+		if (cid == 0xb105f00d)
+			dev->periphid = pid;
+
+		if (dev->periphid)
+			snprintf(dev->dev.name, sizeof(dev->dev.name),
+				 "AMBA PL%03X",
+				 dev->periphid & 0xfff);
+		else
+			strlcpy(dev->dev.name, "AMBA unknown",
+				sizeof(dev->dev.name));
+
+		ret = device_register(&dev->dev);
+		if (ret == 0) {
+			device_create_file(&dev->dev, &dev_attr_id);
+			device_create_file(&dev->dev, &dev_attr_irq);
+			device_create_file(&dev->dev, &dev_attr_resource);
+		} else {
+ out:
+			release_resource(&dev->res);
+		}
+	}
+	return ret;
+}
+
+/**
+ *	amba_device_unregister - unregister an AMBA device
+ *	@dev: AMBA device to remove
+ *
+ *	Remove the specified AMBA device from the Linux device
+ *	manager.  All files associated with this object will be
+ *	destroyed, and device drivers notified that the device has
+ *	been removed.  The AMBA device's resources including
+ *	the amba_device structure will be freed once all
+ *	references to it have been dropped.
+ */
+void amba_device_unregister(struct amba_device *dev)
+{
+	device_unregister(&dev->dev);
+}
+
+EXPORT_SYMBOL(amba_driver_register);
+EXPORT_SYMBOL(amba_driver_unregister);
+EXPORT_SYMBOL(amba_device_register);
+EXPORT_SYMBOL(amba_device_unregister);
diff -Nru a/arch/arm/common/icst525.c b/arch/arm/common/icst525.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/arm/common/icst525.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,160 @@
+/*
+ *  linux/arch/arm/common/icst525.c
+ *
+ *  Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Support functions for calculating clocks/divisors for the ICST525
+ *  clock generators.  See http://www.icst.com/ for more information
+ *  on these devices.
+ */
+#include <linux/module.h>
+#include <linux/kernel.h>
+
+#include <asm/hardware/icst525.h>
+
+/*
+ * Divisors for each OD setting.
+ */
+static unsigned char s2div[8] = { 10, 2, 8, 4, 5, 7, 9, 6 };
+
+unsigned long icst525_khz(const struct icst525_params *p, struct icst525_vco vco)
+{
+	return p->ref * 2 * (vco.v + 8) / ((vco.r + 2) * s2div[vco.s]);
+}
+
+EXPORT_SYMBOL(icst525_khz);
+
+/*
+ * Ascending divisor S values.
+ */
+static unsigned char idx2s[] = { 1, 3, 4, 7, 5, 2, 6, 0 };
+
+struct icst525_vco
+icst525_khz_to_vco(const struct icst525_params *p, unsigned long freq)
+{
+	struct icst525_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max };
+	unsigned long f;
+	unsigned int i = 0, rd, best = (unsigned int)-1;
+
+	/*
+	 * First, find the PLL output divisor such
+	 * that the PLL output is within spec.
+	 */
+	do {
+		f = freq * s2div[idx2s[i]];
+
+		/*
+		 * f must be between 10MHz and
+		 *  320MHz (5V) or 200MHz (3V)
+		 */
+		if (f > 10000 && f <= p->vco_max)
+			break;
+	} while (i < ARRAY_SIZE(idx2s));
+
+	if (i > ARRAY_SIZE(idx2s))
+		return vco;
+
+	vco.s = idx2s[i];
+
+	/*
+	 * Now find the closest divisor combination
+	 * which gives a PLL output of 'f'.
+	 */
+	for (rd = p->rd_min; rd <= p->rd_max; rd++) {
+		unsigned long fref_div, f_pll;
+		unsigned int vd;
+		int f_diff;
+
+		fref_div = (2 * p->ref) / rd;
+
+		vd = (f + fref_div / 2) / fref_div;
+		if (vd < p->vd_min || vd > p->vd_max)
+			continue;
+
+		f_pll = fref_div * vd;
+		f_diff = f_pll - f;
+		if (f_diff < 0)
+			f_diff = -f_diff;
+
+		if ((unsigned)f_diff < best) {
+			vco.v = vd - 8;
+			vco.r = rd - 2;
+			if (f_diff == 0)
+				break;
+			best = f_diff;
+		}
+	}
+
+	return vco;
+}
+
+EXPORT_SYMBOL(icst525_khz_to_vco);
+
+struct icst525_vco
+icst525_ps_to_vco(const struct icst525_params *p, unsigned long period)
+{
+	struct icst525_vco vco = { .s = 1, .v = p->vd_max, .r = p->rd_max };
+	unsigned long f, ps;
+	unsigned int i = 0, rd, best = (unsigned int)-1;
+
+	ps = 1000000000UL / p->vco_max;
+
+	/*
+	 * First, find the PLL output divisor such
+	 * that the PLL output is within spec.
+	 */
+	do {
+		f = period / s2div[idx2s[i]];
+
+		/*
+		 * f must be between 10MHz and
+		 *  320MHz (5V) or 200MHz (3V)
+		 */
+		if (f >= ps && f < 100000)
+			break;
+	} while (i < ARRAY_SIZE(idx2s));
+
+	if (i > ARRAY_SIZE(idx2s))
+		return vco;
+
+	vco.s = idx2s[i];
+
+	ps = 500000000UL / p->ref;
+
+	/*
+	 * Now find the closest divisor combination
+	 * which gives a PLL output of 'f'.
+	 */
+	for (rd = p->rd_min; rd <= p->rd_max; rd++) {
+		unsigned long f_in_div, f_pll;
+		unsigned int vd;
+		int f_diff;
+
+		f_in_div = ps * rd;
+
+		vd = (f_in_div + f / 2) / f;
+		if (vd < p->vd_min || vd > p->vd_max)
+			continue;
+
+		f_pll = (f_in_div + vd / 2) / vd;
+		f_diff = f_pll - f;
+		if (f_diff < 0)
+			f_diff = -f_diff;
+
+		if ((unsigned)f_diff < best) {
+			vco.v = vd - 8;
+			vco.r = rd - 2;
+			if (f_diff == 0)
+				break;
+			best = f_diff;
+		}
+	}
+
+	return vco;
+}
+
+EXPORT_SYMBOL(icst525_ps_to_vco);
diff -Nru a/arch/arm/mach-integrator/core.c b/arch/arm/mach-integrator/core.c
--- a/arch/arm/mach-integrator/core.c	Wed Jun 18 23:42:08 2003
+++ b/arch/arm/mach-integrator/core.c	Wed Jun 18 23:42:08 2003
@@ -31,6 +31,8 @@
 #include <asm/irq.h>
 #include <asm/setup.h>
 #include <asm/mach-types.h>
+#include <asm/hardware/amba.h>
+#include <asm/hardware/amba_kmi.h>
 
 #include <asm/mach/arch.h>
 #include <asm/mach/irq.h>
@@ -104,7 +106,7 @@
 	.mask	= sc_mask_irq,
 	.unmask = sc_unmask_irq,
 };
- 
+
 static void __init integrator_init_irq(void)
 {
 	unsigned int i;
@@ -125,6 +127,52 @@
 		}
 	}
 }
+
+static struct amba_device kmi0_device = {
+	.dev		= {
+		.bus_id	= "mb:18",
+	},
+	.res		= {
+		.start	= KMI0_BASE,
+		.end	= KMI0_BASE + KMI_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	.irq		= IRQ_KMIINT0,
+	.periphid	= 0x00041050,
+};
+
+static struct amba_device kmi1_device = {
+	.dev		= {
+		.bus_id	= "mb:19",
+	},
+	.res		= {
+		.start	= KMI1_BASE,
+		.end	= KMI1_BASE + KMI_SIZE - 1,
+		.flags	= IORESOURCE_MEM,
+	},
+	.irq		= IRQ_KMIINT1,
+	.periphid	= 0x00041050,
+};
+
+static struct amba_device *amba_devs[] __initdata = {
+	&kmi0_device,
+	&kmi1_device,
+};
+
+static int __init register_devices(void)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(amba_devs); i++) {
+		struct amba_device *d = amba_devs[i];
+
+		amba_device_register(d, &iomem_resource);
+	}
+
+	return 0;
+}
+
+arch_initcall(register_devices);
 
 MACHINE_START(INTEGRATOR, "ARM-Integrator")
 	MAINTAINER("ARM Ltd/Deep Blue Solutions Ltd")
diff -Nru a/arch/arm/mach-integrator/cpu.c b/arch/arm/mach-integrator/cpu.c
--- a/arch/arm/mach-integrator/cpu.c	Wed Jun 18 23:42:07 2003
+++ b/arch/arm/mach-integrator/cpu.c	Wed Jun 18 23:42:07 2003
@@ -23,6 +23,7 @@
 
 #include <asm/hardware.h>
 #include <asm/io.h>
+#include <asm/hardware/icst525.h>
 
 static struct cpufreq_driver integrator_driver;
 
@@ -31,75 +32,40 @@
 #define CM_STAT (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_STAT_OFFSET)
 #define CM_LOCK (IO_ADDRESS(INTEGRATOR_HDR_BASE)+INTEGRATOR_HDR_LOCK_OFFSET)
 
-struct vco {
-	unsigned char vdw;
-	unsigned char od;
+static const struct icst525_params lclk_params = {
+	.ref		= 24000,
+	.vco_max	= 320000,
+	.vd_min		= 8,
+	.vd_max		= 132,
+	.rd_min		= 24,
+	.rd_max		= 24,
 };
 
-/*
- * Divisors for each OD setting.
- */
-static unsigned char cc_divisor[8] = { 10, 2, 8, 4, 5, 7, 9, 6 };
-
-static unsigned int vco_to_freq(struct vco vco, int factor)
-{
-	return 2000 * (vco.vdw + 8) / cc_divisor[vco.od] / factor;
-}
-
-/*
- * Divisor indexes in ascending divisor order
- */
-static unsigned char s2od[] = { 1, 3, 4, 7, 5, 2, 6, 0 };
-
-static struct vco freq_to_vco(unsigned int freq_khz, int factor)
-{
-	struct vco vco = {0, 0};
-	unsigned int i, f;
-
-	freq_khz *= factor;
-
-	for (i = 0; i < 8; i++) {
-		f = freq_khz * cc_divisor[s2od[i]];
-		/* f must be between 10MHz and 320MHz */
-		if (f > 10000 && f <= 320000)
-			break;
-	}
-
-	vco.od  = s2od[i];
-	vco.vdw = f / 2000 - 8;
-
-	return vco;
-}
-
+static const struct icst525_params cclk_params = {
+	.ref		= 24000,
+	.vco_max	= 320000,
+	.vd_min		= 12,
+	.vd_max		= 160,
+	.rd_min		= 24,
+	.rd_max		= 24,
+};
 
 /*
  * Validate the speed policy.
  */
 static int integrator_verify_policy(struct cpufreq_policy *policy)
 {
-	struct vco vco;
+	struct icst525_vco vco;
 
 	cpufreq_verify_within_limits(policy, 
 				     policy->cpuinfo.min_freq, 
 				     policy->cpuinfo.max_freq);
 
-	vco = freq_to_vco(policy->max, 1);
-
-	if (vco.vdw < 4)
-		vco.vdw = 4;
-	if (vco.vdw > 152)
-		vco.vdw = 152;
-
-	policy->max = vco_to_freq(vco, 1);
-
-	vco = freq_to_vco(policy->min, 1);
-
-	if (vco.vdw < 4)
-		vco.vdw = 4;
-	if (vco.vdw > 152)
-		vco.vdw = 152;
+	vco = icst525_khz_to_vco(&cclk_params, policy->max);
+	policy->max = icst525_khz(&cclk_params, vco);
 
-	policy->min = vco_to_freq(vco, 1);
+	vco = icst525_khz_to_vco(&cclk_params, policy->min);
+	policy->min = icst525_khz(&cclk_params, vco);
 
 	cpufreq_verify_within_limits(policy, 
 				     policy->cpuinfo.min_freq, 
@@ -115,7 +81,7 @@
 {
 	unsigned long cpus_allowed;
 	int cpu = policy->cpu;
-	struct vco vco;
+	struct icst525_vco vco;
 	struct cpufreq_freqs freqs;
 	u_int cm_osc;
 
@@ -133,19 +99,20 @@
 
 	/* get current setting */
 	cm_osc = __raw_readl(CM_OSC);
-	vco.od = (cm_osc >> 8) & 7;
-	vco.vdw = cm_osc & 255;
-	freqs.old = vco_to_freq(vco, 1);
+	vco.s = (cm_osc >> 8) & 7;
+	vco.v = cm_osc & 255;
+	vco.r = 22;
+	freqs.old = icst525_khz(&cclk_params, vco);
 
-	/* freq_to_vco rounds down -- so we need the next larger freq in
-	 * case of CPUFREQ_RELATION_L.
+	/* icst525_khz_to_vco rounds down -- so we need the next
+	 * larger freq in case of CPUFREQ_RELATION_L.
 	 */
 	if (relation == CPUFREQ_RELATION_L)
 		target_freq += 1999;
 	if (target_freq > policy->max)
 		target_freq = policy->max;
-	vco = freq_to_vco(target_freq, 1);
-	freqs.new = vco_to_freq(vco, 1);
+	vco = icst525_khz_to_vco(&cclk_params, target_freq);
+	freqs.new = icst525_khz(&cclk_params, vco);
 
 	freqs.cpu = policy->cpu;
 
@@ -158,7 +125,7 @@
 
 	cm_osc = __raw_readl(CM_OSC);
 	cm_osc &= 0xfffff800;
-	cm_osc |= vco.vdw | vco.od << 8;
+	cm_osc |= vco.v | vco.s << 8;
 
 	__raw_writel(0xa05f, CM_LOCK);
 	__raw_writel(cm_osc, CM_OSC);
@@ -179,7 +146,7 @@
 	unsigned long cpus_allowed;
 	unsigned int cpu = policy->cpu;
 	u_int cm_osc, cm_stat, mem_freq_khz;
-	struct vco vco;
+	struct icst525_vco vco;
 
 	cpus_allowed = current->cpus_allowed;
 
@@ -189,23 +156,26 @@
 	/* detect memory etc. */
 	cm_stat = __raw_readl(CM_STAT);
 	cm_osc = __raw_readl(CM_OSC);
-	vco.od  = (cm_osc >> 20) & 7;
-	vco.vdw = (cm_osc >> 12) & 255;
-	mem_freq_khz = vco_to_freq(vco, 2);
+	vco.s = (cm_osc >> 20) & 7;
+	vco.v = (cm_osc >> 12) & 255;
+	vco.r = 22;
+	mem_freq_khz = icst525_khz(&lclk_params, vco) / 2;
 
 	printk(KERN_INFO "CPU%d: Module id: %d\n", cpu, cm_stat & 255);
 	printk(KERN_INFO "CPU%d: Memory clock = %d.%03d MHz\n",
 	       cpu, mem_freq_khz / 1000, mem_freq_khz % 1000);
 
-	vco.od = (cm_osc >> 8) & 7;
-	vco.vdw = cm_osc & 255;
+	vco.s = (cm_osc >> 8) & 7;
+	vco.v = cm_osc & 255;
+	vco.r = 22;
 
 	/* set default policy and cpuinfo */
 	policy->policy = CPUFREQ_POLICY_PERFORMANCE;
 	policy->cpuinfo.max_freq = 160000;
 	policy->cpuinfo.min_freq = 12000;
 	policy->cpuinfo.transition_latency = 1000; /* 1 ms, assumed */
-	policy->cur = policy->min = policy->max = vco_to_freq(vco, 1); /* current freq */
+	policy->cur = policy->min = policy->max =
+		icst525_khz(&cclk_params, vco); /* current freq */
 
 	set_cpus_allowed(current, cpus_allowed);
 
diff -Nru a/arch/arm/mach-sa1100/irq.c b/arch/arm/mach-sa1100/irq.c
--- a/arch/arm/mach-sa1100/irq.c	Wed Jun 18 23:42:09 2003
+++ b/arch/arm/mach-sa1100/irq.c	Wed Jun 18 23:42:09 2003
@@ -211,14 +211,14 @@
 	.end	= 0x9005ffff,
 };
 
-static struct {
+static struct sa1100irq_state {
 	unsigned int	saved;
 	unsigned int	icmr;
 	unsigned int	iclr;
 	unsigned int	iccr;
 } sa1100irq_state;
 
-static int sa1100irq_suspend(struct device *dev, u32 state, u32 level)
+static int sa1100irq_suspend(struct sys_device *dev, u32 state)
 {
 	struct sa1100irq_state *st = &sa1100irq_state;
 
diff -Nru a/arch/arm/mm/fault-armv.c b/arch/arm/mm/fault-armv.c
--- a/arch/arm/mm/fault-armv.c	Wed Jun 18 23:42:06 2003
+++ b/arch/arm/mm/fault-armv.c	Wed Jun 18 23:42:06 2003
@@ -213,7 +213,7 @@
 		if (off >= (mpnt->vm_end - mpnt->vm_start) >> PAGE_SHIFT)
 			continue;
 
-		flush_cache_page(mpnt, off);
+		flush_cache_page(mpnt, mpnt->vm_start + (off << PAGE_SHIFT));
 	}
 }
 
diff -Nru a/arch/arm/mm/mm-armv.c b/arch/arm/mm/mm-armv.c
--- a/arch/arm/mm/mm-armv.c	Wed Jun 18 23:42:08 2003
+++ b/arch/arm/mm/mm-armv.c	Wed Jun 18 23:42:08 2003
@@ -309,9 +309,9 @@
 	const char *policy;
 
 	/*
-	 * ARMv5 can use ECC memory.
+	 * ARMv5 and higher can use ECC memory.
 	 */
-	if (cpu_arch == CPU_ARCH_ARMv5) {
+	if (cpu_arch >= CPU_ARCH_ARMv5) {
 		mem_types[MT_VECTORS].prot_l1 |= ecc_mask;
 		mem_types[MT_MEMORY].prot_sect |= ecc_mask;
 	} else {
diff -Nru a/arch/arm/vmlinux-armv.lds.in b/arch/arm/vmlinux-armv.lds.in
--- a/arch/arm/vmlinux-armv.lds.in	Wed Jun 18 23:42:06 2003
+++ b/arch/arm/vmlinux-armv.lds.in	Wed Jun 18 23:42:06 2003
@@ -53,7 +53,9 @@
 		__con_initcall_start = .;
 			*(.con_initcall.init)
 		__con_initcall_end = .;
-		SECURITY_INIT
+		__security_initcall_start = .;
+			*(.security_initcall.init)
+		__security_initcall_end = .;
 		. = ALIGN(32);
 		__initramfs_start = .;
 			usr/built-in.o(.init.ramfs)
diff -Nru a/arch/cris/Kconfig b/arch/cris/Kconfig
--- a/arch/cris/Kconfig	Wed Jun 18 23:42:09 2003
+++ b/arch/cris/Kconfig	Wed Jun 18 23:42:09 2003
@@ -25,34 +25,7 @@
 
 menu "General setup"
 
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
+source "fs/Kconfig.binfmt"
 
 config ETRAX_KGDB
 	bool "Use kernel gdb debugger"
diff -Nru a/arch/h8300/Kconfig b/arch/h8300/Kconfig
--- a/arch/h8300/Kconfig	Wed Jun 18 23:42:08 2003
+++ b/arch/h8300/Kconfig	Wed Jun 18 23:42:08 2003
@@ -141,10 +141,7 @@
 config KCORE_ELF
 	default y
 
-config BINFMT_FLAT
-	tristate "Kernel support for flat binaries"
-	help
-	  Support uClinux FLAT format binaries.
+source "fs/Kconfig.binfmt"
 
 endmenu
 
diff -Nru a/arch/i386/Kconfig b/arch/i386/Kconfig
--- a/arch/i386/Kconfig	Wed Jun 18 23:42:06 2003
+++ b/arch/i386/Kconfig	Wed Jun 18 23:42:06 2003
@@ -1190,81 +1190,7 @@
 
 endchoice
 
-config BINFMT_AOUT
-	tristate "Kernel support for a.out binaries"
-	---help---
-	  A.out (Assembler.OUTput) is a set of formats for libraries and
-	  executables used in the earliest versions of UNIX. Linux used the
-	  a.out formats QMAGIC and ZMAGIC until they were replaced with the
-	  ELF format.
-
-	  As more and more programs are converted to ELF, the use for a.out
-	  will gradually diminish. If you disable this option it will reduce
-	  your kernel by one page. This is not much and by itself does not
-	  warrant removing support. However its removal is a good idea if you
-	  wish to ensure that absolutely none of your programs will use this
-	  older executable format. If you don't know what to answer at this
-	  point then answer Y. If someone told you "You need a kernel with
-	  QMAGIC support" then you'll have to say Y here. You may answer M to
-	  compile a.out support as a module and later load the module when you
-	  want to use a program or library in a.out format. The module will be
-	  called binfmt_aout. Saying M or N here is dangerous though,
-	  because some crucial programs on your system might still be in A.OUT
-	  format.
-
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  use this part of the kernel.
-
-	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 endmenu
 
diff -Nru a/arch/i386/kernel/nmi.c b/arch/i386/kernel/nmi.c
--- a/arch/i386/kernel/nmi.c	Wed Jun 18 23:42:07 2003
+++ b/arch/i386/kernel/nmi.c	Wed Jun 18 23:42:07 2003
@@ -23,17 +23,27 @@
 #include <linux/mc146818rtc.h>
 #include <linux/kernel_stat.h>
 #include <linux/module.h>
+#include <linux/nmi.h>
 #include <linux/sysdev.h>
 
 #include <asm/smp.h>
 #include <asm/mtrr.h>
 #include <asm/mpspec.h>
+#include <asm/nmi.h>
 
 unsigned int nmi_watchdog = NMI_NONE;
 static unsigned int nmi_hz = HZ;
 unsigned int nmi_perfctr_msr;	/* the MSR to reset in NMI handler */
 extern void show_registers(struct pt_regs *regs);
 
+/* nmi_active:
+ * +1: the lapic NMI watchdog is active, but can be disabled
+ *  0: the lapic NMI watchdog has not been set up, and cannot
+ *     be enabled
+ * -1: the lapic NMI watchdog is disabled, but can be enabled
+ */
+static int nmi_active;
+
 #define K7_EVNTSEL_ENABLE	(1 << 22)
 #define K7_EVNTSEL_INT		(1 << 20)
 #define K7_EVNTSEL_OS		(1 << 17)
@@ -91,6 +101,7 @@
 			continue;
 		if (nmi_count(cpu) - prev_nmi_count[cpu] <= 5) {
 			printk("CPU#%d: NMI appears to be stuck!\n", cpu);
+			nmi_active = 0;
 			return -1;
 		}
 	}
@@ -131,21 +142,15 @@
 	 * We can enable the IO-APIC watchdog
 	 * unconditionally.
 	 */
-	if (nmi == NMI_IO_APIC)
+	if (nmi == NMI_IO_APIC) {
+		nmi_active = 1;
 		nmi_watchdog = nmi;
+	}
 	return 1;
 }
 
 __setup("nmi_watchdog=", setup_nmi_watchdog);
 
-/* nmi_active:
- * +1: the lapic NMI watchdog is active, but can be disabled
- *  0: the lapic NMI watchdog has not been set up, and cannot
- *     be enabled
- * -1: the lapic NMI watchdog is disabled, but can be enabled
- */
-static int nmi_active;
-
 void disable_lapic_nmi_watchdog(void)
 {
 	if (nmi_active <= 0)
@@ -179,6 +184,27 @@
 	}
 }
 
+void disable_timer_nmi_watchdog(void)
+{
+	if ((nmi_watchdog != NMI_IO_APIC) || (nmi_active <= 0))
+		return;
+
+	disable_irq(0);
+	unset_nmi_callback();
+	nmi_active = -1;
+	nmi_watchdog = NMI_NONE;
+}
+
+void enable_timer_nmi_watchdog(void)
+{
+	if (nmi_active < 0) {
+		nmi_watchdog = NMI_IO_APIC;
+		touch_nmi_watchdog();
+		nmi_active = 1;
+		enable_irq(0);
+	}
+}
+
 #ifdef CONFIG_PM
 
 static int nmi_pm_active; /* nmi_active before suspend */
@@ -429,3 +455,5 @@
 EXPORT_SYMBOL(nmi_watchdog);
 EXPORT_SYMBOL(disable_lapic_nmi_watchdog);
 EXPORT_SYMBOL(enable_lapic_nmi_watchdog);
+EXPORT_SYMBOL(disable_timer_nmi_watchdog);
+EXPORT_SYMBOL(enable_timer_nmi_watchdog);
diff -Nru a/arch/i386/kernel/setup.c b/arch/i386/kernel/setup.c
--- a/arch/i386/kernel/setup.c	Wed Jun 18 23:42:07 2003
+++ b/arch/i386/kernel/setup.c	Wed Jun 18 23:42:07 2003
@@ -96,7 +96,6 @@
 extern void generic_apic_probe(char *);
 extern int root_mountflags;
 extern char _text, _etext, _edata, _end;
-extern int blk_nohighio;
 
 unsigned long saved_videomode;
 
@@ -994,15 +993,6 @@
 #endif
 #endif
 }
-
-static int __init highio_setup(char *str)
-{
-	printk("i386: disabling HIGHMEM block I/O\n");
-	blk_nohighio = 1;
-	return 1;
-}
-__setup("nohighio", highio_setup);
- 
 
 #include "setup_arch_post.h"
 /*
diff -Nru a/arch/i386/oprofile/Makefile b/arch/i386/oprofile/Makefile
--- a/arch/i386/oprofile/Makefile	Wed Jun 18 23:42:09 2003
+++ b/arch/i386/oprofile/Makefile	Wed Jun 18 23:42:09 2003
@@ -9,3 +9,4 @@
 oprofile-y				:= $(DRIVER_OBJS) init.o
 oprofile-$(CONFIG_X86_LOCAL_APIC) 	+= nmi_int.o op_model_athlon.o \
 					   op_model_ppro.o op_model_p4.o
+oprofile-$(CONFIG_X86_IO_APIC)		+= nmi_timer_int.o
diff -Nru a/arch/i386/oprofile/init.c b/arch/i386/oprofile/init.c
--- a/arch/i386/oprofile/init.c	Wed Jun 18 23:42:07 2003
+++ b/arch/i386/oprofile/init.c	Wed Jun 18 23:42:07 2003
@@ -16,15 +16,21 @@
  */
  
 extern int nmi_init(struct oprofile_operations ** ops);
+extern int nmi_timer_init(struct oprofile_operations **ops);
 extern void nmi_exit(void);
 
 int __init oprofile_arch_init(struct oprofile_operations ** ops)
 {
+	int ret = -ENODEV;
 #ifdef CONFIG_X86_LOCAL_APIC
-	return nmi_init(ops);
-#else
-	return -ENODEV;
+	ret = nmi_init(ops);
 #endif
+
+#ifdef CONFIG_X86_IO_APIC
+	if (ret < 0)
+		ret = nmi_timer_init(ops);
+#endif
+	return ret;
 }
 
 
diff -Nru a/arch/i386/oprofile/nmi_int.c b/arch/i386/oprofile/nmi_int.c
--- a/arch/i386/oprofile/nmi_int.c	Wed Jun 18 23:42:09 2003
+++ b/arch/i386/oprofile/nmi_int.c	Wed Jun 18 23:42:09 2003
@@ -182,8 +182,8 @@
 static void nmi_shutdown(void)
 {
 	nmi_enabled = 0;
-	unset_nmi_callback();
 	on_each_cpu(nmi_cpu_shutdown, NULL, 0, 1);
+	unset_nmi_callback();
 	enable_lapic_nmi_watchdog();
 }
 
diff -Nru a/arch/i386/oprofile/nmi_timer_int.c b/arch/i386/oprofile/nmi_timer_int.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/i386/oprofile/nmi_timer_int.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,57 @@
+/**
+ * @file nmi_timer_int.c
+ *
+ * @remark Copyright 2003 OProfile authors
+ * @remark Read the file COPYING
+ *
+ * @author Zwane Mwaikambo <zwane@linuxpower.ca>
+ */
+
+#include <linux/init.h>
+#include <linux/smp.h>
+#include <linux/irq.h>
+#include <linux/oprofile.h>
+#include <linux/rcupdate.h>
+
+
+#include <asm/nmi.h>
+#include <asm/apic.h>
+#include <asm/ptrace.h>
+ 
+static int nmi_timer_callback(struct pt_regs * regs, int cpu)
+{
+	unsigned long eip = instruction_pointer(regs);
+ 
+	oprofile_add_sample(eip, !user_mode(regs), 0, cpu);
+	return 1;
+}
+
+static int timer_start(void)
+{
+	disable_timer_nmi_watchdog();
+	set_nmi_callback(nmi_timer_callback);
+	return 0;
+}
+
+
+static void timer_stop(void)
+{
+	enable_timer_nmi_watchdog();
+	unset_nmi_callback();
+	synchronize_kernel();
+}
+
+
+static struct oprofile_operations nmi_timer_ops = {
+	.start	= timer_start,
+	.stop	= timer_stop,
+	.cpu_type = "timer"
+};
+
+ 
+int __init nmi_timer_init(struct oprofile_operations ** ops)
+{
+	*ops = &nmi_timer_ops;
+	printk(KERN_INFO "oprofile: using NMI timer interrupt.\n");
+	return 0;
+}
diff -Nru a/arch/ia64/Kconfig b/arch/ia64/Kconfig
--- a/arch/ia64/Kconfig	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/Kconfig	Wed Jun 18 23:42:09 2003
@@ -26,6 +26,10 @@
 	bool
 	default y
 
+config TIME_INTERPOLATION
+	bool
+	default y
+
 choice
 	prompt "IA-64 processor type"
 	default ITANIUM
@@ -63,7 +67,7 @@
 	  HP-simulator   For the HP simulator
 	  (<http://software.hp.com/ia64linux/>).
 	  HP-zx1         For HP zx1-based systems.
-	  SN1-simulator  For the SGI SN1 simulator.
+	  SGI-SN2	 For SGI Altix systems
 	  DIG-compliant  For DIG ("Developer's Interface Guide") compliant
 	  systems.
 
@@ -82,9 +86,6 @@
 	  for the zx1 I/O MMU and makes root bus bridges appear in PCI config
 	  space (required for zx1 agpgart support).
 
-config IA64_SGI_SN1
-	bool "SGI-SN1"
-
 config IA64_SGI_SN2
 	bool "SGI-SN2"
 
@@ -190,8 +191,8 @@
 # align cache-sensitive data to 128 bytes
 config IA64_L1_CACHE_SHIFT
 	int
-	default "7" if MCKINLEY || ITANIUM && IA64_SGI_SN1
-	default "6" if ITANIUM && !IA64_SGI_SN1
+	default "7" if MCKINLEY
+	default "6" if ITANIUM
 
 # align cache-sensitive data to 64 bytes
 config MCKINLEY_ASTEP_SPECIFIC
@@ -210,7 +211,7 @@
 
 config NUMA
 	bool "Enable NUMA support" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
-	default y if IA64_SGI_SN1 || IA64_SGI_SN2
+	default y if IA64_SGI_SN2
 	help
 	  Say Y to compile the kernel to support NUMA (Non-Uniform Memory
 	  Access).  This option is for configuring high-end multiprocessor
@@ -234,7 +235,7 @@
 
 config DISCONTIGMEM
 	bool
-	depends on IA64_SGI_SN1 || IA64_SGI_SN2 || (IA64_GENERIC || IA64_DIG || IA64_HP_ZX1) && NUMA
+	depends on IA64_SGI_SN2 || (IA64_GENERIC || IA64_DIG || IA64_HP_ZX1) && NUMA
 	default y
 	help
 	  Say Y to support efficient handling of discontiguous physical memory,
@@ -259,7 +260,7 @@
 
 config IA64_MCA
 	bool "Enable IA-64 Machine Check Abort" if IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
-	default y if IA64_SGI_SN1 || IA64_SGI_SN2
+	default y if IA64_SGI_SN2
 	help
 	  Say Y here to enable machine check support for IA-64.  If you're
 	  unsure, answer Y.
@@ -288,17 +289,12 @@
 
 config IOSAPIC
 	bool
-	depends on IA64_GENERIC || IA64_DIG || IA64_HP_ZX1
-	default y
-
-config IA64_SGI_SN
-	bool
-	depends on IA64_SGI_SN1 || IA64_SGI_SN2
+	depends on IA64_GENERIC || IA64_DIG || IA64_HP_ZX1 || IA64_SGI_SN2
 	default y
 
 config IA64_SGI_SN_DEBUG
 	bool "Enable extra debugging code"
-	depends on IA64_SGI_SN1 || IA64_SGI_SN2
+	depends on IA64_SGI_SN2
 	help
 	  Turns on extra debugging code in the SGI SN (Scalable NUMA) platform
 	  for IA-64.  Unless you are debugging problems on an SGI SN IA-64 box,
@@ -306,14 +302,14 @@
 
 config IA64_SGI_SN_SIM
 	bool "Enable SGI Medusa Simulator Support"
-	depends on IA64_SGI_SN1 || IA64_SGI_SN2
+	depends on IA64_SGI_SN2
 	help
 	  If you are compiling a kernel that will run under SGI's IA-64
 	  simulator (Medusa) then say Y, otherwise say N.
 
 config IA64_SGI_AUTOTEST
 	bool "Enable autotest (llsc). Option to run cache test instead of booting"
-	depends on IA64_SGI_SN1 || IA64_SGI_SN2
+	depends on IA64_SGI_SN2
 	help
 	  Build a kernel used for hardware validation. If you include the
 	  keyword "autotest" on the boot command line, the kernel does NOT boot.
@@ -323,7 +319,7 @@
 
 config SERIAL_SGI_L1_PROTOCOL
 	bool "Enable protocol mode for the L1 console"
-	depends on IA64_SGI_SN1 || IA64_SGI_SN2
+	depends on IA64_SGI_SN2
 	help
 	  Uses protocol mode instead of raw mode for the level 1 console on the
 	  SGI SN (Scalable NUMA) platform for IA-64.  If you are compiling for
@@ -331,17 +327,9 @@
 
 config PERCPU_IRQ
 	bool
-	depends on IA64_SGI_SN1 || IA64_SGI_SN2
+	depends on IA64_SGI_SN2
 	default y
 
-config PCIBA
-	tristate "PCIBA support"
-	depends on IA64_SGI_SN1 || IA64_SGI_SN2
-	help
-	  IRIX PCIBA-inspired user mode PCI interface for the SGI SN (Scalable
-	  NUMA) platform for IA-64.  Unless you are compiling a kernel for an
-	  SGI SN IA-64 box, say N.
-
 # On IA-64, we always want an ELF /proc/kcore.
 config KCORE_ELF
 	bool
@@ -493,38 +481,7 @@
 	depends on SMP
 	default "64"
 
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp.  Once you have registered such a binary class with the
-	  kernel, you can start one of those programs simply by typing in its
-	  name at a shell prompt; Linux will automatically feed it to the
-	  correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  use this part of the kernel.
-
-	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 if !IA64_HP_SIM
 
@@ -729,20 +686,18 @@
 
 source "drivers/usb/Kconfig"
 
-source "lib/Kconfig"
 
 source "net/bluetooth/Kconfig"
 
 endif
 
+source "lib/Kconfig"
+
 source "arch/ia64/hp/sim/Kconfig"
 
 
 menu "Kernel hacking"
 
-config FSYS
-	bool "Light-weight system-call support (via epc)"
-
 choice
 	prompt "Physical memory granularity"
 	default IA64_GRANULE_64MB
@@ -809,7 +764,7 @@
 
 config IA64_EARLY_PRINTK
 	bool "Early printk support"
-	depends on DEBUG_KERNEL
+	depends on DEBUG_KERNEL && !IA64_GENERIC
 	help
 	  Selecting this option uses the VGA screen or serial console for
 	  printk() output before the consoles are initialised.  It is useful
diff -Nru a/arch/ia64/Makefile b/arch/ia64/Makefile
--- a/arch/ia64/Makefile	Wed Jun 18 23:42:05 2003
+++ b/arch/ia64/Makefile	Wed Jun 18 23:42:05 2003
@@ -18,8 +18,8 @@
 AFLAGS_KERNEL	:= -mconstant-gp
 EXTRA		:=
 
-cflags-y	:= -pipe $(EXTRA) -ffixed-r13 -mfixed-range=f10-f15,f32-f127 \
-		   -falign-functions=32
+cflags-y	:= -pipe $(EXTRA) -ffixed-r13 -mfixed-range=f12-f15,f32-f127 \
+		   -falign-functions=32 -frename-registers
 CFLAGS_KERNEL	:= -mconstant-gp
 
 GCC_VERSION=$(shell $(CC) -v 2>&1 | fgrep 'gcc version' | cut -f3 -d' ' | cut -f1 -d'.')
@@ -27,6 +27,10 @@
 
 GAS_STATUS=$(shell arch/ia64/scripts/check-gas $(CC) $(OBJDUMP))
 
+arch-cppflags	:= $(shell arch/ia64/scripts/toolchain-flags $(CC) $(LD) $(OBJDUMP))
+cflags-y	+= $(arch-cppflags)
+AFLAGS		+= $(arch-cppflags)
+
 ifeq ($(GAS_STATUS),buggy)
 $(error Sorry, you need a newer version of the assember, one that is built from	\
 	a source-tree that post-dates 18-Dec-2002.  You can find a pre-compiled	\
@@ -35,19 +39,18 @@
 		ftp://ftp.hpl.hp.com/pub/linux-ia64/gas-030124.tar.gz)
 endif
 
-ifneq ($(GCC_VERSION),2)
-	cflags-$(CONFIG_ITANIUM) += -frename-registers
+ifeq ($(GCC_VERSION),2)
+$(error Sorry, your compiler is too old.  GCC v2.96 is known to generate bad code.)
 endif
 
 ifeq ($(GCC_VERSION),3)
  ifeq ($(GCC_MINOR_VERSION),4)
-	cflags-$(CONFIG_ITANIUM) += -mtune=merced
-	cflags-$(CONFIG_MCKINLEY) += -mtune=mckinley
+	cflags-$(CONFIG_ITANIUM)	+= -mtune=merced
+	cflags-$(CONFIG_MCKINLEY)	+= -mtune=mckinley
  endif
 endif
 
 cflags-$(CONFIG_ITANIUM_BSTEP_SPECIFIC)	+= -mb-step
-cflags-$(CONFIG_IA64_SGI_SN)		+= -DBRINGUP
 
 CFLAGS += $(cflags-y)
 head-y := arch/ia64/kernel/head.o arch/ia64/kernel/init_task.o
@@ -58,7 +61,7 @@
 core-$(CONFIG_IA64_DIG) 	+= arch/ia64/dig/
 core-$(CONFIG_IA64_GENERIC) 	+= arch/ia64/dig/
 core-$(CONFIG_IA64_HP_ZX1)	+= arch/ia64/dig/
-core-$(CONFIG_IA64_SGI_SN)	+= arch/ia64/sn/
+core-$(CONFIG_IA64_SGI_SN2)	+= arch/ia64/sn/
 
 drivers-$(CONFIG_PCI)		+= arch/ia64/pci/
 drivers-$(CONFIG_IA64_HP_SIM)	+= arch/ia64/hp/sim/
@@ -66,33 +69,37 @@
 drivers-$(CONFIG_IA64_GENERIC)	+= arch/ia64/hp/common/ arch/ia64/hp/zx1/ arch/ia64/hp/sim/
 
 boot := arch/ia64/boot
-tools := arch/ia64/tools
-
-.PHONY: boot compressed include/asm-ia64/offsets.h
 
-all: prepare vmlinux
+.PHONY: boot compressed check
 
 compressed: vmlinux.gz
 
 vmlinux.gz: vmlinux
-	$(Q)$(MAKE) $(build)=$(boot) vmlinux.gz
+	$(Q)$(MAKE) $(build)=$(boot) $@
 
 check: vmlinux
-	arch/ia64/scripts/unwcheck.sh vmlinux
+	arch/ia64/scripts/unwcheck.sh $<
 
 archclean:
 	$(Q)$(MAKE) $(clean)=$(boot)
-	$(Q)$(MAKE) $(clean)=$(tools)
 
-CLEAN_FILES += include/asm-ia64/offsets.h vmlinux.gz bootloader
+CLEAN_FILES += include/asm-ia64/.offsets.h.stamp include/asm-ia64/offsets.h vmlinux.gz bootloader
 
 prepare: include/asm-ia64/offsets.h
 
+include/asm-$(ARCH)/offsets.h: arch/$(ARCH)/kernel/asm-offsets.s
+	$(call filechk,gen-asm-offsets)
+
+arch/ia64/kernel/asm-offsets.s: include/asm-ia64/.offsets.h.stamp
+
+include/asm-ia64/.offsets.h.stamp:
+	[ -s include/asm-ia64/offsets.h ] \
+	 || echo "#define IA64_TASK_SIZE 0" > include/asm-ia64/offsets.h
+	touch $@
+
 boot:	lib/lib.a vmlinux
 	$(Q)$(MAKE) $(build)=$(boot) $@
 
-include/asm-ia64/offsets.h: include/asm include/linux/version.h include/config/MARKER
-	$(Q)$(MAKE) $(build)=$(tools) $@
 
 define archhelp
   echo '  compressed	- Build compressed kernel image'
diff -Nru a/arch/ia64/boot/bootloader.c b/arch/ia64/boot/bootloader.c
--- a/arch/ia64/boot/bootloader.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/boot/bootloader.c	Wed Jun 18 23:42:09 2003
@@ -55,6 +55,9 @@
 
 #include "../kernel/fw-emu.c"
 
+/* This needs to be defined because lib/string.c:strlcat() calls it in case of error... */
+asm (".global printk; printk = 0");
+
 /*
  * Set a break point on this function so that symbols are available to set breakpoints in
  * the kernel being debugged.
@@ -181,10 +184,10 @@
 			continue;
 
 		req.len = elf_phdr->p_filesz;
-		req.addr = __pa(elf_phdr->p_vaddr);
+		req.addr = __pa(elf_phdr->p_paddr);
 		ssc(fd, 1, (long) &req, elf_phdr->p_offset, SSC_READ);
 		ssc((long) &stat, 0, 0, 0, SSC_WAIT_COMPLETION);
-		memset((char *)__pa(elf_phdr->p_vaddr) + elf_phdr->p_filesz, 0,
+		memset((char *)__pa(elf_phdr->p_paddr) + elf_phdr->p_filesz, 0,
 		       elf_phdr->p_memsz - elf_phdr->p_filesz);
 	}
 	ssc(fd, 0, 0, 0, SSC_CLOSE);
diff -Nru a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
--- a/arch/ia64/hp/common/sba_iommu.c	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/hp/common/sba_iommu.c	Wed Jun 18 23:42:06 2003
@@ -1682,6 +1682,10 @@
 	ioc_resource_init(ioc);
 	ioc_sac_init(ioc);
 
+	if ((long) ~IOVP_MASK > (long) ia64_max_iommu_merge_mask)
+		ia64_max_iommu_merge_mask = ~IOVP_MASK;
+	MAX_DMA_ADDRESS = ~0UL;
+
 	printk(KERN_INFO PFX
 		"%s %d.%d HPA 0x%lx IOVA space %dMb at 0x%lx\n",
 		ioc->name, (ioc->rev >> 4) & 0xF, ioc->rev & 0xF,
@@ -1898,22 +1902,26 @@
 	struct ioc *ioc;
 	acpi_status status;
 	u64 hpa, length;
-	struct acpi_device_info dev_info;
+	struct acpi_buffer buffer;
+	struct acpi_device_info *dev_info;
 
 	status = hp_acpi_csr_space(device->handle, &hpa, &length);
 	if (ACPI_FAILURE(status))
 		return 1;
 
-	status = acpi_get_object_info(device->handle, &dev_info);
+	buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
+	status = acpi_get_object_info(device->handle, &buffer);
 	if (ACPI_FAILURE(status))
 		return 1;
+	dev_info = buffer.pointer;
 
 	/*
 	 * For HWP0001, only SBA appears in ACPI namespace.  It encloses the PCI
 	 * root bridges, and its CSR space includes the IOC function.
 	 */
-	if (strncmp("HWP0001", dev_info.hardware_id, 7) == 0)
+	if (strncmp("HWP0001", dev_info->hardware_id.value, 7) == 0)
 		hpa += ZX1_IOC_OFFSET;
+	ACPI_MEM_FREE(dev_info);
 
 	ioc = ioc_init(hpa, device->handle);
 	if (!ioc)
@@ -1933,8 +1941,6 @@
 static int __init
 sba_init(void)
 {
-	MAX_DMA_ADDRESS = ~0UL;
-
 	acpi_bus_register_driver(&acpi_sba_ioc_driver);
 
 #ifdef CONFIG_PCI
diff -Nru a/arch/ia64/hp/sim/Kconfig b/arch/ia64/hp/sim/Kconfig
--- a/arch/ia64/hp/sim/Kconfig	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/hp/sim/Kconfig	Wed Jun 18 23:42:07 2003
@@ -8,6 +8,10 @@
 config HP_SIMSERIAL
 	bool "Simulated serial driver support"
 
+config HP_SIMSERIAL_CONSOLE
+	bool "Console for HP simulator"
+	depends on HP_SIMSERIAL
+
 config HP_SIMSCSI
 	bool "Simulated SCSI disk"
 	depends on SCSI
diff -Nru a/arch/ia64/hp/sim/Makefile b/arch/ia64/hp/sim/Makefile
--- a/arch/ia64/hp/sim/Makefile	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/hp/sim/Makefile	Wed Jun 18 23:42:08 2003
@@ -7,9 +7,10 @@
 # Copyright (C) Srinivasa Thirumalachar (sprasad@engr.sgi.com)
 #
 
-obj-y := hpsim_console.o hpsim_irq.o hpsim_setup.o
+obj-y := hpsim_irq.o hpsim_setup.o
 obj-$(CONFIG_IA64_GENERIC) += hpsim_machvec.o
 
 obj-$(CONFIG_HP_SIMETH)	+= simeth.o
 obj-$(CONFIG_HP_SIMSERIAL) += simserial.o
+obj-$(CONFIG_HP_SIMSERIAL_CONSOLE) += hpsim_console.o
 obj-$(CONFIG_HP_SIMSCSI) += simscsi.o
diff -Nru a/arch/ia64/hp/sim/hpsim_setup.c b/arch/ia64/hp/sim/hpsim_setup.c
--- a/arch/ia64/hp/sim/hpsim_setup.c	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/hp/sim/hpsim_setup.c	Wed Jun 18 23:42:08 2003
@@ -5,6 +5,7 @@
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  * Copyright (C) 1999 Vijay Chander <vijay@engr.sgi.com>
  */
+#include <linux/config.h>
 #include <linux/console.h>
 #include <linux/init.h>
 #include <linux/kdev_t.h>
@@ -24,8 +25,6 @@
 
 #include "hpsim_ssc.h"
 
-extern struct console hpsim_cons;
-
 /*
  * Simulator system call.
  */
@@ -56,5 +55,11 @@
 {
 	ROOT_DEV = Root_SDA1;		/* default to first SCSI drive */
 
-	register_console(&hpsim_cons);
+#ifdef CONFIG_HP_SIMSERIAL_CONSOLE
+	{
+		extern struct console hpsim_cons;
+		if (ia64_platform_is("hpsim"))
+			register_console(&hpsim_cons);
+	}
+#endif
 }
diff -Nru a/arch/ia64/hp/sim/simserial.c b/arch/ia64/hp/sim/simserial.c
--- a/arch/ia64/hp/sim/simserial.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/hp/sim/simserial.c	Wed Jun 18 23:42:07 2003
@@ -1031,6 +1031,9 @@
 	int			i;
 	struct serial_state	*state;
 
+	if (!ia64_platform_is("hpsim"))
+		return -ENODEV;
+
 	hp_simserial_driver = alloc_tty_driver(1);
 	if (!hp_simserial_driver)
 		return -ENOMEM;
diff -Nru a/arch/ia64/ia32/binfmt_elf32.c b/arch/ia64/ia32/binfmt_elf32.c
--- a/arch/ia64/ia32/binfmt_elf32.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/ia32/binfmt_elf32.c	Wed Jun 18 23:42:09 2003
@@ -16,7 +16,8 @@
 
 #include <asm/param.h>
 #include <asm/signal.h>
-#include <asm/ia32.h>
+
+#include "ia32priv.h"
 
 #define CONFIG_BINFMT_ELF32
 
diff -Nru a/arch/ia64/ia32/ia32_entry.S b/arch/ia64/ia32/ia32_entry.S
--- a/arch/ia64/ia32/ia32_entry.S	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/ia32/ia32_entry.S	Wed Jun 18 23:42:07 2003
@@ -44,14 +44,8 @@
 	br.call.sptk.many rp=do_fork
 .ret0:	.restore sp
 	adds sp=IA64_SWITCH_STACK_SIZE,sp	// pop the switch stack
-	mov r2=-1000
-	adds r3=IA64_TASK_PID_OFFSET,r8
-	;;
-	cmp.leu p6,p0=r8,r2
 	mov ar.pfs=loc1
 	mov rp=loc0
-	;;
-(p6)	ld4 r8=[r3]
 	br.ret.sptk.many rp
 END(ia32_clone)
 
@@ -183,14 +177,8 @@
 	br.call.sptk.few rp=do_fork
 .ret5:	.restore sp
 	adds sp=IA64_SWITCH_STACK_SIZE,sp	// pop the switch stack
-	mov r2=-1000
-	adds r3=IA64_TASK_PID_OFFSET,r8
-	;;
-	cmp.leu p6,p0=r8,r2
 	mov ar.pfs=loc1
 	mov rp=loc0
-	;;
-(p6)	ld4 r8=[r3]
 	br.ret.sptk.many rp
 END(sys32_fork)
 
@@ -439,8 +427,8 @@
 	data8 sys_ni_syscall
 	data8 sys_ni_syscall
 	data8 compat_sys_futex	/* 240 */
-	data8 compat_sys_setaffinity
-	data8 compat_sys_getaffinity
+	data8 compat_sys_sched_setaffinity
+	data8 compat_sys_sched_getaffinity
 	data8 sys_ni_syscall
 	data8 sys_ni_syscall
 	data8 sys_ni_syscall	/* 245 */
diff -Nru a/arch/ia64/ia32/ia32_ioctl.c b/arch/ia64/ia32/ia32_ioctl.c
--- a/arch/ia64/ia32/ia32_ioctl.c	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/ia32/ia32_ioctl.c	Wed Jun 18 23:42:08 2003
@@ -11,36 +11,107 @@
 #include <linux/dirent.h>
 #include <linux/fs.h>		/* argh, msdos_fs.h isn't self-contained... */
 #include <linux/signal.h>	/* argh, msdos_fs.h isn't self-contained... */
+#include <linux/compat.h>
 
-#include <asm/ia32.h>
+#include "ia32priv.h"
 
-#include <linux/msdos_fs.h>
-#include <linux/mtio.h>
-#include <linux/ncp_fs.h>
-#include <linux/capi.h>
-#include <linux/videodev.h>
-#include <linux/synclink.h>
-#include <linux/atmdev.h>
-#include <linux/atm_eni.h>
-#include <linux/atm_nicstar.h>
-#include <linux/atm_zatm.h>
-#include <linux/atm_idt77105.h>
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/smp.h>
+#include <linux/smp_lock.h>
+#include <linux/ioctl.h>
+#include <linux/if.h>
+#include <linux/slab.h>
+#include <linux/hdreg.h>
+#include <linux/raid/md.h>
+#include <linux/kd.h>
+#include <linux/route.h>
+#include <linux/in6.h>
+#include <linux/ipv6_route.h>
+#include <linux/skbuff.h>
+#include <linux/netlink.h>
+#include <linux/vt.h>
+#include <linux/file.h>
+#include <linux/fd.h>
 #include <linux/ppp_defs.h>
 #include <linux/if_ppp.h>
-#include <linux/ixjuser.h>
-#include <linux/i2o-dev.h>
+#include <linux/if_pppox.h>
+#include <linux/mtio.h>
+#include <linux/cdrom.h>
+#include <linux/loop.h>
+#include <linux/auto_fs.h>
+#include <linux/auto_fs4.h>
+#include <linux/devfs_fs.h>
+#include <linux/tty.h>
+#include <linux/vt_kern.h>
+#include <linux/fb.h>
+#include <linux/ext2_fs.h>
+#include <linux/videodev.h>
+#include <linux/netdevice.h>
+#include <linux/raw.h>
+#include <linux/smb_fs.h>
+#include <linux/blkpg.h>
+#include <linux/blk.h>
+#include <linux/elevator.h>
+#include <linux/rtc.h>
+#include <linux/pci.h>
+#include <linux/rtc.h>
+#include <linux/module.h>
+#include <linux/serial.h>
+#include <linux/reiserfs_fs.h>
+#include <linux/if_tun.h>
+#include <linux/dirent.h>
+#include <linux/ctype.h>
+#include <linux/ncp_fs.h>
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/rfcomm.h>
+
 #include <scsi/scsi.h>
 /* Ugly hack. */
-#undef	__KERNEL__
+#undef __KERNEL__
 #include <scsi/scsi_ioctl.h>
-#define	__KERNEL__
+#define __KERNEL__
 #include <scsi/sg.h>
 
+#include <asm/types.h>
+#include <asm/uaccess.h>
+#include <linux/ethtool.h>
+#include <linux/mii.h>
+#include <linux/if_bonding.h>
+#include <linux/watchdog.h>
+
+#include <asm/module.h>
+#include <asm/ioctl32.h>
+#include <linux/soundcard.h>
+#include <linux/lp.h>
+
+#include <linux/atm.h>
+#include <linux/atmarp.h>
+#include <linux/atmclip.h>
+#include <linux/atmdev.h>
+#include <linux/atmioc.h>
+#include <linux/atmlec.h>
+#include <linux/atmmpc.h>
+#include <linux/atmsvc.h>
+#include <linux/atm_tcp.h>
+#include <linux/sonet.h>
+#include <linux/atm_suni.h>
+#include <linux/mtd/mtd.h>
+
+#include <net/bluetooth/bluetooth.h>
+#include <net/bluetooth/hci.h>
+
+#include <linux/usb.h>
+#include <linux/usbdevice_fs.h>
+#include <linux/nbd.h>
+#include <linux/random.h>
+#include <linux/filter.h>
+
 #include <../drivers/char/drm/drm.h>
 #include <../drivers/char/drm/mga_drm.h>
 #include <../drivers/char/drm/i810_drm.h>
 
-
 #define IOCTL_NR(a)	((a) & ~(_IOC_SIZEMASK << _IOC_SIZESHIFT))
 
 #define DO_IOCTL(fd, cmd, arg) ({			\
@@ -57,6 +128,9 @@
 
 asmlinkage long sys_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg);
 
+#define	VFAT_IOCTL_READDIR_BOTH32	_IOR('r', 1, struct linux32_dirent[2])
+#define	VFAT_IOCTL_READDIR_SHORT32	_IOR('r', 2, struct linux32_dirent[2])
+
 static long
 put_dirent32 (struct dirent *d, struct linux32_dirent *d32)
 {
@@ -67,6 +141,23 @@
 		|| put_user(d->d_reclen, &d32->d_reclen)
 		|| copy_to_user(d32->d_name, d->d_name, namelen + 1));
 }
+
+static int vfat_ioctl32(unsigned fd, unsigned cmd,  void *ptr) 
+{
+	int ret;
+	mm_segment_t oldfs = get_fs();
+	struct dirent d[2]; 
+
+	set_fs(KERNEL_DS);
+	ret = sys_ioctl(fd,cmd,(unsigned long)&d); 
+	set_fs(oldfs); 
+	if (!ret) { 
+		ret |= put_dirent32(&d[0], (struct linux32_dirent *)ptr); 
+		ret |= put_dirent32(&d[1], ((struct linux32_dirent *)ptr) + 1); 
+	}
+	return ret; 
+} 
+
 /*
  *  The transform code for the SG_IO ioctl was brazenly lifted from
  *  the Sparc64 port in the file `arch/sparc64/kernel/ioctl32.c'.
@@ -294,3 +385,83 @@
 	}
 	return err;
 }
+
+static __inline__ void *alloc_user_space(long len)
+{
+	struct pt_regs	*regs = ((struct pt_regs *)((unsigned long) current +
+						    IA64_STK_OFFSET)) - 1;
+	return (void *)regs->r12 - len; 
+}
+
+struct ifmap32 {
+	u32 mem_start;
+	u32 mem_end;
+	unsigned short base_addr;
+	unsigned char irq;
+	unsigned char dma;
+	unsigned char port;
+};
+
+struct ifreq32 {
+#define IFHWADDRLEN     6
+#define IFNAMSIZ        16
+        union {
+                char    ifrn_name[IFNAMSIZ];            /* if name, e.g. "en0" */
+        } ifr_ifrn;
+        union {
+                struct  sockaddr ifru_addr;
+                struct  sockaddr ifru_dstaddr;
+                struct  sockaddr ifru_broadaddr;
+                struct  sockaddr ifru_netmask;
+                struct  sockaddr ifru_hwaddr;
+                short   ifru_flags;
+                int     ifru_ivalue;
+                int     ifru_mtu;
+                struct  ifmap32 ifru_map;
+                char    ifru_slave[IFNAMSIZ];   /* Just fits the size */
+		char	ifru_newname[IFNAMSIZ];
+                compat_caddr_t ifru_data;
+        } ifr_ifru;
+};
+
+int siocdevprivate_ioctl(unsigned int fd, unsigned int cmd, unsigned long arg)
+{
+	struct ifreq *u_ifreq64;
+	struct ifreq32 *u_ifreq32 = (struct ifreq32 *) arg;
+	char tmp_buf[IFNAMSIZ];
+	void *data64;
+	u32 data32;
+
+	if (copy_from_user(&tmp_buf[0], &(u_ifreq32->ifr_ifrn.ifrn_name[0]),
+			   IFNAMSIZ))
+		return -EFAULT;
+	if (__get_user(data32, &u_ifreq32->ifr_ifru.ifru_data))
+		return -EFAULT;
+	data64 = (void *) P(data32);
+
+	u_ifreq64 = alloc_user_space(sizeof(*u_ifreq64));
+
+	/* Don't check these user accesses, just let that get trapped
+	 * in the ioctl handler instead.
+	 */
+	copy_to_user(&u_ifreq64->ifr_ifrn.ifrn_name[0], &tmp_buf[0], IFNAMSIZ);
+	__put_user(data64, &u_ifreq64->ifr_ifru.ifru_data);
+
+	return sys_ioctl(fd, cmd, (unsigned long) u_ifreq64);
+}
+
+typedef int (* ioctl32_handler_t)(unsigned int, unsigned int, unsigned long, struct file *);
+
+#define COMPATIBLE_IOCTL(cmd)		HANDLE_IOCTL((cmd),sys_ioctl)
+#define HANDLE_IOCTL(cmd,handler)	{ (cmd), (ioctl32_handler_t)(handler), NULL },
+#define IOCTL_TABLE_START \
+	struct ioctl_trans ioctl_start[] = {
+#define IOCTL_TABLE_END \
+	}; struct ioctl_trans ioctl_end[0];
+
+IOCTL_TABLE_START
+#include <linux/compat_ioctl.h>
+HANDLE_IOCTL(VFAT_IOCTL_READDIR_BOTH32, vfat_ioctl32)
+HANDLE_IOCTL(VFAT_IOCTL_READDIR_SHORT32, vfat_ioctl32)
+HANDLE_IOCTL(SG_IO,sg_ioctl_trans)
+IOCTL_TABLE_END
diff -Nru a/arch/ia64/ia32/ia32_ldt.c b/arch/ia64/ia32/ia32_ldt.c
--- a/arch/ia64/ia32/ia32_ldt.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/ia32/ia32_ldt.c	Wed Jun 18 23:42:09 2003
@@ -14,7 +14,8 @@
 #include <linux/vmalloc.h>
 
 #include <asm/uaccess.h>
-#include <asm/ia32.h>
+
+#include "ia32priv.h"
 
 #define P(p)	((void *) (unsigned long) (p))
 
diff -Nru a/arch/ia64/ia32/ia32_signal.c b/arch/ia64/ia32/ia32_signal.c
--- a/arch/ia64/ia32/ia32_signal.c	Wed Jun 18 23:42:05 2003
+++ b/arch/ia64/ia32/ia32_signal.c	Wed Jun 18 23:42:05 2003
@@ -28,7 +28,8 @@
 #include <asm/rse.h>
 #include <asm/sigcontext.h>
 #include <asm/segment.h>
-#include <asm/ia32.h>
+
+#include "ia32priv.h"
 
 #include "../kernel/sigframe.h"
 
@@ -179,8 +180,10 @@
  *    datasel    ar.fdr(32:47)
  *
  *    _st[(0+TOS)%8]   f8
- *    _st[(1+TOS)%8]   f9                    (f8, f9 from ptregs)
- *      : :            :                     (f10..f15 from live reg)
+ *    _st[(1+TOS)%8]   f9
+ *    _st[(2+TOS)%8]   f10
+ *    _st[(3+TOS)%8]   f11                   (f8..f11 from ptregs)
+ *      : :            :                     (f12..f15 from live reg)
  *      : :            :
  *    _st[(7+TOS)%8]   f15                   TOS=sw.top(bits11:13)
  *
@@ -262,8 +265,8 @@
 	__put_user( 0, &save->magic); //#define X86_FXSR_MAGIC   0x0000
 
 	/*
-	 * save f8 and f9  from pt_regs
-	 * save f10..f15 from live register set
+	 * save f8..f11  from pt_regs
+	 * save f12..f15 from live register set
 	 */
 	/*
 	 *  Find the location where f8 has to go in fp reg stack.  This depends on
@@ -278,11 +281,11 @@
 	copy_to_user(&save->_st[(0+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
 	ia64f2ia32f(fpregp, &ptp->f9);
 	copy_to_user(&save->_st[(1+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
-
-	__stfe(fpregp, 10);
+	ia64f2ia32f(fpregp, &ptp->f10);
 	copy_to_user(&save->_st[(2+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
-	__stfe(fpregp, 11);
+	ia64f2ia32f(fpregp, &ptp->f11);
 	copy_to_user(&save->_st[(3+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
+
 	__stfe(fpregp, 12);
 	copy_to_user(&save->_st[(4+fr8_st_map)&0x7], fpregp, sizeof(struct _fpreg_ia32));
 	__stfe(fpregp, 13);
@@ -394,8 +397,8 @@
 	asm volatile ( "mov ar.fdr=%0;" :: "r"(fdr));
 
 	/*
-	 * restore f8, f9 onto pt_regs
-	 * restore f10..f15 onto live registers
+	 * restore f8..f11 onto pt_regs
+	 * restore f12..f15 onto live registers
 	 */
 	/*
 	 *  Find the location where f8 has to go in fp reg stack.  This depends on
@@ -411,11 +414,11 @@
 	ia32f2ia64f(&ptp->f8, fpregp);
 	copy_from_user(fpregp, &save->_st[(1+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
 	ia32f2ia64f(&ptp->f9, fpregp);
-
 	copy_from_user(fpregp, &save->_st[(2+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
-	__ldfe(10, fpregp);
+	ia32f2ia64f(&ptp->f10, fpregp);
 	copy_from_user(fpregp, &save->_st[(3+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
-	__ldfe(11, fpregp);
+	ia32f2ia64f(&ptp->f11, fpregp);
+
 	copy_from_user(fpregp, &save->_st[(4+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
 	__ldfe(12, fpregp);
 	copy_from_user(fpregp, &save->_st[(5+fr8_st_map)&0x7], sizeof(struct _fpreg_ia32));
@@ -738,11 +741,11 @@
 
 #define COPY(ia64x, ia32x)	err |= __get_user(regs->ia64x, &sc->ia32x)
 
-#define copyseg_gs(tmp)		(regs->r16 |= (unsigned long) tmp << 48)
-#define copyseg_fs(tmp)		(regs->r16 |= (unsigned long) tmp << 32)
+#define copyseg_gs(tmp)		(regs->r16 |= (unsigned long) (tmp) << 48)
+#define copyseg_fs(tmp)		(regs->r16 |= (unsigned long) (tmp) << 32)
 #define copyseg_cs(tmp)		(regs->r17 |= tmp)
-#define copyseg_ss(tmp)		(regs->r17 |= (unsigned long) tmp << 16)
-#define copyseg_es(tmp)		(regs->r16 |= (unsigned long) tmp << 16)
+#define copyseg_ss(tmp)		(regs->r17 |= (unsigned long) (tmp) << 16)
+#define copyseg_es(tmp)		(regs->r16 |= (unsigned long) (tmp) << 16)
 #define copyseg_ds(tmp)		(regs->r16 |= tmp)
 
 #define COPY_SEG(seg)					\
diff -Nru a/arch/ia64/ia32/ia32_support.c b/arch/ia64/ia32/ia32_support.c
--- a/arch/ia64/ia32/ia32_support.c	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/ia32/ia32_support.c	Wed Jun 18 23:42:06 2003
@@ -22,7 +22,8 @@
 #include <asm/pgtable.h>
 #include <asm/system.h>
 #include <asm/processor.h>
-#include <asm/ia32.h>
+
+#include "ia32priv.h"
 
 extern void die_if_kernel (char *str, struct pt_regs *regs, long err);
 
@@ -60,30 +61,26 @@
 	regs->r27 = load_desc(regs->r16 >>  0);		/* DSD */
 	regs->r28 = load_desc(regs->r16 >> 32);		/* FSD */
 	regs->r29 = load_desc(regs->r16 >> 48);		/* GSD */
-	task->thread.csd = load_desc(regs->r17 >>  0);	/* CSD */
-	task->thread.ssd = load_desc(regs->r17 >> 16);	/* SSD */
+	regs->ar_csd = load_desc(regs->r17 >>  0);	/* CSD */
+	regs->ar_ssd = load_desc(regs->r17 >> 16);	/* SSD */
 }
 
 void
 ia32_save_state (struct task_struct *t)
 {
-	unsigned long eflag, fsr, fcr, fir, fdr, csd, ssd;
+	unsigned long eflag, fsr, fcr, fir, fdr;
 
 	asm ("mov %0=ar.eflag;"
 	     "mov %1=ar.fsr;"
 	     "mov %2=ar.fcr;"
 	     "mov %3=ar.fir;"
 	     "mov %4=ar.fdr;"
-	     "mov %5=ar.csd;"
-	     "mov %6=ar.ssd;"
-	     : "=r"(eflag), "=r"(fsr), "=r"(fcr), "=r"(fir), "=r"(fdr), "=r"(csd), "=r"(ssd));
+	     : "=r"(eflag), "=r"(fsr), "=r"(fcr), "=r"(fir), "=r"(fdr));
 	t->thread.eflag = eflag;
 	t->thread.fsr = fsr;
 	t->thread.fcr = fcr;
 	t->thread.fir = fir;
 	t->thread.fdr = fdr;
-	t->thread.csd = csd;
-	t->thread.ssd = ssd;
 	ia64_set_kr(IA64_KR_IO_BASE, t->thread.old_iob);
 	ia64_set_kr(IA64_KR_TSSD, t->thread.old_k1);
 }
@@ -91,7 +88,7 @@
 void
 ia32_load_state (struct task_struct *t)
 {
-	unsigned long eflag, fsr, fcr, fir, fdr, csd, ssd, tssd;
+	unsigned long eflag, fsr, fcr, fir, fdr, tssd;
 	struct pt_regs *regs = ia64_task_regs(t);
 	int nr = get_cpu();	/* LDT and TSS depend on CPU number: */
 
@@ -100,8 +97,6 @@
 	fcr = t->thread.fcr;
 	fir = t->thread.fir;
 	fdr = t->thread.fdr;
-	csd = t->thread.csd;
-	ssd = t->thread.ssd;
 	tssd = load_desc(_TSS(nr));					/* TSSD */
 
 	asm volatile ("mov ar.eflag=%0;"
@@ -109,9 +104,7 @@
 		      "mov ar.fcr=%2;"
 		      "mov ar.fir=%3;"
 		      "mov ar.fdr=%4;"
-		      "mov ar.csd=%5;"
-		      "mov ar.ssd=%6;"
-		      :: "r"(eflag), "r"(fsr), "r"(fcr), "r"(fir), "r"(fdr), "r"(csd), "r"(ssd));
+		      :: "r"(eflag), "r"(fsr), "r"(fcr), "r"(fir), "r"(fdr));
 	current->thread.old_iob = ia64_get_kr(IA64_KR_IO_BASE);
 	current->thread.old_k1 = ia64_get_kr(IA64_KR_TSSD);
 	ia64_set_kr(IA64_KR_IO_BASE, IA32_IOBASE);
@@ -179,6 +172,13 @@
 	siginfo.si_imm = 0;
 	siginfo.si_code = TRAP_BRKPT;
 	force_sig_info(SIGTRAP, &siginfo, current);
+}
+
+void
+ia32_cpu_init (void)
+{
+	/* initialize global ia32 state - CR0 and CR4 */
+	asm volatile ("mov ar.cflg = %0" :: "r" (((ulong) IA32_CR4 << 32) | IA32_CR0));
 }
 
 static int __init
diff -Nru a/arch/ia64/ia32/ia32_traps.c b/arch/ia64/ia32/ia32_traps.c
--- a/arch/ia64/ia32/ia32_traps.c	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/ia32/ia32_traps.c	Wed Jun 18 23:42:06 2003
@@ -12,7 +12,8 @@
 #include <linux/kernel.h>
 #include <linux/sched.h>
 
-#include <asm/ia32.h>
+#include "ia32priv.h"
+
 #include <asm/ptrace.h>
 
 int
diff -Nru a/arch/ia64/ia32/ia32priv.h b/arch/ia64/ia32/ia32priv.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/ia32/ia32priv.h	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,477 @@
+#ifndef _ASM_IA64_IA32_H
+#define _ASM_IA64_IA32_H
+
+#include <linux/config.h>
+
+#include <asm/ia32.h>
+
+#ifdef CONFIG_IA32_SUPPORT
+
+#include <linux/binfmts.h>
+#include <linux/compat.h>
+
+/*
+ * 32 bit structures for IA32 support.
+ */
+
+#define IA32_PAGE_SHIFT		12	/* 4KB pages */
+#define IA32_PAGE_SIZE		(1UL << IA32_PAGE_SHIFT)
+#define IA32_PAGE_MASK		(~(IA32_PAGE_SIZE - 1))
+#define IA32_PAGE_ALIGN(addr)	(((addr) + IA32_PAGE_SIZE - 1) & IA32_PAGE_MASK)
+#define IA32_CLOCKS_PER_SEC	100	/* Cast in stone for IA32 Linux */
+
+/* sigcontext.h */
+/*
+ * As documented in the iBCS2 standard..
+ *
+ * The first part of "struct _fpstate" is just the
+ * normal i387 hardware setup, the extra "status"
+ * word is used to save the coprocessor status word
+ * before entering the handler.
+ */
+struct _fpreg_ia32 {
+       unsigned short significand[4];
+       unsigned short exponent;
+};
+
+struct _fpxreg_ia32 {
+        unsigned short significand[4];
+        unsigned short exponent;
+        unsigned short padding[3];
+};
+
+struct _xmmreg_ia32 {
+        unsigned int element[4];
+};
+
+
+struct _fpstate_ia32 {
+       unsigned int    cw,
+		       sw,
+		       tag,
+		       ipoff,
+		       cssel,
+		       dataoff,
+		       datasel;
+       struct _fpreg_ia32      _st[8];
+       unsigned short  status;
+       unsigned short  magic;          /* 0xffff = regular FPU data only */
+
+       /* FXSR FPU environment */
+       unsigned int         _fxsr_env[6];   /* FXSR FPU env is ignored */
+       unsigned int         mxcsr;
+       unsigned int         reserved;
+       struct _fpxreg_ia32  _fxsr_st[8];    /* FXSR FPU reg data is ignored */
+       struct _xmmreg_ia32  _xmm[8];
+       unsigned int         padding[56];
+};
+
+struct sigcontext_ia32 {
+       unsigned short gs, __gsh;
+       unsigned short fs, __fsh;
+       unsigned short es, __esh;
+       unsigned short ds, __dsh;
+       unsigned int edi;
+       unsigned int esi;
+       unsigned int ebp;
+       unsigned int esp;
+       unsigned int ebx;
+       unsigned int edx;
+       unsigned int ecx;
+       unsigned int eax;
+       unsigned int trapno;
+       unsigned int err;
+       unsigned int eip;
+       unsigned short cs, __csh;
+       unsigned int eflags;
+       unsigned int esp_at_signal;
+       unsigned short ss, __ssh;
+       unsigned int fpstate;		/* really (struct _fpstate_ia32 *) */
+       unsigned int oldmask;
+       unsigned int cr2;
+};
+
+/* user.h */
+/*
+ * IA32 (Pentium III/4) FXSR, SSE support
+ *
+ * Provide support for the GDB 5.0+ PTRACE_{GET|SET}FPXREGS requests for
+ * interacting with the FXSR-format floating point environment.  Floating
+ * point data can be accessed in the regular format in the usual manner,
+ * and both the standard and SIMD floating point data can be accessed via
+ * the new ptrace requests.  In either case, changes to the FPU environment
+ * will be reflected in the task's state as expected.
+ */
+struct ia32_user_i387_struct {
+	int	cwd;
+	int	swd;
+	int	twd;
+	int	fip;
+	int	fcs;
+	int	foo;
+	int	fos;
+	/* 8*10 bytes for each FP-reg = 80 bytes */
+	struct _fpreg_ia32 	st_space[8];
+};
+
+struct ia32_user_fxsr_struct {
+	unsigned short	cwd;
+	unsigned short	swd;
+	unsigned short	twd;
+	unsigned short	fop;
+	int	fip;
+	int	fcs;
+	int	foo;
+	int	fos;
+	int	mxcsr;
+	int	reserved;
+	int	st_space[32];	/* 8*16 bytes for each FP-reg = 128 bytes */
+	int	xmm_space[32];	/* 8*16 bytes for each XMM-reg = 128 bytes */
+	int	padding[56];
+};
+
+/* signal.h */
+#define IA32_SET_SA_HANDLER(ka,handler,restorer)				\
+				((ka)->sa.sa_handler = (__sighandler_t)		\
+					(((unsigned long)(restorer) << 32)	\
+					 | ((handler) & 0xffffffff)))
+#define IA32_SA_HANDLER(ka)	((unsigned long) (ka)->sa.sa_handler & 0xffffffff)
+#define IA32_SA_RESTORER(ka)	((unsigned long) (ka)->sa.sa_handler >> 32)
+
+struct sigaction32 {
+       unsigned int sa_handler;		/* Really a pointer, but need to deal with 32 bits */
+       unsigned int sa_flags;
+       unsigned int sa_restorer;	/* Another 32 bit pointer */
+       compat_sigset_t sa_mask;		/* A 32 bit mask */
+};
+
+struct old_sigaction32 {
+       unsigned int  sa_handler;	/* Really a pointer, but need to deal
+					     with 32 bits */
+       compat_old_sigset_t sa_mask;		/* A 32 bit mask */
+       unsigned int sa_flags;
+       unsigned int sa_restorer;	/* Another 32 bit pointer */
+};
+
+typedef struct sigaltstack_ia32 {
+	unsigned int	ss_sp;
+	int		ss_flags;
+	unsigned int	ss_size;
+} stack_ia32_t;
+
+struct ucontext_ia32 {
+	unsigned int	  uc_flags;
+	unsigned int	  uc_link;
+	stack_ia32_t	  uc_stack;
+	struct sigcontext_ia32 uc_mcontext;
+	sigset_t	  uc_sigmask;	/* mask last for extensibility */
+};
+
+struct stat64 {
+	unsigned short	st_dev;
+	unsigned char	__pad0[10];
+	unsigned int	__st_ino;
+	unsigned int	st_mode;
+	unsigned int	st_nlink;
+	unsigned int	st_uid;
+	unsigned int	st_gid;
+	unsigned short	st_rdev;
+	unsigned char	__pad3[10];
+	unsigned int	st_size_lo;
+	unsigned int	st_size_hi;
+	unsigned int	st_blksize;
+	unsigned int	st_blocks;	/* Number 512-byte blocks allocated. */
+	unsigned int	__pad4;		/* future possible st_blocks high bits */
+	unsigned int	st_atime;
+	unsigned int	st_atime_nsec;
+	unsigned int	st_mtime;
+	unsigned int	st_mtime_nsec;
+	unsigned int	st_ctime;
+	unsigned int	st_ctime_nsec;
+	unsigned int	st_ino_lo;
+	unsigned int	st_ino_hi;
+};
+
+typedef union sigval32 {
+	int sival_int;
+	unsigned int sival_ptr;
+} sigval_t32;
+
+typedef struct siginfo32 {
+	int si_signo;
+	int si_errno;
+	int si_code;
+
+	union {
+		int _pad[((128/sizeof(int)) - 3)];
+
+		/* kill() */
+		struct {
+			unsigned int _pid;	/* sender's pid */
+			unsigned int _uid;	/* sender's uid */
+		} _kill;
+
+		/* POSIX.1b timers */
+		struct {
+			timer_t _tid;		/* timer id */
+			int _overrun;		/* overrun count */
+			char _pad[sizeof(unsigned int) - sizeof(int)];
+			sigval_t32 _sigval;	/* same as below */
+			int _sys_private;       /* not to be passed to user */
+		} _timer;
+
+		/* POSIX.1b signals */
+		struct {
+			unsigned int _pid;	/* sender's pid */
+			unsigned int _uid;	/* sender's uid */
+			sigval_t32 _sigval;
+		} _rt;
+
+		/* SIGCHLD */
+		struct {
+			unsigned int _pid;	/* which child */
+			unsigned int _uid;	/* sender's uid */
+			int _status;		/* exit code */
+			compat_clock_t _utime;
+			compat_clock_t _stime;
+		} _sigchld;
+
+		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
+		struct {
+			unsigned int _addr;	/* faulting insn/memory ref. */
+		} _sigfault;
+
+		/* SIGPOLL */
+		struct {
+			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
+			int _fd;
+		} _sigpoll;
+	} _sifields;
+} siginfo_t32;
+
+struct linux32_dirent {
+	u32	d_ino;
+	u32	d_off;
+	u16	d_reclen;
+	char	d_name[256];
+};
+
+struct old_linux32_dirent {
+	u32	d_ino;
+	u32	d_offset;
+	u16	d_namlen;
+	char	d_name[1];
+};
+
+/*
+ * IA-32 ELF specific definitions for IA-64.
+ */
+
+#define _ASM_IA64_ELF_H		/* Don't include elf.h */
+
+#include <linux/sched.h>
+#include <asm/processor.h>
+
+/*
+ * This is used to ensure we don't load something for the wrong architecture.
+ */
+#define elf_check_arch(x) ((x)->e_machine == EM_386)
+
+/*
+ * These are used to set parameters in the core dumps.
+ */
+#define ELF_CLASS	ELFCLASS32
+#define ELF_DATA	ELFDATA2LSB
+#define ELF_ARCH	EM_386
+
+#define IA32_PAGE_OFFSET	0xc0000000
+#define IA32_STACK_TOP		IA32_PAGE_OFFSET
+
+/*
+ * The system segments (GDT, TSS, LDT) have to be mapped below 4GB so the IA-32 engine can
+ * access them.
+ */
+#define IA32_GDT_OFFSET		(IA32_PAGE_OFFSET)
+#define IA32_TSS_OFFSET		(IA32_PAGE_OFFSET + PAGE_SIZE)
+#define IA32_LDT_OFFSET		(IA32_PAGE_OFFSET + 2*PAGE_SIZE)
+
+#define USE_ELF_CORE_DUMP
+#define ELF_EXEC_PAGESIZE	IA32_PAGE_SIZE
+
+/*
+ * This is the location that an ET_DYN program is loaded if exec'ed.
+ * Typical use of this is to invoke "./ld.so someprog" to test out a
+ * new version of the loader.  We need to make sure that it is out of
+ * the way of the program that it will "exec", and that there is
+ * sufficient room for the brk.
+ */
+#define ELF_ET_DYN_BASE		(IA32_PAGE_OFFSET/3 + 0x1000000)
+
+void ia64_elf32_init(struct pt_regs *regs);
+#define ELF_PLAT_INIT(_r, load_addr)	ia64_elf32_init(_r)
+
+#define elf_addr_t	u32
+
+/* ELF register definitions.  This is needed for core dump support.  */
+
+#define ELF_NGREG	128			/* XXX fix me */
+#define ELF_NFPREG	128			/* XXX fix me */
+
+typedef unsigned long elf_greg_t;
+typedef elf_greg_t elf_gregset_t[ELF_NGREG];
+
+typedef struct {
+	unsigned long w0;
+	unsigned long w1;
+} elf_fpreg_t;
+typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
+
+/* This macro yields a bitmask that programs can use to figure out
+   what instruction set this CPU supports.  */
+#define ELF_HWCAP	0
+
+/* This macro yields a string that ld.so will use to load
+   implementation specific libraries for optimization.  Not terribly
+   relevant until we have real hardware to play with... */
+#define ELF_PLATFORM	0
+
+#ifdef __KERNEL__
+# define SET_PERSONALITY(EX,IBCS2)				\
+	(current->personality = (IBCS2) ? PER_SVR4 : PER_LINUX)
+#endif
+
+#define IA32_EFLAG	0x200
+
+/*
+ * IA-32 ELF specific definitions for IA-64.
+ */
+
+#define __USER_CS      0x23
+#define __USER_DS      0x2B
+
+#define FIRST_TSS_ENTRY 6
+#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1)
+#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))
+#define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3))
+
+#define IA32_SEGSEL_RPL		(0x3 << 0)
+#define IA32_SEGSEL_TI		(0x1 << 2)
+#define IA32_SEGSEL_INDEX_SHIFT	3
+
+#define IA32_SEG_BASE		16
+#define IA32_SEG_TYPE		40
+#define IA32_SEG_SYS		44
+#define IA32_SEG_DPL		45
+#define IA32_SEG_P		47
+#define IA32_SEG_HIGH_LIMIT	48
+#define IA32_SEG_AVL		52
+#define IA32_SEG_DB		54
+#define IA32_SEG_G		55
+#define IA32_SEG_HIGH_BASE	56
+
+#define IA32_SEG_DESCRIPTOR(base, limit, segtype, nonsysseg, dpl, segpresent, avl, segdb, gran)	\
+	       (((limit) & 0xffff)								\
+		| (((unsigned long) (base) & 0xffffff) << IA32_SEG_BASE)			\
+		| ((unsigned long) (segtype) << IA32_SEG_TYPE)					\
+		| ((unsigned long) (nonsysseg) << IA32_SEG_SYS)					\
+		| ((unsigned long) (dpl) << IA32_SEG_DPL)					\
+		| ((unsigned long) (segpresent) << IA32_SEG_P)					\
+		| ((((unsigned long) (limit) >> 16) & 0xf) << IA32_SEG_HIGH_LIMIT)		\
+		| ((unsigned long) (avl) << IA32_SEG_AVL)					\
+		| ((unsigned long) (segdb) << IA32_SEG_DB)					\
+		| ((unsigned long) (gran) << IA32_SEG_G)					\
+		| ((((unsigned long) (base) >> 24) & 0xff) << IA32_SEG_HIGH_BASE))
+
+#define SEG_LIM		32
+#define SEG_TYPE	52
+#define SEG_SYS		56
+#define SEG_DPL		57
+#define SEG_P		59
+#define SEG_AVL		60
+#define SEG_DB		62
+#define SEG_G		63
+
+/* Unscramble an IA-32 segment descriptor into the IA-64 format.  */
+#define IA32_SEG_UNSCRAMBLE(sd)									 \
+	(   (((sd) >> IA32_SEG_BASE) & 0xffffff) | ((((sd) >> IA32_SEG_HIGH_BASE) & 0xff) << 24) \
+	 | ((((sd) & 0xffff) | ((((sd) >> IA32_SEG_HIGH_LIMIT) & 0xf) << 16)) << SEG_LIM)	 \
+	 | ((((sd) >> IA32_SEG_TYPE) & 0xf) << SEG_TYPE)					 \
+	 | ((((sd) >> IA32_SEG_SYS) & 0x1) << SEG_SYS)						 \
+	 | ((((sd) >> IA32_SEG_DPL) & 0x3) << SEG_DPL)						 \
+	 | ((((sd) >> IA32_SEG_P) & 0x1) << SEG_P)						 \
+	 | ((((sd) >> IA32_SEG_AVL) & 0x1) << SEG_AVL)						 \
+	 | ((((sd) >> IA32_SEG_DB) & 0x1) << SEG_DB)						 \
+	 | ((((sd) >> IA32_SEG_G) & 0x1) << SEG_G))
+
+#define IA32_IOBASE	0x2000000000000000 /* Virtual address for I/O space */
+
+#define IA32_CR0	0x80000001	/* Enable PG and PE bits */
+#define IA32_CR4	0x600		/* MMXEX and FXSR on */
+
+/*
+ *  IA32 floating point control registers starting values
+ */
+
+#define IA32_FSR_DEFAULT	0x55550000		/* set all tag bits */
+#define IA32_FCR_DEFAULT	0x17800000037fUL	/* extended precision, all masks */
+
+#define IA32_PTRACE_GETREGS	12
+#define IA32_PTRACE_SETREGS	13
+#define IA32_PTRACE_GETFPREGS	14
+#define IA32_PTRACE_SETFPREGS	15
+#define IA32_PTRACE_GETFPXREGS	18
+#define IA32_PTRACE_SETFPXREGS	19
+
+#define ia32_start_thread(regs,new_ip,new_sp) do {				\
+	set_fs(USER_DS);							\
+	ia64_psr(regs)->cpl = 3;	/* set user mode */			\
+	ia64_psr(regs)->ri = 0;		/* clear return slot number */		\
+	ia64_psr(regs)->is = 1;		/* IA-32 instruction set */		\
+	regs->cr_iip = new_ip;							\
+	regs->ar_rsc = 0xc;		/* enforced lazy mode, priv. level 3 */	\
+	regs->ar_rnat = 0;							\
+	regs->loadrs = 0;							\
+	regs->r12 = new_sp;							\
+} while (0)
+
+/*
+ * Local Descriptor Table (LDT) related declarations.
+ */
+
+#define IA32_LDT_ENTRIES	8192		/* Maximum number of LDT entries supported. */
+#define IA32_LDT_ENTRY_SIZE	8		/* The size of each LDT entry. */
+
+struct ia32_modify_ldt_ldt_s {
+	unsigned int entry_number;
+	unsigned int base_addr;
+	unsigned int limit;
+	unsigned int seg_32bit:1;
+	unsigned int contents:2;
+	unsigned int read_exec_only:1;
+	unsigned int limit_in_pages:1;
+	unsigned int seg_not_present:1;
+	unsigned int useable:1;
+};
+
+struct linux_binprm;
+
+extern void ia32_init_addr_space (struct pt_regs *regs);
+extern int ia32_setup_arg_pages (struct linux_binprm *bprm);
+extern unsigned long ia32_do_mmap (struct file *, unsigned long, unsigned long, int, int, loff_t);
+extern void ia32_load_segment_descriptors (struct task_struct *task);
+
+#define ia32f2ia64f(dst,src) \
+	do { \
+	register double f6 asm ("f6"); \
+	asm volatile ("ldfe f6=[%2];; stf.spill [%1]=f6" : "=f"(f6): "r"(dst), "r"(src) : "memory"); \
+	} while(0)
+
+#define ia64f2ia32f(dst,src) \
+	do { \
+	register double f6 asm ("f6"); \
+	asm volatile ("ldf.fill f6=[%2];; stfe [%1]=f6" : "=f"(f6): "r"(dst),  "r"(src) : "memory"); \
+	} while(0)
+
+#endif /* !CONFIG_IA32_SUPPORT */
+
+#endif /* _ASM_IA64_IA32_H */
diff -Nru a/arch/ia64/ia32/sys_ia32.c b/arch/ia64/ia32/sys_ia32.c
--- a/arch/ia64/ia32/sys_ia32.c	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/ia32/sys_ia32.c	Wed Jun 18 23:42:08 2003
@@ -53,7 +53,8 @@
 #include <asm/types.h>
 #include <asm/uaccess.h>
 #include <asm/semaphore.h>
-#include <asm/ia32.h>
+
+#include "ia32priv.h"
 
 #include <net/scm.h>
 #include <net/sock.h>
@@ -206,9 +207,8 @@
 
 
 static int
-get_page_prot (unsigned long addr)
+get_page_prot (struct vm_area_struct *vma, unsigned long addr)
 {
-	struct vm_area_struct *vma = find_vma(current->mm, addr);
 	int prot = 0;
 
 	if (!vma || vma->vm_start > addr)
@@ -231,14 +231,26 @@
 mmap_subpage (struct file *file, unsigned long start, unsigned long end, int prot, int flags,
 	      loff_t off)
 {
-	void *page = (void *) get_zeroed_page(GFP_KERNEL);
+	void *page = NULL;
 	struct inode *inode;
-	unsigned long ret;
-	int old_prot = get_page_prot(start);
+	unsigned long ret = 0;
+	struct vm_area_struct *vma = find_vma(current->mm, start);
+	int old_prot = get_page_prot(vma, start);
 
 	DBG("mmap_subpage(file=%p,start=0x%lx,end=0x%lx,prot=%x,flags=%x,off=0x%llx)\n",
 	    file, start, end, prot, flags, off);
 
+
+	/* Optimize the case where the old mmap and the new mmap are both anonymous */
+	if ((old_prot & PROT_WRITE) && (flags & MAP_ANONYMOUS) && !vma->vm_file) {
+		if (clear_user((void *) start, end - start)) {
+			ret = -EFAULT;
+			goto out;
+		}
+		goto skip_mmap;
+	}
+
+	page = (void *) get_zeroed_page(GFP_KERNEL);
 	if (!page)
 		return -ENOMEM;
 
@@ -263,6 +275,7 @@
 			copy_to_user((void *) end, page + PAGE_OFF(end),
 				     PAGE_SIZE - PAGE_OFF(end));
 	}
+
 	if (!(flags & MAP_ANONYMOUS)) {
 		/* read the file contents */
 		inode = file->f_dentry->d_inode;
@@ -273,10 +286,13 @@
 			goto out;
 		}
 	}
+
+ skip_mmap:
 	if (!(prot & PROT_WRITE))
 		ret = sys_mprotect(PAGE_START(start), PAGE_SIZE, prot | old_prot);
   out:
-	free_page((unsigned long) page);
+	if (page)
+		free_page((unsigned long) page);
 	return ret;
 }
 
@@ -532,11 +548,12 @@
 mprotect_subpage (unsigned long address, int new_prot)
 {
 	int old_prot;
+	struct vm_area_struct *vma;
 
 	if (new_prot == PROT_NONE)
 		return 0;		/* optimize case where nothing changes... */
-
-	old_prot = get_page_prot(address);
+	vma = find_vma(current->mm, address);
+	old_prot = get_page_prot(vma, address);
 	return sys_mprotect(address, PAGE_SIZE, new_prot | old_prot);
 }
 
@@ -642,7 +659,6 @@
    sorts of things, like timeval and itimerval.  */
 
 extern struct timezone sys_tz;
-extern int do_sys_settimeofday (struct timeval *tv, struct timezone *tz);
 
 asmlinkage long
 sys32_gettimeofday (struct compat_timeval *tv, struct timezone *tz)
@@ -664,18 +680,21 @@
 sys32_settimeofday (struct compat_timeval *tv, struct timezone *tz)
 {
 	struct timeval ktv;
+	struct timespec kts;
 	struct timezone ktz;
 
 	if (tv) {
 		if (get_tv32(&ktv, tv))
 			return -EFAULT;
+		kts.tv_sec = ktv.tv_sec;
+		kts.tv_nsec = ktv.tv_usec * 1000;
 	}
 	if (tz) {
 		if (copy_from_user(&ktz, tz, sizeof(ktz)))
 			return -EFAULT;
 	}
 
-	return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
+	return do_sys_settimeofday(tv ? &kts : NULL, tz ? &ktz : NULL);
 }
 
 struct getdents32_callback {
@@ -836,9 +855,8 @@
 		}
 	}
 
-	size = FDS_BYTES(n);
 	ret = -EINVAL;
-	if (n < 0 || size < n)
+	if (n < 0)
 		goto out_nofds;
 
 	if (n > current->files->max_fdset)
@@ -850,6 +868,7 @@
 	 * long-words.
 	 */
 	ret = -ENOMEM;
+	size = FDS_BYTES(n);
 	bits = kmalloc(6 * size, GFP_KERNEL);
 	if (!bits)
 		goto out_nofds;
@@ -1102,7 +1121,7 @@
 };
 
 struct shmid64_ds32 {
-	struct ipc64_perm shm_perm;
+	struct ipc64_perm32 shm_perm;
 	compat_size_t shm_segsz;
 	compat_time_t   shm_atime;
 	unsigned int __unused1;
@@ -1320,7 +1339,6 @@
 msgctl32 (int first, int second, void *uptr)
 {
 	int err = -EINVAL, err2;
-	struct msqid_ds m;
 	struct msqid64_ds m64;
 	struct msqid_ds32 *up32 = (struct msqid_ds32 *)uptr;
 	struct msqid64_ds32 *up64 = (struct msqid64_ds32 *)uptr;
@@ -1336,21 +1354,21 @@
 
 	      case IPC_SET:
 		if (version == IPC_64) {
-			err = get_user(m.msg_perm.uid, &up64->msg_perm.uid);
-			err |= get_user(m.msg_perm.gid, &up64->msg_perm.gid);
-			err |= get_user(m.msg_perm.mode, &up64->msg_perm.mode);
-			err |= get_user(m.msg_qbytes, &up64->msg_qbytes);
+			err = get_user(m64.msg_perm.uid, &up64->msg_perm.uid);
+			err |= get_user(m64.msg_perm.gid, &up64->msg_perm.gid);
+			err |= get_user(m64.msg_perm.mode, &up64->msg_perm.mode);
+			err |= get_user(m64.msg_qbytes, &up64->msg_qbytes);
 		} else {
-			err = get_user(m.msg_perm.uid, &up32->msg_perm.uid);
-			err |= get_user(m.msg_perm.gid, &up32->msg_perm.gid);
-			err |= get_user(m.msg_perm.mode, &up32->msg_perm.mode);
-			err |= get_user(m.msg_qbytes, &up32->msg_qbytes);
+			err = get_user(m64.msg_perm.uid, &up32->msg_perm.uid);
+			err |= get_user(m64.msg_perm.gid, &up32->msg_perm.gid);
+			err |= get_user(m64.msg_perm.mode, &up32->msg_perm.mode);
+			err |= get_user(m64.msg_qbytes, &up32->msg_qbytes);
 		}
 		if (err)
 			break;
 		old_fs = get_fs();
 		set_fs(KERNEL_DS);
-		err = sys_msgctl(first, second, &m);
+		err = sys_msgctl(first, second, &m64);
 		set_fs(old_fs);
 		break;
 
@@ -1430,7 +1448,7 @@
 shmctl32 (int first, int second, void *uptr)
 {
 	int err = -EFAULT, err2;
-	struct shmid_ds s;
+
 	struct shmid64_ds s64;
 	struct shmid_ds32 *up32 = (struct shmid_ds32 *)uptr;
 	struct shmid64_ds32 *up64 = (struct shmid64_ds32 *)uptr;
@@ -1482,19 +1500,19 @@
 
 	      case IPC_SET:
 		if (version == IPC_64) {
-			err = get_user(s.shm_perm.uid, &up64->shm_perm.uid);
-			err |= get_user(s.shm_perm.gid, &up64->shm_perm.gid);
-			err |= get_user(s.shm_perm.mode, &up64->shm_perm.mode);
+			err = get_user(s64.shm_perm.uid, &up64->shm_perm.uid);
+			err |= get_user(s64.shm_perm.gid, &up64->shm_perm.gid);
+			err |= get_user(s64.shm_perm.mode, &up64->shm_perm.mode);
 		} else {
-			err = get_user(s.shm_perm.uid, &up32->shm_perm.uid);
-			err |= get_user(s.shm_perm.gid, &up32->shm_perm.gid);
-			err |= get_user(s.shm_perm.mode, &up32->shm_perm.mode);
+			err = get_user(s64.shm_perm.uid, &up32->shm_perm.uid);
+			err |= get_user(s64.shm_perm.gid, &up32->shm_perm.gid);
+			err |= get_user(s64.shm_perm.mode, &up32->shm_perm.mode);
 		}
 		if (err)
 			break;
 		old_fs = get_fs();
 		set_fs(KERNEL_DS);
-		err = sys_shmctl(first, second, &s);
+		err = sys_shmctl(first, second, &s64);
 		set_fs(old_fs);
 		break;
 
@@ -1798,12 +1816,16 @@
 		ia64f2ia32f(f, &ptp->f9);
 		break;
 	      case 2:
+		ia64f2ia32f(f, &ptp->f10);
+		break;
 	      case 3:
+		ia64f2ia32f(f, &ptp->f11);
+		break;
 	      case 4:
 	      case 5:
 	      case 6:
 	      case 7:
-		ia64f2ia32f(f, &swp->f10 + (regno - 2));
+		ia64f2ia32f(f, &swp->f12 + (regno - 4));
 		break;
 	}
 	copy_to_user(reg, f, sizeof(*reg));
@@ -1824,12 +1846,16 @@
 		copy_from_user(&ptp->f9, reg, sizeof(*reg));
 		break;
 	      case 2:
+		copy_from_user(&ptp->f10, reg, sizeof(*reg));
+		break;
 	      case 3:
+		copy_from_user(&ptp->f11, reg, sizeof(*reg));
+		break;
 	      case 4:
 	      case 5:
 	      case 6:
 	      case 7:
-		copy_from_user(&swp->f10 + (regno - 2), reg, sizeof(*reg));
+		copy_from_user(&swp->f12 + (regno - 4), reg, sizeof(*reg));
 		break;
 	}
 	return;
@@ -1860,7 +1886,7 @@
 	ptp = ia64_task_regs(tsk);
 	tos = (tsk->thread.fsr >> 11) & 7;
 	for (i = 0; i < 8; i++)
-		put_fpreg(i, (struct _fpreg_ia32 *)&save->st_space[4*i], ptp, swp, tos);
+		put_fpreg(i, &save->st_space[i], ptp, swp, tos);
 	return 0;
 }
 
@@ -1893,7 +1919,7 @@
 	ptp = ia64_task_regs(tsk);
 	tos = (tsk->thread.fsr >> 11) & 7;
 	for (i = 0; i < 8; i++)
-		get_fpreg(i, (struct _fpreg_ia32 *)&save->st_space[4*i], ptp, swp, tos);
+		get_fpreg(i, &save->st_space[i], ptp, swp, tos);
 	return 0;
 }
 
diff -Nru a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile
--- a/arch/ia64/kernel/Makefile	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/kernel/Makefile	Wed Jun 18 23:42:09 2003
@@ -4,12 +4,11 @@
 
 extra-y	:= head.o init_task.o
 
-obj-y := acpi.o entry.o efi.o efi_stub.o gate.o ia64_ksyms.o irq.o irq_ia64.o irq_lsapic.o	\
-	 ivt.o machvec.o pal.o perfmon.o process.o ptrace.o sal.o semaphore.o setup.o signal.o	\
-	 sys_ia64.o time.o traps.o unaligned.o unwind.o
+obj-y := acpi.o entry.o efi.o efi_stub.o gate-data.o fsys.o ia64_ksyms.o irq.o irq_ia64.o	\
+	 irq_lsapic.o ivt.o machvec.o pal.o patch.o process.o perfmon.o ptrace.o sal.o		\
+	 semaphore.o setup.o signal.o sys_ia64.o time.o traps.o unaligned.o unwind.o
 
 obj-$(CONFIG_EFI_VARS)		+= efivars.o
-obj-$(CONFIG_FSYS)		+= fsys.o
 obj-$(CONFIG_IA64_BRL_EMU)	+= brl_emu.o
 obj-$(CONFIG_IA64_GENERIC)	+= acpi-ext.o
 obj-$(CONFIG_IA64_HP_ZX1)	+= acpi-ext.o
@@ -18,3 +17,30 @@
 obj-$(CONFIG_IOSAPIC)		+= iosapic.o
 obj-$(CONFIG_MODULES)		+= module.o
 obj-$(CONFIG_SMP)		+= smp.o smpboot.o
+obj-$(CONFIG_PERFMON)		+= perfmon_default_smpl.o
+
+# The gate DSO image is built using a special linker script.
+targets += gate.so gate-syms.o
+
+AFLAGS_gate.lds.o += -P -C -U$(ARCH)
+arch/ia64/kernel/gate.lds.s: %.s: %.S scripts FORCE
+	$(call if_changed_dep,as_s_S)
+
+quiet_cmd_gate = GATE $@
+      cmd_gate = $(CC) -nostdlib $(GATECFLAGS_$(@F)) -Wl,-T,$(filter-out FORCE,$^) -o $@
+
+GATECFLAGS_gate.so = -shared -s -Wl,-soname=linux-gate.so.1
+$(obj)/gate.so: $(src)/gate.lds.s $(obj)/gate.o FORCE
+	$(call if_changed,gate)
+
+$(obj)/built-in.o: $(obj)/gate-syms.o
+$(obj)/built-in.o: ld_flags += -R $(obj)/gate-syms.o
+
+GATECFLAGS_gate-syms.o = -r
+$(obj)/gate-syms.o: $(src)/gate.lds.s $(obj)/gate.o FORCE
+	$(call if_changed,gate)
+
+# gate-data.o contains the gate DSO image as data in section .data.gate.
+# We must build gate.so before we can assemble it.
+# Note: kbuild does not track this dependency due to usage of .incbin
+$(obj)/gate-data.o: $(obj)/gate.so
diff -Nru a/arch/ia64/kernel/acpi-ext.c b/arch/ia64/kernel/acpi-ext.c
--- a/arch/ia64/kernel/acpi-ext.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/kernel/acpi-ext.c	Wed Jun 18 23:42:09 2003
@@ -84,7 +84,6 @@
 	acpi_status status;
 	u8 *data;
 	u32 length;
-	int i;
 
 	status = acpi_find_vendor_resource(obj, &hp_ccsr_descriptor, &data, &length);
 
diff -Nru a/arch/ia64/kernel/acpi.c b/arch/ia64/kernel/acpi.c
--- a/arch/ia64/kernel/acpi.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/kernel/acpi.c	Wed Jun 18 23:42:07 2003
@@ -96,6 +96,9 @@
 	if (!strcmp(hdr->oem_id, "HP")) {
 		return "hpzx1";
 	}
+	else if (!strcmp(hdr->oem_id, "SGI")) {
+		return "sn2";
+	}
 
 	return "dig";
 #else
@@ -103,8 +106,6 @@
 	return "hpsim";
 # elif defined (CONFIG_IA64_HP_ZX1)
 	return "hpzx1";
-# elif defined (CONFIG_IA64_SGI_SN1)
-	return "sn1";
 # elif defined (CONFIG_IA64_SGI_SN2)
 	return "sn2";
 # elif defined (CONFIG_IA64_DIG)
@@ -191,21 +192,19 @@
 
 	printk(KERN_INFO "CPU %d (0x%04x)", total_cpus, (lsapic->id << 8) | lsapic->eid);
 
-	if (lsapic->flags.enabled) {
-		available_cpus++;
+	if (!lsapic->flags.enabled)
+		printk(" disabled");
+	else if (available_cpus >= NR_CPUS)
+		printk(" ignored (increase NR_CPUS)");
+	else {
 		printk(" enabled");
 #ifdef CONFIG_SMP
-		smp_boot_data.cpu_phys_id[total_cpus] = (lsapic->id << 8) | lsapic->eid;
+		smp_boot_data.cpu_phys_id[available_cpus] = (lsapic->id << 8) | lsapic->eid;
 		if (hard_smp_processor_id()
-		    == (unsigned int) smp_boot_data.cpu_phys_id[total_cpus])
+		    == (unsigned int) smp_boot_data.cpu_phys_id[available_cpus])
 			printk(" (BSP)");
 #endif
-	}
-	else {
-		printk(" disabled");
-#ifdef CONFIG_SMP
-		smp_boot_data.cpu_phys_id[total_cpus] = -1;
-#endif
+		++available_cpus;
 	}
 
 	printk("\n");
@@ -694,11 +693,11 @@
 #endif
 
 #ifdef CONFIG_SMP
+	smp_boot_data.cpu_count = available_cpus;
 	if (available_cpus == 0) {
 		printk(KERN_INFO "ACPI: Found 0 CPUS; assuming 1\n");
 		available_cpus = 1; /* We've got at least one of these, no? */
 	}
-	smp_boot_data.cpu_count = total_cpus;
 
 	smp_build_cpu_map();
 # ifdef CONFIG_NUMA
diff -Nru a/arch/ia64/kernel/asm-offsets.c b/arch/ia64/kernel/asm-offsets.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/kernel/asm-offsets.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,189 @@
+/*
+ * Generate definitions needed by assembly language modules.
+ * This code generates raw asm output which is post-processed
+ * to extract and format the required data.
+ */
+
+#include <linux/config.h>
+
+#include <linux/sched.h>
+
+#include <asm-ia64/processor.h>
+#include <asm-ia64/ptrace.h>
+#include <asm-ia64/siginfo.h>
+#include <asm-ia64/sigcontext.h>
+
+#include "../kernel/sigframe.h"
+
+#define DEFINE(sym, val) \
+        asm volatile("\n->" #sym " %0 " #val : : "i" (val))
+
+#define BLANK() asm volatile("\n->" : : )
+
+void foo(void)
+{
+	DEFINE(IA64_TASK_SIZE, sizeof (struct task_struct));
+	DEFINE(IA64_THREAD_INFO_SIZE, sizeof (struct thread_info));
+	DEFINE(IA64_PT_REGS_SIZE, sizeof (struct pt_regs));
+	DEFINE(IA64_SWITCH_STACK_SIZE, sizeof (struct switch_stack));
+	DEFINE(IA64_SIGINFO_SIZE, sizeof (struct siginfo));
+	DEFINE(IA64_CPU_SIZE, sizeof (struct cpuinfo_ia64));
+	DEFINE(SIGFRAME_SIZE, sizeof (struct sigframe));
+	DEFINE(UNW_FRAME_INFO_SIZE, sizeof (struct unw_frame_info));
+
+	BLANK();
+
+	DEFINE(IA64_TASK_CLEAR_CHILD_TID_OFFSET,offsetof (struct task_struct, clear_child_tid));
+	DEFINE(IA64_TASK_GROUP_LEADER_OFFSET, offsetof (struct task_struct, group_leader));
+	DEFINE(IA64_TASK_PID_OFFSET, offsetof (struct task_struct, pid));
+	DEFINE(IA64_TASK_REAL_PARENT_OFFSET, offsetof (struct task_struct, real_parent));
+	DEFINE(IA64_TASK_TGID_OFFSET, offsetof (struct task_struct, tgid));
+	DEFINE(IA64_TASK_THREAD_KSP_OFFSET, offsetof (struct task_struct, thread.ksp));
+	DEFINE(IA64_TASK_THREAD_ON_USTACK_OFFSET, offsetof (struct task_struct, thread.on_ustack));
+
+	BLANK();
+
+	DEFINE(IA64_PT_REGS_B6_OFFSET, offsetof (struct pt_regs, b6));
+	DEFINE(IA64_PT_REGS_B7_OFFSET, offsetof (struct pt_regs, b7));
+	DEFINE(IA64_PT_REGS_AR_CSD_OFFSET, offsetof (struct pt_regs, ar_csd));
+	DEFINE(IA64_PT_REGS_AR_SSD_OFFSET, offsetof (struct pt_regs, ar_ssd));
+	DEFINE(IA64_PT_REGS_R8_OFFSET, offsetof (struct pt_regs, r8));
+	DEFINE(IA64_PT_REGS_R9_OFFSET, offsetof (struct pt_regs, r9));
+	DEFINE(IA64_PT_REGS_R10_OFFSET, offsetof (struct pt_regs, r10));
+	DEFINE(IA64_PT_REGS_R11_OFFSET, offsetof (struct pt_regs, r11));
+	DEFINE(IA64_PT_REGS_CR_IPSR_OFFSET, offsetof (struct pt_regs, cr_ipsr));
+	DEFINE(IA64_PT_REGS_CR_IIP_OFFSET, offsetof (struct pt_regs, cr_iip));
+	DEFINE(IA64_PT_REGS_CR_IFS_OFFSET, offsetof (struct pt_regs, cr_ifs));
+	DEFINE(IA64_PT_REGS_AR_UNAT_OFFSET, offsetof (struct pt_regs, ar_unat));
+	DEFINE(IA64_PT_REGS_AR_PFS_OFFSET, offsetof (struct pt_regs, ar_pfs));
+	DEFINE(IA64_PT_REGS_AR_RSC_OFFSET, offsetof (struct pt_regs, ar_rsc));
+	DEFINE(IA64_PT_REGS_AR_RNAT_OFFSET, offsetof (struct pt_regs, ar_rnat));
+
+	DEFINE(IA64_PT_REGS_AR_BSPSTORE_OFFSET, offsetof (struct pt_regs, ar_bspstore));
+	DEFINE(IA64_PT_REGS_PR_OFFSET, offsetof (struct pt_regs, pr));
+	DEFINE(IA64_PT_REGS_B0_OFFSET, offsetof (struct pt_regs, b0));
+	DEFINE(IA64_PT_REGS_LOADRS_OFFSET, offsetof (struct pt_regs, loadrs));
+	DEFINE(IA64_PT_REGS_R1_OFFSET, offsetof (struct pt_regs, r1));
+	DEFINE(IA64_PT_REGS_R12_OFFSET, offsetof (struct pt_regs, r12));
+	DEFINE(IA64_PT_REGS_R13_OFFSET, offsetof (struct pt_regs, r13));
+	DEFINE(IA64_PT_REGS_AR_FPSR_OFFSET, offsetof (struct pt_regs, ar_fpsr));
+	DEFINE(IA64_PT_REGS_R15_OFFSET, offsetof (struct pt_regs, r15));
+	DEFINE(IA64_PT_REGS_R14_OFFSET, offsetof (struct pt_regs, r14));
+	DEFINE(IA64_PT_REGS_R2_OFFSET, offsetof (struct pt_regs, r2));
+	DEFINE(IA64_PT_REGS_R3_OFFSET, offsetof (struct pt_regs, r3));
+	DEFINE(IA64_PT_REGS_R16_OFFSET, offsetof (struct pt_regs, r16));
+	DEFINE(IA64_PT_REGS_R17_OFFSET, offsetof (struct pt_regs, r17));
+	DEFINE(IA64_PT_REGS_R18_OFFSET, offsetof (struct pt_regs, r18));
+	DEFINE(IA64_PT_REGS_R19_OFFSET, offsetof (struct pt_regs, r19));
+	DEFINE(IA64_PT_REGS_R20_OFFSET, offsetof (struct pt_regs, r20));
+	DEFINE(IA64_PT_REGS_R21_OFFSET, offsetof (struct pt_regs, r21));
+	DEFINE(IA64_PT_REGS_R22_OFFSET, offsetof (struct pt_regs, r22));
+	DEFINE(IA64_PT_REGS_R23_OFFSET, offsetof (struct pt_regs, r23));
+	DEFINE(IA64_PT_REGS_R24_OFFSET, offsetof (struct pt_regs, r24));
+	DEFINE(IA64_PT_REGS_R25_OFFSET, offsetof (struct pt_regs, r25));
+	DEFINE(IA64_PT_REGS_R26_OFFSET, offsetof (struct pt_regs, r26));
+	DEFINE(IA64_PT_REGS_R27_OFFSET, offsetof (struct pt_regs, r27));
+	DEFINE(IA64_PT_REGS_R28_OFFSET, offsetof (struct pt_regs, r28));
+	DEFINE(IA64_PT_REGS_R29_OFFSET, offsetof (struct pt_regs, r29));
+	DEFINE(IA64_PT_REGS_R30_OFFSET, offsetof (struct pt_regs, r30));
+	DEFINE(IA64_PT_REGS_R31_OFFSET, offsetof (struct pt_regs, r31));
+	DEFINE(IA64_PT_REGS_AR_CCV_OFFSET, offsetof (struct pt_regs, ar_ccv));
+	DEFINE(IA64_PT_REGS_F6_OFFSET, offsetof (struct pt_regs, f6));
+	DEFINE(IA64_PT_REGS_F7_OFFSET, offsetof (struct pt_regs, f7));
+	DEFINE(IA64_PT_REGS_F8_OFFSET, offsetof (struct pt_regs, f8));
+	DEFINE(IA64_PT_REGS_F9_OFFSET, offsetof (struct pt_regs, f9));
+	DEFINE(IA64_PT_REGS_F10_OFFSET, offsetof (struct pt_regs, f10));
+	DEFINE(IA64_PT_REGS_F11_OFFSET, offsetof (struct pt_regs, f11));
+
+	BLANK();
+
+	DEFINE(IA64_SWITCH_STACK_CALLER_UNAT_OFFSET, offsetof (struct switch_stack, caller_unat));
+	DEFINE(IA64_SWITCH_STACK_AR_FPSR_OFFSET, offsetof (struct switch_stack, ar_fpsr));
+	DEFINE(IA64_SWITCH_STACK_F2_OFFSET, offsetof (struct switch_stack, f2));
+	DEFINE(IA64_SWITCH_STACK_F3_OFFSET, offsetof (struct switch_stack, f3));
+	DEFINE(IA64_SWITCH_STACK_F4_OFFSET, offsetof (struct switch_stack, f4));
+	DEFINE(IA64_SWITCH_STACK_F5_OFFSET, offsetof (struct switch_stack, f5));
+	DEFINE(IA64_SWITCH_STACK_F12_OFFSET, offsetof (struct switch_stack, f12));
+	DEFINE(IA64_SWITCH_STACK_F13_OFFSET, offsetof (struct switch_stack, f13));
+	DEFINE(IA64_SWITCH_STACK_F14_OFFSET, offsetof (struct switch_stack, f14));
+	DEFINE(IA64_SWITCH_STACK_F15_OFFSET, offsetof (struct switch_stack, f15));
+	DEFINE(IA64_SWITCH_STACK_F16_OFFSET, offsetof (struct switch_stack, f16));
+	DEFINE(IA64_SWITCH_STACK_F17_OFFSET, offsetof (struct switch_stack, f17));
+	DEFINE(IA64_SWITCH_STACK_F18_OFFSET, offsetof (struct switch_stack, f18));
+	DEFINE(IA64_SWITCH_STACK_F19_OFFSET, offsetof (struct switch_stack, f19));
+	DEFINE(IA64_SWITCH_STACK_F20_OFFSET, offsetof (struct switch_stack, f20));
+	DEFINE(IA64_SWITCH_STACK_F21_OFFSET, offsetof (struct switch_stack, f21));
+	DEFINE(IA64_SWITCH_STACK_F22_OFFSET, offsetof (struct switch_stack, f22));
+	DEFINE(IA64_SWITCH_STACK_F23_OFFSET, offsetof (struct switch_stack, f23));
+	DEFINE(IA64_SWITCH_STACK_F24_OFFSET, offsetof (struct switch_stack, f24));
+	DEFINE(IA64_SWITCH_STACK_F25_OFFSET, offsetof (struct switch_stack, f25));
+	DEFINE(IA64_SWITCH_STACK_F26_OFFSET, offsetof (struct switch_stack, f26));
+	DEFINE(IA64_SWITCH_STACK_F27_OFFSET, offsetof (struct switch_stack, f27));
+	DEFINE(IA64_SWITCH_STACK_F28_OFFSET, offsetof (struct switch_stack, f28));
+	DEFINE(IA64_SWITCH_STACK_F29_OFFSET, offsetof (struct switch_stack, f29));
+	DEFINE(IA64_SWITCH_STACK_F30_OFFSET, offsetof (struct switch_stack, f30));
+	DEFINE(IA64_SWITCH_STACK_F31_OFFSET, offsetof (struct switch_stack, f31));
+	DEFINE(IA64_SWITCH_STACK_R4_OFFSET, offsetof (struct switch_stack, r4));
+	DEFINE(IA64_SWITCH_STACK_R5_OFFSET, offsetof (struct switch_stack, r5));
+	DEFINE(IA64_SWITCH_STACK_R6_OFFSET, offsetof (struct switch_stack, r6));
+	DEFINE(IA64_SWITCH_STACK_R7_OFFSET, offsetof (struct switch_stack, r7));
+	DEFINE(IA64_SWITCH_STACK_B0_OFFSET, offsetof (struct switch_stack, b0));
+	DEFINE(IA64_SWITCH_STACK_B1_OFFSET, offsetof (struct switch_stack, b1));
+	DEFINE(IA64_SWITCH_STACK_B2_OFFSET, offsetof (struct switch_stack, b2));
+	DEFINE(IA64_SWITCH_STACK_B3_OFFSET, offsetof (struct switch_stack, b3));
+	DEFINE(IA64_SWITCH_STACK_B4_OFFSET, offsetof (struct switch_stack, b4));
+	DEFINE(IA64_SWITCH_STACK_B5_OFFSET, offsetof (struct switch_stack, b5));
+	DEFINE(IA64_SWITCH_STACK_AR_PFS_OFFSET, offsetof (struct switch_stack, ar_pfs));
+	DEFINE(IA64_SWITCH_STACK_AR_LC_OFFSET, offsetof (struct switch_stack, ar_lc));
+	DEFINE(IA64_SWITCH_STACK_AR_UNAT_OFFSET, offsetof (struct switch_stack, ar_unat));
+	DEFINE(IA64_SWITCH_STACK_AR_RNAT_OFFSET, offsetof (struct switch_stack, ar_rnat));
+	DEFINE(IA64_SWITCH_STACK_AR_BSPSTORE_OFFSET, offsetof (struct switch_stack, ar_bspstore));
+	DEFINE(IA64_SWITCH_STACK_PR_OFFSET, offsetof (struct switch_stack, pr));
+
+	BLANK();
+
+	DEFINE(IA64_SIGCONTEXT_IP_OFFSET, offsetof (struct sigcontext, sc_ip));
+	DEFINE(IA64_SIGCONTEXT_AR_BSP_OFFSET, offsetof (struct sigcontext, sc_ar_bsp));
+	DEFINE(IA64_SIGCONTEXT_AR_FPSR_OFFSET, offsetof (struct sigcontext, sc_ar_fpsr));
+	DEFINE(IA64_SIGCONTEXT_AR_RNAT_OFFSET, offsetof (struct sigcontext, sc_ar_rnat));
+	DEFINE(IA64_SIGCONTEXT_AR_UNAT_OFFSET, offsetof (struct sigcontext, sc_ar_unat));
+	DEFINE(IA64_SIGCONTEXT_B0_OFFSET, offsetof (struct sigcontext, sc_br[0]));
+	DEFINE(IA64_SIGCONTEXT_CFM_OFFSET, offsetof (struct sigcontext, sc_cfm));
+	DEFINE(IA64_SIGCONTEXT_FLAGS_OFFSET, offsetof (struct sigcontext, sc_flags));
+	DEFINE(IA64_SIGCONTEXT_FR6_OFFSET, offsetof (struct sigcontext, sc_fr[6]));
+	DEFINE(IA64_SIGCONTEXT_PR_OFFSET, offsetof (struct sigcontext, sc_pr));
+	DEFINE(IA64_SIGCONTEXT_R12_OFFSET, offsetof (struct sigcontext, sc_gr[12]));
+	DEFINE(IA64_SIGCONTEXT_RBS_BASE_OFFSET,offsetof (struct sigcontext, sc_rbs_base));
+	DEFINE(IA64_SIGCONTEXT_LOADRS_OFFSET, offsetof (struct sigcontext, sc_loadrs));
+
+	BLANK();
+
+	DEFINE(IA64_SIGFRAME_ARG0_OFFSET, offsetof (struct sigframe, arg0));
+	DEFINE(IA64_SIGFRAME_ARG1_OFFSET, offsetof (struct sigframe, arg1));
+	DEFINE(IA64_SIGFRAME_ARG2_OFFSET, offsetof (struct sigframe, arg2));
+	DEFINE(IA64_SIGFRAME_HANDLER_OFFSET, offsetof (struct sigframe, handler));
+	DEFINE(IA64_SIGFRAME_SIGCONTEXT_OFFSET, offsetof (struct sigframe, sc));
+	BLANK();
+    /* for assembly files which can't include sched.h: */
+	DEFINE(IA64_CLONE_VFORK, CLONE_VFORK);
+	DEFINE(IA64_CLONE_VM, CLONE_VM);
+
+	BLANK();
+    /* used by fsys_gettimeofday in arch/ia64/kernel/fsys.S */
+	DEFINE(IA64_CPUINFO_ITM_DELTA_OFFSET, offsetof (struct cpuinfo_ia64, itm_delta));
+	DEFINE(IA64_CPUINFO_ITM_NEXT_OFFSET, offsetof (struct cpuinfo_ia64, itm_next));
+	DEFINE(IA64_CPUINFO_NSEC_PER_CYC_OFFSET, offsetof (struct cpuinfo_ia64, nsec_per_cyc));
+	DEFINE(IA64_TIMESPEC_TV_NSEC_OFFSET, offsetof (struct timespec, tv_nsec));
+
+
+	DEFINE(CLONE_IDLETASK_BIT, 12);
+#if CLONE_IDLETASK != (1 << 12)
+# error "CLONE_IDLETASK_BIT incorrect, please fix"
+#endif
+
+	DEFINE(CLONE_SETTLS_BIT, 19);
+#if CLONE_SETTLS != (1<<19)
+# error "CLONE_SETTLS_BIT incorrect, please fix"
+#endif
+
+}
diff -Nru a/arch/ia64/kernel/efi_stub.S b/arch/ia64/kernel/efi_stub.S
--- a/arch/ia64/kernel/efi_stub.S	Wed Jun 18 23:42:05 2003
+++ b/arch/ia64/kernel/efi_stub.S	Wed Jun 18 23:42:05 2003
@@ -62,7 +62,7 @@
 	mov b6=r2
 	;;
 	andcm r16=loc3,r16		// get psr with IT, DT, and RT bits cleared
-	br.call.sptk.many rp=ia64_switch_mode
+	br.call.sptk.many rp=ia64_switch_mode_phys
 .ret0:	mov out4=in5
 	mov out0=in1
 	mov out1=in2
@@ -73,7 +73,7 @@
 	br.call.sptk.many rp=b6		// call the EFI function
 .ret1:	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
 	mov r16=loc3
-	br.call.sptk.many rp=ia64_switch_mode // return to virtual mode
+	br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
 .ret2:	mov ar.rsc=loc4			// restore RSE configuration
 	mov ar.pfs=loc1
 	mov rp=loc0
diff -Nru a/arch/ia64/kernel/entry.S b/arch/ia64/kernel/entry.S
--- a/arch/ia64/kernel/entry.S	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/kernel/entry.S	Wed Jun 18 23:42:06 2003
@@ -5,10 +5,13 @@
  *
  * Copyright (C) 1998-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999, 2002-2003
+ *	Asit Mallick <Asit.K.Mallick@intel.com>
+ * 	Don Dugger <Don.Dugger@intel.com>
+ *	Suresh Siddha <suresh.b.siddha@intel.com>
+ *	Fenghua Yu <fenghua.yu@intel.com>
  * Copyright (C) 1999 VA Linux Systems
  * Copyright (C) 1999 Walt Drummond <drummond@valinux.com>
- * Copyright (C) 1999 Asit Mallick <Asit.K.Mallick@intel.com>
- * Copyright (C) 1999 Don Dugger <Don.Dugger@intel.com>
  */
 /*
  * ia64_switch_to now places correct virtual mapping in in TR2 for
@@ -74,19 +77,18 @@
 	 * this executes in less than 20 cycles even on Itanium, so it's not worth
 	 * optimizing for...).
 	 */
+	mov ar.unat=0; 		mov ar.lc=0
 	mov r4=0;		mov f2=f0;		mov b1=r0
 	mov r5=0;		mov f3=f0;		mov b2=r0
 	mov r6=0;		mov f4=f0;		mov b3=r0
 	mov r7=0;		mov f5=f0;		mov b4=r0
-	mov ar.unat=0;		mov f10=f0;		mov b5=r0
-	ldf.fill f11=[sp];	ldf.fill f12=[sp];	mov f13=f0
+	ldf.fill f12=[sp];	mov f13=f0;		mov b5=r0
 	ldf.fill f14=[sp];	ldf.fill f15=[sp];	mov f16=f0
 	ldf.fill f17=[sp];	ldf.fill f18=[sp];	mov f19=f0
 	ldf.fill f20=[sp];	ldf.fill f21=[sp];	mov f22=f0
 	ldf.fill f23=[sp];	ldf.fill f24=[sp];	mov f25=f0
 	ldf.fill f26=[sp];	ldf.fill f27=[sp];	mov f28=f0
 	ldf.fill f29=[sp];	ldf.fill f30=[sp];	mov f31=f0
-	mov ar.lc=0
 	br.ret.sptk.many rp
 END(ia64_execve)
 
@@ -114,14 +116,8 @@
 	br.call.sptk.many rp=do_fork
 .ret1:	.restore sp
 	adds sp=IA64_SWITCH_STACK_SIZE,sp	// pop the switch stack
-	mov r2=-1000
-	adds r3=IA64_TASK_PID_OFFSET,r8
-	;;
-	cmp.leu p6,p0=r8,r2
 	mov ar.pfs=loc1
 	mov rp=loc0
-	;;
-(p6)	ld4 r8=[r3]
 	br.ret.sptk.many rp
 END(sys_clone2)
 
@@ -149,14 +145,8 @@
 	br.call.sptk.many rp=do_fork
 .ret2:	.restore sp
 	adds sp=IA64_SWITCH_STACK_SIZE,sp	// pop the switch stack
-	mov r2=-1000
-	adds r3=IA64_TASK_PID_OFFSET,r8
-	;;
-	cmp.leu p6,p0=r8,r2
 	mov ar.pfs=loc1
 	mov rp=loc0
-	;;
-(p6)	ld4 r8=[r3]
 	br.ret.sptk.many rp
 END(sys_clone)
 
@@ -178,15 +168,12 @@
 	;;
 	st8 [r22]=sp			// save kernel stack pointer of old task
 	shr.u r26=r20,IA64_GRANULE_SHIFT
-	shr.u r17=r20,KERNEL_TR_PAGE_SHIFT
-	;;
-	cmp.ne p6,p7=KERNEL_TR_PAGE_NUM,r17
 	adds r21=IA64_TASK_THREAD_KSP_OFFSET,in0
 	;;
 	/*
 	 * If we've already mapped this task's page, we can skip doing it again.
 	 */
-(p6)	cmp.eq p7,p6=r26,r27
+	cmp.eq p7,p6=r26,r27
 (p6)	br.cond.dpnt .map
 	;;
 .done:
@@ -224,14 +211,12 @@
 END(ia64_switch_to)
 
 /*
- * Note that interrupts are enabled during save_switch_stack and
- * load_switch_stack.  This means that we may get an interrupt with
- * "sp" pointing to the new kernel stack while ar.bspstore is still
- * pointing to the old kernel backing store area.  Since ar.rsc,
- * ar.rnat, ar.bsp, and ar.bspstore are all preserved by interrupts,
- * this is not a problem.  Also, we don't need to specify unwind
- * information for preserved registers that are not modified in
- * save_switch_stack as the right unwind information is already
+ * Note that interrupts are enabled during save_switch_stack and load_switch_stack.  This
+ * means that we may get an interrupt with "sp" pointing to the new kernel stack while
+ * ar.bspstore is still pointing to the old kernel backing store area.  Since ar.rsc,
+ * ar.rnat, ar.bsp, and ar.bspstore are all preserved by interrupts, this is not a
+ * problem.  Also, we don't need to specify unwind information for preserved registers
+ * that are not modified in save_switch_stack as the right unwind information is already
  * specified at the call-site of save_switch_stack.
  */
 
@@ -305,8 +290,6 @@
 	st8 [r14]=r21,SW(B1)-SW(B0)		// save b0
 	st8 [r15]=r23,SW(B3)-SW(B2)		// save b2
 	mov r25=b4
-	stf.spill [r2]=f10,32
-	stf.spill [r3]=f11,32
 	mov r26=b5
 	;;
 	st8 [r14]=r22,SW(B4)-SW(B1)		// save b1
@@ -405,9 +388,6 @@
 	ldf.fill f4=[r14],32
 	ldf.fill f5=[r15],32
 	;;
-	ldf.fill f10=[r14],32
-	ldf.fill f11=[r15],32
-	;;
 	ldf.fill f12=[r14],32
 	ldf.fill f13=[r15],32
 	;;
@@ -525,11 +505,11 @@
 (p6)	br.cond.sptk strace_error		// syscall failed ->
 	;;					// avoid RAW on r10
 strace_save_retval:
-.mem.offset 0,0;	st8.spill [r2]=r8	// store return value in slot for r8
-.mem.offset 8,0;	st8.spill [r3]=r10	// clear error indication in slot for r10
+.mem.offset 0,0; st8.spill [r2]=r8		// store return value in slot for r8
+.mem.offset 8,0; st8.spill [r3]=r10		// clear error indication in slot for r10
 ia64_strace_leave_kernel:
 	br.call.sptk.many rp=invoke_syscall_trace // give parent a chance to catch return value
-.rety:	br.cond.sptk ia64_leave_kernel
+.rety:	br.cond.sptk ia64_leave_syscall
 
 strace_error:
 	ld8 r3=[r2]				// load pt_regs.r8
@@ -575,129 +555,288 @@
 	adds r2=PT(R8)+16,sp			// r2 = &pt_regs.r8
 	adds r3=PT(R10)+16,sp			// r3 = &pt_regs.r10
 	;;
-	.mem.offset 0,0
-(p6)	st8.spill [r2]=r8	// store return value in slot for r8 and set unat bit
-	.mem.offset 8,0
-(p6)	st8.spill [r3]=r0	// clear error indication in slot for r10 and set unat bit
+.mem.offset 0,0; (p6) st8.spill [r2]=r8	// store return value in slot for r8 and set unat bit
+.mem.offset 8,0; (p6) st8.spill [r3]=r0	// clear error indication in slot for r10 and set unat bit
 (p7)	br.cond.spnt handle_syscall_error	// handle potential syscall failure
 END(ia64_ret_from_syscall)
 	// fall through
-GLOBAL_ENTRY(ia64_leave_kernel)
+/*
+ * ia64_leave_syscall(): Same as ia64_leave_kernel, except that it doesn't
+ *	need to switch to bank 0 and doesn't restore the scratch registers.
+ *	To avoid leaking kernel bits, the scratch registers are set to
+ *	the following known-to-be-safe values:
+ *
+ *		  r1: restored (global pointer)
+ *		  r2: cleared
+ *		  r3: 1 (when returning to user-level)
+ *	      r8-r11: restored (syscall return value(s))
+ *		 r12: restored (user-level stack pointer)
+ *		 r13: restored (user-level thread pointer)
+ *		 r14: cleared
+ *		 r15: restored (syscall #)
+ *	     r16-r19: cleared
+ *		 r20: user-level ar.fpsr
+ *		 r21: user-level b0
+ *		 r22: user-level b6
+ *		 r23: user-level ar.bspstore
+ *		 r24: user-level ar.rnat
+ *		 r25: user-level ar.unat
+ *		 r26: user-level ar.pfs
+ *		 r27: user-level ar.rsc
+ *		 r28: user-level ip
+ *		 r29: user-level psr
+ *		 r30: user-level cfm
+ *		 r31: user-level pr
+ *	      f6-f11: cleared
+ *		  pr: restored (user-level pr)
+ *		  b0: restored (user-level rp)
+ *	          b6: restored
+ *		  b7: cleared
+ *	     ar.unat: restored (user-level ar.unat)
+ *	      ar.pfs: restored (user-level ar.pfs)
+ *	      ar.rsc: restored (user-level ar.rsc)
+ *	     ar.rnat: restored (user-level ar.rnat)
+ *	 ar.bspstore: restored (user-level ar.bspstore)
+ *	     ar.fpsr: restored (user-level ar.fpsr)
+ *	      ar.ccv: cleared
+ *	      ar.csd: cleared
+ *	      ar.ssd: cleared
+ */
+GLOBAL_ENTRY(ia64_leave_syscall)
 	PT_REGS_UNWIND_INFO(0)
-	// work.need_resched etc. mustn't get changed by this CPU before it returns to
-	// user- or fsys-mode:
-(pUStk)	cmp.eq.unc p6,p0=r0,r0			// p6 <- pUStk
+	/*
+	 * work.need_resched etc. mustn't get changed by this CPU before it returns to
+	 * user- or fsys-mode, hence we disable interrupts early on:
+	 */
 #ifdef CONFIG_PREEMPT
 	rsm psr.i				// disable interrupts
-	adds r17=TI_FLAGS+IA64_TASK_SIZE,r13
+#else
+(pUStk)	rsm psr.i
+#endif
+	cmp.eq pLvSys,p0=r0,r0			// pLvSys=1: leave from syscall
+(pUStk)	cmp.eq.unc p6,p0=r0,r0			// p6 <- pUStk
+.work_processed_syscall:
+#ifdef CONFIG_PREEMPT
 (pKStk) adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
 	;;
-(pKStk) ld4  r21=[r20]			// preempt_count ->r21
+	.pred.rel.mutex pUStk,pKStk
+(pKStk) ld4 r21=[r20]			// r21 <- preempt_count
+(pUStk)	mov r21=0			// r21 <- 0
+	;;
+(p6)	cmp.eq.unc p6,p0=r21,r0		// p6 <- p6 && (r21 == 0)
+#endif /* CONFIG_PREEMPT */
+	adds r16=PT(LOADRS)+16,r12
+	adds r17=PT(AR_BSPSTORE)+16,r12
+	adds r18=TI_FLAGS+IA64_TASK_SIZE,r13
+	;;
+(p6)	ld4 r31=[r18]				// load current_thread_info()->flags
+	ld8 r19=[r16],PT(B6)-PT(LOADRS)		// load ar.rsc value for "loadrs"
+	nop.i 0
+	;;
+	ld8 r23=[r17],PT(R9)-PT(AR_BSPSTORE)	// load ar.bspstore (may be garbage)
+	ld8 r22=[r16],PT(R8)-PT(B6)		// load b6
+(p6)	and r15=TIF_WORK_MASK,r31		// any work other than TIF_SYSCALL_TRACE?
 	;;
-(pKStk)	cmp4.eq	p6,p0=r21,r0		// p6 <- preempt_count == 0
+
+	mov.m ar.ccv=r0		// clear ar.ccv
+(p6)	cmp4.ne.unc p6,p0=r15, r0		// any special work pending?
+(p6)	br.cond.spnt .work_pending
+	;;
+	// start restoring the state saved on the kernel stack (struct pt_regs):
+	ld8.fill r8=[r16],16
+	ld8.fill r9=[r17],16
+	mov f6=f0		// clear f6
+	;;
+	ld8.fill r10=[r16],16
+	ld8.fill r11=[r17],16
+	mov f7=f0		// clear f7
+	;;
+	ld8 r29=[r16],16	// load cr.ipsr
+	ld8 r28=[r17],16	// load cr.iip
+	mov f8=f0		// clear f8
 	;;
-#else /* CONFIG_PREEMPT */
+	ld8 r30=[r16],16	// load cr.ifs
+	ld8 r25=[r17],16	// load ar.unat
+	cmp.eq p9,p0=r0,r0	// set p9 to indicate that we should restore cr.ifs
+	;;
+	rsm psr.i | psr.ic	// initiate turning off of interrupt and interruption collection
+	invala			// invalidate ALAT
+	mov f9=f0		// clear f9
+
+	mov.m ar.ssd=r0		// clear ar.ssd
+	mov.m ar.csd=r0		// clear ar.csd
+	mov f10=f0		// clear f10
+	;;
+	ld8 r26=[r16],16	// load ar.pfs
+	ld8 r27=[r17],PT(PR)-PT(AR_RSC)	// load ar.rsc
+	mov f11=f0		// clear f11
+	;;
+	ld8 r24=[r16],PT(B0)-PT(AR_RNAT)	// load ar.rnat (may be garbage)
+	ld8 r31=[r17],PT(R1)-PT(PR)		// load predicates
+(pUStk) add r14=IA64_TASK_THREAD_ON_USTACK_OFFSET,r13
+	;;
+	ld8 r21=[r16],PT(R12)-PT(B0) // load b0
+	ld8.fill r1=[r17],16	// load r1
+(pUStk) mov r3=1
+	;;
+	ld8.fill r12=[r16],16
+	ld8.fill r13=[r17],16
+	mov r2=r0		// clear r2
+	;;
+	ld8 r20=[r16]		// load ar.fpsr
+	ld8.fill r15=[r17]	// load r15
+	mov b7=r0		// clear b7
+	;;
+(pUStk) st1 [r14]=r3
+	movl r17=THIS_CPU(ia64_phys_stacked_size_p8)
+	;;
+	mov r16=ar.bsp		// get existing backing store pointer
+	srlz.i			// ensure interruption collection is off
+	mov r14=r0		// clear r14
+	;;
+	ld4 r17=[r17]		// r17 = cpu_data->phys_stacked_size_p8
+	mov b6=r22				// restore b6
+	shr.u r18=r19,16	// get byte size of existing "dirty" partition
+(pKStk) br.cond.dpnt.many skip_rbs_switch
+	br.cond.sptk.many rbs_switch
+END(ia64_leave_syscall)
+
+GLOBAL_ENTRY(ia64_leave_kernel)
+	PT_REGS_UNWIND_INFO(0)
+	/*
+	 * work.need_resched etc. mustn't get changed by this CPU before it returns to
+	 * user- or fsys-mode, hence we disable interrupts early on:
+	 */
+#ifdef CONFIG_PREEMPT
+	rsm psr.i				// disable interrupts
+#else
 (pUStk)	rsm psr.i
+#endif
+	cmp.eq p0,pLvSys=r0,r0			// pLvSys=0: leave from kernel
+(pUStk)	cmp.eq.unc p6,p0=r0,r0			// p6 <- pUStk
 	;;
-(pUStk)	adds r17=TI_FLAGS+IA64_TASK_SIZE,r13
+.work_processed_kernel:
+#ifdef CONFIG_PREEMPT
+	adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
+	;;
+	.pred.rel.mutex pUStk,pKStk
+(pKStk)	ld4 r21=[r20]			// r21 <- preempt_count
+(pUStk)	mov r21=0			// r21 <- 0
 	;;
+(p6)	cmp.eq.unc p6,p0=r21,r0		// p6 <- p6 && (r21 == 0)
 #endif /* CONFIG_PREEMPT */
-.work_processed:
-(p6)	ld4 r18=[r17]				// load current_thread_info()->flags
-	adds r2=PT(R8)+16,r12
-	adds r3=PT(R9)+16,r12
+	adds r17=TI_FLAGS+IA64_TASK_SIZE,r13
 	;;
-	// start restoring the state saved on the kernel stack (struct pt_regs):
-	ld8.fill r8=[r2],16
-	ld8.fill r9=[r3],16
-(p6)	and r19=TIF_WORK_MASK,r18		// any work other than TIF_SYSCALL_TRACE?
+(p6)	ld4 r31=[r17]				// load current_thread_info()->flags
+	adds r21=PT(PR)+16,r12
+	;;
+
+	lfetch [r21],PT(CR_IPSR)-PT(PR)
+	adds r2=PT(B6)+16,r12
+	adds r3=PT(R16)+16,r12
 	;;
-	ld8.fill r10=[r2],16
-	ld8.fill r11=[r3],16
+	lfetch [r21]
+	ld8 r28=[r2],8		// load b6
+	adds r29=PT(R24)+16,r12
+
+	ld8.fill r16=[r3],PT(AR_CSD)-PT(R16)
+	adds r30=PT(AR_CCV)+16,r12
+(p6)	and r19=TIF_WORK_MASK,r31		// any work other than TIF_SYSCALL_TRACE?
+	;;
+	ld8.fill r24=[r29]
+	ld8 r15=[r30]		// load ar.ccv
 (p6)	cmp4.ne.unc p6,p0=r19, r0		// any special work pending?
 	;;
-	ld8.fill r16=[r2],16
-	ld8.fill r17=[r3],16
+	ld8 r29=[r2],16		// load b7
+	ld8 r30=[r3],16		// load ar.csd
 (p6)	br.cond.spnt .work_pending
 	;;
+	ld8 r31=[r2],16		// load ar.ssd
+	ld8.fill r8=[r3],16
+	;;
+	ld8.fill r9=[r2],16
+	ld8.fill r10=[r3],PT(R17)-PT(R10)
+	;;
+	ld8.fill r11=[r2],PT(R18)-PT(R11)
+	ld8.fill r17=[r3],16
+	;;
 	ld8.fill r18=[r2],16
 	ld8.fill r19=[r3],16
 	;;
 	ld8.fill r20=[r2],16
 	ld8.fill r21=[r3],16
+	mov ar.csd=r30
+	mov ar.ssd=r31
 	;;
-	ld8.fill r22=[r2],16
-	ld8.fill r23=[r3],16
-	;;
-	ld8.fill r24=[r2],16
-	ld8.fill r25=[r3],16
-	;;
-	ld8.fill r26=[r2],16
-	ld8.fill r27=[r3],16
+	rsm psr.i | psr.ic	// initiate turning off of interrupt and interruption collection
+	invala			// invalidate ALAT
 	;;
-	ld8.fill r28=[r2],16
-	ld8.fill r29=[r3],16
+	ld8.fill r22=[r2],24
+	ld8.fill r23=[r3],24
+	mov b6=r28
 	;;
-	ld8.fill r30=[r2],16
-	ld8.fill r31=[r3],16
+	ld8.fill r25=[r2],16
+	ld8.fill r26=[r3],16
+	mov b7=r29
 	;;
-	rsm psr.i | psr.ic	// initiate turning off of interrupt and interruption collection
-	invala			// invalidate ALAT
+	ld8.fill r27=[r2],16
+	ld8.fill r28=[r3],16
 	;;
-	ld8 r1=[r2],16		// ar.ccv
-	ld8 r13=[r3],16		// ar.fpsr
+	ld8.fill r29=[r2],16
+	ld8.fill r30=[r3],24
 	;;
-	ld8 r14=[r2],16		// b0
-	ld8 r15=[r3],16+8	// b7
+	ld8.fill r31=[r2],PT(F9)-PT(R31)
+	adds r3=PT(F10)-PT(F6),r3
 	;;
-	ldf.fill f6=[r2],32
-	ldf.fill f7=[r3],32
+	ldf.fill f9=[r2],PT(F6)-PT(F9)
+	ldf.fill f10=[r3],PT(F8)-PT(F10)
 	;;
-	ldf.fill f8=[r2],32
-	ldf.fill f9=[r3],32
+	ldf.fill f6=[r2],PT(F7)-PT(F6)
 	;;
-	mov ar.ccv=r1
-	mov ar.fpsr=r13
-	mov b0=r14
+	ldf.fill f7=[r2],PT(F11)-PT(F7)
+	ldf.fill f8=[r3],32
 	;;
 	srlz.i			// ensure interruption collection is off
-	mov b7=r15
+	mov ar.ccv=r15
+	;;
 	bsw.0			// switch back to bank 0 (no stop bit required beforehand...)
 	;;
+	ldf.fill f11=[r2]
 (pUStk)	mov r18=IA64_KR(CURRENT)	// Itanium 2: 12 cycle read latency
-	adds r16=16,r12
-	adds r17=24,r12
+	adds r16=PT(CR_IPSR)+16,r12
+	adds r17=PT(CR_IIP)+16,r12
 	;;
-	ld8 rCRIPSR=[r16],16	// load cr.ipsr
-	ld8 rCRIIP=[r17],16	// load cr.iip
+	ld8 r29=[r16],16	// load cr.ipsr
+	ld8 r28=[r17],16	// load cr.iip
 	;;
-	ld8 rCRIFS=[r16],16	// load cr.ifs
-	ld8 rARUNAT=[r17],16	// load ar.unat
-	cmp.eq p9,p0=r0,r0	// set p9 to indicate that we should restore cr.ifs
+	ld8 r30=[r16],16	// load cr.ifs
+	ld8 r25=[r17],16	// load ar.unat
 	;;
-	ld8 rARPFS=[r16],16	// load ar.pfs
-	ld8 rARRSC=[r17],16	// load ar.rsc
+	ld8 r26=[r16],16	// load ar.pfs
+	ld8 r27=[r17],16	// load ar.rsc
+	cmp.eq p9,p0=r0,r0	// set p9 to indicate that we should restore cr.ifs
 	;;
-	ld8 rARRNAT=[r16],16	// load ar.rnat (may be garbage)
-	ld8 rARBSPSTORE=[r17],16 // load ar.bspstore (may be garbage)
+	ld8 r24=[r16],16	// load ar.rnat (may be garbage)
+	ld8 r23=[r17],16// load ar.bspstore (may be garbage)
 	;;
-	ld8 rARPR=[r16],16	// load predicates
-	ld8 rB6=[r17],16	// load b6
+	ld8 r31=[r16],16	// load predicates
+	ld8 r21=[r17],16	// load b0
 	;;
 	ld8 r19=[r16],16	// load ar.rsc value for "loadrs"
 	ld8.fill r1=[r17],16	// load r1
 	;;
-	ld8.fill r2=[r16],16
-	ld8.fill r3=[r17],16
-	;;
 	ld8.fill r12=[r16],16
 	ld8.fill r13=[r17],16
 (pUStk)	adds r18=IA64_TASK_THREAD_ON_USTACK_OFFSET,r18
 	;;
-	ld8.fill r14=[r16]
-	ld8.fill r15=[r17]
+	ld8 r20=[r16],16	// ar.fpsr
+	ld8.fill r15=[r17],16
+	;;
+	ld8.fill r14=[r16],16
+	ld8.fill r2=[r17]
 (pUStk)	mov r17=1
 	;;
+	ld8.fill r3=[r16]
 (pUStk)	st1 [r18]=r17		// restore current->thread.on_ustack
 	shr.u r18=r19,16	// get byte size of existing "dirty" partition
 	;;
@@ -713,6 +852,8 @@
 	 * NOTE: alloc, loadrs, and cover can't be predicated.
 	 */
 (pNonSys) br.cond.dpnt dont_preserve_current_frame
+
+rbs_switch:
 	cover				// add current frame into dirty partition and set cr.ifs
 	;;
 	mov r19=ar.bsp			// get new backing store pointer
@@ -765,7 +906,7 @@
 }{ .mib
 	mov loc3=0
 	mov loc4=0
-(pRecurse) br.call.sptk.many b6=rse_clear_invalid
+(pRecurse) br.call.sptk.many b0=rse_clear_invalid
 
 }{ .mfi	// cycle 2
 	mov loc5=0
@@ -774,7 +915,7 @@
 }{ .mib
 	mov loc6=0
 	mov loc7=0
-(pReturn) br.ret.sptk.many b6
+(pReturn) br.ret.sptk.many b0
 }
 #else /* !CONFIG_ITANIUM */
 	alloc loc0=ar.pfs,2,Nregs-2,2,0
@@ -789,14 +930,14 @@
 	mov loc5=0
 	mov loc6=0
 	mov loc7=0
-(pRecurse) br.call.sptk.many b6=rse_clear_invalid
+(pRecurse) br.call.sptk.few b0=rse_clear_invalid
 	;;
 	mov loc8=0
 	mov loc9=0
 	cmp.ne pReturn,p0=r0,in1	// if recursion count != 0, we need to do a br.ret
 	mov loc10=0
 	mov loc11=0
-(pReturn) br.ret.sptk.many b6
+(pReturn) br.ret.sptk.many b0
 #endif /* !CONFIG_ITANIUM */
 #	undef pRecurse
 #	undef pReturn
@@ -806,59 +947,65 @@
 	loadrs
 	;;
 skip_rbs_switch:
-	mov b6=rB6
-	mov ar.pfs=rARPFS
-(pUStk)	mov ar.bspstore=rARBSPSTORE
-(p9)	mov cr.ifs=rCRIFS
-	mov cr.ipsr=rCRIPSR
-	mov cr.iip=rCRIIP
-	;;
-(pUStk)	mov ar.rnat=rARRNAT	// must happen with RSE in lazy mode
-	mov ar.rsc=rARRSC
-	mov ar.unat=rARUNAT
-	mov pr=rARPR,-1
+(pLvSys)	mov r19=r0		// clear r19 for leave_syscall, no-op otherwise
+	mov b0=r21
+	mov ar.pfs=r26
+(pUStk)	mov ar.bspstore=r23
+(p9)	mov cr.ifs=r30
+(pLvSys)mov r16=r0		// clear r16 for leave_syscall, no-op otherwise
+	mov cr.ipsr=r29
+	mov ar.fpsr=r20
+(pLvSys)mov r17=r0		// clear r17 for leave_syscall, no-op otherwise
+	mov cr.iip=r28
+	;;
+(pUStk)	mov ar.rnat=r24		// must happen with RSE in lazy mode
+(pLvSys)mov r18=r0		// clear r18 for leave_syscall, no-op otherwise
+	mov ar.rsc=r27
+	mov ar.unat=r25
+	mov pr=r31,-1
 	rfi
 
+	/*
+	 * On entry:
+	 *	r20 = &current->thread_info->pre_count (if CONFIG_PREEMPT)
+	 *	r31 = current->thread_info->flags
+	 * On exit:
+	 *	p6 = TRUE if work-pending-check needs to be redone
+	 */
 .work_pending:
-	tbit.z p6,p0=r18,TIF_NEED_RESCHED		// current_thread_info()->need_resched==0?
+	tbit.z p6,p0=r31,TIF_NEED_RESCHED		// current_thread_info()->need_resched==0?
 (p6)	br.cond.sptk.few .notify
 #ifdef CONFIG_PREEMPT
-(pKStk)	dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1
+(pKStk) dep r21=-1,r0,PREEMPT_ACTIVE_BIT,1
 	;;
 (pKStk) st4 [r20]=r21
-	ssm  psr.i		// enable interrupts
+	ssm psr.i		// enable interrupts
 #endif
-
-#if __GNUC__ < 3
-	br.call.spnt.many rp=invoke_schedule
-#else
 	br.call.spnt.many rp=schedule
-#endif
 .ret9:	cmp.eq p6,p0=r0,r0				// p6 <- 1
 	rsm psr.i		// disable interrupts
 	;;
-	adds r17=TI_FLAGS+IA64_TASK_SIZE,r13
 #ifdef CONFIG_PREEMPT
 (pKStk)	adds r20=TI_PRE_COUNT+IA64_TASK_SIZE,r13
 	;;
 (pKStk)	st4 [r20]=r0		// preempt_count() <- 0
 #endif
-	br.cond.sptk.many .work_processed		// re-check
+(pLvSys)br.cond.sptk.many .work_processed_syscall	// re-check
+	br.cond.sptk.many .work_processed_kernel	// re-check
 
 .notify:
 	br.call.spnt.many rp=notify_resume_user
 .ret10:	cmp.ne p6,p0=r0,r0				// p6 <- 0
-	br.cond.sptk.many .work_processed		// don't re-check
+(pLvSys)br.cond.sptk.many .work_processed_syscall	// don't re-check
+	br.cond.sptk.many .work_processed_kernel	// don't re-check
 END(ia64_leave_kernel)
 
 ENTRY(handle_syscall_error)
 	/*
-	 * Some system calls (e.g., ptrace, mmap) can return arbitrary
-	 * values which could lead us to mistake a negative return
-	 * value as a failed syscall.  Those syscall must deposit
-	 * a non-zero value in pt_regs.r8 to indicate an error.
-	 * If pt_regs.r8 is zero, we assume that the call completed
-	 * successfully.
+	 * Some system calls (e.g., ptrace, mmap) can return arbitrary values which could
+	 * lead us to mistake a negative return value as a failed syscall.  Those syscall
+	 * must deposit a non-zero value in pt_regs.r8 to indicate an error.  If
+	 * pt_regs.r8 is zero, we assume that the call completed successfully.
 	 */
 	PT_REGS_UNWIND_INFO(0)
 	ld8 r3=[r2]		// load pt_regs.r8
@@ -873,7 +1020,7 @@
 	;;
 .mem.offset 0,0; st8.spill [r2]=r9	// store errno in pt_regs.r8 and set unat bit
 .mem.offset 8,0; st8.spill [r3]=r10	// store error indication in pt_regs.r10 and set unat bit
-	br.cond.sptk ia64_leave_kernel
+	br.cond.sptk ia64_leave_syscall
 END(handle_syscall_error)
 
 	/*
@@ -892,31 +1039,6 @@
 	br.ret.sptk.many rp
 END(ia64_invoke_schedule_tail)
 
-#if __GNUC__ < 3
-
-	/*
-	 * Invoke schedule() while preserving in0-in7, which may be needed
-	 * in case a system call gets restarted.  Note that declaring schedule()
-	 * with asmlinkage() is NOT enough because that will only preserve as many
-	 * registers as there are formal arguments.
-	 *
-	 * XXX fix me: with gcc 3.0, we won't need this anymore because syscall_linkage
-	 *	renders all eight input registers (in0-in7) as "untouchable".
-	 */
-ENTRY(invoke_schedule)
-	.prologue ASM_UNW_PRLG_RP|ASM_UNW_PRLG_PFS, ASM_UNW_PRLG_GRSAVE(8)
-	alloc loc1=ar.pfs,8,2,0,0
-	mov loc0=rp
-	;;
-	.body
-	br.call.sptk.many rp=schedule
-.ret14:	mov ar.pfs=loc1
-	mov rp=loc0
-	br.ret.sptk.many rp
-END(invoke_schedule)
-
-#endif /* __GNUC__ < 3 */
-
 	/*
 	 * Setup stack and call do_notify_resume_user().  Note that pSys and pNonSys need to
 	 * be set up by the caller.  We declare 8 input registers so the system call
@@ -984,6 +1106,23 @@
 	.body
 	cmp.eq pNonSys,pSys=r0,r0		// sigreturn isn't a normal syscall...
 	;;
+	/*
+	 * leave_kernel() restores f6-f11 from pt_regs, but since the streamlined
+	 * syscall-entry path does not save them we save them here instead.  Note: we
+	 * don't need to save any other registers that are not saved by the stream-lined
+	 * syscall path, because restore_sigcontext() restores them.
+	 */
+	adds r16=PT(F6)+32,sp
+	adds r17=PT(F7)+32,sp
+	;;
+ 	stf.spill [r16]=f6,32
+ 	stf.spill [r17]=f7,32
+	;;
+ 	stf.spill [r16]=f8,32
+ 	stf.spill [r17]=f9,32
+	;;
+ 	stf.spill [r16]=f10
+ 	stf.spill [r17]=f11
 	adds out0=16,sp				// out0 = &sigscratch
 	br.call.sptk.many rp=ia64_rt_sigreturn
 .ret19:	.restore sp 0
@@ -1313,3 +1452,6 @@
 	data8 ia64_ni_syscall
 	data8 ia64_ni_syscall
 	data8 ia64_ni_syscall
+	data8 ia64_ni_syscall
+
+	.org sys_call_table + 8*NR_syscalls	// guard against failures to increase NR_syscalls
diff -Nru a/arch/ia64/kernel/entry.h b/arch/ia64/kernel/entry.h
--- a/arch/ia64/kernel/entry.h	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/kernel/entry.h	Wed Jun 18 23:42:07 2003
@@ -4,8 +4,9 @@
  * Preserved registers that are shared between code in ivt.S and entry.S.  Be
  * careful not to step on these!
  */
-#define pKStk		p2	/* will leave_kernel return to kernel-stacks? */
-#define pUStk		p3	/* will leave_kernel return to user-stacks? */
+#define pLvSys		p1	/* set 1 if leave from syscall; otherwise, set 0*/
+#define pKStk		p2	/* will leave_{kernel,syscall} return to kernel-stacks? */
+#define pUStk		p3	/* will leave_{kernel,syscall} return to user-stacks? */
 #define pSys		p4	/* are we processing a (synchronous) system call? */
 #define pNonSys		p5	/* complement of pSys */
 
@@ -13,6 +14,7 @@
 #define SW(f)		(IA64_SWITCH_STACK_##f##_OFFSET)
 
 #define PT_REGS_SAVES(off)			\
+	.unwabi 3, 'i';				\
 	.unwabi @svr4, 'i';			\
 	.fframe IA64_PT_REGS_SIZE+16+(off);	\
 	.spillsp rp, PT(CR_IIP)+16+(off);	\
diff -Nru a/arch/ia64/kernel/fsys.S b/arch/ia64/kernel/fsys.S
--- a/arch/ia64/kernel/fsys.S	Wed Jun 18 23:42:05 2003
+++ b/arch/ia64/kernel/fsys.S	Wed Jun 18 23:42:05 2003
@@ -14,6 +14,11 @@
 #include <asm/offsets.h>
 #include <asm/percpu.h>
 #include <asm/thread_info.h>
+#include <asm/sal.h>
+#include <asm/system.h>
+#include <asm/unistd.h>
+
+#include "entry.h"
 
 /*
  * See Documentation/ia64/fsys.txt for details on fsyscalls.
@@ -38,6 +43,9 @@
  */
 
 ENTRY(fsys_ni_syscall)
+	.prologue
+	.altrp b6
+	.body
 	mov r8=ENOSYS
 	mov r10=-1
 	MCKINLEY_E9_WORKAROUND
@@ -45,6 +53,9 @@
 END(fsys_ni_syscall)
 
 ENTRY(fsys_getpid)
+	.prologue
+	.altrp b6
+	.body
 	add r9=TI_FLAGS+IA64_TASK_SIZE,r16
 	;;
 	ld4 r9=[r9]
@@ -60,6 +71,9 @@
 END(fsys_getpid)
 
 ENTRY(fsys_getppid)
+	.prologue
+	.altrp b6
+	.body
 	add r17=IA64_TASK_GROUP_LEADER_OFFSET,r16
 	;;
 	ld8 r17=[r17]				// r17 = current->group_leader
@@ -105,6 +119,9 @@
 END(fsys_getppid)
 
 ENTRY(fsys_set_tid_address)
+	.prologue
+	.altrp b6
+	.body
 	add r9=TI_FLAGS+IA64_TASK_SIZE,r16
 	;;
 	ld4 r9=[r9]
@@ -142,23 +159,33 @@
  *	   we ought to either skip the ITC-based interpolation or run an ntp-like
  *	   daemon to keep the ITCs from drifting too far apart.
  */
+
 ENTRY(fsys_gettimeofday)
+	.prologue
+	.altrp b6
+	.body
 	add r9=TI_FLAGS+IA64_TASK_SIZE,r16
 	movl r3=THIS_CPU(cpu_info)
 
 	mov.m r31=ar.itc		// put time stamp into r31 (ITC) == now		(35 cyc)
-	movl r19=xtime			// xtime is a timespec struct
-	;;
-
 #ifdef CONFIG_SMP
 	movl r10=__per_cpu_offset
+	movl r2=sal_platform_features
 	;;
+
+	ld8 r2=[r2]
+	movl r19=xtime			// xtime is a timespec struct
+
 	ld8 r10=[r10]			// r10 <- __per_cpu_offset[0]
-	movl r21=cpu_info__per_cpu
+	movl r21=THIS_CPU(cpu_info)
 	;;
 	add r10=r21, r10		// r10 <- &cpu_data(time_keeper_id)
+	tbit.nz p8,p0 = r2, IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT_BIT
+(p8)	br.spnt.many fsys_fallback_syscall
 #else
+	;;
 	mov r10=r3
+	movl r19=xtime			// xtime is a timespec struct
 #endif
 	ld4 r9=[r9]
 	movl r17=xtime_lock
@@ -305,262 +332,374 @@
 	br.ret.spnt.many b6		// return with r8 set to EINVAL
 END(fsys_gettimeofday)
 
+ENTRY(fsys_fallback_syscall)
+	.prologue
+	.altrp b6
+	.body
+	/*
+	 * We only get here from light-weight syscall handlers.  Thus, we already
+	 * know that r15 contains a valid syscall number.  No need to re-check.
+	 */
+	adds r17=-1024,r15
+	movl r14=sys_call_table
+	;;
+	shladd r18=r17,3,r14
+	;;
+	ld8 r18=[r18]				// load normal (heavy-weight) syscall entry-point
+	mov r29=psr				// read psr (12 cyc load latency)
+	mov r27=ar.rsc
+	mov r21=ar.fpsr
+	mov r26=ar.pfs
+END(fsys_fallback_syscall)
+	/* FALL THROUGH */
+GLOBAL_ENTRY(fsys_bubble_down)
+	.prologue
+	.altrp b6
+	.body
+	/*
+	 * We get here for syscalls that don't have a lightweight handler.  For those, we
+	 * need to bubble down into the kernel and that requires setting up a minimal
+	 * pt_regs structure, and initializing the CPU state more or less as if an
+	 * interruption had occurred.  To make syscall-restarts work, we setup pt_regs
+	 * such that cr_iip points to the second instruction in syscall_via_break.
+	 * Decrementing the IP hence will restart the syscall via break and not
+	 * decrementing IP will return us to the caller, as usual.  Note that we preserve
+	 * the value of psr.pp rather than initializing it from dcr.pp.  This makes it
+	 * possible to distinguish fsyscall execution from other privileged execution.
+	 *
+	 * On entry:
+	 *	- normal fsyscall handler register usage, except that we also have:
+	 *	- r18: address of syscall entry point
+	 *	- r21: ar.fpsr
+	 *	- r26: ar.pfs
+	 *	- r27: ar.rsc
+	 *	- r29: psr
+	 */
+#	define PSR_PRESERVED_BITS	(IA64_PSR_UP | IA64_PSR_MFL | IA64_PSR_MFH | IA64_PSR_PK \
+					 | IA64_PSR_DT | IA64_PSR_PP | IA64_PSR_SP | IA64_PSR_RT \
+					 | IA64_PSR_IC)
+	/*
+	 * Reading psr.l gives us only bits 0-31, psr.it, and psr.mc.  The rest we have
+	 * to synthesize.
+	 */
+#	define PSR_ONE_BITS		((3 << IA64_PSR_CPL0_BIT) | (0x1 << IA64_PSR_RI_BIT) \
+					 | IA64_PSR_BN)
+
+	invala
+	movl r8=PSR_ONE_BITS
+
+	mov r25=ar.unat			// save ar.unat (5 cyc)
+	movl r9=PSR_PRESERVED_BITS
+
+	mov ar.rsc=0			// set enforced lazy mode, pl 0, little-endian, loadrs=0
+	movl r28=__kernel_syscall_via_break
+	;;
+	mov r23=ar.bspstore		// save ar.bspstore (12 cyc)
+	mov r31=pr			// save pr (2 cyc)
+	mov r20=r1			// save caller's gp in r20
+	;;
+	mov r2=r16			// copy current task addr to addl-addressable register
+	and r9=r9,r29
+	mov r19=b6			// save b6 (2 cyc)
+	;;
+	mov psr.l=r9			// slam the door (17 cyc to srlz.i)
+	or r29=r8,r29			// construct cr.ipsr value to save
+	addl r22=IA64_RBS_OFFSET,r2	// compute base of RBS
+	;;
+	mov.m r24=ar.rnat		// read ar.rnat (5 cyc lat)
+	lfetch.fault.excl.nt1 [r22]
+	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r2
+
+	// ensure previous insn group is issued before we stall for srlz.i:
+	;;
+	srlz.i				// ensure new psr.l has been established
+	/////////////////////////////////////////////////////////////////////////////
+	////////// from this point on, execution is not interruptible anymore
+	/////////////////////////////////////////////////////////////////////////////
+	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r2	// compute base of memory stack
+	cmp.ne pKStk,pUStk=r0,r0	// set pKStk <- 0, pUStk <- 1
+	;;
+	st1 [r16]=r0			// clear current->thread.on_ustack flag
+	mov ar.bspstore=r22		// switch to kernel RBS
+	mov b6=r18			// copy syscall entry-point to b6 (7 cyc)
+	add r3=TI_FLAGS+IA64_TASK_SIZE,r2
+	;;
+	ld4 r3=[r3]				// r2 = current_thread_info()->flags
+	mov r18=ar.bsp			// save (kernel) ar.bsp (12 cyc)
+	mov ar.rsc=0x3			// set eager mode, pl 0, little-endian, loadrs=0
+	br.call.sptk.many b7=ia64_syscall_setup
+	;;
+	ssm psr.i
+	movl r2=ia64_ret_from_syscall
+	;;
+	mov rp=r2				// set the real return addr
+	tbit.z p8,p0=r3,TIF_SYSCALL_TRACE
+
+(p8)	br.call.sptk.many b6=b6			// ignore this return addr
+	br.cond.sptk ia64_trace_syscall
+END(fsys_bubble_down)
+
 	.rodata
 	.align 8
 	.globl fsyscall_table
+
+	data8 fsys_bubble_down
 fsyscall_table:
 	data8 fsys_ni_syscall
-	data8 fsys_fallback_syscall	// exit			// 1025
-	data8 fsys_fallback_syscall	// read
-	data8 fsys_fallback_syscall	// write
-	data8 fsys_fallback_syscall	// open
-	data8 fsys_fallback_syscall	// close
-	data8 fsys_fallback_syscall	// creat		// 1030
-	data8 fsys_fallback_syscall	// link
-	data8 fsys_fallback_syscall	// unlink
-	data8 fsys_fallback_syscall	// execve
-	data8 fsys_fallback_syscall	// chdir
-	data8 fsys_fallback_syscall	// fchdir		// 1035
-	data8 fsys_fallback_syscall	// utimes
-	data8 fsys_fallback_syscall	// mknod
-	data8 fsys_fallback_syscall	// chmod
-	data8 fsys_fallback_syscall	// chown
-	data8 fsys_fallback_syscall	// lseek		// 1040
-	data8 fsys_getpid
+	data8 0				// exit			// 1025
+	data8 0				// read
+	data8 0				// write
+	data8 0				// open
+	data8 0				// close
+	data8 0				// creat		// 1030
+	data8 0				// link
+	data8 0				// unlink
+	data8 0				// execve
+	data8 0				// chdir
+	data8 0				// fchdir		// 1035
+	data8 0				// utimes
+	data8 0				// mknod
+	data8 0				// chmod
+	data8 0				// chown
+	data8 0				// lseek		// 1040
+	data8 fsys_getpid		// getpid
 	data8 fsys_getppid		// getppid
-	data8 fsys_fallback_syscall	// mount
-	data8 fsys_fallback_syscall	// umount
-	data8 fsys_fallback_syscall	// setuid		// 1045
-	data8 fsys_fallback_syscall	// getuid
-	data8 fsys_fallback_syscall	// geteuid
-	data8 fsys_fallback_syscall	// ptrace
-	data8 fsys_fallback_syscall	// access
-	data8 fsys_fallback_syscall	// sync			// 1050
-	data8 fsys_fallback_syscall	// fsync
-	data8 fsys_fallback_syscall	// fdatasync
-	data8 fsys_fallback_syscall	// kill
-	data8 fsys_fallback_syscall	// rename
-	data8 fsys_fallback_syscall	// mkdir		// 1055
-	data8 fsys_fallback_syscall	// rmdir
-	data8 fsys_fallback_syscall	// dup
-	data8 fsys_fallback_syscall	// pipe
-	data8 fsys_fallback_syscall	// times
-	data8 fsys_fallback_syscall	// brk			// 1060
-	data8 fsys_fallback_syscall	// setgid
-	data8 fsys_fallback_syscall	// getgid
-	data8 fsys_fallback_syscall	// getegid
-	data8 fsys_fallback_syscall	// acct
-	data8 fsys_fallback_syscall	// ioctl		// 1065
-	data8 fsys_fallback_syscall	// fcntl
-	data8 fsys_fallback_syscall	// umask
-	data8 fsys_fallback_syscall	// chroot
-	data8 fsys_fallback_syscall	// ustat
-	data8 fsys_fallback_syscall	// dup2			// 1070
-	data8 fsys_fallback_syscall	// setreuid
-	data8 fsys_fallback_syscall	// setregid
-	data8 fsys_fallback_syscall	// getresuid
-	data8 fsys_fallback_syscall	// setresuid
-	data8 fsys_fallback_syscall	// getresgid		// 1075
-	data8 fsys_fallback_syscall	// setresgid
-	data8 fsys_fallback_syscall	// getgroups
-	data8 fsys_fallback_syscall	// setgroups
-	data8 fsys_fallback_syscall	// getpgid
-	data8 fsys_fallback_syscall	// setpgid		// 1080
-	data8 fsys_fallback_syscall	// setsid
-	data8 fsys_fallback_syscall	// getsid
-	data8 fsys_fallback_syscall	// sethostname
-	data8 fsys_fallback_syscall	// setrlimit
-	data8 fsys_fallback_syscall	// getrlimit		// 1085
-	data8 fsys_fallback_syscall	// getrusage
+	data8 0				// mount
+	data8 0				// umount
+	data8 0				// setuid		// 1045
+	data8 0				// getuid
+	data8 0				// geteuid
+	data8 0				// ptrace
+	data8 0				// access
+	data8 0				// sync			// 1050
+	data8 0				// fsync
+	data8 0				// fdatasync
+	data8 0				// kill
+	data8 0				// rename
+	data8 0				// mkdir		// 1055
+	data8 0				// rmdir
+	data8 0				// dup
+	data8 0				// pipe
+	data8 0				// times
+	data8 0				// brk			// 1060
+	data8 0				// setgid
+	data8 0				// getgid
+	data8 0				// getegid
+	data8 0				// acct
+	data8 0				// ioctl		// 1065
+	data8 0				// fcntl
+	data8 0				// umask
+	data8 0				// chroot
+	data8 0				// ustat
+	data8 0				// dup2			// 1070
+	data8 0				// setreuid
+	data8 0				// setregid
+	data8 0				// getresuid
+	data8 0				// setresuid
+	data8 0				// getresgid		// 1075
+	data8 0				// setresgid
+	data8 0				// getgroups
+	data8 0				// setgroups
+	data8 0				// getpgid
+	data8 0				// setpgid		// 1080
+	data8 0				// setsid
+	data8 0				// getsid
+	data8 0				// sethostname
+	data8 0				// setrlimit
+	data8 0				// getrlimit		// 1085
+	data8 0				// getrusage
 	data8 fsys_gettimeofday		// gettimeofday
-	data8 fsys_fallback_syscall	// settimeofday
-	data8 fsys_fallback_syscall	// select
-	data8 fsys_fallback_syscall	// poll			// 1090
-	data8 fsys_fallback_syscall	// symlink
-	data8 fsys_fallback_syscall	// readlink
-	data8 fsys_fallback_syscall	// uselib
-	data8 fsys_fallback_syscall	// swapon
-	data8 fsys_fallback_syscall	// swapoff		// 1095
-	data8 fsys_fallback_syscall	// reboot
-	data8 fsys_fallback_syscall	// truncate
-	data8 fsys_fallback_syscall	// ftruncate
-	data8 fsys_fallback_syscall	// fchmod
-	data8 fsys_fallback_syscall	// fchown		// 1100
-	data8 fsys_fallback_syscall	// getpriority
-	data8 fsys_fallback_syscall	// setpriority
-	data8 fsys_fallback_syscall	// statfs
-	data8 fsys_fallback_syscall	// fstatfs
-	data8 fsys_fallback_syscall	// gettid		// 1105
-	data8 fsys_fallback_syscall	// semget
-	data8 fsys_fallback_syscall	// semop
-	data8 fsys_fallback_syscall	// semctl
-	data8 fsys_fallback_syscall	// msgget
-	data8 fsys_fallback_syscall	// msgsnd		// 1110
-	data8 fsys_fallback_syscall	// msgrcv
-	data8 fsys_fallback_syscall	// msgctl
-	data8 fsys_fallback_syscall	// shmget
-	data8 fsys_fallback_syscall	// shmat
-	data8 fsys_fallback_syscall	// shmdt		// 1115
-	data8 fsys_fallback_syscall	// shmctl
-	data8 fsys_fallback_syscall	// syslog
-	data8 fsys_fallback_syscall	// setitimer
-	data8 fsys_fallback_syscall	// getitimer
-	data8 fsys_fallback_syscall		 		// 1120
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall	// vhangup
-	data8 fsys_fallback_syscall	// lchown
-	data8 fsys_fallback_syscall	// remap_file_pages	// 1125
-	data8 fsys_fallback_syscall	// wait4
-	data8 fsys_fallback_syscall	// sysinfo
-	data8 fsys_fallback_syscall	// clone
-	data8 fsys_fallback_syscall	// setdomainname
-	data8 fsys_fallback_syscall	// newuname		// 1130
-	data8 fsys_fallback_syscall	// adjtimex
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall	// init_module
-	data8 fsys_fallback_syscall	// delete_module
-	data8 fsys_fallback_syscall				// 1135
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall	// quotactl
-	data8 fsys_fallback_syscall	// bdflush
-	data8 fsys_fallback_syscall	// sysfs
-	data8 fsys_fallback_syscall	// personality		// 1140
-	data8 fsys_fallback_syscall	// afs_syscall
-	data8 fsys_fallback_syscall	// setfsuid
-	data8 fsys_fallback_syscall	// setfsgid
-	data8 fsys_fallback_syscall	// getdents
-	data8 fsys_fallback_syscall	// flock		// 1145
-	data8 fsys_fallback_syscall	// readv
-	data8 fsys_fallback_syscall	// writev
-	data8 fsys_fallback_syscall	// pread64
-	data8 fsys_fallback_syscall	// pwrite64
-	data8 fsys_fallback_syscall	// sysctl		// 1150
-	data8 fsys_fallback_syscall	// mmap
-	data8 fsys_fallback_syscall	// munmap
-	data8 fsys_fallback_syscall	// mlock
-	data8 fsys_fallback_syscall	// mlockall
-	data8 fsys_fallback_syscall	// mprotect		// 1155
-	data8 fsys_fallback_syscall	// mremap
-	data8 fsys_fallback_syscall	// msync
-	data8 fsys_fallback_syscall	// munlock
-	data8 fsys_fallback_syscall	// munlockall
-	data8 fsys_fallback_syscall	// sched_getparam	// 1160
-	data8 fsys_fallback_syscall	// sched_setparam
-	data8 fsys_fallback_syscall	// sched_getscheduler
-	data8 fsys_fallback_syscall	// sched_setscheduler
-	data8 fsys_fallback_syscall	// sched_yield
-	data8 fsys_fallback_syscall	// sched_get_priority_max	// 1165
-	data8 fsys_fallback_syscall	// sched_get_priority_min
-	data8 fsys_fallback_syscall	// sched_rr_get_interval
-	data8 fsys_fallback_syscall	// nanosleep
-	data8 fsys_fallback_syscall	// nfsservctl
-	data8 fsys_fallback_syscall	// prctl		// 1170
-	data8 fsys_fallback_syscall	// getpagesize
-	data8 fsys_fallback_syscall	// mmap2
-	data8 fsys_fallback_syscall	// pciconfig_read
-	data8 fsys_fallback_syscall	// pciconfig_write
-	data8 fsys_fallback_syscall	// perfmonctl		// 1175
-	data8 fsys_fallback_syscall	// sigaltstack
-	data8 fsys_fallback_syscall	// rt_sigaction
-	data8 fsys_fallback_syscall	// rt_sigpending
-	data8 fsys_fallback_syscall	// rt_sigprocmask
-	data8 fsys_fallback_syscall	// rt_sigqueueinfo	// 1180
-	data8 fsys_fallback_syscall	// rt_sigreturn
-	data8 fsys_fallback_syscall	// rt_sigsuspend
-	data8 fsys_fallback_syscall	// rt_sigtimedwait
-	data8 fsys_fallback_syscall	// getcwd
-	data8 fsys_fallback_syscall	// capget		// 1185
-	data8 fsys_fallback_syscall	// capset
-	data8 fsys_fallback_syscall	// sendfile
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall	// socket		// 1190
-	data8 fsys_fallback_syscall	// bind
-	data8 fsys_fallback_syscall	// connect
-	data8 fsys_fallback_syscall	// listen
-	data8 fsys_fallback_syscall	// accept
-	data8 fsys_fallback_syscall	// getsockname		// 1195
-	data8 fsys_fallback_syscall	// getpeername
-	data8 fsys_fallback_syscall	// socketpair
-	data8 fsys_fallback_syscall	// send
-	data8 fsys_fallback_syscall	// sendto
-	data8 fsys_fallback_syscall	// recv			// 1200
-	data8 fsys_fallback_syscall	// recvfrom
-	data8 fsys_fallback_syscall	// shutdown
-	data8 fsys_fallback_syscall	// setsockopt
-	data8 fsys_fallback_syscall	// getsockopt
-	data8 fsys_fallback_syscall	// sendmsg		// 1205
-	data8 fsys_fallback_syscall	// recvmsg
-	data8 fsys_fallback_syscall	// pivot_root
-	data8 fsys_fallback_syscall	// mincore
-	data8 fsys_fallback_syscall	// madvise
-	data8 fsys_fallback_syscall	// newstat		// 1210
-	data8 fsys_fallback_syscall	// newlstat
-	data8 fsys_fallback_syscall	// newfstat
-	data8 fsys_fallback_syscall	// clone2
-	data8 fsys_fallback_syscall	// getdents64
-	data8 fsys_fallback_syscall	// getunwind		// 1215
-	data8 fsys_fallback_syscall	// readahead
-	data8 fsys_fallback_syscall	// setxattr
-	data8 fsys_fallback_syscall	// lsetxattr
-	data8 fsys_fallback_syscall	// fsetxattr
-	data8 fsys_fallback_syscall	// getxattr		// 1220
-	data8 fsys_fallback_syscall	// lgetxattr
-	data8 fsys_fallback_syscall	// fgetxattr
-	data8 fsys_fallback_syscall	// listxattr
-	data8 fsys_fallback_syscall	// llistxattr
-	data8 fsys_fallback_syscall	// flistxattr		// 1225
-	data8 fsys_fallback_syscall	// removexattr
-	data8 fsys_fallback_syscall	// lremovexattr
-	data8 fsys_fallback_syscall	// fremovexattr
-	data8 fsys_fallback_syscall	// tkill
-	data8 fsys_fallback_syscall	// futex		// 1230
-	data8 fsys_fallback_syscall	// sched_setaffinity
-	data8 fsys_fallback_syscall	// sched_getaffinity
+	data8 0				// settimeofday
+	data8 0				// select
+	data8 0				// poll			// 1090
+	data8 0				// symlink
+	data8 0				// readlink
+	data8 0				// uselib
+	data8 0				// swapon
+	data8 0				// swapoff		// 1095
+	data8 0				// reboot
+	data8 0				// truncate
+	data8 0				// ftruncate
+	data8 0				// fchmod
+	data8 0				// fchown		// 1100
+	data8 0				// getpriority
+	data8 0				// setpriority
+	data8 0				// statfs
+	data8 0				// fstatfs
+	data8 0				// gettid		// 1105
+	data8 0				// semget
+	data8 0				// semop
+	data8 0				// semctl
+	data8 0				// msgget
+	data8 0				// msgsnd		// 1110
+	data8 0				// msgrcv
+	data8 0				// msgctl
+	data8 0				// shmget
+	data8 0				// shmat
+	data8 0				// shmdt		// 1115
+	data8 0				// shmctl
+	data8 0				// syslog
+	data8 0				// setitimer
+	data8 0				// getitimer
+	data8 0					 		// 1120
+	data8 0
+	data8 0
+	data8 0				// vhangup
+	data8 0				// lchown
+	data8 0				// remap_file_pages	// 1125
+	data8 0				// wait4
+	data8 0				// sysinfo
+	data8 0				// clone
+	data8 0				// setdomainname
+	data8 0				// newuname		// 1130
+	data8 0				// adjtimex
+	data8 0
+	data8 0				// init_module
+	data8 0				// delete_module
+	data8 0							// 1135
+	data8 0
+	data8 0				// quotactl
+	data8 0				// bdflush
+	data8 0				// sysfs
+	data8 0				// personality		// 1140
+	data8 0				// afs_syscall
+	data8 0				// setfsuid
+	data8 0				// setfsgid
+	data8 0				// getdents
+	data8 0				// flock		// 1145
+	data8 0				// readv
+	data8 0				// writev
+	data8 0				// pread64
+	data8 0				// pwrite64
+	data8 0				// sysctl		// 1150
+	data8 0				// mmap
+	data8 0				// munmap
+	data8 0				// mlock
+	data8 0				// mlockall
+	data8 0				// mprotect		// 1155
+	data8 0				// mremap
+	data8 0				// msync
+	data8 0				// munlock
+	data8 0				// munlockall
+	data8 0				// sched_getparam	// 1160
+	data8 0				// sched_setparam
+	data8 0				// sched_getscheduler
+	data8 0				// sched_setscheduler
+	data8 0				// sched_yield
+	data8 0				// sched_get_priority_max	// 1165
+	data8 0				// sched_get_priority_min
+	data8 0				// sched_rr_get_interval
+	data8 0				// nanosleep
+	data8 0				// nfsservctl
+	data8 0				// prctl		// 1170
+	data8 0				// getpagesize
+	data8 0				// mmap2
+	data8 0				// pciconfig_read
+	data8 0				// pciconfig_write
+	data8 0				// perfmonctl		// 1175
+	data8 0				// sigaltstack
+	data8 0				// rt_sigaction
+	data8 0				// rt_sigpending
+	data8 0				// rt_sigprocmask
+	data8 0				// rt_sigqueueinfo	// 1180
+	data8 0				// rt_sigreturn
+	data8 0				// rt_sigsuspend
+	data8 0				// rt_sigtimedwait
+	data8 0				// getcwd
+	data8 0				// capget		// 1185
+	data8 0				// capset
+	data8 0				// sendfile
+	data8 0
+	data8 0
+	data8 0				// socket		// 1190
+	data8 0				// bind
+	data8 0				// connect
+	data8 0				// listen
+	data8 0				// accept
+	data8 0				// getsockname		// 1195
+	data8 0				// getpeername
+	data8 0				// socketpair
+	data8 0				// send
+	data8 0				// sendto
+	data8 0				// recv			// 1200
+	data8 0				// recvfrom
+	data8 0				// shutdown
+	data8 0				// setsockopt
+	data8 0				// getsockopt
+	data8 0				// sendmsg		// 1205
+	data8 0				// recvmsg
+	data8 0				// pivot_root
+	data8 0				// mincore
+	data8 0				// madvise
+	data8 0				// newstat		// 1210
+	data8 0				// newlstat
+	data8 0				// newfstat
+	data8 0				// clone2
+	data8 0				// getdents64
+	data8 0				// getunwind		// 1215
+	data8 0				// readahead
+	data8 0				// setxattr
+	data8 0				// lsetxattr
+	data8 0				// fsetxattr
+	data8 0				// getxattr		// 1220
+	data8 0				// lgetxattr
+	data8 0				// fgetxattr
+	data8 0				// listxattr
+	data8 0				// llistxattr
+	data8 0				// flistxattr		// 1225
+	data8 0				// removexattr
+	data8 0				// lremovexattr
+	data8 0				// fremovexattr
+	data8 0				// tkill
+	data8 0				// futex		// 1230
+	data8 0				// sched_setaffinity
+	data8 0				// sched_getaffinity
 	data8 fsys_set_tid_address	// set_tid_address
-	data8 fsys_fallback_syscall	// unused
-	data8 fsys_fallback_syscall	// unused		// 1235
-	data8 fsys_fallback_syscall	// exit_group
-	data8 fsys_fallback_syscall	// lookup_dcookie
-	data8 fsys_fallback_syscall	// io_setup
-	data8 fsys_fallback_syscall	// io_destroy
-	data8 fsys_fallback_syscall	// io_getevents		// 1240
-	data8 fsys_fallback_syscall	// io_submit
-	data8 fsys_fallback_syscall	// io_cancel
-	data8 fsys_fallback_syscall	// epoll_create
-	data8 fsys_fallback_syscall	// epoll_ctl
-	data8 fsys_fallback_syscall	// epoll_wait		// 1245
-	data8 fsys_fallback_syscall	// restart_syscall
-	data8 fsys_fallback_syscall	// semtimedop
-	data8 fsys_fallback_syscall	// timer_create
-	data8 fsys_fallback_syscall	// timer_settime
-	data8 fsys_fallback_syscall	// timer_gettime 	// 1250
-	data8 fsys_fallback_syscall	// timer_getoverrun
-	data8 fsys_fallback_syscall	// timer_delete
-	data8 fsys_fallback_syscall	// clock_settime
-	data8 fsys_fallback_syscall	// clock_gettime
-	data8 fsys_fallback_syscall	// clock_getres		// 1255
-	data8 fsys_fallback_syscall	// clock_nanosleep
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall				// 1260
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall				// 1265
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall				// 1270
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall				// 1275
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall
-	data8 fsys_fallback_syscall
+	data8 0				// unused
+	data8 0				// unused		// 1235
+	data8 0				// exit_group
+	data8 0				// lookup_dcookie
+	data8 0				// io_setup
+	data8 0				// io_destroy
+	data8 0				// io_getevents		// 1240
+	data8 0				// io_submit
+	data8 0				// io_cancel
+	data8 0				// epoll_create
+	data8 0				// epoll_ctl
+	data8 0				// epoll_wait		// 1245
+	data8 0				// restart_syscall
+	data8 0				// semtimedop
+	data8 0				// timer_create
+	data8 0				// timer_settime
+	data8 0				// timer_gettime 	// 1250
+	data8 0				// timer_getoverrun
+	data8 0				// timer_delete
+	data8 0				// clock_settime
+	data8 0				// clock_gettime
+	data8 0				// clock_getres		// 1255
+	data8 0				// clock_nanosleep
+	data8 0
+	data8 0
+	data8 0
+	data8 0							// 1260
+	data8 0
+	data8 0
+	data8 0
+	data8 0
+	data8 0							// 1265
+	data8 0
+	data8 0
+	data8 0
+	data8 0
+	data8 0							// 1270
+	data8 0
+	data8 0
+	data8 0
+	data8 0
+	data8 0							// 1275
+	data8 0
+	data8 0
+	data8 0
+	data8 0
+
+	.org fsyscall_table + 8*NR_syscalls	// guard against failures to increase NR_syscalls
diff -Nru a/arch/ia64/kernel/gate-data.S b/arch/ia64/kernel/gate-data.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/kernel/gate-data.S	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,3 @@
+	.section .data.gate, "ax"
+
+	.incbin "arch/ia64/kernel/gate.so"
diff -Nru a/arch/ia64/kernel/gate.S b/arch/ia64/kernel/gate.S
--- a/arch/ia64/kernel/gate.S	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/kernel/gate.S	Wed Jun 18 23:42:08 2003
@@ -6,20 +6,47 @@
  * 	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
+#include <linux/config.h>
+
 #include <asm/asmmacro.h>
+#include <asm/errno.h>
 #include <asm/offsets.h>
 #include <asm/sigcontext.h>
 #include <asm/system.h>
 #include <asm/unistd.h>
-#include <asm/page.h>
-
-	.section .text.gate, "ax"
-.start_gate:
 
+/*
+ * We can't easily refer to symbols inside the kernel.  To avoid full runtime relocation,
+ * complications with the linker (which likes to create PLT stubs for branches
+ * to targets outside the shared object) and to avoid multi-phase kernel builds, we
+ * simply create minimalistic "patch lists" in special ELF sections.
+ */
+	.section ".data.patch.fsyscall_table", "a"
+	.previous
+#define LOAD_FSYSCALL_TABLE(reg)			\
+[1:]	movl reg=0;					\
+	.xdata4 ".data.patch.fsyscall_table", 1b-.
+
+	.section ".data.patch.brl_fsys_bubble_down", "a"
+	.previous
+#define BRL_COND_FSYS_BUBBLE_DOWN(pr)			\
+[1:](pr)brl.cond.sptk 0;				\
+	.xdata4 ".data.patch.brl_fsys_bubble_down", 1b-.
 
-#ifdef CONFIG_FSYS
-
-#include <asm/errno.h>
+GLOBAL_ENTRY(__kernel_syscall_via_break)
+	.prologue
+	.altrp b6
+	.body
+	/*
+	 * Note: for (fast) syscall restart to work, the break instruction must be
+	 *	 the first one in the bundle addressed by syscall_via_break.
+	 */
+{ .mib
+	break 0x100000
+	nop.i 0
+	br.ret.sptk.many b6
+}
+END(__kernel_syscall_via_break)
 
 /*
  * On entry:
@@ -34,7 +61,8 @@
  *	all other "scratch" registers:	undefined
  *	all "preserved" registers:	same as on entry
  */
-GLOBAL_ENTRY(syscall_via_epc)
+
+GLOBAL_ENTRY(__kernel_syscall_via_epc)
 	.prologue
 	.altrp b6
 	.body
@@ -49,52 +77,50 @@
 	epc
 }
 	;;
-	rsm psr.be
-	movl r18=fsyscall_table
+	rsm psr.be // note: on McKinley "rsm psr.be/srlz.d" is slightly faster than "rum psr.be"
+	LOAD_FSYSCALL_TABLE(r14)
 
-	mov r16=IA64_KR(CURRENT)
-	mov r19=255
+	mov r16=IA64_KR(CURRENT)		// 12 cycle read latency
+	mov r19=NR_syscalls-1
 	;;
-	shladd r18=r17,3,r18
-	cmp.geu p6,p0=r19,r17			// (syscall > 0 && syscall <= 1024+255)?
+	shladd r18=r17,3,r14
+
+	srlz.d
+	cmp.ne p8,p0=r0,r0			// p8 <- FALSE
+	/* Note: if r17 is a NaT, p6 will be set to zero.  */
+	cmp.geu p6,p7=r19,r17			// (syscall > 0 && syscall < 1024+NR_syscalls)?
 	;;
-	srlz.d					// ensure little-endian byteorder is in effect
 (p6)	ld8 r18=[r18]
+	mov r29=psr				// read psr (12 cyc load latency)
+	add r14=-8,r14				// r14 <- addr of fsys_bubble_down entry
 	;;
 (p6)	mov b7=r18
+(p6)	tbit.z p8,p0=r18,0
+(p8)	br.dptk.many b7
+
+	mov r27=ar.rsc
+	mov r21=ar.fpsr
+	mov r26=ar.pfs
+/*
+ * brl.cond doesn't work as intended because the linker would convert this branch
+ * into a branch to a PLT.  Perhaps there will be a way to avoid this with some
+ * future version of the linker.  In the meantime, we just use an indirect branch
+ * instead.
+ */
+#ifdef CONFIG_ITANIUM
+(p6)	ld8 r14=[r14]				// r14 <- fsys_bubble_down
+	;;
+(p6)	mov b7=r14
 (p6)	br.sptk.many b7
+#else
+	BRL_COND_FSYS_BUBBLE_DOWN(p6)
+#endif
 
 	mov r10=-1
 	mov r8=ENOSYS
 	MCKINLEY_E9_WORKAROUND
 	br.ret.sptk.many b6
-END(syscall_via_epc)
-
-GLOBAL_ENTRY(syscall_via_break)
-	.prologue
-	.altrp b6
-	.body
-	break 0x100000
-	br.ret.sptk.many b6
-END(syscall_via_break)
-
-GLOBAL_ENTRY(fsys_fallback_syscall)
-	/*
-	 * It would be better/fsyser to do the SAVE_MIN magic directly here, but for now
-	 * we simply fall back on doing a system-call via break.  Good enough
-	 * to get started.  (Note: we have to do this through the gate page again, since
-	 * the br.ret will switch us back to user-level privilege.)
-	 *
-	 * XXX Move this back to fsys.S after changing it over to avoid break 0x100000.
-	 */
-	movl r2=(syscall_via_break - .start_gate) + GATE_ADDR
-	;;
-	MCKINLEY_E9_WORKAROUND
-	mov b7=r2
-	br.ret.sptk.many b7
-END(fsys_fallback_syscall)
-
-#endif /* CONFIG_FSYS */
+END(__kernel_syscall_via_epc)
 
 #	define ARG0_OFF		(16 + IA64_SIGFRAME_ARG0_OFFSET)
 #	define ARG1_OFF		(16 + IA64_SIGFRAME_ARG1_OFFSET)
@@ -145,7 +171,8 @@
 	 */
 
 #define SIGTRAMP_SAVES										\
-	.unwabi @svr4, 's';	/* mark this as a sigtramp handler (saves scratch regs) */	\
+	.unwabi 3, 's';		/* mark this as a sigtramp handler (saves scratch regs) */	\
+	.unwabi @svr4, 's'; /* backwards compatibility with old unwinders (remove in v2.7) */	\
 	.savesp ar.unat, UNAT_OFF+SIGCONTEXT_OFF;						\
 	.savesp ar.fpsr, FPSR_OFF+SIGCONTEXT_OFF;						\
 	.savesp pr, PR_OFF+SIGCONTEXT_OFF;     							\
@@ -153,7 +180,7 @@
 	.savesp ar.pfs, CFM_OFF+SIGCONTEXT_OFF;							\
 	.vframesp SP_OFF+SIGCONTEXT_OFF
 
-GLOBAL_ENTRY(ia64_sigtramp)
+GLOBAL_ENTRY(__kernel_sigtramp)
 	// describe the state that is active when we get here:
 	.prologue
 	SIGTRAMP_SAVES
@@ -335,4 +362,4 @@
 	mov ar.rsc=0xf				// (will be restored later on from sc_ar_rsc)
 	// invala not necessary as that will happen when returning to user-mode
 	br.cond.sptk back_from_restore_rbs
-END(ia64_sigtramp)
+END(__kernel_sigtramp)
diff -Nru a/arch/ia64/kernel/gate.lds.S b/arch/ia64/kernel/gate.lds.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/kernel/gate.lds.S	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,95 @@
+/*
+ * Linker script for gate DSO.  The gate pages are an ELF shared object prelinked to its
+ * virtual address, with only one read-only segment and one execute-only segment (both fit
+ * in one page).  This script controls its layout.
+ */
+
+#include <linux/config.h>
+
+#include <asm/system.h>
+
+SECTIONS
+{
+  . = GATE_ADDR + SIZEOF_HEADERS;
+
+  .hash				: { *(.hash) }				:readable
+  .dynsym			: { *(.dynsym) }
+  .dynstr			: { *(.dynstr) }
+  .gnu.version			: { *(.gnu.version) }
+  .gnu.version_d		: { *(.gnu.version_d) }
+  .gnu.version_r		: { *(.gnu.version_r) }
+  .dynamic			: { *(.dynamic) }			:readable :dynamic
+
+  /*
+   * This linker script is used both with -r and with -shared.  For the layouts to match,
+   * we need to skip more than enough space for the dynamic symbol table et al.  If this
+   * amount is insufficient, ld -shared will barf.  Just increase it here.
+   */
+  . = GATE_ADDR + 0x500;
+
+  .data.patch			: {
+				    __start_gate_mckinley_e9_patchlist = .;
+				    *(.data.patch.mckinley_e9)
+				    __end_gate_mckinley_e9_patchlist = .;
+
+				    __start_gate_vtop_patchlist = .;
+				    *(.data.patch.vtop)
+				    __end_gate_vtop_patchlist = .;
+
+				    __start_gate_fsyscall_patchlist = .;
+				    *(.data.patch.fsyscall_table)
+				    __end_gate_fsyscall_patchlist = .;
+
+				    __start_gate_brl_fsys_bubble_down_patchlist = .;
+				    *(.data.patch.brl_fsys_bubble_down)
+				    __end_gate_brl_fsys_bubble_down_patchlist = .;
+  }									:readable
+  .IA_64.unwind_info		: { *(.IA_64.unwind_info*) }
+  .IA_64.unwind			: { *(.IA_64.unwind*) }			:readable :unwind
+#ifdef HAVE_BUGGY_SEGREL
+  .text (GATE_ADDR + PAGE_SIZE)	: { *(.text) *(.text.*) }		:readable
+#else
+  . = ALIGN (PERCPU_PAGE_SIZE) + (. & (PERCPU_PAGE_SIZE - 1));
+  .text				: { *(.text) *(.text.*) }		:epc
+#endif
+
+  /DISCARD/			: {
+  	*(.got.plt) *(.got)
+	*(.data .data.* .gnu.linkonce.d.*)
+	*(.dynbss)
+	*(.bss .bss.* .gnu.linkonce.b.*)
+	*(__ex_table)
+  }
+}
+
+/*
+ * We must supply the ELF program headers explicitly to get just one
+ * PT_LOAD segment, and set the flags explicitly to make segments read-only.
+ */
+PHDRS
+{
+  readable  PT_LOAD	FILEHDR	PHDRS	FLAGS(4);	/* PF_R */
+#ifndef HAVE_BUGGY_SEGREL
+  epc	    PT_LOAD	FILEHDR PHDRS	FLAGS(1);	/* PF_X */
+#endif
+  dynamic   PT_DYNAMIC			FLAGS(4);	/* PF_R */
+  unwind    0x70000001; /* PT_IA_64_UNWIND, but ld doesn't match the name */
+}
+
+/*
+ * This controls what symbols we export from the DSO.
+ */
+VERSION
+{
+  LINUX_2.5 {
+    global:
+	__kernel_syscall_via_break;
+	__kernel_syscall_via_epc;
+	__kernel_sigtramp;
+
+    local: *;
+  };
+}
+
+/* The ELF entry point can be used to set the AT_SYSINFO value.  */
+ENTRY(__kernel_syscall_via_epc)
diff -Nru a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S
--- a/arch/ia64/kernel/head.S	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/kernel/head.S	Wed Jun 18 23:42:08 2003
@@ -60,22 +60,42 @@
 	mov r4=r0
 	.body
 
-	/*
-	 * Initialize the region register for region 7 and install a translation register
-	 * that maps the kernel's text and data:
-	 */
 	rsm psr.i | psr.ic
-	mov r16=((ia64_rid(IA64_REGION_ID_KERNEL, PAGE_OFFSET) << 8) | (IA64_GRANULE_SHIFT << 2))
 	;;
 	srlz.i
+	;;
+	/*
+	 * Initialize kernel region registers:
+	 *	rr[5]: VHPT enabled, page size = PAGE_SHIFT
+	 *	rr[6]: VHPT disabled, page size = IA64_GRANULE_SHIFT
+	 *	rr[5]: VHPT disabled, page size = IA64_GRANULE_SHIFT
+	 */
+	mov r16=((ia64_rid(IA64_REGION_ID_KERNEL, (5<<61)) << 8) | (PAGE_SHIFT << 2) | 1)
+	movl r17=(5<<61)
+	mov r18=((ia64_rid(IA64_REGION_ID_KERNEL, (6<<61)) << 8) | (IA64_GRANULE_SHIFT << 2))
+	movl r19=(6<<61)
+	mov r20=((ia64_rid(IA64_REGION_ID_KERNEL, (7<<61)) << 8) | (IA64_GRANULE_SHIFT << 2))
+	movl r21=(7<<61)
+	;;
+	mov rr[r17]=r16
+	mov rr[r19]=r18
+	mov rr[r21]=r20
+	;;
+	/*
+	 * Now pin mappings into the TLB for kernel text and data
+	 */
 	mov r18=KERNEL_TR_PAGE_SHIFT<<2
 	movl r17=KERNEL_START
 	;;
-	mov rr[r17]=r16
 	mov cr.itir=r18
 	mov cr.ifa=r17
 	mov r16=IA64_TR_KERNEL
-	movl r18=((1 << KERNEL_TR_PAGE_SHIFT) | PAGE_KERNEL)
+	mov r3=ip
+	movl r18=PAGE_KERNEL
+	;;
+	dep r2=0,r3,0,KERNEL_TR_PAGE_SHIFT
+	;;
+	or r18=r2,r18
 	;;
 	srlz.i
 	;;
@@ -113,16 +133,6 @@
 	mov ar.fpsr=r2
 	;;
 
-#ifdef CONFIG_IA64_EARLY_PRINTK
-	mov r3=(6<<8) | (IA64_GRANULE_SHIFT<<2)
-	movl r2=6<<61
-	;;
-	mov rr[r2]=r3
-	;;
-	srlz.i
-	;;
-#endif
-
 #define isAP	p2	// are we an Application Processor?
 #define isBP	p3	// are we the Bootstrap Processor?
 
@@ -143,12 +153,36 @@
 	movl r2=init_thread_union
 	cmp.eq isBP,isAP=r0,r0
 #endif
-	mov r16=KERNEL_TR_PAGE_NUM
 	;;
+	tpa r3=r2		// r3 == phys addr of task struct
+	// load mapping for stack (virtaddr in r2, physaddr in r3)
+	rsm psr.ic
+	movl r17=PAGE_KERNEL
+	;;
+	srlz.d
+	dep r18=0,r3,0,12
+	;;
+	or r18=r17,r18
+	dep r2=-1,r3,61,3	// IMVA of task
+	;;
+	mov r17=rr[r2]
+	shr.u r16=r3,IA64_GRANULE_SHIFT
+	;;
+	dep r17=0,r17,8,24
+	;;
+	mov cr.itir=r17
+	mov cr.ifa=r2
+
+	mov r19=IA64_TR_CURRENT_STACK
+	;;
+	itr.d dtr[r19]=r18
+	;;
+	ssm psr.ic
+	srlz.d
+  	;;
 
 	// load the "current" pointer (r13) and ar.k6 with the current task
 	mov IA64_KR(CURRENT)=r2		// virtual address
-	// initialize k4 to a safe value (64-128MB is mapped by TR_KERNEL)
 	mov IA64_KR(CURRENT_STACK)=r16
 	mov r13=r2
 	/*
@@ -665,14 +699,14 @@
 END(__ia64_init_fpu)
 
 /*
- * Switch execution mode from virtual to physical or vice versa.
+ * Switch execution mode from virtual to physical
  *
  * Inputs:
  *	r16 = new psr to establish
  *
  * Note: RSE must already be in enforced lazy mode
  */
-GLOBAL_ENTRY(ia64_switch_mode)
+GLOBAL_ENTRY(ia64_switch_mode_phys)
  {
 	alloc r2=ar.pfs,0,0,0,0
 	rsm psr.i | psr.ic		// disable interrupts and interrupt collection
@@ -682,35 +716,86 @@
  {
 	flushrs				// must be first insn in group
 	srlz.i
-	shr.u r19=r15,61		// r19 <- top 3 bits of current IP
  }
 	;;
 	mov cr.ipsr=r16			// set new PSR
-	add r3=1f-ia64_switch_mode,r15
-	xor r15=0x7,r19			// flip the region bits
+	add r3=1f-ia64_switch_mode_phys,r15
 
 	mov r17=ar.bsp
 	mov r14=rp			// get return address into a general register
+	;;
 
-	// switch RSE backing store:
+	// going to physical mode, use tpa to translate virt->phys
+	tpa r17=r17
+	tpa r3=r3
+	tpa sp=sp
+	tpa r14=r14
 	;;
-	dep r17=r15,r17,61,3		// make ar.bsp physical or virtual
+
 	mov r18=ar.rnat			// save ar.rnat
-	;;
 	mov ar.bspstore=r17		// this steps on ar.rnat
-	dep r3=r15,r3,61,3		// make rfi return address physical or virtual
+	mov cr.iip=r3
+	mov cr.ifs=r0
 	;;
+	mov ar.rnat=r18			// restore ar.rnat
+	rfi				// must be last insn in group
+	;;
+1:	mov rp=r14
+	br.ret.sptk.many rp
+END(ia64_switch_mode_phys)
+
+/*
+ * Switch execution mode from physical to virtual
+ *
+ * Inputs:
+ *	r16 = new psr to establish
+ *
+ * Note: RSE must already be in enforced lazy mode
+ */
+GLOBAL_ENTRY(ia64_switch_mode_virt)
+ {
+	alloc r2=ar.pfs,0,0,0,0
+	rsm psr.i | psr.ic		// disable interrupts and interrupt collection
+	mov r15=ip
+ }
+	;;
+ {
+	flushrs				// must be first insn in group
+	srlz.i
+ }
+	;;
+	mov cr.ipsr=r16			// set new PSR
+	add r3=1f-ia64_switch_mode_virt,r15
+
+	mov r17=ar.bsp
+	mov r14=rp			// get return address into a general register
+	;;
+
+	// going to virtual
+	//   - for code addresses, set upper bits of addr to KERNEL_START
+	//   - for stack addresses, set upper 3 bits to 0xe.... Dont change any of the
+	//     lower bits since we want it to stay identity mapped
+	movl r18=KERNEL_START
+	dep r3=0,r3,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT
+	dep r14=0,r14,KERNEL_TR_PAGE_SHIFT,64-KERNEL_TR_PAGE_SHIFT
+	dep r17=-1,r17,61,3
+	dep sp=-1,sp,61,3
+	;;
+	or r3=r3,r18
+	or r14=r14,r18
+	;;
+
+	mov r18=ar.rnat			// save ar.rnat
+	mov ar.bspstore=r17		// this steps on ar.rnat
 	mov cr.iip=r3
 	mov cr.ifs=r0
-	dep sp=r15,sp,61,3		// make stack pointer physical or virtual
 	;;
 	mov ar.rnat=r18			// restore ar.rnat
-	dep r14=r15,r14,61,3		// make function return address physical or virtual
 	rfi				// must be last insn in group
 	;;
 1:	mov rp=r14
 	br.ret.sptk.many rp
-END(ia64_switch_mode)
+END(ia64_switch_mode_virt)
 
 #ifdef CONFIG_IA64_BRL_EMU
 
@@ -753,7 +838,7 @@
 	 *   r29    - available for use.
 	 *   r30    - available for use.
 	 *   r31    - address of lock, available for use.
-	 *   b7     - return address
+	 *   b6     - return address
 	 *   p14    - available for use.
 	 *
 	 * If you patch this code to use more registers, do not forget to update
diff -Nru a/arch/ia64/kernel/ia64_ksyms.c b/arch/ia64/kernel/ia64_ksyms.c
--- a/arch/ia64/kernel/ia64_ksyms.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/kernel/ia64_ksyms.c	Wed Jun 18 23:42:07 2003
@@ -65,6 +65,9 @@
 
 #include <asm/processor.h>
 EXPORT_SYMBOL(cpu_info__per_cpu);
+#ifdef CONFIG_SMP
+EXPORT_SYMBOL(__per_cpu_offset);
+#endif
 EXPORT_SYMBOL(kernel_thread);
 
 #include <asm/system.h>
@@ -88,6 +91,7 @@
 EXPORT_SYMBOL(smp_call_function);
 EXPORT_SYMBOL(smp_call_function_single);
 EXPORT_SYMBOL(cpu_online_map);
+EXPORT_SYMBOL(phys_cpu_present_map);
 EXPORT_SYMBOL(ia64_cpu_to_sapicid);
 #else /* !CONFIG_SMP */
 
@@ -124,6 +128,18 @@
 EXPORT_SYMBOL_NOVERS(__moddi3);
 EXPORT_SYMBOL_NOVERS(__umoddi3);
 
+#if defined(CONFIG_MD_RAID5) || defined(CONFIG_MD_RAID5_MODULE)
+extern void xor_ia64_2(void);
+extern void xor_ia64_3(void);
+extern void xor_ia64_4(void);
+extern void xor_ia64_5(void);
+
+EXPORT_SYMBOL_NOVERS(xor_ia64_2);
+EXPORT_SYMBOL_NOVERS(xor_ia64_3);
+EXPORT_SYMBOL_NOVERS(xor_ia64_4);
+EXPORT_SYMBOL_NOVERS(xor_ia64_5);
+#endif
+
 extern unsigned long ia64_iobase;
 EXPORT_SYMBOL(ia64_iobase);
 
@@ -147,10 +163,15 @@
 EXPORT_SYMBOL(ia64_mv);
 #endif
 EXPORT_SYMBOL(machvec_noop);
+EXPORT_SYMBOL(machvec_memory_fence);
+EXPORT_SYMBOL(zero_page_memmap_ptr);
 #ifdef CONFIG_PERFMON
 #include <asm/perfmon.h>
-EXPORT_SYMBOL(pfm_install_alternate_syswide_subsystem);
-EXPORT_SYMBOL(pfm_remove_alternate_syswide_subsystem);
+EXPORT_SYMBOL(pfm_register_buffer_fmt);
+EXPORT_SYMBOL(pfm_unregister_buffer_fmt);
+EXPORT_SYMBOL(pfm_mod_fast_read_pmds);
+EXPORT_SYMBOL(pfm_mod_read_pmds);
+EXPORT_SYMBOL(pfm_mod_write_pmcs);
 #endif
 
 #ifdef CONFIG_NUMA
@@ -169,10 +190,25 @@
 EXPORT_SYMBOL(unw_access_ar);
 EXPORT_SYMBOL(unw_access_pr);
 
-#if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4)
-extern void ia64_spinlock_contention_pre3_4 (void);
+#ifdef CONFIG_SMP
+# if __GNUC__ < 3 || (__GNUC__ == 3 && __GNUC_MINOR__ < 4)
+/*
+ * This is not a normal routine and we don't want a function descriptor for it, so we use
+ * a fake declaration here.
+ */
+extern char ia64_spinlock_contention_pre3_4;
 EXPORT_SYMBOL(ia64_spinlock_contention_pre3_4);
-#else
-extern void ia64_spinlock_contention (void);
+# else
+/*
+ * This is not a normal routine and we don't want a function descriptor for it, so we use
+ * a fake declaration here.
+ */
+extern char ia64_spinlock_contention;
 EXPORT_SYMBOL(ia64_spinlock_contention);
+# endif
 #endif
+
+EXPORT_SYMBOL(ia64_max_iommu_merge_mask);
+
+#include <linux/pm.h>
+EXPORT_SYMBOL(pm_idle);
diff -Nru a/arch/ia64/kernel/init_task.c b/arch/ia64/kernel/init_task.c
--- a/arch/ia64/kernel/init_task.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/kernel/init_task.c	Wed Jun 18 23:42:09 2003
@@ -36,7 +36,7 @@
 	unsigned long stack[KERNEL_STACK_SIZE/sizeof (unsigned long)];
 } init_thread_union __attribute__((section(".data.init_task"))) = {{
 	.task =		INIT_TASK(init_thread_union.s.task),
-	.thread_info =	INIT_THREAD_INFO(init_thread_union.s.thread_info)
+	.thread_info =	INIT_THREAD_INFO(init_thread_union.s.task)
 }};
 
 asm (".global init_task; init_task = init_thread_union");
diff -Nru a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
--- a/arch/ia64/kernel/irq.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/kernel/irq.c	Wed Jun 18 23:42:09 2003
@@ -65,7 +65,7 @@
 /*
  * Controller mappings for all interrupt sources:
  */
-irq_desc_t irq_desc[NR_IRQS] __cacheline_aligned = {
+irq_desc_t _irq_desc[NR_IRQS] __cacheline_aligned = {
 	[0 ... NR_IRQS-1] = {
 		.status = IRQ_DISABLED,
 		.handler = &no_irq_type,
@@ -235,7 +235,6 @@
 {
 	int status = 1;	/* Force the "do bottom halves" bit */
 	int retval = 0;
-	struct irqaction *first_action = action;
 
 	if (!(action->flags & SA_INTERRUPT))
 		local_irq_enable();
@@ -248,30 +247,88 @@
 	if (status & SA_SAMPLE_RANDOM)
 		add_interrupt_randomness(irq);
 	local_irq_disable();
-	if (retval != 1) {
-		static int count = 100;
-		if (count) {
-			count--;
-			if (retval) {
-				printk("irq event %d: bogus retval mask %x\n",
-					irq, retval);
-			} else {
-				printk("irq %d: nobody cared!\n", irq);
-			}
-			dump_stack();
-			printk("handlers:\n");
-			action = first_action;
-			do {
-				printk("[<%p>]", action->handler);
-				print_symbol(" (%s)",
-					(unsigned long)action->handler);
-				printk("\n");
-				action = action->next;
-			} while (action);
-		}
+	return retval;
+}
+
+static void __report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
+{
+	struct irqaction *action;
+
+	if (action_ret != IRQ_HANDLED && action_ret != IRQ_NONE) {
+		printk(KERN_ERR "irq event %d: bogus return value %x\n",
+				irq, action_ret);
+	} else {
+		printk(KERN_ERR "irq %d: nobody cared!\n", irq);
+	}
+	dump_stack();
+	printk(KERN_ERR "handlers:\n");
+	action = desc->action;
+	do {
+		printk(KERN_ERR "[<%p>]", action->handler);
+		print_symbol(" (%s)",
+			(unsigned long)action->handler);
+		printk("\n");
+		action = action->next;
+	} while (action);
+}
+
+static void report_bad_irq(int irq, irq_desc_t *desc, irqreturn_t action_ret)
+{
+	static int count = 100;
+
+	if (count) {
+		count--;
+		__report_bad_irq(irq, desc, action_ret);
+	}
+}
+
+static int noirqdebug;
+
+static int __init noirqdebug_setup(char *str)
+{
+	noirqdebug = 1;
+	printk("IRQ lockup detection disabled\n");
+	return 1;
+}
+
+__setup("noirqdebug", noirqdebug_setup);
+
+/*
+ * If 99,900 of the previous 100,000 interrupts have not been handled then
+ * assume that the IRQ is stuck in some manner.  Drop a diagnostic and try to
+ * turn the IRQ off.
+ *
+ * (The other 100-of-100,000 interrupts may have been a correctly-functioning
+ *  device sharing an IRQ with the failing one)
+ *
+ * Called under desc->lock
+ */
+static void note_interrupt(int irq, irq_desc_t *desc, irqreturn_t action_ret)
+{
+	if (action_ret != IRQ_HANDLED) {
+		desc->irqs_unhandled++;
+		if (action_ret != IRQ_NONE)
+			report_bad_irq(irq, desc, action_ret);
 	}
 
-	return status;
+	desc->irq_count++;
+	if (desc->irq_count < 100000)
+		return;
+
+	desc->irq_count = 0;
+	if (desc->irqs_unhandled > 99900) {
+		/*
+		 * The interrupt is stuck
+		 */
+		__report_bad_irq(irq, desc, action_ret);
+		/*
+		 * Now kill the IRQ
+		 */
+		printk(KERN_EMERG "Disabling IRQ #%d\n", irq);
+		desc->status |= IRQ_DISABLED;
+		desc->handler->disable(irq);
+	}
+	desc->irqs_unhandled = 0;
 }
 
 /*
@@ -380,21 +437,24 @@
 	 * 0 return value means that this irq is already being
 	 * handled by some other CPU. (or is disabled)
 	 */
-	int cpu;
 	irq_desc_t *desc = irq_desc(irq);
 	struct irqaction * action;
+	irqreturn_t action_ret;
 	unsigned int status;
+	int cpu;
 
 	irq_enter();
-	cpu = smp_processor_id();
+	cpu = smp_processor_id(); /* for CONFIG_PREEMPT, this must come after irq_enter()! */
 
 	kstat_cpu(cpu).irqs[irq]++;
 
 	if (desc->status & IRQ_PER_CPU) {
 		/* no locking required for CPU-local interrupts: */
 		desc->handler->ack(irq);
-		handle_IRQ_event(irq, regs, desc->action);
+		action_ret = handle_IRQ_event(irq, regs, desc->action);
 		desc->handler->end(irq);
+		if (!noirqdebug)
+			note_interrupt(irq, desc, action_ret);
 	} else {
 		spin_lock(&desc->lock);
 		desc->handler->ack(irq);
@@ -438,9 +498,10 @@
 		 */
 		for (;;) {
 			spin_unlock(&desc->lock);
-			handle_IRQ_event(irq, regs, action);
+			action_ret = handle_IRQ_event(irq, regs, action);
 			spin_lock(&desc->lock);
-
+			if (!noirqdebug)
+				note_interrupt(irq, desc, action_ret);
 			if (!(desc->status & IRQ_PENDING))
 				break;
 			desc->status &= ~IRQ_PENDING;
diff -Nru a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
--- a/arch/ia64/kernel/ivt.S	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/kernel/ivt.S	Wed Jun 18 23:42:06 2003
@@ -1,9 +1,14 @@
 /*
  * arch/ia64/kernel/ivt.S
  *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
  *	Stephane Eranian <eranian@hpl.hp.com>
  *	David Mosberger <davidm@hpl.hp.com>
+ * Copyright (C) 2000, 2002-2003 Intel Co
+ *	Asit Mallick <asit.k.mallick@intel.com>
+ *      Suresh Siddha <suresh.b.siddha@intel.com>
+ *      Kenneth Chen <kenneth.w.chen@intel.com>
+ *      Fenghua Yu <fenghua.yu@intel.com>
  *
  * 00/08/23 Asit Mallick <asit.k.mallick@intel.com> TLB handling for SMP
  * 00/12/20 David Mosberger-Tang <davidm@hpl.hp.com> DTLB/ITLB handler now uses virtual PT.
@@ -122,8 +127,11 @@
 	shr.u r18=r22,PGDIR_SHIFT		// get bits 33-63 of the faulting address
 	;;
 (p7)	dep r17=r17,r19,(PAGE_SHIFT-3),3	// put region number bits in place
-	srlz.d					// ensure "rsm psr.dt" has taken effect
-(p6)	movl r19=__pa(swapper_pg_dir)		// region 5 is rooted at swapper_pg_dir
+
+	srlz.d
+	LOAD_PHYSICAL(p6, r19, swapper_pg_dir)	// region 5 is rooted at swapper_pg_dir
+
+	.pred.rel "mutex", p6, p7
 (p6)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
 (p7)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
 	;;
@@ -415,8 +423,11 @@
 	shr.u r18=r16,PGDIR_SHIFT		// get bits 33-63 of faulting address
 	;;
 (p7)	dep r17=r17,r19,(PAGE_SHIFT-3),3	// put region number bits in place
+
 	srlz.d
-(p6)	movl r19=__pa(swapper_pg_dir)		// region 5 is rooted at swapper_pg_dir
+	LOAD_PHYSICAL(p6, r19, swapper_pg_dir)	// region 5 is rooted at swapper_pg_dir
+
+	.pred.rel "mutex", p6, p7
 (p6)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT
 (p7)	shr.u r21=r21,PGDIR_SHIFT+PAGE_SHIFT-3
 	;;
@@ -622,103 +633,95 @@
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x2c00 Entry 11 (size 64 bundles) Break instruction (33)
 ENTRY(break_fault)
+	/*
+	 * The streamlined system call entry/exit paths only save/restore the initial part
+	 * of pt_regs.  This implies that the callers of system-calls must adhere to the
+	 * normal procedure calling conventions.
+	 *
+	 *   Registers to be saved & restored:
+	 *	CR registers: cr.ipsr, cr.iip, cr.ifs
+	 *	AR registers: ar.unat, ar.pfs, ar.rsc, ar.rnat, ar.bspstore, ar.fpsr
+	 * 	others: pr, b0, b6, loadrs, r1, r11, r12, r13, r15
+	 *   Registers to be restored only:
+	 * 	r8-r11: output value from the system call.
+	 *
+	 * During system call exit, scratch registers (including r15) are modified/cleared
+	 * to prevent leaking bits from kernel to user level.
+	 */
 	DBG_FAULT(11)
-	mov r16=cr.iim
-	mov r17=__IA64_BREAK_SYSCALL
-	mov r31=pr		// prepare to save predicates
+	mov r16=IA64_KR(CURRENT)		// r16 = current task; 12 cycle read lat.
+	mov r17=cr.iim
+	mov r18=__IA64_BREAK_SYSCALL
+	mov r21=ar.fpsr
+	mov r29=cr.ipsr
+	mov r19=b6
+	mov r25=ar.unat
+	mov r27=ar.rsc
+	mov r26=ar.pfs
+	mov r28=cr.iip
+	mov r31=pr				// prepare to save predicates
+	mov r20=r1
 	;;
-	cmp.eq p0,p7=r16,r17	// is this a system call? (p7 <- false, if so)
+	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16
+	cmp.eq p0,p7=r18,r17			// is this a system call? (p7 <- false, if so)
 (p7)	br.cond.spnt non_syscall
+	;;
+	ld1 r17=[r16]				// load current->thread.on_ustack flag
+	st1 [r16]=r0				// clear current->thread.on_ustack flag
+	add r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16	// set r1 for MINSTATE_START_SAVE_MIN_VIRT
+	;;
+	invala
 
-	SAVE_MIN				// uses r31; defines r2:
+	/* adjust return address so we skip over the break instruction: */
 
-	ssm psr.ic | PSR_DEFAULT_BITS
+	extr.u r8=r29,41,2			// extract ei field from cr.ipsr
 	;;
-	srlz.i					// guarantee that interruption collection is on
-	cmp.eq pSys,pNonSys=r0,r0		// set pSys=1, pNonSys=0
+	cmp.eq p6,p7=2,r8			// isr.ei==2?
+	mov r2=r1				// setup r2 for ia64_syscall_setup
 	;;
-(p15)	ssm psr.i		// restore psr.i
-	adds r8=(IA64_PT_REGS_R8_OFFSET-IA64_PT_REGS_R16_OFFSET),r2
+(p6)	mov r8=0				// clear ei to 0
+(p6)	adds r28=16,r28				// switch cr.iip to next bundle cr.ipsr.ei wrapped
+(p7)	adds r8=1,r8				// increment ei to next slot
 	;;
-	stf8 [r8]=f1		// ensure pt_regs.r8 != 0 (see handle_syscall_error)
-	adds r3=8,r2		// set up second base pointer for SAVE_REST
+	cmp.eq pKStk,pUStk=r0,r17		// are we in kernel mode already?
+	dep r29=r8,r29,41,2			// insert new ei into cr.ipsr
 	;;
-	SAVE_REST
-	br.call.sptk.many rp=demine_args	// clear NaT bits in (potential) syscall args
 
-	mov r3=255
-	adds r15=-1024,r15			// r15 contains the syscall number---subtract 1024
+	// switch from user to kernel RBS:
+	MINSTATE_START_SAVE_MIN_VIRT
+	br.call.sptk.many b7=ia64_syscall_setup
 	;;
-	cmp.geu p6,p7=r3,r15		// (syscall > 0 && syscall <= 1024+255) ?
-	movl r16=sys_call_table
+	MINSTATE_END_SAVE_MIN_VIRT		// switch to bank 1
+	ssm psr.ic | PSR_DEFAULT_BITS
 	;;
-(p6)	shladd r16=r15,3,r16
-	movl r15=ia64_ret_from_syscall
-(p7)	adds r16=(__NR_ni_syscall-1024)*8,r16	// force __NR_ni_syscall
+	srlz.i					// guarantee that interruption collection is on
 	;;
-	ld8 r16=[r16]				// load address of syscall entry point
-	mov rp=r15				// set the real return addr
+(p15)	ssm psr.i				// restore psr.i
 	;;
-	mov b6=r16
-
-	// arrange things so we skip over break instruction when returning:
+	mov r3=NR_syscalls - 1
+	movl r16=sys_call_table
 
-	adds r16=16,sp				// get pointer to cr_ipsr
-	adds r17=24,sp				// get pointer to cr_iip
-	add r2=TI_FLAGS+IA64_TASK_SIZE,r13
-	;;
-	ld8 r18=[r16]				// fetch cr_ipsr
-	ld4 r2=[r2]				// r2 = current_thread_info()->flags
+	adds r15=-1024,r15			// r15 contains the syscall number---subtract 1024
+	movl r2=ia64_ret_from_syscall
 	;;
-	ld8 r19=[r17]				// fetch cr_iip
-	extr.u r20=r18,41,2			// extract ei field
+	shladd r20=r15,3,r16			// r20 = sys_call_table + 8*(syscall-1024)
+	cmp.geu p0,p7=r3,r15			// (syscall > 0 && syscall < 1024 + NR_syscalls) ?
+	mov rp=r2				// set the real return addr
 	;;
-	cmp.eq p6,p7=2,r20			// isr.ei==2?
-	adds r19=16,r19				// compute address of next bundle
+(p7)	add r20=(__NR_ni_syscall-1024)*8,r16	// force __NR_ni_syscall
+	add r2=TI_FLAGS+IA64_TASK_SIZE,r13
 	;;
-(p6)	mov r20=0				// clear ei to 0
-(p7)	adds r20=1,r20				// increment ei to next slot
+	ld8 r20=[r20]				// load address of syscall entry point
+	ld4 r2=[r2]				// r2 = current_thread_info()->flags
 	;;
-(p6)	st8 [r17]=r19				// store new cr.iip if cr.isr.ei wrapped around
-	dep r18=r20,r18,41,2			// insert new ei into cr.isr
 	tbit.z p8,p0=r2,TIF_SYSCALL_TRACE
+	mov b6=r20
 	;;
-	st8 [r16]=r18				// store new value for cr.isr
-
 (p8)	br.call.sptk.many b6=b6			// ignore this return addr
 	br.cond.sptk ia64_trace_syscall
 	// NOT REACHED
 END(break_fault)
 
-ENTRY_MIN_ALIGN(demine_args)
-	alloc r2=ar.pfs,8,0,0,0
-	tnat.nz p8,p0=in0
-	tnat.nz p9,p0=in1
-	;;
-(p8)	mov in0=-1
-	tnat.nz p10,p0=in2
-	tnat.nz p11,p0=in3
-
-(p9)	mov in1=-1
-	tnat.nz p12,p0=in4
-	tnat.nz p13,p0=in5
-	;;
-(p10)	mov in2=-1
-	tnat.nz p14,p0=in6
-	tnat.nz p15,p0=in7
-
-(p11)	mov in3=-1
-	tnat.nz p8,p0=r15	// demining r15 is not a must, but it is safer
-
-(p12)	mov in4=-1
-(p13)	mov in5=-1
-	;;
-(p14)	mov in6=-1
-(p15)	mov in7=-1
-(p8)	mov r15=-1
-	br.ret.sptk.many rp
-END(demine_args)
-
 	.org ia64_ivt+0x3000
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x3000 Entry 12 (size 64 bundles) External Interrupt (4)
@@ -726,7 +729,6 @@
 	DBG_FAULT(12)
 	mov r31=pr		// prepare to save predicates
 	;;
-
 	SAVE_MIN_WITH_COVER	// uses r31; defines r2 and r3
 	ssm psr.ic | PSR_DEFAULT_BITS
 	;;
@@ -739,7 +741,7 @@
 	mov out0=cr.ivr		// pass cr.ivr as first arg
 	add out1=16,sp		// pass pointer to pt_regs as second arg
 	;;
-	srlz.d			// make  sure we see the effect of cr.ivr
+	srlz.d			// make sure we see the effect of cr.ivr
 	movl r14=ia64_leave_kernel
 	;;
 	mov rp=r14
@@ -758,6 +760,131 @@
 	DBG_FAULT(14)
 	FAULT(14)
 
+	/*
+	 * There is no particular reason for this code to be here, other than that
+	 * there happens to be space here that would go unused otherwise.  If this
+	 * fault ever gets "unreserved", simply moved the following code to a more
+	 * suitable spot...
+	 *
+	 * ia64_syscall_setup() is a separate subroutine so that it can
+	 *	allocate stacked registers so it can safely demine any
+	 *	potential NaT values from the input registers.
+	 *
+	 * On entry:
+	 *	- executing on bank 0 or bank 1 register set (doesn't matter)
+	 *	-  r1: stack pointer
+	 *	-  r2: current task pointer
+	 *	-  r3: preserved
+	 *	- r11: original contents (saved ar.pfs to be saved)
+	 *	- r12: original contents (sp to be saved)
+	 *	- r13: original contents (tp to be saved)
+	 *	- r15: original contents (syscall # to be saved)
+	 *	- r18: saved bsp (after switching to kernel stack)
+	 *	- r19: saved b6
+	 *	- r20: saved r1 (gp)
+	 *	- r21: saved ar.fpsr
+	 *	- r22: kernel's register backing store base (krbs_base)
+	 *	- r23: saved ar.bspstore
+	 *	- r24: saved ar.rnat
+	 *	- r25: saved ar.unat
+	 *	- r26: saved ar.pfs
+	 *	- r27: saved ar.rsc
+	 *	- r28: saved cr.iip
+	 *	- r29: saved cr.ipsr
+	 *	- r31: saved pr
+	 *	-  b0: original contents (to be saved)
+	 * On exit:
+	 *	- executing on bank 1 registers
+	 *	- psr.ic enabled, interrupts restored
+	 *	-  r1: kernel's gp
+	 *	-  r3: preserved (same as on entry)
+	 *	- r12: points to kernel stack
+	 *	- r13: points to current task
+	 *	- p15: TRUE if interrupts need to be re-enabled
+	 *	- ar.fpsr: set to kernel settings
+	 */
+GLOBAL_ENTRY(ia64_syscall_setup)
+#if PT(B6) != 0
+# error This code assumes that b6 is the first field in pt_regs.
+#endif
+	st8 [r1]=r19				// save b6
+	add r16=PT(CR_IPSR),r1			// initialize first base pointer
+	add r17=PT(R11),r1			// initialize second base pointer
+	;;
+	alloc r19=ar.pfs,8,0,0,0		// ensure in0-in7 are writable
+	st8 [r16]=r29,PT(CR_IFS)-PT(CR_IPSR)	// save cr.ipsr
+	tnat.nz p8,p0=in0
+
+	st8.spill [r17]=r11,PT(CR_IIP)-PT(R11)	// save r11
+	tnat.nz p9,p0=in1
+(pKStk)	mov r18=r0				// make sure r18 isn't NaT
+	;;
+
+	st8 [r17]=r28,PT(AR_UNAT)-PT(CR_IIP)	// save cr.iip
+	mov r28=b0				// save b0 (2 cyc)
+(p8)	mov in0=-1
+	;;
+
+	st8 [r16]=r0,PT(AR_PFS)-PT(CR_IFS)	// clear cr.ifs
+	st8 [r17]=r25,PT(AR_RSC)-PT(AR_UNAT)	// save ar.unat
+(p9)	mov in1=-1
+	;;
+
+	st8 [r16]=r26,PT(AR_RNAT)-PT(AR_PFS)	// save ar.pfs
+	st8 [r17]=r27,PT(AR_BSPSTORE)-PT(AR_RSC)// save ar.rsc
+	tnat.nz p10,p0=in2
+
+(pUStk) sub r18=r18,r22				// r18=RSE.ndirty*8
+	tbit.nz p15,p0=r29,IA64_PSR_I_BIT
+	tnat.nz p11,p0=in3
+	;;
+(pKStk) adds r16=PT(PR)-PT(AR_RNAT),r16		// skip over ar_rnat field
+(pKStk) adds r17=PT(B0)-PT(AR_BSPSTORE),r17	// skip over ar_bspstore field
+(p10)	mov in2=-1
+
+(p11)	mov in3=-1
+	tnat.nz p12,p0=in4
+	tnat.nz p13,p0=in5
+	;;
+(pUStk) st8 [r16]=r24,PT(PR)-PT(AR_RNAT)	// save ar.rnat
+(pUStk) st8 [r17]=r23,PT(B0)-PT(AR_BSPSTORE)	// save ar.bspstore
+	shl r18=r18,16				// compute ar.rsc to be used for "loadrs"
+	;;
+	st8 [r16]=r31,PT(LOADRS)-PT(PR)		// save predicates
+	st8 [r17]=r28,PT(R1)-PT(B0)		// save b0
+(p12)	mov in4=-1
+	;;
+	st8 [r16]=r18,PT(R12)-PT(LOADRS)	// save ar.rsc value for "loadrs"
+	st8.spill [r17]=r20,PT(R13)-PT(R1)	// save original r1
+(p13)	mov in5=-1
+	;;
+
+.mem.offset 0,0; st8.spill [r16]=r12,PT(AR_FPSR)-PT(R12)	// save r12
+.mem.offset 8,0; st8.spill [r17]=r13,PT(R15)-PT(R13)		// save r13
+	tnat.nz p14,p0=in6
+	;;
+	st8 [r16]=r21,PT(R8)-PT(AR_FPSR)	// save ar.fpsr
+	st8.spill [r17]=r15			// save r15
+	tnat.nz p8,p0=in7
+	;;
+	stf8 [r16]=f1		// ensure pt_regs.r8 != 0 (see handle_syscall_error)
+	adds r12=-16,r1		// switch to kernel memory stack (with 16 bytes of scratch)
+(p14)	mov in6=-1
+
+	mov r13=r2				// establish `current'
+	movl r1=__gp				// establish kernel global pointer
+	;;
+(p8)	mov in7=-1
+	tnat.nz p9,p0=r15
+
+	cmp.eq pSys,pNonSys=r0,r0		// set pSys=1, pNonSys=0
+	movl r17=FPSR_DEFAULT
+	;;
+	mov.m ar.fpsr=r17			// set ar.fpsr to kernel default value
+(p9)	mov r15=-1
+	br.ret.sptk.many b7
+END(ia64_syscall_setup)
+
 	.org ia64_ivt+0x3c00
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x3c00 Entry 15 (size 64 bundles) Reserved
@@ -809,90 +936,6 @@
 	DBG_FAULT(16)
 	FAULT(16)
 
-#ifdef CONFIG_IA32_SUPPORT
-
-	/*
-	 * There is no particular reason for this code to be here, other than that
-	 * there happens to be space here that would go unused otherwise.  If this
-	 * fault ever gets "unreserved", simply moved the following code to a more
-	 * suitable spot...
-	 */
-
-	// IA32 interrupt entry point
-
-ENTRY(dispatch_to_ia32_handler)
-	SAVE_MIN
-	;;
-	mov r14=cr.isr
-	ssm psr.ic | PSR_DEFAULT_BITS
-	;;
-	srlz.i					// guarantee that interruption collection is on
-	;;
-(p15)	ssm psr.i
-	adds r3=8,r2            // Base pointer for SAVE_REST
-	;;
-	SAVE_REST
-	;;
-	mov r15=0x80
-	shr r14=r14,16          // Get interrupt number
-	;;
-	cmp.ne p6,p0=r14,r15
-(p6)    br.call.dpnt.many b6=non_ia32_syscall
-
-	adds r14=IA64_PT_REGS_R8_OFFSET + 16,sp	// 16 byte hole per SW conventions
-	adds r15=IA64_PT_REGS_R1_OFFSET + 16,sp
-	;;
-	cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
-	st8 [r15]=r8		// save original EAX in r1 (IA32 procs don't use the GP)
-	;;
-	alloc r15=ar.pfs,0,0,6,0	// must first in an insn group
-	;;
-	ld4 r8=[r14],8		// r8 == eax (syscall number)
-	mov r15=250		// number of entries in ia32 system call table
-	;;
-	cmp.ltu.unc p6,p7=r8,r15
-	ld4 out1=[r14],8	// r9 == ecx
-	;;
-	ld4 out2=[r14],8	// r10 == edx
-	;;
-	ld4 out0=[r14]		// r11 == ebx
-	adds r14=(IA64_PT_REGS_R8_OFFSET-(8*3)) + 16,sp
-	;;
-	ld4 out5=[r14],8	// r13 == ebp
-	;;
-	ld4 out3=[r14],8	// r14 == esi
-	adds r2=TI_FLAGS+IA64_TASK_SIZE,r13
-	;;
-	ld4 out4=[r14]		// r15 == edi
-	movl r16=ia32_syscall_table
-	;;
-(p6)    shladd r16=r8,3,r16	// force ni_syscall if not valid syscall number
-	ld4 r2=[r2]		// r2 = current_thread_info()->flags
-	;;
-	ld8 r16=[r16]
-	tbit.z p8,p0=r2,TIF_SYSCALL_TRACE
-	;;
-	mov b6=r16
-	movl r15=ia32_ret_from_syscall
-	;;
-	mov rp=r15
-(p8)	br.call.sptk.many b6=b6
-	br.cond.sptk ia32_trace_syscall
-
-non_ia32_syscall:
-	alloc r15=ar.pfs,0,0,2,0
-	mov out0=r14				// interrupt #
-	add out1=16,sp				// pointer to pt_regs
-	;;			// avoid WAW on CFM
-	br.call.sptk.many rp=ia32_bad_interrupt
-.ret1:	movl r15=ia64_leave_kernel
-	;;
-	mov rp=r15
-	br.ret.sptk.many rp
-END(dispatch_to_ia32_handler)
-
-#endif /* CONFIG_IA32_SUPPORT */
-
 	.org ia64_ivt+0x4400
 /////////////////////////////////////////////////////////////////////////////////////////
 // 0x4400 Entry 17 (size 64 bundles) Reserved
@@ -1428,3 +1471,89 @@
 // 0x7f00 Entry 67 (size 16 bundles) Reserved
 	DBG_FAULT(67)
 	FAULT(67)
+
+#ifdef CONFIG_IA32_SUPPORT
+
+	/*
+	 * There is no particular reason for this code to be here, other than that
+	 * there happens to be space here that would go unused otherwise.  If this
+	 * fault ever gets "unreserved", simply moved the following code to a more
+	 * suitable spot...
+	 */
+
+	// IA32 interrupt entry point
+
+ENTRY(dispatch_to_ia32_handler)
+	SAVE_MIN
+	;;
+	mov r14=cr.isr
+	ssm psr.ic | PSR_DEFAULT_BITS
+	;;
+	srlz.i					// guarantee that interruption collection is on
+	;;
+(p15)	ssm psr.i
+	adds r3=8,r2		// Base pointer for SAVE_REST
+	;;
+	SAVE_REST
+	;;
+	mov r15=0x80
+	shr r14=r14,16		// Get interrupt number
+	;;
+	cmp.ne p6,p0=r14,r15
+(p6)	br.call.dpnt.many b6=non_ia32_syscall
+
+	adds r14=IA64_PT_REGS_R8_OFFSET + 16,sp	// 16 byte hole per SW conventions
+	adds r15=IA64_PT_REGS_R1_OFFSET + 16,sp
+	;;
+	cmp.eq pSys,pNonSys=r0,r0 // set pSys=1, pNonSys=0
+	ld8 r8=[r14]		// get r8
+	;;
+	st8 [r15]=r8		// save original EAX in r1 (IA32 procs don't use the GP)
+	;;
+	alloc r15=ar.pfs,0,0,6,0	// must first in an insn group
+	;;
+	ld4 r8=[r14],8		// r8 == eax (syscall number)
+	mov r15=250		// number of entries in ia32 system call table
+	;;
+	cmp.ltu.unc p6,p7=r8,r15
+	ld4 out1=[r14],8	// r9 == ecx
+	;;
+	ld4 out2=[r14],8	// r10 == edx
+	;;
+	ld4 out0=[r14]		// r11 == ebx
+	adds r14=(IA64_PT_REGS_R13_OFFSET) + 16,sp
+	;;
+	ld4 out5=[r14],PT(R14)-PT(R13)	// r13 == ebp
+	;;
+	ld4 out3=[r14],PT(R15)-PT(R14)	// r14 == esi
+	adds r2=TI_FLAGS+IA64_TASK_SIZE,r13
+	;;
+	ld4 out4=[r14]		// r15 == edi
+	movl r16=ia32_syscall_table
+	;;
+(p6)	shladd r16=r8,3,r16	// force ni_syscall if not valid syscall number
+	ld4 r2=[r2]		// r2 = current_thread_info()->flags
+	;;
+	ld8 r16=[r16]
+	tbit.z p8,p0=r2,TIF_SYSCALL_TRACE
+	;;
+	mov b6=r16
+	movl r15=ia32_ret_from_syscall
+	;;
+	mov rp=r15
+(p8)	br.call.sptk.many b6=b6
+	br.cond.sptk ia32_trace_syscall
+
+non_ia32_syscall:
+	alloc r15=ar.pfs,0,0,2,0
+	mov out0=r14				// interrupt #
+	add out1=16,sp				// pointer to pt_regs
+	;;			// avoid WAW on CFM
+	br.call.sptk.many rp=ia32_bad_interrupt
+.ret1:	movl r15=ia64_leave_kernel
+	;;
+	mov rp=r15
+	br.ret.sptk.many rp
+END(dispatch_to_ia32_handler)
+
+#endif /* CONFIG_IA32_SUPPORT */
diff -Nru a/arch/ia64/kernel/mca.c b/arch/ia64/kernel/mca.c
--- a/arch/ia64/kernel/mca.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/kernel/mca.c	Wed Jun 18 23:42:07 2003
@@ -322,7 +322,7 @@
 }
 
 void
-init_handler_platform (sal_log_processor_info_t *proc_ptr,
+init_handler_platform (pal_min_state_area_t *ms,
 		       struct pt_regs *pt, struct switch_stack *sw)
 {
 	struct unw_frame_info info;
@@ -337,15 +337,18 @@
 	 */
 	printk("Delaying for 5 seconds...\n");
 	udelay(5*1000000);
-	show_min_state(&SAL_LPI_PSI_INFO(proc_ptr)->min_state_area);
+	show_min_state(ms);
 
 	printk("Backtrace of current task (pid %d, %s)\n", current->pid, current->comm);
-	fetch_min_state(&SAL_LPI_PSI_INFO(proc_ptr)->min_state_area, pt, sw);
+	fetch_min_state(ms, pt, sw);
 	unw_init_from_interruption(&info, current, pt, sw);
 	ia64_do_show_stack(&info, NULL);
 
+#ifdef CONFIG_SMP
+	/* read_trylock() would be handy... */
 	if (!tasklist_lock.write_lock)
 		read_lock(&tasklist_lock);
+#endif
 	{
 		struct task_struct *g, *t;
 		do_each_thread (g, t) {
@@ -353,11 +356,13 @@
 				continue;
 
 			printk("\nBacktrace of pid %d (%s)\n", t->pid, t->comm);
-			show_stack(t);
+			show_stack(t, NULL);
 		} while_each_thread (g, t);
 	}
+#ifdef CONFIG_SMP
 	if (!tasklist_lock.write_lock)
 		read_unlock(&tasklist_lock);
+#endif
 
 	printk("\nINIT dump complete.  Please reboot now.\n");
 	while (1);			/* hang city if no debugger */
@@ -657,17 +662,17 @@
 
 	IA64_MCA_DEBUG("ia64_mca_init: registered mca rendezvous spinloop and wakeup mech.\n");
 
-	ia64_mc_info.imi_mca_handler        = __pa(mca_hldlr_ptr->fp);
+	ia64_mc_info.imi_mca_handler        = ia64_tpa(mca_hldlr_ptr->fp);
 	/*
 	 * XXX - disable SAL checksum by setting size to 0; should be
-	 *	__pa(ia64_os_mca_dispatch_end) - __pa(ia64_os_mca_dispatch);
+	 *	ia64_tpa(ia64_os_mca_dispatch_end) - ia64_tpa(ia64_os_mca_dispatch);
 	 */
 	ia64_mc_info.imi_mca_handler_size	= 0;
 
 	/* Register the os mca handler with SAL */
 	if ((rc = ia64_sal_set_vectors(SAL_VECTOR_OS_MCA,
 				       ia64_mc_info.imi_mca_handler,
-				       mca_hldlr_ptr->gp,
+				       ia64_tpa(mca_hldlr_ptr->gp),
 				       ia64_mc_info.imi_mca_handler_size,
 				       0, 0, 0)))
 	{
@@ -677,15 +682,15 @@
 	}
 
 	IA64_MCA_DEBUG("ia64_mca_init: registered os mca handler with SAL at 0x%lx, gp = 0x%lx\n",
-		       ia64_mc_info.imi_mca_handler, mca_hldlr_ptr->gp);
+		       ia64_mc_info.imi_mca_handler, ia64_tpa(mca_hldlr_ptr->gp));
 
 	/*
 	 * XXX - disable SAL checksum by setting size to 0, should be
 	 * IA64_INIT_HANDLER_SIZE
 	 */
-	ia64_mc_info.imi_monarch_init_handler		= __pa(mon_init_ptr->fp);
+	ia64_mc_info.imi_monarch_init_handler		= ia64_tpa(mon_init_ptr->fp);
 	ia64_mc_info.imi_monarch_init_handler_size	= 0;
-	ia64_mc_info.imi_slave_init_handler		= __pa(slave_init_ptr->fp);
+	ia64_mc_info.imi_slave_init_handler		= ia64_tpa(slave_init_ptr->fp);
 	ia64_mc_info.imi_slave_init_handler_size	= 0;
 
 	IA64_MCA_DEBUG("ia64_mca_init: os init handler at %lx\n",
@@ -694,10 +699,10 @@
 	/* Register the os init handler with SAL */
 	if ((rc = ia64_sal_set_vectors(SAL_VECTOR_OS_INIT,
 				       ia64_mc_info.imi_monarch_init_handler,
-				       __pa(ia64_get_gp()),
+				       ia64_tpa(ia64_get_gp()),
 				       ia64_mc_info.imi_monarch_init_handler_size,
 				       ia64_mc_info.imi_slave_init_handler,
-				       __pa(ia64_get_gp()),
+				       ia64_tpa(ia64_get_gp()),
 				       ia64_mc_info.imi_slave_init_handler_size)))
 	{
 		printk(KERN_ERR "ia64_mca_init: Failed to register m/s init handlers with SAL. "
@@ -1235,32 +1240,19 @@
 void
 ia64_init_handler (struct pt_regs *pt, struct switch_stack *sw)
 {
-	sal_log_processor_info_t *proc_ptr;
-	ia64_err_rec_t *plog_ptr;
+	pal_min_state_area_t *ms;
 
-	printk(KERN_INFO "Entered OS INIT handler\n");
-
-	/* Get the INIT processor log */
-	if (!ia64_log_get(SAL_INFO_TYPE_INIT, (prfunc_t)printk))
-		return;                 // no record retrieved
-
-#ifdef IA64_DUMP_ALL_PROC_INFO
-	ia64_log_print(SAL_INFO_TYPE_INIT, (prfunc_t)printk);
-#endif
+	printk(KERN_INFO "Entered OS INIT handler. PSP=%lx\n",
+		ia64_sal_to_os_handoff_state.proc_state_param);
 
 	/*
-	 * get pointer to min state save area
-	 *
+	 * Address of minstate area provided by PAL is physical,
+	 * uncacheable (bit 63 set). Convert to Linux virtual
+	 * address in region 6.
 	 */
-	plog_ptr=(ia64_err_rec_t *)IA64_LOG_CURR_BUFFER(SAL_INFO_TYPE_INIT);
-	proc_ptr = &plog_ptr->proc_err;
-
-	ia64_process_min_state_save(&SAL_LPI_PSI_INFO(proc_ptr)->min_state_area);
-
-	/* Clear the INIT SAL logs now that they have been saved in the OS buffer */
-	ia64_sal_clear_state_info(SAL_INFO_TYPE_INIT);
+	ms = (pal_min_state_area_t *)(ia64_sal_to_os_handoff_state.pal_min_state | (6ul<<61));
 
-	init_handler_platform(proc_ptr, pt, sw);	/* call platform specific routines */
+	init_handler_platform(ms, pt, sw);	/* call platform specific routines */
 }
 
 /*
diff -Nru a/arch/ia64/kernel/mca_asm.S b/arch/ia64/kernel/mca_asm.S
--- a/arch/ia64/kernel/mca_asm.S	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/kernel/mca_asm.S	Wed Jun 18 23:42:09 2003
@@ -50,14 +50,15 @@
  *		6. GR12 = Return address to location within SAL_CHECK
  */
 #define SAL_TO_OS_MCA_HANDOFF_STATE_SAVE(_tmp)		\
-	movl	_tmp=ia64_sal_to_os_handoff_state;;	\
-	DATA_VA_TO_PA(_tmp);;				\
+	LOAD_PHYSICAL(p0, _tmp, ia64_sal_to_os_handoff_state);; \
 	st8	[_tmp]=r1,0x08;;			\
 	st8	[_tmp]=r8,0x08;;			\
 	st8	[_tmp]=r9,0x08;;			\
 	st8	[_tmp]=r10,0x08;;			\
 	st8	[_tmp]=r11,0x08;;			\
-	st8	[_tmp]=r12,0x08
+	st8	[_tmp]=r12,0x08;;			\
+	st8	[_tmp]=r17,0x08;;			\
+	st8	[_tmp]=r18,0x08
 
 /*
  * OS_MCA_TO_SAL_HANDOFF_STATE (SAL 3.0 spec)
@@ -70,9 +71,8 @@
  *	returns ptr to SAL rtn save loc in _tmp
  */
 #define OS_MCA_TO_SAL_HANDOFF_STATE_RESTORE(_tmp)	\
-(p6)	movl	_tmp=ia64_sal_to_os_handoff_state;;	\
-(p7)	movl	_tmp=ia64_os_to_sal_handoff_state;;	\
-	DATA_VA_TO_PA(_tmp);;				\
+	LOAD_PHYSICAL(p6, _tmp, ia64_sal_to_os_handoff_state);; \
+	LOAD_PHYSICAL(p7, _tmp, ia64_os_to_sal_handoff_state);; \
 (p6)	movl	r8=IA64_MCA_COLD_BOOT;			\
 (p6)	movl	r10=IA64_MCA_SAME_CONTEXT;		\
 (p6)	add     _tmp=0x18,_tmp;;			\
diff -Nru a/arch/ia64/kernel/minstate.h b/arch/ia64/kernel/minstate.h
--- a/arch/ia64/kernel/minstate.h	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/kernel/minstate.h	Wed Jun 18 23:42:09 2003
@@ -5,42 +5,24 @@
 #include "entry.h"
 
 /*
- * A couple of convenience macros that make writing and reading
- * SAVE_MIN and SAVE_REST easier.
- */
-#define rARPR		r31
-#define rCRIFS		r30
-#define rCRIPSR		r29
-#define rCRIIP		r28
-#define rARRSC		r27
-#define rARPFS		r26
-#define rARUNAT		r25
-#define rARRNAT		r24
-#define rARBSPSTORE	r23
-#define rKRBS		r22
-#define rB6		r21
-#define rR1		r20
-
-/*
- * Here start the source dependent macros.
- */
-
-/*
  * For ivt.s we want to access the stack virtually so we don't have to disable translation
  * on interrupts.
+ *
+ *  On entry:
+ *	r1:	pointer to current task (ar.k6)
  */
 #define MINSTATE_START_SAVE_MIN_VIRT								\
 (pUStk)	mov ar.rsc=0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
 	;;											\
-(pUStk)	mov.m rARRNAT=ar.rnat;									\
-(pUStk)	addl rKRBS=IA64_RBS_OFFSET,r1;			/* compute base of RBS */		\
+(pUStk)	mov.m r24=ar.rnat;									\
+(pUStk)	addl r22=IA64_RBS_OFFSET,r1;			/* compute base of RBS */		\
 (pKStk) mov r1=sp;					/* get sp  */				\
 	;;											\
-(pUStk) lfetch.fault.excl.nt1 [rKRBS];								\
+(pUStk) lfetch.fault.excl.nt1 [r22];								\
 (pUStk)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;	/* compute base of memory stack */	\
-(pUStk)	mov rARBSPSTORE=ar.bspstore;			/* save ar.bspstore */			\
+(pUStk)	mov r23=ar.bspstore;				/* save ar.bspstore */			\
 	;;											\
-(pUStk)	mov ar.bspstore=rKRBS;				/* switch to kernel RBS */		\
+(pUStk)	mov ar.bspstore=r22;				/* switch to kernel RBS */		\
 (pKStk) addl r1=-IA64_PT_REGS_SIZE,r1;			/* if in kernel mode, use sp (r12) */	\
 	;;											\
 (pUStk)	mov r18=ar.bsp;										\
@@ -57,16 +39,16 @@
 #define MINSTATE_START_SAVE_MIN_PHYS								\
 (pKStk) movl sp=ia64_init_stack+IA64_STK_OFFSET-IA64_PT_REGS_SIZE;				\
 (pUStk)	mov ar.rsc=0;		/* set enforced lazy mode, pl 0, little-endian, loadrs=0 */	\
-(pUStk)	addl rKRBS=IA64_RBS_OFFSET,r1;		/* compute base of register backing store */	\
+(pUStk)	addl r22=IA64_RBS_OFFSET,r1;		/* compute base of register backing store */	\
 	;;											\
-(pUStk)	mov rARRNAT=ar.rnat;									\
-(pKStk) dep r1=0,sp,61,3;				/* compute physical addr of sp	*/	\
+(pUStk)	mov r24=ar.rnat;									\
+(pKStk) tpa r1=sp;				/* compute physical addr of sp	*/		\
 (pUStk)	addl r1=IA64_STK_OFFSET-IA64_PT_REGS_SIZE,r1;	/* compute base of memory stack */	\
-(pUStk)	mov rARBSPSTORE=ar.bspstore;			/* save ar.bspstore */			\
-(pUStk)	dep rKRBS=-1,rKRBS,61,3;			/* compute kernel virtual addr of RBS */\
+(pUStk)	mov r23=ar.bspstore;				/* save ar.bspstore */			\
+(pUStk)	dep r22=-1,r22,61,3;			/* compute kernel virtual addr of RBS */	\
 	;;											\
 (pKStk) addl r1=-IA64_PT_REGS_SIZE,r1;		/* if in kernel mode, use sp (r12) */		\
-(pUStk)	mov ar.bspstore=rKRBS;			/* switch to kernel RBS */			\
+(pUStk)	mov ar.bspstore=r22;			/* switch to kernel RBS */			\
 	;;											\
 (pUStk)	mov r18=ar.bsp;										\
 (pUStk)	mov ar.rsc=0x3;		/* set eager mode, pl 0, little-endian, loadrs=0 */		\
@@ -99,153 +81,170 @@
  *
  * Upon exit, the state is as follows:
  *	psr.ic: off
- *	r2 = points to &pt_regs.r16
+ *	 r2 = points to &pt_regs.r16
+ *	 r8 = contents of ar.ccv
+ *	 r9 = contents of ar.csd
+ *	r10 = contents of ar.ssd
+ *	r11 = FPSR_DEFAULT
  *	r12 = kernel sp (kernel virtual address)
  *	r13 = points to current task_struct (kernel virtual address)
  *	p15 = TRUE if psr.i is set in cr.ipsr
- *	predicate registers (other than p2, p3, and p15), b6, r3, r8, r9, r10, r11, r14, r15:
+ *	predicate registers (other than p2, p3, and p15), b6, r3, r14, r15:
  *		preserved
  *
  * Note that psr.ic is NOT turned on by this macro.  This is so that
  * we can pass interruption state as arguments to a handler.
  */
-#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA)							  \
-	mov rARRSC=ar.rsc;		/* M */							  \
-	mov rARUNAT=ar.unat;		/* M */							  \
-	mov rR1=r1;			/* A */							  \
-	MINSTATE_GET_CURRENT(r1);	/* M (or M;;I) */					  \
-	mov rCRIPSR=cr.ipsr;		/* M */							  \
-	mov rARPFS=ar.pfs;		/* I */							  \
-	mov rCRIIP=cr.iip;		/* M */							  \
-	mov rB6=b6;			/* I */	/* rB6 = branch reg 6 */			  \
-	COVER;				/* B;; (or nothing) */					  \
-	;;											  \
-	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r1;						  \
-	;;											  \
-	ld1 r17=[r16];				/* load current->thread.on_ustack flag */	  \
-	st1 [r16]=r0;				/* clear current->thread.on_ustack flag */	  \
-	/* switch from user to kernel RBS: */							  \
-	;;											  \
-	invala;				/* M */							  \
-	SAVE_IFS;										  \
-	cmp.eq pKStk,pUStk=r0,r17;		/* are we in kernel mode already? (psr.cpl==0) */ \
-	;;											  \
-	MINSTATE_START_SAVE_MIN									  \
-	add r17=L1_CACHE_BYTES,r1			/* really: biggest cache-line size */	  \
-	;;											  \
-	st8 [r1]=rCRIPSR;	/* save cr.ipsr */						  \
-	lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES;						  \
-	add r16=16,r1;					/* initialize first base pointer */	  \
-	;;											  \
-	lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES;						  \
-	;;											  \
-	lfetch.fault.excl.nt1 [r17];								  \
-	adds r17=8,r1;					/* initialize second base pointer */	  \
-(pKStk)	mov r18=r0;		/* make sure r18 isn't NaT */					  \
-	;;											  \
-	st8 [r17]=rCRIIP,16;	/* save cr.iip */						  \
-	st8 [r16]=rCRIFS,16;	/* save cr.ifs */						  \
-(pUStk)	sub r18=r18,rKRBS;	/* r18=RSE.ndirty*8 */						  \
-	;;											  \
-	st8 [r17]=rARUNAT,16;	/* save ar.unat */						  \
-	st8 [r16]=rARPFS,16;	/* save ar.pfs */						  \
-	shl r18=r18,16;		/* compute ar.rsc to be used for "loadrs" */			  \
-	;;											  \
-	st8 [r17]=rARRSC,16;	/* save ar.rsc */						  \
-(pUStk)	st8 [r16]=rARRNAT,16;	/* save ar.rnat */						  \
-(pKStk)	adds r16=16,r16;	/* skip over ar_rnat field */					  \
-	;;			/* avoid RAW on r16 & r17 */					  \
-(pUStk)	st8 [r17]=rARBSPSTORE,16;	/* save ar.bspstore */					  \
-	st8 [r16]=rARPR,16;	/* save predicates */						  \
-(pKStk)	adds r17=16,r17;	/* skip over ar_bspstore field */				  \
-	;;											  \
-	st8 [r17]=rB6,16;	/* save b6 */							  \
-	st8 [r16]=r18,16;	/* save ar.rsc value for "loadrs" */				  \
-	tbit.nz p15,p0=rCRIPSR,IA64_PSR_I_BIT							  \
-	;;											  \
-.mem.offset 8,0;	st8.spill [r17]=rR1,16;	/* save original r1 */				  \
-.mem.offset 0,0;	st8.spill [r16]=r2,16;							  \
-	;;											  \
-.mem.offset 8,0;	st8.spill [r17]=r3,16;							  \
-.mem.offset 0,0;	st8.spill [r16]=r12,16;							  \
-	adds r2=IA64_PT_REGS_R16_OFFSET,r1;							  \
-	;;											  \
-.mem.offset 8,0;	st8.spill [r17]=r13,16;							  \
-.mem.offset 0,0;	st8.spill [r16]=r14,16;							  \
-	cmp.eq pNonSys,pSys=r0,r0	/* initialize pSys=0, pNonSys=1 */			  \
-	;;											  \
-.mem.offset 8,0;	st8.spill [r17]=r15,16;							  \
-.mem.offset 0,0;	st8.spill [r16]=r8,16;							  \
-	dep r14=-1,r0,61,3;									  \
-	;;											  \
-.mem.offset 8,0;	st8.spill [r17]=r9,16;							  \
-.mem.offset 0,0;	st8.spill [r16]=r10,16;							  \
-	adds r12=-16,r1;	/* switch to kernel memory stack (with 16 bytes of scratch) */	  \
-	;;											  \
-.mem.offset 8,0;	st8.spill [r17]=r11,16;							  \
-	mov r13=IA64_KR(CURRENT);	/* establish `current' */				  \
-	;;											  \
-	EXTRA;											  \
-	movl r1=__gp;		/* establish kernel global pointer */				  \
-	;;											  \
+#define DO_SAVE_MIN(COVER,SAVE_IFS,EXTRA)							\
+	MINSTATE_GET_CURRENT(r16);	/* M (or M;;I) */					\
+	mov r27=ar.rsc;			/* M */							\
+	mov r20=r1;			/* A */							\
+	mov r25=ar.unat;		/* M */							\
+	mov r29=cr.ipsr;		/* M */							\
+	mov r26=ar.pfs;			/* I */							\
+	mov r28=cr.iip;			/* M */							\
+	mov r21=ar.fpsr;		/* M */							\
+	COVER;				/* B;; (or nothing) */					\
+	;;											\
+	adds r16=IA64_TASK_THREAD_ON_USTACK_OFFSET,r16;						\
+	;;											\
+	ld1 r17=[r16];				/* load current->thread.on_ustack flag */	\
+	st1 [r16]=r0;				/* clear current->thread.on_ustack flag */	\
+	adds r1=-IA64_TASK_THREAD_ON_USTACK_OFFSET,r16						\
+	/* switch from user to kernel RBS: */							\
+	;;											\
+	invala;				/* M */							\
+	SAVE_IFS;										\
+	cmp.eq pKStk,pUStk=r0,r17;		/* are we in kernel mode already? */		\
+	;;											\
+	MINSTATE_START_SAVE_MIN									\
+	adds r17=2*L1_CACHE_BYTES,r1;		/* really: biggest cache-line size */		\
+	adds r16=PT(CR_IPSR),r1;								\
+	;;											\
+	lfetch.fault.excl.nt1 [r17],L1_CACHE_BYTES;						\
+	st8 [r16]=r29;		/* save cr.ipsr */						\
+	;;											\
+	lfetch.fault.excl.nt1 [r17];								\
+	tbit.nz p15,p0=r29,IA64_PSR_I_BIT;							\
+	mov r29=b0										\
+	;;											\
+	adds r16=PT(R8),r1;	/* initialize first base pointer */				\
+	adds r17=PT(R9),r1;	/* initialize second base pointer */				\
+(pKStk)	mov r18=r0;		/* make sure r18 isn't NaT */					\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r8,16;								\
+.mem.offset 8,0; st8.spill [r17]=r9,16;								\
+        ;;											\
+.mem.offset 0,0; st8.spill [r16]=r10,24;							\
+.mem.offset 8,0; st8.spill [r17]=r11,24;							\
+        ;;											\
+	st8 [r16]=r28,16;	/* save cr.iip */						\
+	st8 [r17]=r30,16;	/* save cr.ifs */						\
+(pUStk)	sub r18=r18,r22;	/* r18=RSE.ndirty*8 */						\
+	mov r8=ar.ccv;										\
+	mov r9=ar.csd;										\
+	mov r10=ar.ssd;										\
+	movl r11=FPSR_DEFAULT;   /* L-unit */							\
+	;;											\
+	st8 [r16]=r25,16;	/* save ar.unat */						\
+	st8 [r17]=r26,16;	/* save ar.pfs */						\
+	shl r18=r18,16;		/* compute ar.rsc to be used for "loadrs" */			\
+	;;											\
+	st8 [r16]=r27,16;	/* save ar.rsc */						\
+(pUStk)	st8 [r17]=r24,16;	/* save ar.rnat */						\
+(pKStk)	adds r17=16,r17;	/* skip over ar_rnat field */					\
+	;;			/* avoid RAW on r16 & r17 */					\
+(pUStk)	st8 [r16]=r23,16;	/* save ar.bspstore */						\
+	st8 [r17]=r31,16;	/* save predicates */						\
+(pKStk)	adds r16=16,r16;	/* skip over ar_bspstore field */				\
+	;;											\
+	st8 [r16]=r29,16;	/* save b0 */							\
+	st8 [r17]=r18,16;	/* save ar.rsc value for "loadrs" */				\
+	cmp.eq pNonSys,pSys=r0,r0	/* initialize pSys=0, pNonSys=1 */			\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r20,16;	/* save original r1 */				\
+.mem.offset 8,0; st8.spill [r17]=r12,16;							\
+	adds r12=-16,r1;	/* switch to kernel memory stack (with 16 bytes of scratch) */	\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r13,16;							\
+.mem.offset 8,0; st8.spill [r17]=r21,16;	/* save ar.fpsr */				\
+	mov r13=IA64_KR(CURRENT);	/* establish `current' */				\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r15,16;							\
+.mem.offset 8,0; st8.spill [r17]=r14,16;							\
+	dep r14=-1,r0,61,3;									\
+	;;											\
+.mem.offset 0,0; st8.spill [r16]=r2,16;								\
+.mem.offset 8,0; st8.spill [r17]=r3,16;								\
+	adds r2=IA64_PT_REGS_R16_OFFSET,r1;							\
+	;;											\
+	EXTRA;											\
+	movl r1=__gp;		/* establish kernel global pointer */				\
+	;;											\
 	MINSTATE_END_SAVE_MIN
 
 /*
- * SAVE_REST saves the remainder of pt_regs (with psr.ic on).  This
- * macro guarantees to preserve all predicate registers, r8, r9, r10,
- * r11, r14, and r15.
+ * SAVE_REST saves the remainder of pt_regs (with psr.ic on).
  *
  * Assumed state upon entry:
  *	psr.ic: on
  *	r2:	points to &pt_regs.r16
  *	r3:	points to &pt_regs.r17
+ *	r8:	contents of ar.ccv
+ *	r9:	contents of ar.csd
+ *	r10:	contents of ar.ssd
+ *	r11:	FPSR_DEFAULT
+ *
+ * Registers r14 and r15 are guaranteed not to be touched by SAVE_REST.
  */
 #define SAVE_REST				\
-.mem.offset 0,0;	st8.spill [r2]=r16,16;	\
-	;;					\
-.mem.offset 8,0;	st8.spill [r3]=r17,16;	\
-.mem.offset 0,0;	st8.spill [r2]=r18,16;	\
-	;;					\
-.mem.offset 8,0;	st8.spill [r3]=r19,16;	\
-.mem.offset 0,0;	st8.spill [r2]=r20,16;	\
+.mem.offset 0,0; st8.spill [r2]=r16,16;		\
+.mem.offset 8,0; st8.spill [r3]=r17,16;		\
 	;;					\
-	mov r16=ar.ccv;		/* M-unit */	\
-	movl r18=FPSR_DEFAULT	/* L-unit */	\
+.mem.offset 0,0; st8.spill [r2]=r18,16;		\
+.mem.offset 8,0; st8.spill [r3]=r19,16;		\
 	;;					\
-	mov r17=ar.fpsr;	/* M-unit */	\
-	mov ar.fpsr=r18;	/* M-unit */	\
+.mem.offset 0,0; st8.spill [r2]=r20,16;		\
+.mem.offset 8,0; st8.spill [r3]=r21,16;		\
+	mov r18=b6;				\
 	;;					\
-.mem.offset 8,0;	st8.spill [r3]=r21,16;	\
-.mem.offset 0,0;	st8.spill [r2]=r22,16;	\
-	mov r18=b0;				\
-	;;					\
-.mem.offset 8,0;	st8.spill [r3]=r23,16;	\
-.mem.offset 0,0;	st8.spill [r2]=r24,16;	\
+.mem.offset 0,0; st8.spill [r2]=r22,16;		\
+.mem.offset 8,0; st8.spill [r3]=r23,16;		\
 	mov r19=b7;				\
 	;;					\
-.mem.offset 8,0;	st8.spill [r3]=r25,16;	\
-.mem.offset 0,0;	st8.spill [r2]=r26,16;	\
-	;;					\
-.mem.offset 8,0;	st8.spill [r3]=r27,16;	\
-.mem.offset 0,0;	st8.spill [r2]=r28,16;	\
+.mem.offset 0,0; st8.spill [r2]=r24,16;		\
+.mem.offset 8,0; st8.spill [r3]=r25,16;		\
 	;;					\
-.mem.offset 8,0;	st8.spill [r3]=r29,16;	\
-.mem.offset 0,0;	st8.spill [r2]=r30,16;	\
+.mem.offset 0,0; st8.spill [r2]=r26,16;		\
+.mem.offset 8,0; st8.spill [r3]=r27,16;		\
 	;;					\
-.mem.offset 8,0;	st8.spill [r3]=r31,16;	\
-	st8 [r2]=r16,16;	/* ar.ccv */	\
+.mem.offset 0,0; st8.spill [r2]=r28,16;		\
+.mem.offset 8,0; st8.spill [r3]=r29,16;		\
 	;;					\
-	st8 [r3]=r17,16;	/* ar.fpsr */	\
-	st8 [r2]=r18,16;	/* b0 */	\
+.mem.offset 0,0; st8.spill [r2]=r30,16;		\
+.mem.offset 8,0; st8.spill [r3]=r31,32;		\
 	;;					\
-	st8 [r3]=r19,16+8;	/* b7 */	\
+	mov ar.fpsr=r11;	/* M-unit */	\
+	st8 [r2]=r8,8;		/* ar.ccv */	\
+	adds r24=PT(B6)-PT(F7),r3;		\
 	;;					\
 	stf.spill [r2]=f6,32;			\
 	stf.spill [r3]=f7,32;			\
 	;;					\
 	stf.spill [r2]=f8,32;			\
-	stf.spill [r3]=f9,32
+	stf.spill [r3]=f9,32;			\
+	;;					\
+	stf.spill [r2]=f10;			\
+	stf.spill [r3]=f11;			\
+	adds r25=PT(B7)-PT(F11),r3;		\
+	;;					\
+	st8 [r24]=r18,16;       /* b6 */	\
+	st8 [r25]=r19,16;       /* b7 */	\
+	;;					\
+	st8 [r24]=r9;        	/* ar.csd */	\
+	st8 [r25]=r10;      	/* ar.ssd */	\
+	;;
 
-#define SAVE_MIN_WITH_COVER	DO_SAVE_MIN(cover, mov rCRIFS=cr.ifs,)
-#define SAVE_MIN_WITH_COVER_R19	DO_SAVE_MIN(cover, mov rCRIFS=cr.ifs, mov r15=r19)
-#define SAVE_MIN		DO_SAVE_MIN(     , mov rCRIFS=r0, )
+#define SAVE_MIN_WITH_COVER	DO_SAVE_MIN(cover, mov r30=cr.ifs,)
+#define SAVE_MIN_WITH_COVER_R19	DO_SAVE_MIN(cover, mov r30=cr.ifs, mov r15=r19)
+#define SAVE_MIN		DO_SAVE_MIN(     , mov r30=r0, )
diff -Nru a/arch/ia64/kernel/module.c b/arch/ia64/kernel/module.c
--- a/arch/ia64/kernel/module.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/kernel/module.c	Wed Jun 18 23:42:07 2003
@@ -18,7 +18,8 @@
    LTOFF22X
    LTOFF22X
    LTOFF_FPTR22
-   PCREL21B
+   PCREL21B	(for br.call only; br.cond is not supported out of modules!)
+   PCREL60B	(for brl.cond only; brl.call is not supported for modules!)
    PCREL64LSB
    SECREL32LSB
    SEGREL64LSB
@@ -33,6 +34,7 @@
 #include <linux/string.h>
 #include <linux/vmalloc.h>
 
+#include <asm/patch.h>
 #include <asm/unaligned.h>
 
 #define ARCH_MODULE_DEBUG 0
@@ -158,27 +160,6 @@
 	return (uint64_t) insn & 0x3;
 }
 
-/* Patch instruction with "val" where "mask" has 1 bits. */
-static void
-apply (struct insn *insn, uint64_t mask, uint64_t val)
-{
-	uint64_t m0, m1, v0, v1, b0, b1, *b = (uint64_t *) bundle(insn);
-#	define insn_mask ((1UL << 41) - 1)
-	unsigned long shift;
-
-	b0 = b[0]; b1 = b[1];
-	shift = 5 + 41 * slot(insn); /* 5 bits of template, then 3 x 41-bit instructions */
-	if (shift >= 64) {
-		m1 = mask << (shift - 64);
-		v1 = val << (shift - 64);
-	} else {
-		m0 = mask << shift; m1 = mask >> (64 - shift);
-		v0 = val  << shift; v1 = val >> (64 - shift);
-		b[0] = (b0 & ~m0) | (v0 & m0);
-	}
-	b[1] = (b1 & ~m1) | (v1 & m1);
-}
-
 static int
 apply_imm64 (struct module *mod, struct insn *insn, uint64_t val)
 {
@@ -187,12 +168,7 @@
 		       mod->name, slot(insn));
 		return 0;
 	}
-	apply(insn, 0x01fffefe000, (  ((val & 0x8000000000000000) >> 27) /* bit 63 -> 36 */
-				    | ((val & 0x0000000000200000) <<  0) /* bit 21 -> 21 */
-				    | ((val & 0x00000000001f0000) <<  6) /* bit 16 -> 22 */
-				    | ((val & 0x000000000000ff80) << 20) /* bit  7 -> 27 */
-				    | ((val & 0x000000000000007f) << 13) /* bit  0 -> 13 */));
-	apply((void *) insn - 1, 0x1ffffffffff, val >> 22);
+	ia64_patch_imm64((u64) insn, val);
 	return 1;
 }
 
@@ -208,9 +184,7 @@
 		printk(KERN_ERR "%s: value %ld out of IMM60 range\n", mod->name, (int64_t) val);
 		return 0;
 	}
-	apply(insn, 0x011ffffe000, (  ((val & 0x1000000000000000) >> 24) /* bit 60 -> 36 */
-				    | ((val & 0x00000000000fffff) << 13) /* bit  0 -> 13 */));
-	apply((void *) insn - 1, 0x1fffffffffc, val >> 18);
+	ia64_patch_imm60((u64) insn, val);
 	return 1;
 }
 
@@ -221,10 +195,10 @@
 		printk(KERN_ERR "%s: value %li out of IMM22 range\n", mod->name, (int64_t)val);
 		return 0;
 	}
-	apply(insn, 0x01fffcfe000, (  ((val & 0x200000) << 15) /* bit 21 -> 36 */
-				    | ((val & 0x1f0000)	<<  6) /* bit 16 -> 22 */
-				    | ((val & 0x00ff80) << 20) /* bit  7 -> 27 */
-				    | ((val & 0x00007f)	<< 13) /* bit  0 -> 13 */));
+	ia64_patch((u64) insn, 0x01fffcfe000, (  ((val & 0x200000) << 15) /* bit 21 -> 36 */
+					       | ((val & 0x1f0000) <<  6) /* bit 16 -> 22 */
+					       | ((val & 0x00ff80) << 20) /* bit  7 -> 27 */
+					       | ((val & 0x00007f) << 13) /* bit  0 -> 13 */));
 	return 1;
 }
 
@@ -235,8 +209,8 @@
 		printk(KERN_ERR "%s: value %li out of IMM21b range\n", mod->name, (int64_t)val);
 		return 0;
 	}
-	apply(insn, 0x11ffffe000, (  ((val & 0x100000) << 16) /* bit 20 -> 36 */
-				   | ((val & 0x0fffff) << 13) /* bit  0 -> 13 */));
+	ia64_patch((u64) insn, 0x11ffffe000, (  ((val & 0x100000) << 16) /* bit 20 -> 36 */
+					      | ((val & 0x0fffff) << 13) /* bit  0 -> 13 */));
 	return 1;
 }
 
@@ -281,7 +255,7 @@
 	b0 = b[0]; b1 = b[1];
 	off = (  ((b1 & 0x00fffff000000000) >> 36)		/* imm20b -> bit 0 */
 	       | ((b0 >> 48) << 20) | ((b1 & 0x7fffff) << 36)	/* imm39 -> bit 20 */
-	       | ((b1 & 0x0800000000000000) << 1));		/* i -> bit 60 */
+	       | ((b1 & 0x0800000000000000) << 0));		/* i -> bit 59 */
 	return (long) plt->bundle[1] + 16*off;
 }
 
@@ -751,7 +725,7 @@
 			if (gp_addressable(mod, val)) {
 				/* turn "ld8" into "mov": */
 				DEBUGP("%s: patching ld8 at %p to mov\n", __FUNCTION__, location);
-				apply(location, 0x1fff80fe000, 0x10000000000);
+				ia64_patch((u64) location, 0x1fff80fe000, 0x10000000000);
 			}
 			return 0;
 
@@ -889,7 +863,8 @@
 }
 
 #ifdef CONFIG_SMP
-void percpu_modcopy(void *pcpudst, const void *src, unsigned long size)
+void
+percpu_modcopy (void  *pcpudst, const void *src, unsigned long size)
 {
 	unsigned int i;
 	for (i = 0; i < NR_CPUS; i++)
diff -Nru a/arch/ia64/kernel/pal.S b/arch/ia64/kernel/pal.S
--- a/arch/ia64/kernel/pal.S	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/kernel/pal.S	Wed Jun 18 23:42:09 2003
@@ -164,7 +164,7 @@
 	;;
 	mov loc4=ar.rsc			// save RSE configuration
 	dep.z loc2=loc2,0,61		// convert pal entry point to physical
-	dep.z r8=r8,0,61		// convert rp to physical
+	tpa r8=r8			// convert rp to physical
 	;;
 	mov b7 = loc2			// install target to branch reg
 	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
@@ -174,13 +174,13 @@
 	or loc3=loc3,r17		// add in psr the bits to set
 	;;
 	andcm r16=loc3,r16		// removes bits to clear from psr
-	br.call.sptk.many rp=ia64_switch_mode
+	br.call.sptk.many rp=ia64_switch_mode_phys
 .ret1:	mov rp = r8			// install return address (physical)
 	br.cond.sptk.many b7
 1:
 	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
 	mov r16=loc3			// r16= original psr
-	br.call.sptk.many rp=ia64_switch_mode // return to virtual mode
+	br.call.sptk.many rp=ia64_switch_mode_virt // return to virtual mode
 .ret2:
 	mov psr.l = loc3		// restore init PSR
 
@@ -228,13 +228,13 @@
 	mov b7 = loc2			// install target to branch reg
 	;;
 	andcm r16=loc3,r16		// removes bits to clear from psr
-	br.call.sptk.many rp=ia64_switch_mode
+	br.call.sptk.many rp=ia64_switch_mode_phys
 .ret6:
 	br.call.sptk.many rp=b7		// now make the call
 .ret7:
 	mov ar.rsc=0			// put RSE in enforced lazy, LE mode
 	mov r16=loc3			// r16= original psr
-	br.call.sptk.many rp=ia64_switch_mode	// return to virtual mode
+	br.call.sptk.many rp=ia64_switch_mode_virt	// return to virtual mode
 
 .ret8:	mov psr.l  = loc3		// restore init PSR
 	mov ar.pfs = loc1
diff -Nru a/arch/ia64/kernel/patch.c b/arch/ia64/kernel/patch.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/kernel/patch.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,194 @@
+/*
+ * Instruction-patching support.
+ *
+ * Copyright (C) 2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ */
+#include <linux/init.h>
+#include <linux/string.h>
+
+#include <asm/patch.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/unistd.h>
+
+/*
+ * This was adapted from code written by Tony Luck:
+ *
+ * The 64-bit value in a "movl reg=value" is scattered between the two words of the bundle
+ * like this:
+ *
+ * 6  6         5         4         3         2         1
+ * 3210987654321098765432109876543210987654321098765432109876543210
+ * ABBBBBBBBBBBBBBBBBBBBBBBCCCCCCCCCCCCCCCCCCDEEEEEFFFFFFFFFGGGGGGG
+ *
+ * CCCCCCCCCCCCCCCCCCxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
+ * xxxxAFFFFFFFFFEEEEEDxGGGGGGGxxxxxxxxxxxxxBBBBBBBBBBBBBBBBBBBBBBB
+ */
+static u64
+get_imm64 (u64 insn_addr)
+{
+	u64 *p = (u64 *) (insn_addr & -16);	/* mask out slot number */
+
+	return ( (p[1] & 0x0800000000000000UL) << 4)  | /*A*/
+		((p[1] & 0x00000000007fffffUL) << 40) | /*B*/
+		((p[0] & 0xffffc00000000000UL) >> 24) | /*C*/
+		((p[1] & 0x0000100000000000UL) >> 23) | /*D*/
+		((p[1] & 0x0003e00000000000UL) >> 29) | /*E*/
+		((p[1] & 0x07fc000000000000UL) >> 43) | /*F*/
+		((p[1] & 0x000007f000000000UL) >> 36);  /*G*/
+}
+
+/* Patch instruction with "val" where "mask" has 1 bits. */
+void
+ia64_patch (u64 insn_addr, u64 mask, u64 val)
+{
+	u64 m0, m1, v0, v1, b0, b1, *b = (u64 *) (insn_addr & -16);
+#	define insn_mask ((1UL << 41) - 1)
+	unsigned long shift;
+
+	b0 = b[0]; b1 = b[1];
+	shift = 5 + 41 * (insn_addr % 16); /* 5 bits of template, then 3 x 41-bit instructions */
+	if (shift >= 64) {
+		m1 = mask << (shift - 64);
+		v1 = val << (shift - 64);
+	} else {
+		m0 = mask << shift; m1 = mask >> (64 - shift);
+		v0 = val  << shift; v1 = val >> (64 - shift);
+		b[0] = (b0 & ~m0) | (v0 & m0);
+	}
+	b[1] = (b1 & ~m1) | (v1 & m1);
+}
+
+void
+ia64_patch_imm64 (u64 insn_addr, u64 val)
+{
+	ia64_patch(insn_addr,
+		   0x01fffefe000, (  ((val & 0x8000000000000000) >> 27) /* bit 63 -> 36 */
+				   | ((val & 0x0000000000200000) <<  0) /* bit 21 -> 21 */
+				   | ((val & 0x00000000001f0000) <<  6) /* bit 16 -> 22 */
+				   | ((val & 0x000000000000ff80) << 20) /* bit  7 -> 27 */
+				   | ((val & 0x000000000000007f) << 13) /* bit  0 -> 13 */));
+	ia64_patch(insn_addr - 1, 0x1ffffffffff, val >> 22);
+}
+
+void
+ia64_patch_imm60 (u64 insn_addr, u64 val)
+{
+	ia64_patch(insn_addr,
+		   0x011ffffe000, (  ((val & 0x1000000000000000) >> 24) /* bit 60 -> 36 */
+				   | ((val & 0x00000000000fffff) << 13) /* bit  0 -> 13 */));
+	ia64_patch(insn_addr - 1, 0x1fffffffffc, val >> 18);
+}
+
+/*
+ * We need sometimes to load the physical address of a kernel
+ * object.  Often we can convert the virtual address to physical
+ * at execution time, but sometimes (either for performance reasons
+ * or during error recovery) we cannot to this.  Patch the marked
+ * bundles to load the physical address.
+ */
+void __init
+ia64_patch_vtop (unsigned long start, unsigned long end)
+{
+	s32 *offp = (s32 *) start;
+	u64 ip;
+
+	while (offp < (s32 *) end) {
+		ip = (u64) offp + *offp;
+
+		/* replace virtual address with corresponding physical address: */
+		ia64_patch_imm64(ip, ia64_tpa(get_imm64(ip)));
+		ia64_fc((void *) ip);
+		++offp;
+	}
+	ia64_sync_i();
+	ia64_srlz_i();
+}
+
+void
+ia64_patch_mckinley_e9 (unsigned long start, unsigned long end)
+{
+	static int first_time = 1;
+	int need_workaround;
+	s32 *offp = (s32 *) start;
+	u64 *wp;
+
+	need_workaround = (local_cpu_data->family == 0x1f && local_cpu_data->model == 0);
+
+	if (first_time) {
+		first_time = 0;
+		if (need_workaround)
+			printk(KERN_INFO "Leaving McKinley Errata 9 workaround enabled\n");
+		else
+			printk(KERN_INFO "McKinley Errata 9 workaround not needed; "
+			       "disabling it\n");
+	}
+	if (need_workaround)
+		return;
+
+	while (offp < (s32 *) end) {
+		wp = (u64 *) ia64_imva((char *) offp + *offp);
+		wp[0] = 0x0000000100000000;
+		wp[1] = 0x0004000000000200;
+		ia64_fc(wp);
+		++offp;
+	}
+	ia64_sync_i();
+	ia64_srlz_i();
+}
+
+static void
+patch_fsyscall_table (unsigned long start, unsigned long end)
+{
+	extern unsigned long fsyscall_table[NR_syscalls];
+	s32 *offp = (s32 *) start;
+	u64 ip;
+
+	while (offp < (s32 *) end) {
+		ip = (u64) ia64_imva((char *) offp + *offp);
+		ia64_patch_imm64(ip, (u64) fsyscall_table);
+		ia64_fc((void *) ip);
+		++offp;
+	}
+	ia64_sync_i();
+	ia64_srlz_i();
+}
+
+static void
+patch_brl_fsys_bubble_down (unsigned long start, unsigned long end)
+{
+	extern char fsys_bubble_down[];
+	s32 *offp = (s32 *) start;
+	u64 ip;
+
+	while (offp < (s32 *) end) {
+		ip = (u64) offp + *offp;
+		ia64_patch_imm60((u64) ia64_imva((void *) ip),
+				 (u64) (fsys_bubble_down - (ip & -16)) / 16);
+		ia64_fc((void *) ip);
+		++offp;
+	}
+	ia64_sync_i();
+	ia64_srlz_i();
+}
+
+void
+ia64_patch_gate (void)
+{
+	extern char __start_gate_mckinley_e9_patchlist;
+	extern char __end_gate_mckinley_e9_patchlist;
+	extern char __start_gate_vtop_patchlist;
+	extern char __end_gate_vtop_patchlist;
+	extern char __start_gate_fsyscall_patchlist;
+	extern char __end_gate_fsyscall_patchlist;
+	extern char __start_gate_brl_fsys_bubble_down_patchlist;
+	extern char __end_gate_brl_fsys_bubble_down_patchlist;
+#	define START(name)	((unsigned long) &__start_gate_##name##_patchlist)
+#	define END(name)	((unsigned long)&__end_gate_##name##_patchlist)
+
+	patch_fsyscall_table(START(fsyscall), END(fsyscall));
+	patch_brl_fsys_bubble_down(START(brl_fsys_bubble_down), END(brl_fsys_bubble_down));
+	ia64_patch_vtop(START(vtop), END(vtop));
+	ia64_patch_mckinley_e9(START(mckinley_e9), END(mckinley_e9));
+}
diff -Nru a/arch/ia64/kernel/perfmon.c b/arch/ia64/kernel/perfmon.c
--- a/arch/ia64/kernel/perfmon.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/kernel/perfmon.c	Wed Jun 18 23:42:09 2003
@@ -1,16 +1,22 @@
 /*
- * This file implements the perfmon subsystem which is used
+ * This file implements the perfmon-2 subsystem which is used
  * to program the IA-64 Performance Monitoring Unit (PMU).
  *
- * Originally Written by Ganesh Venkitachalam, IBM Corp.
- * Copyright (C) 1999 Ganesh Venkitachalam <venkitac@us.ibm.com>
+ * The initial version of perfmon.c was written by
+ * Ganesh Venkitachalam, IBM Corp.
  *
- * Modifications by Stephane Eranian, Hewlett-Packard Co.
- * Modifications by David Mosberger-Tang, Hewlett-Packard Co.
+ * Then it was modified for perfmon-1.x by Stephane Eranian and 
+ * David Mosberger, Hewlett Packard Co.
+ * 
+ * Version Perfmon-2.x is a rewrite of perfmon-1.x
+ * by Stephane Eranian, Hewlett Packard Co. 
  *
  * Copyright (C) 1999-2003  Hewlett Packard Co
  *               Stephane Eranian <eranian@hpl.hp.com>
  *               David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * More information about perfmon available at:
+ * 	http://www.hpl.hp.com/research/linux/perfmon
  */
 
 #include <linux/config.h>
@@ -23,7 +29,13 @@
 #include <linux/vmalloc.h>
 #include <linux/mm.h>
 #include <linux/sysctl.h>
-#include <linux/smp.h>
+#include <linux/list.h>
+#include <linux/file.h>
+#include <linux/poll.h>
+#include <linux/vfs.h>
+#include <linux/pagemap.h>
+#include <linux/mount.h>
+#include <linux/version.h>
 
 #include <asm/bitops.h>
 #include <asm/errno.h>
@@ -33,123 +45,206 @@
 #include <asm/signal.h>
 #include <asm/system.h>
 #include <asm/uaccess.h>
-#include <asm/delay.h> /* for ia64_get_itc() */
+#include <asm/delay.h>
 
 #ifdef CONFIG_PERFMON
-
 /*
- * For PMUs which rely on the debug registers for some features, you must
- * you must enable the following flag to activate the support for
- * accessing the registers via the perfmonctl() interface.
+ * perfmon context state
  */
-#if defined(CONFIG_ITANIUM) || defined(CONFIG_MCKINLEY)
-#define PFM_PMU_USES_DBR	1
-#endif
+#define PFM_CTX_UNLOADED	1	/* context is not loaded onto any task */
+#define PFM_CTX_LOADED		2	/* context is loaded onto a task */
+#define PFM_CTX_MASKED		3	/* context is loaded but monitoring is masked due to overflow */
+#define PFM_CTX_ZOMBIE		4	/* owner of the context is closing it */
+#define PFM_CTX_TERMINATED	5	/* the task the context was loaded onto is gone */
 
-/*
- * perfmon context states
- */
-#define PFM_CTX_DISABLED	0
-#define PFM_CTX_ENABLED		1
+#define CTX_LOADED(c)        (c)->ctx_state = PFM_CTX_LOADED
+#define CTX_UNLOADED(c)      (c)->ctx_state = PFM_CTX_UNLOADED
+#define CTX_ZOMBIE(c)        (c)->ctx_state = PFM_CTX_ZOMBIE
+#define CTX_DESTROYED(c)     (c)->ctx_state = PFM_CTX_DESTROYED
+#define CTX_MASKED(c)        (c)->ctx_state = PFM_CTX_MASKED
+#define CTX_TERMINATED(c)    (c)->ctx_state = PFM_CTX_TERMINATED
+
+#define CTX_IS_UNLOADED(c)   ((c)->ctx_state == PFM_CTX_UNLOADED)
+#define CTX_IS_LOADED(c)     ((c)->ctx_state == PFM_CTX_LOADED)
+#define CTX_IS_ZOMBIE(c)     ((c)->ctx_state == PFM_CTX_ZOMBIE)
+#define CTX_IS_MASKED(c)     ((c)->ctx_state == PFM_CTX_MASKED)
+#define CTX_IS_TERMINATED(c) ((c)->ctx_state == PFM_CTX_TERMINATED)
+#define CTX_IS_DEAD(c)	     ((c)->ctx_state == PFM_CTX_TERMINATED || (c)->ctx_state == PFM_CTX_ZOMBIE)
+
+#define PFM_INVALID_ACTIVATION	(~0UL)
 
-/*
- * Reset register flags
- */
-#define PFM_PMD_LONG_RESET	1
-#define PFM_PMD_SHORT_RESET	2
 
 /*
- * Misc macros and definitions
+ * depth of message queue
  */
-#define PMU_FIRST_COUNTER	4
-#define PMU_MAX_PMCS		256
-#define PMU_MAX_PMDS		256
+#define PFM_MAX_MSGS		32
+#define PFM_CTXQ_EMPTY(g)	((g)->ctx_msgq_head == (g)->ctx_msgq_tail)
 
 /*
  * type of a PMU register (bitmask).
  * bitmask structure:
  * 	bit0   : register implemented
- * 	bit1   : end marker 
+ * 	bit1   : end marker
  * 	bit2-3 : reserved
- * 	bit4-7 : register type
+ * 	bit4   : pmc has pmc.pm
+ * 	bit5   : pmc controls a counter (has pmc.oi), pmd is used as counter
+ * 	bit6-7 : register type
  * 	bit8-31: reserved
  */
+#define PFM_REG_NOTIMPL		0x0 /* not implemented at all */
 #define PFM_REG_IMPL		0x1 /* register implemented */
 #define PFM_REG_END		0x2 /* end marker */
 #define PFM_REG_MONITOR		(0x1<<4|PFM_REG_IMPL) /* a PMC with a pmc.pm field only */
-#define PFM_REG_COUNTING	(0x2<<4|PFM_REG_IMPL) /* a PMC with a pmc.pm AND pmc.oi, a PMD used as a counter */
-#define PFM_REG_CONTROL		(0x3<<4|PFM_REG_IMPL) /* PMU control register */
-#define	PFM_REG_CONFIG		(0x4<<4|PFM_REG_IMPL) /* refine configuration */
-#define PFM_REG_BUFFER	 	(0x5<<4|PFM_REG_IMPL) /* PMD used as buffer */
+#define PFM_REG_COUNTING	(0x2<<4|PFM_REG_MONITOR|PFM_REG_IMPL) /* a monitor + pmc.oi+ PMD used as a counter */
+#define PFM_REG_CONTROL		(0x4<<4|PFM_REG_IMPL) /* PMU control register */
+#define	PFM_REG_CONFIG		(0x8<<4|PFM_REG_IMPL) /* configuration register */
+#define PFM_REG_BUFFER	 	(0xc<<4|PFM_REG_IMPL) /* PMD used as buffer */
 
 #define PMC_IS_LAST(i)	(pmu_conf.pmc_desc[i].type & PFM_REG_END)
 #define PMD_IS_LAST(i)	(pmu_conf.pmd_desc[i].type & PFM_REG_END)
 
-#define PFM_IS_DISABLED() pmu_conf.disabled
+#define PFM_IS_DISABLED() (pmu_conf.enabled == 0)
 
-#define PMC_OVFL_NOTIFY(ctx, i)	((ctx)->ctx_soft_pmds[i].flags &  PFM_REGFL_OVFL_NOTIFY)
-#define PFM_FL_INHERIT_MASK	(PFM_FL_INHERIT_NONE|PFM_FL_INHERIT_ONCE|PFM_FL_INHERIT_ALL)
+#define PMC_OVFL_NOTIFY(ctx, i)	((ctx)->ctx_pmds[i].flags &  PFM_REGFL_OVFL_NOTIFY)
 
-/* i assume unsigned */
+/* i assumed unsigned */
 #define PMC_IS_IMPL(i)	  (i< PMU_MAX_PMCS && (pmu_conf.pmc_desc[i].type & PFM_REG_IMPL))
 #define PMD_IS_IMPL(i)	  (i< PMU_MAX_PMDS && (pmu_conf.pmd_desc[i].type & PFM_REG_IMPL))
 
-/* XXX: these three assume that register i is implemented */
-#define PMD_IS_COUNTING(i) (pmu_conf.pmd_desc[i].type == PFM_REG_COUNTING)
-#define PMC_IS_COUNTING(i) (pmu_conf.pmc_desc[i].type == PFM_REG_COUNTING)
-#define PMC_IS_MONITOR(i)  (pmu_conf.pmc_desc[i].type == PFM_REG_MONITOR)
+/* XXX: these assume that register i is implemented */
+#define PMD_IS_COUNTING(i) ((pmu_conf.pmd_desc[i].type & PFM_REG_COUNTING) == PFM_REG_COUNTING)
+#define PMC_IS_COUNTING(i) ((pmu_conf.pmc_desc[i].type & PFM_REG_COUNTING) == PFM_REG_COUNTING)
+#define PMC_IS_MONITOR(i)  ((pmu_conf.pmc_desc[i].type & PFM_REG_MONITOR)  == PFM_REG_MONITOR)
 #define PMC_DFL_VAL(i)     pmu_conf.pmc_desc[i].default_value
 #define PMC_RSVD_MASK(i)   pmu_conf.pmc_desc[i].reserved_mask
 #define PMD_PMD_DEP(i)	   pmu_conf.pmd_desc[i].dep_pmd[0]
 #define PMC_PMD_DEP(i)	   pmu_conf.pmc_desc[i].dep_pmd[0]
 
-/* k assume unsigned */
-#define IBR_IS_IMPL(k)	  (k<pmu_conf.num_ibrs)
-#define DBR_IS_IMPL(k)	  (k<pmu_conf.num_dbrs)
+/* k assumed unsigned (up to 64 registers) */
+#define IBR_IS_IMPL(k)	  (k< IA64_NUM_DBG_REGS)
+#define DBR_IS_IMPL(k)	  (k< IA64_NUM_DBG_REGS)
 
-#define CTX_IS_ENABLED(c) 	((c)->ctx_flags.state == PFM_CTX_ENABLED)
 #define CTX_OVFL_NOBLOCK(c)	((c)->ctx_fl_block == 0)
-#define CTX_INHERIT_MODE(c)	((c)->ctx_fl_inherit)
-#define CTX_HAS_SMPL(c)		((c)->ctx_psb != NULL)
+#define CTX_HAS_SMPL(c)		((c)->ctx_fl_is_sampling)
+#define PFM_CTX_TASK(h)		(h)->ctx_task
+
 /* XXX: does not support more than 64 PMDs */
 #define CTX_USED_PMD(ctx, mask) (ctx)->ctx_used_pmds[0] |= (mask)
 #define CTX_IS_USED_PMD(ctx, c) (((ctx)->ctx_used_pmds[0] & (1UL << (c))) != 0UL)
 
+#define CTX_USED_MONITOR(ctx, mask) (ctx)->ctx_used_monitors[0] |= (mask)
 
 #define CTX_USED_IBR(ctx,n) 	(ctx)->ctx_used_ibrs[(n)>>6] |= 1UL<< ((n) % 64)
 #define CTX_USED_DBR(ctx,n) 	(ctx)->ctx_used_dbrs[(n)>>6] |= 1UL<< ((n) % 64)
 #define CTX_USES_DBREGS(ctx)	(((pfm_context_t *)(ctx))->ctx_fl_using_dbreg==1)
+#define PFM_CODE_RR	0	/* requesting code range restriction */
+#define PFM_DATA_RR	1	/* requestion data range restriction */
 
-#define LOCK_CTX(ctx)	spin_lock(&(ctx)->ctx_lock)
-#define UNLOCK_CTX(ctx)	spin_unlock(&(ctx)->ctx_lock)
+#define PFM_CPUINFO_CLEAR(v)	pfm_get_cpu_var(pfm_syst_info) &= ~(v)
+#define PFM_CPUINFO_SET(v)	pfm_get_cpu_var(pfm_syst_info) |= (v)
+#define PFM_CPUINFO_GET()	pfm_get_cpu_var(pfm_syst_info)
 
-#define SET_PMU_OWNER(t)    do { pmu_owners[smp_processor_id()].owner = (t); } while(0)
-#define PMU_OWNER()	    pmu_owners[smp_processor_id()].owner
+/*
+ * context protection macros
+ * in SMP:
+ * 	- we need to protect against CPU concurrency (spin_lock)
+ * 	- we need to protect against PMU overflow interrupts (local_irq_disable)
+ * in UP:
+ * 	- we need to protect against PMU overflow interrupts (local_irq_disable)
+ *
+ * spin_lock_irqsave()/spin_lock_irqrestore():
+ * 	in SMP: local_irq_disable + spin_lock
+ * 	in UP : local_irq_disable
+ *
+ * spin_lock()/spin_lock():
+ * 	in UP : removed automatically
+ * 	in SMP: protect against context accesses from other CPU. interrupts
+ * 	        are not masked. This is useful for the PMU interrupt handler
+ * 	        because we know we will not get PMU concurrency in that code.
+ */
+#define PROTECT_CTX(c, f) \
+	do {  \
+		DPRINT(("spinlock_irq_save ctx %p by [%d]\n", c, current->pid)); \
+		spin_lock_irqsave(&(c)->ctx_lock, f); \
+		DPRINT(("spinlocked ctx %p  by [%d]\n", c, current->pid)); \
+	} while(0)
+
+#define UNPROTECT_CTX(c, f) \
+	do { \
+		DPRINT(("spinlock_irq_restore ctx %p by [%d]\n", c, current->pid)); \
+		spin_unlock_irqrestore(&(c)->ctx_lock, f); \
+	} while(0)
+
+#define PROTECT_CTX_NOPRINT(c, f) \
+	do {  \
+		spin_lock_irqsave(&(c)->ctx_lock, f); \
+	} while(0)
+
+
+#define UNPROTECT_CTX_NOPRINT(c, f) \
+	do { \
+		spin_unlock_irqrestore(&(c)->ctx_lock, f); \
+	} while(0)
+
+
+#define PROTECT_CTX_NOIRQ(c) \
+	do {  \
+		spin_lock(&(c)->ctx_lock); \
+	} while(0)
+
+#define UNPROTECT_CTX_NOIRQ(c) \
+	do { \
+		spin_unlock(&(c)->ctx_lock); \
+	} while(0)
 
-#define LOCK_PFS()	    spin_lock(&pfm_sessions.pfs_lock)
-#define UNLOCK_PFS()	    spin_unlock(&pfm_sessions.pfs_lock)
+
+#ifdef CONFIG_SMP
+
+#define GET_ACTIVATION()	pfm_get_cpu_var(pmu_activation_number)
+#define INC_ACTIVATION()	pfm_get_cpu_var(pmu_activation_number)++
+#define SET_ACTIVATION(c)	(c)->ctx_last_activation = GET_ACTIVATION()
+
+#else /* !CONFIG_SMP */
+#define SET_ACTIVATION(t) 	do {} while(0)
+#define GET_ACTIVATION(t) 	do {} while(0)
+#define INC_ACTIVATION(t) 	do {} while(0)
+#endif /* CONFIG_SMP */
+
+#define SET_PMU_OWNER(t, c)	do { pfm_get_cpu_var(pmu_owner) = (t); pfm_get_cpu_var(pmu_ctx) = (c); } while(0)
+#define GET_PMU_OWNER()		pfm_get_cpu_var(pmu_owner)
+#define GET_PMU_CTX()		pfm_get_cpu_var(pmu_ctx)
+
+#define LOCK_PFS()	    	spin_lock(&pfm_sessions.pfs_lock)
+#define UNLOCK_PFS()	    	spin_unlock(&pfm_sessions.pfs_lock)
 
 #define PFM_REG_RETFLAG_SET(flags, val)	do { flags &= ~PFM_REG_RETFL_MASK; flags |= (val); } while(0)
 
-#define PFM_CPUINFO_CLEAR(v)	__get_cpu_var(pfm_syst_info) &= ~(v)
-#define PFM_CPUINFO_SET(v)	__get_cpu_var(pfm_syst_info) |= (v)
+#ifdef CONFIG_SMP
+#define PFM_CPU_ONLINE_MAP	cpu_online_map
+#define cpu_is_online(i)	(PFM_CPU_ONLINE_MAP & (1UL << i))
+#else
+#define PFM_CPU_ONLINE_MAP	 1UL
+#define cpu_is_online(i)	(i==0)
+#endif
+
+/*
+ * cmp0 must be the value of pmc0
+ */
+#define PMC0_HAS_OVFL(cmp0)  (cmp0 & ~0x1UL)
 
 /*
  * debugging
  */
-#define DBprintk(a) \
+#define DPRINT(a) \
 	do { \
-		if (pfm_sysctl.debug >0) { printk("%s.%d: CPU%d ", __FUNCTION__, __LINE__, smp_processor_id()); printk a; } \
+		if (unlikely(pfm_sysctl.debug >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), current->pid); printk a; } \
 	} while (0)
 
-#define DBprintk_ovfl(a) \
+#define DPRINT_ovfl(a) \
 	do { \
-		if (pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0) { printk("%s.%d: CPU%d ", __FUNCTION__, __LINE__, smp_processor_id()); printk a; } \
+		if (unlikely(pfm_sysctl.debug > 0 && pfm_sysctl.debug_ovfl >0)) { printk("%s.%d: CPU%d [%d] ", __FUNCTION__, __LINE__, smp_processor_id(), current->pid); printk a; } \
 	} while (0)
-
-
-
-/* 
+/*
  * Architected PMC structure
  */
 typedef struct {
@@ -163,123 +258,127 @@
 } pfm_monitor_t;
 
 /*
- * There is one such data structure per perfmon context. It is used to describe the
- * sampling buffer. It is to be shared among siblings whereas the pfm_context 
- * is not.
- * Therefore we maintain a refcnt which is incremented on fork().
- * This buffer is private to the kernel only the actual sampling buffer 
- * including its header are exposed to the user. This construct allows us to 
- * export the buffer read-write, if needed, without worrying about security 
- * problems.
- */
-typedef struct _pfm_smpl_buffer_desc {
-	spinlock_t		psb_lock;	/* protection lock */
-	unsigned long		psb_refcnt;	/* how many users for the buffer */
-	int			psb_flags;	/* bitvector of flags (not yet used) */
-
-	void			*psb_addr;	/* points to location of first entry */
-	unsigned long		psb_entries;	/* maximum number of entries */
-	unsigned long		psb_size;	/* aligned size of buffer */
-	unsigned long		psb_index;	/* next free entry slot XXX: must use the one in buffer */
-	unsigned long		psb_entry_size;	/* size of each entry including entry header */
-
-	perfmon_smpl_hdr_t	*psb_hdr;	/* points to sampling buffer header */
-
-	struct _pfm_smpl_buffer_desc *psb_next;	/* next psb, used for rvfreeing of psb_hdr */
-
-} pfm_smpl_buffer_desc_t;
-
-/*
- * psb_flags
- */
-#define PSB_HAS_VMA	0x1		/* a virtual mapping for the buffer exists */
-
-#define LOCK_PSB(p)	spin_lock(&(p)->psb_lock)
-#define UNLOCK_PSB(p)	spin_unlock(&(p)->psb_lock)
-
-/*
  * 64-bit software counter structure
  */
 typedef struct {
-	u64 val;	/* virtual 64bit counter value */
-	u64 lval;	/* last value */
-	u64 long_reset;	/* reset value on sampling overflow */
-	u64 short_reset;/* reset value on overflow */
-	u64 reset_pmds[4]; /* which other pmds to reset when this counter overflows */
-	u64 seed;	/* seed for random-number generator */
-	u64 mask;	/* mask for random-number generator */
-	unsigned int flags; /* notify/do not notify */
+	unsigned long	val;		/* virtual 64bit counter value */
+	unsigned long	lval;		/* last reset value */
+	unsigned long	long_reset;	/* reset value on sampling overflow */
+	unsigned long	short_reset;    /* reset value on overflow */
+	unsigned long	reset_pmds[4];  /* which other pmds to reset when this counter overflows */
+	unsigned long	smpl_pmds[4];   /* which pmds are accessed when counter overflow */
+	unsigned long	seed;		/* seed for random-number generator */
+	unsigned long	mask;		/* mask for random-number generator */
+	unsigned int 	flags;		/* notify/do not notify */
+	unsigned int 	reserved;	/* for future use */
+	unsigned long	eventid;	/* overflow event identifier */
 } pfm_counter_t;
 
 /*
- * perfmon context. One per process, is cloned on fork() depending on 
- * inheritance flags
+ * context flags
  */
 typedef struct {
-	unsigned int state:1;		/* 0=disabled, 1=enabled */
-	unsigned int inherit:2;		/* inherit mode */
 	unsigned int block:1;		/* when 1, task will blocked on user notifications */
 	unsigned int system:1;		/* do system wide monitoring */
-	unsigned int frozen:1;		/* pmu must be kept frozen on ctxsw in */
-	unsigned int protected:1;	/* allow access to creator of context only */
 	unsigned int using_dbreg:1;	/* using range restrictions (debug registers) */
+	unsigned int is_sampling:1;	/* true if using a custom format */
 	unsigned int excl_idle:1;	/* exclude idle task in system wide session */
-	unsigned int unsecure:1;	/* sp = 0 for non self-monitored task */
-	unsigned int trap_reason:2;	/* reason for going into pfm_block_ovfl_reset() */
-	unsigned int reserved:20;
+	unsigned int unsecure:1;	/* exclude idle task in system wide session */
+	unsigned int going_zombie:1;	/* context is zombie (MASKED+blocking) */
+	unsigned int trap_reason:2;	/* reason for going into pfm_handle_work() */
+	unsigned int no_msg:1;		/* no message sent on overflow */
+	unsigned int reserved:22;
 } pfm_context_flags_t;
 
 #define PFM_TRAP_REASON_NONE		0x0	/* default value */
-#define PFM_TRAP_REASON_BLOCKSIG	0x1	/* we need to block on overflow and signal user */
-#define PFM_TRAP_REASON_SIG		0x2	/* we simply need to signal user */
-#define PFM_TRAP_REASON_RESET		0x3	/* we need to reset PMDs */
+#define PFM_TRAP_REASON_BLOCK		0x1	/* we need to block on overflow */
+#define PFM_TRAP_REASON_RESET		0x2	/* we need to reset PMDs */
+
 
 /*
  * perfmon context: encapsulates all the state of a monitoring session
- * XXX: probably need to change layout
  */
+
 typedef struct pfm_context {
-	pfm_smpl_buffer_desc_t	*ctx_psb;		/* sampling buffer, if any */
-	unsigned long		ctx_smpl_vaddr;		/* user level virtual address of smpl buffer */
+	spinlock_t		ctx_lock;		/* context protection */
 
-	spinlock_t		ctx_lock;
-	pfm_context_flags_t	ctx_flags;		/* block/noblock */
+	pfm_context_flags_t	ctx_flags;		/* bitmask of flags  (block reason incl.) */
+	unsigned int		ctx_state;		/* state: active/inactive (no bitfield) */
 
-	struct task_struct	*ctx_notify_task;	/* who to notify on overflow */
-	struct task_struct	*ctx_owner;		/* pid of creator (debug) */
+	struct task_struct 	*ctx_task;		/* task to which context is attached */
 
 	unsigned long		ctx_ovfl_regs[4];	/* which registers overflowed (notification) */
-	unsigned long		ctx_smpl_regs[4];	/* which registers to record on overflow */
 
 	struct semaphore	ctx_restart_sem;   	/* use for blocking notification mode */
 
-	unsigned long		ctx_used_pmds[4];	/* bitmask of PMD used                 */
-	unsigned long		ctx_reload_pmds[4];	/* bitmask of PMD to reload on ctxsw   */
+	unsigned long		ctx_used_pmds[4];	/* bitmask of PMD used            */
+	unsigned long		ctx_all_pmds[4];	/* bitmask of all accessible PMDs */
+	unsigned long		ctx_reload_pmds[4];	/* bitmask of force reload PMD on ctxsw in */
+
+	unsigned long		ctx_all_pmcs[4];	/* bitmask of all accessible PMCs */
+	unsigned long		ctx_reload_pmcs[4];	/* bitmask of force reload PMC on ctxsw in */
+	unsigned long		ctx_used_monitors[4];	/* bitmask of monitor PMC being used */
 
-	unsigned long		ctx_used_pmcs[4];	/* bitmask PMC used by context         */
-	unsigned long		ctx_reload_pmcs[4];	/* bitmask of PMC to reload on ctxsw   */
+	unsigned long		ctx_pmcs[IA64_NUM_PMC_REGS];	/*  saved copies of PMC values */
 
-	unsigned long		ctx_used_ibrs[4];	/* bitmask of used IBR (speedup ctxsw) */
-	unsigned long		ctx_used_dbrs[4];	/* bitmask of used DBR (speedup ctxsw) */
+	unsigned int		ctx_used_ibrs[1];		/* bitmask of used IBR (speedup ctxsw in) */
+	unsigned int		ctx_used_dbrs[1];		/* bitmask of used DBR (speedup ctxsw in) */
+	unsigned long		ctx_dbrs[IA64_NUM_DBG_REGS];	/* DBR values (cache) when not loaded */
+	unsigned long		ctx_ibrs[IA64_NUM_DBG_REGS];	/* IBR values (cache) when not loaded */
 
-	pfm_counter_t		ctx_soft_pmds[IA64_NUM_PMD_REGS]; /* XXX: size should be dynamic */
+	pfm_counter_t		ctx_pmds[IA64_NUM_PMD_REGS]; /* software state for PMDS */
 
-	u64			ctx_saved_psr;		/* copy of psr used for lazy ctxsw */
-	unsigned long		ctx_saved_cpus_allowed;	/* copy of the task cpus_allowed (system wide) */
-	unsigned int		ctx_cpu;		/* CPU used by system wide session */
+	u64			ctx_saved_psr;		/* copy of psr used for ctxsw */
 
-	atomic_t		ctx_last_cpu;		/* CPU id of current or last CPU used */
+	unsigned long		ctx_last_activation;	/* context last activation number for last_cpu */
+	unsigned int		ctx_last_cpu;		/* CPU id of current or last CPU used (SMP only) */
+	unsigned int		ctx_cpu;		/* cpu to which perfmon is applied (system wide) */
+
+	int			ctx_fd;			/* file descriptor used my this context */
+
+	pfm_buffer_fmt_t	*ctx_buf_fmt;		/* buffer format callbacks */
+	void			*ctx_smpl_hdr;		/* points to sampling buffer header kernel vaddr */
+	unsigned long		ctx_smpl_size;		/* size of sampling buffer */
+	void			*ctx_smpl_vaddr;	/* user level virtual address of smpl buffer */
+
+	wait_queue_head_t 	ctx_msgq_wait;
+	pfm_msg_t		ctx_msgq[PFM_MAX_MSGS];
+	int			ctx_msgq_head;
+	int			ctx_msgq_tail;
+	struct fasync_struct	*ctx_async_queue;
+
+	wait_queue_head_t 	ctx_zombieq;		/* termination cleanup wait queue */
 } pfm_context_t;
 
-#define ctx_fl_inherit		ctx_flags.inherit
+/*
+ * magic number used to verify that structure is really
+ * a perfmon context
+ */
+#define PFM_IS_FILE(f)		((f)->f_op == &pfm_file_ops)
+
+#define PFM_GET_CTX(t)	 	((pfm_context_t *)(t)->thread.pfm_context)
+
+#ifdef CONFIG_SMP
+#define SET_LAST_CPU(ctx, v)	(ctx)->ctx_last_cpu = (v)
+#define GET_LAST_CPU(ctx)	(ctx)->ctx_last_cpu
+#else
+#define SET_LAST_CPU(ctx, v)	do {} while(0)
+#define GET_LAST_CPU(ctx)	do {} while(0)
+#endif
+
+
 #define ctx_fl_block		ctx_flags.block
 #define ctx_fl_system		ctx_flags.system
-#define ctx_fl_frozen		ctx_flags.frozen
-#define ctx_fl_protected	ctx_flags.protected
 #define ctx_fl_using_dbreg	ctx_flags.using_dbreg
+#define ctx_fl_is_sampling	ctx_flags.is_sampling
 #define ctx_fl_excl_idle	ctx_flags.excl_idle
-#define ctx_fl_trap_reason	ctx_flags.trap_reason
 #define ctx_fl_unsecure		ctx_flags.unsecure
+#define ctx_fl_going_zombie	ctx_flags.going_zombie
+#define ctx_fl_trap_reason	ctx_flags.trap_reason
+#define ctx_fl_no_msg		ctx_flags.no_msg
+
+#define PFM_SET_WORK_PENDING(t, v)	do { (t)->thread.pfm_needs_checking = v; } while(0);
+#define PFM_GET_WORK_PENDING(t)		(t)->thread.pfm_needs_checking
 
 /*
  * global information about all sessions
@@ -288,7 +387,7 @@
 typedef struct {
 	spinlock_t		pfs_lock;		   /* lock the structure */
 
-	unsigned int 		pfs_task_sessions;	   /* number of per task sessions */
+	unsigned int		pfs_task_sessions;	   /* number of per task sessions */
 	unsigned int		pfs_sys_sessions;	   /* number of per system wide sessions */
 	unsigned int		pfs_sys_use_dbregs;	   /* incremented when a system wide session uses debug regs */
 	unsigned int		pfs_ptrace_use_dbregs;	   /* incremented when a process uses debug regs */
@@ -297,7 +396,7 @@
 
 /*
  * information about a PMC or PMD.
- * dep_pmd[]: a bitmask of dependent PMD registers 
+ * dep_pmd[]: a bitmask of dependent PMD registers
  * dep_pmc[]: a bitmask of dependent PMC registers
  */
 typedef struct {
@@ -305,8 +404,8 @@
 	int			pm_pos;
 	unsigned long		default_value;	/* power-on default value */
 	unsigned long		reserved_mask;	/* bitmask of reserved bits */
-	int			(*read_check)(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
-	int			(*write_check)(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
+	int			(*read_check)(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
+	int			(*write_check)(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
 	unsigned long		dep_pmd[4];
 	unsigned long		dep_pmc[4];
 } pfm_reg_desc_t;
@@ -322,88 +421,122 @@
  * a description of the PMU main characteristics.
  */
 typedef struct {
-	unsigned int  disabled;		/* indicates if perfmon is working properly */
-	unsigned long ovfl_val;		/* overflow value for generic counters   */
-	unsigned long impl_pmcs[4];	/* bitmask of implemented PMCS */
-	unsigned long impl_pmds[4];	/* bitmask of implemented PMDS */
-	unsigned int  num_pmcs;		/* number of implemented PMCS */
-	unsigned int  num_pmds;		/* number of implemented PMDS */
-	unsigned int  num_ibrs;		/* number of implemented IBRS */
-	unsigned int  num_dbrs;		/* number of implemented DBRS */
-	unsigned int  num_counters;	/* number of PMD/PMC counters */
+	unsigned long  ovfl_val;	/* overflow value for counters */
+
 	pfm_reg_desc_t *pmc_desc;	/* detailed PMC register dependencies descriptions */
 	pfm_reg_desc_t *pmd_desc;	/* detailed PMD register dependencies descriptions */
+
+	unsigned int   num_pmcs;	/* number of PMCS: computed at init time */
+	unsigned int   num_pmds;	/* number of PMDS: computed at init time */
+	unsigned long  impl_pmcs[4];	/* bitmask of implemented PMCS */
+	unsigned long  impl_pmds[4];	/* bitmask of implemented PMDS */
+
+	char	      *pmu_name;	/* PMU family name */
+	unsigned int  enabled;		/* indicates if perfmon initialized properly */
+	unsigned int  pmu_family;	/* cpuid family pattern used to identify pmu */
+
+	unsigned int  num_ibrs;		/* number of IBRS: computed at init time */
+	unsigned int  num_dbrs;		/* number of DBRS: computed at init time */
+	unsigned int  num_counters;	/* PMC/PMD counting pairs : computed at init time */
+
+	unsigned int  use_rr_dbregs:1;	/* set if debug registers used for range restriction */
 } pmu_config_t;
 
 /*
- * structure used to pass argument to/from remote CPU 
- * using IPI to check and possibly save the PMU context on SMP systems.
- *
- * not used in UP kernels
+ * debug register related type definitions
  */
 typedef struct {
-	struct task_struct *task;	/* which task we are interested in */
-	int retval;			/* return value of the call: 0=you can proceed, 1=need to wait for completion */
-} pfm_smp_ipi_arg_t;
+	unsigned long ibr_mask:56;
+	unsigned long ibr_plm:4;
+	unsigned long ibr_ig:3;
+	unsigned long ibr_x:1;
+} ibr_mask_reg_t;
+
+typedef struct {
+	unsigned long dbr_mask:56;
+	unsigned long dbr_plm:4;
+	unsigned long dbr_ig:2;
+	unsigned long dbr_w:1;
+	unsigned long dbr_r:1;
+} dbr_mask_reg_t;
+
+typedef union {
+	unsigned long  val;
+	ibr_mask_reg_t ibr;
+	dbr_mask_reg_t dbr;
+} dbreg_t;
+
 
 /*
  * perfmon command descriptions
  */
 typedef struct {
-	int		(*cmd_func)(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs);
+	int		(*cmd_func)(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs);
+	char		*cmd_name;
 	int		cmd_flags;
 	unsigned int	cmd_narg;
 	size_t		cmd_argsize;
+	int		(*cmd_getsize)(void *arg, size_t *sz);
 } pfm_cmd_desc_t;
 
-#define PFM_CMD_PID		0x1	/* command requires pid argument */
-#define PFM_CMD_ARG_READ	0x2	/* command must read argument(s) */
-#define PFM_CMD_ARG_RW		0x4	/* command must read/write argument(s) */
-#define PFM_CMD_CTX		0x8	/* command needs a perfmon context */
-#define PFM_CMD_NOCHK		0x10	/* command does not need to check task's state */
+#define PFM_CMD_FD		0x01	/* command requires a file descriptor */
+#define PFM_CMD_ARG_READ	0x02	/* command must read argument(s) */
+#define PFM_CMD_ARG_RW		0x04	/* command must read/write argument(s) */
+#define PFM_CMD_STOP		0x08	/* command does not work on zombie context */
+
 
 #define PFM_CMD_IDX(cmd)	(cmd)
+#define PFM_CMD_IS_VALID(cmd)	((PFM_CMD_IDX(cmd) >= 0) && (PFM_CMD_IDX(cmd) < PFM_CMD_COUNT) \
+				  && pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_func != NULL)
 
-#define PFM_CMD_IS_VALID(cmd)	((PFM_CMD_IDX(cmd) >= 0)				\
-				 && (PFM_CMD_IDX(cmd) < (int) PFM_CMD_COUNT)		\
-				 && pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_func != NULL)
-
-#define PFM_CMD_USE_PID(cmd)	((pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_PID) != 0)
-#define PFM_CMD_READ_ARG(cmd)	((pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_ARG_READ) != 0)
-#define PFM_CMD_RW_ARG(cmd)	((pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_ARG_RW) != 0)
-#define PFM_CMD_USE_CTX(cmd)	((pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_CTX) != 0)
-#define PFM_CMD_CHK(cmd)	((pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_NOCHK) == 0)
+#define PFM_CMD_NAME(cmd)	pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_name
+#define PFM_CMD_READ_ARG(cmd)	(pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_ARG_READ)
+#define PFM_CMD_RW_ARG(cmd)	(pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_ARG_RW)
+#define PFM_CMD_USE_FD(cmd)	(pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_FD)
+#define PFM_CMD_STOPPED(cmd)	(pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_flags & PFM_CMD_STOP)
 
 #define PFM_CMD_ARG_MANY	-1 /* cannot be zero */
 #define PFM_CMD_NARG(cmd)	(pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_narg)
 #define PFM_CMD_ARG_SIZE(cmd)	(pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_argsize)
+#define PFM_CMD_GETSIZE(cmd)	(pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_getsize)
 
 typedef struct {
 	int	debug;		/* turn on/off debugging via syslog */
 	int	debug_ovfl;	/* turn on/off debug printk in overflow handler */
 	int	fastctxsw;	/* turn on/off fast (unsecure) ctxsw */
+	int 	debug_pfm_read;
 } pfm_sysctl_t;
 
 typedef struct {
-	unsigned long pfm_spurious_ovfl_intr_count; /* keep track of spurious ovfl interrupts */
-	unsigned long pfm_ovfl_intr_count; /* keep track of ovfl interrupts */
-	unsigned long pfm_recorded_samples_count;
-	unsigned long pfm_full_smpl_buffer_count; /* how many times the sampling buffer was full */
+	unsigned long pfm_spurious_ovfl_intr_count;	/* keep track of spurious ovfl interrupts */
+	unsigned long pfm_ovfl_intr_count; 		/* keep track of ovfl interrupts */
+	unsigned long pfm_ovfl_intr_cycles;		/* cycles spent processing ovfl interrupts */
+	unsigned long pfm_ovfl_intr_cycles_min;		/* min cycles spent processing ovfl interrupts */
+	unsigned long pfm_ovfl_intr_cycles_max;		/* max cycles spent processing ovfl interrupts */
+	unsigned long pfm_sysupdt_count;
+	unsigned long pfm_sysupdt_cycles;
+	unsigned long pfm_smpl_handler_calls;
+	unsigned long pfm_smpl_handler_cycles;
 	char pad[SMP_CACHE_BYTES] ____cacheline_aligned;
 } pfm_stats_t;
 
 /*
  * perfmon internal variables
  */
-static pfm_session_t	pfm_sessions;	/* global sessions information */
-static struct proc_dir_entry *perfmon_dir; /* for debug only */
-static pfm_stats_t	pfm_stats[NR_CPUS];
-static pfm_intr_handler_desc_t	*pfm_alternate_intr_handler;
+static pfm_stats_t		pfm_stats[NR_CPUS];
+static pfm_session_t		pfm_sessions;	/* global sessions information */
 
-DEFINE_PER_CPU(unsigned long, pfm_syst_info);
+static struct proc_dir_entry 	*perfmon_dir;
+static pfm_uuid_t		pfm_null_uuid = {0,};
+
+static spinlock_t		pfm_smpl_fmt_lock;
+static pfm_buffer_fmt_t		*pfm_buffer_fmt_list;
+#define LOCK_BUF_FMT_LIST()	    spin_lock(&pfm_smpl_fmt_lock)
+#define UNLOCK_BUF_FMT_LIST()	    spin_unlock(&pfm_smpl_fmt_lock)
 
 /* sysctl() controls */
 static pfm_sysctl_t pfm_sysctl;
+int pfm_debug_var;
 
 static ctl_table pfm_ctl_table[]={
 	{1, "debug", &pfm_sysctl.debug, sizeof(int), 0666, NULL, &proc_dointvec, NULL,},
@@ -424,24 +557,181 @@
 static void pfm_vm_close(struct vm_area_struct * area);
 
 static struct vm_operations_struct pfm_vm_ops={
-	.close = pfm_vm_close
+	close: pfm_vm_close
 };
 
 /*
- * keep track of task owning the PMU per CPU.
+ * Linux 2.5 vs. 2.4 helper macros and definitions
+ *
+ * if not at least 2.5.69, then assume 2.4.x.
  */
-static struct {
-	struct task_struct *owner;
-	char pad[SMP_CACHE_BYTES] ____cacheline_aligned;
-} pmu_owners[NR_CPUS];
+#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,69)
+
+#define PFM_COMPILED_FOR_2_4 1
+
+#include <linux/wrapper.h>
+
+#define pfm_get_cpu_var(v)	local_cpu_data->v
+#define pfm_get_cpu_data(a,b)	cpu_data((b))->a
+typedef	void pfm_irq_handler_t;
+#define PFM_IRQ_HANDLER_RET(v)
+
+#define DEFINE_PER_CPU(a,b)
+
+static inline int
+pfm_wait_task_inactive(struct task_struct *task)
+{
+#ifdef CONFIG_SMP
+	/* Make sure the child gets off its CPU.. */
+	for (;;) {
+		task_lock(task);
+		if (!task_has_cpu(task)) break;
+		task_unlock(task);
+		do {
+			if (task->state != TASK_STOPPED)
+				return -ESRCH;
+			barrier();
+			cpu_relax();
+		} while (task_has_cpu(task));
+	}
+	task_unlock(task);
+#endif
+	return 0;
+}
+
+static inline void
+pfm_put_task(struct task_struct *task)
+{
+	if (task != current) free_task_struct(task);
+}
+
+static inline void
+pfm_set_task_notify(struct task_struct *task)
+{
+}
+
+static inline void
+pfm_clear_task_notify(void)
+{
+}
+
+static inline void
+pfm_reserve_page(unsigned long a)
+{
+	unsigned long page;
+
+	page = ia64_tpa(a);
+	mem_map_reserve(virt_to_page(__va(page)));
+}
+
+static inline void
+pfm_unreserve_page(unsigned long a)
+{
+	unsigned long page;
+
+	page = ia64_tpa(a);
+	mem_map_unreserve(virt_to_page(__va(page)));
+}
+
+static inline int
+pfm_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long phys_addr, unsigned long size, pgprot_t prot)
+{
+	return remap_page_range(from, phys_addr, size, prot);
+}
+
+static inline unsigned long
+pfm_protect_ctx_ctxsw(pfm_context_t *x)
+{
+	unsigned long f;
+	spin_lock(&(x)->ctx_lock);
+	return f;
+}
+
+static inline unsigned long
+pfm_unprotect_ctx_ctxsw(pfm_context_t *x, unsigned long f)
+{
+	spin_unlock(&(x)->ctx_lock);
+}
+
+#else /* 2.5.69 or higher */
+
+#define pfm_wait_task_inactive(t)	wait_task_inactive(t)
+#define pfm_get_cpu_var(v)		__get_cpu_var(v)
+#define pfm_get_cpu_data(a,b)		per_cpu(a, b)
+typedef	irqreturn_t	pfm_irq_handler_t;
+#define PFM_IRQ_HANDLER_RET(v)	do {  \
+		put_cpu_no_resched(); \
+		return IRQ_HANDLED;   \
+	} while(0);
+
+static inline void
+pfm_put_task(struct task_struct *task)
+{
+	if (task != current) put_task_struct(task);
+}
+
+static inline void
+pfm_set_task_notify(struct task_struct *task)
+{
+	struct thread_info *info;
+
+	info = (struct thread_info *) ((char *) task + IA64_TASK_SIZE);
+	set_bit(TIF_NOTIFY_RESUME, &info->flags);
+}
+
+static inline void
+pfm_clear_task_notify(void)
+{
+	clear_thread_flag(TIF_NOTIFY_RESUME);
+}
+
+static inline void
+pfm_reserve_page(unsigned long a)
+{
+	SetPageReserved(vmalloc_to_page((void *)a));
+}
+static inline void
+pfm_unreserve_page(unsigned long a)
+{
+	ClearPageReserved(vmalloc_to_page((void*)a));
+}
+
+static inline int
+pfm_remap_page_range(struct vm_area_struct *vma, unsigned long from, unsigned long phys_addr, unsigned long size, pgprot_t prot)
+{
+	return remap_page_range(vma, from, phys_addr, size, prot);
+}
+
+static inline unsigned long
+pfm_protect_ctx_ctxsw(pfm_context_t *x)
+{
+	spin_lock_irq(&(x)->ctx_lock);
+	return 0UL;
+}
+
+static inline unsigned long
+pfm_unprotect_ctx_ctxsw(pfm_context_t *x, unsigned long f)
+{
+	spin_unlock(&(x)->ctx_lock);
+}
 
+#endif /* 2.5 vs. 2.4 */
 
+DEFINE_PER_CPU(unsigned long, pfm_syst_info);
+DEFINE_PER_CPU(struct task_struct *, pmu_owner);
+DEFINE_PER_CPU(pfm_context_t  *, pmu_ctx);
+DEFINE_PER_CPU(unsigned long, pmu_activation_number);
+
+
+/* forward declaration */
+static struct file_operations pfm_file_ops;
 
 /*
  * forward declarations
  */
-static void pfm_reset_pmu(struct task_struct *);
+#ifndef CONFIG_SMP
 static void pfm_lazy_save_regs (struct task_struct *ta);
+#endif
 
 #if   defined(CONFIG_ITANIUM)
 #include "perfmon_itanium.h"
@@ -451,6 +741,8 @@
 #include "perfmon_generic.h"
 #endif
 
+static int pfm_end_notify_user(pfm_context_t *ctx);
+
 static inline void
 pfm_clear_psr_pp(void)
 {
@@ -503,16 +795,22 @@
 	ia64_srlz_d();
 }
 
+/*
+ * PMD[i] must be a counter. no check is made
+ */
 static inline unsigned long
 pfm_read_soft_counter(pfm_context_t *ctx, int i)
 {
-	return ctx->ctx_soft_pmds[i].val + (ia64_get_pmd(i) & pmu_conf.ovfl_val);
+	return ctx->ctx_pmds[i].val + (ia64_get_pmd(i) & pmu_conf.ovfl_val);
 }
 
+/*
+ * PMD[i] must be a counter. no check is made
+ */
 static inline void
 pfm_write_soft_counter(pfm_context_t *ctx, int i, unsigned long val)
 {
-	ctx->ctx_soft_pmds[i].val = val  & ~pmu_conf.ovfl_val;
+	ctx->ctx_pmds[i].val = val  & ~pmu_conf.ovfl_val;
 	/*
 	 * writing to unimplemented part is ignore, so we do not need to
 	 * mask off top part
@@ -520,18 +818,56 @@
 	ia64_set_pmd(i, val & pmu_conf.ovfl_val);
 }
 
-/*
- * Generates a unique (per CPU) timestamp
- */
-static inline unsigned long
-pfm_get_stamp(void)
+static pfm_msg_t *
+pfm_get_new_msg(pfm_context_t *ctx)
 {
+	int idx, next;
+
+	next = (ctx->ctx_msgq_tail+1) % PFM_MAX_MSGS;
+
+	DPRINT(("ctx_fd=%p head=%d tail=%d\n", ctx, ctx->ctx_msgq_head, ctx->ctx_msgq_tail));
+	if (next == ctx->ctx_msgq_head) return NULL;
+
+ 	idx = 	ctx->ctx_msgq_tail;
+	ctx->ctx_msgq_tail = next;
+
+	DPRINT(("ctx=%p head=%d tail=%d msg=%d\n", ctx, ctx->ctx_msgq_head, ctx->ctx_msgq_tail, idx));
+
+	return ctx->ctx_msgq+idx;
+}
+
+static pfm_msg_t *
+pfm_get_next_msg(pfm_context_t *ctx)
+{
+	pfm_msg_t *msg;
+
+	DPRINT(("ctx=%p head=%d tail=%d\n", ctx, ctx->ctx_msgq_head, ctx->ctx_msgq_tail));
+
+	if (PFM_CTXQ_EMPTY(ctx)) return NULL;
+
 	/*
-	 * XXX: must find something more efficient
+	 * get oldest message
 	 */
-	return ia64_get_itc();
+	msg = ctx->ctx_msgq+ctx->ctx_msgq_head;
+
+	/*
+	 * and move forward
+	 */
+	ctx->ctx_msgq_head = (ctx->ctx_msgq_head+1) % PFM_MAX_MSGS;
+
+	DPRINT(("ctx=%p head=%d tail=%d type=%d\n", ctx, ctx->ctx_msgq_head, ctx->ctx_msgq_tail, msg->pfm_gen_msg.msg_type));
+
+	return msg;
 }
 
+static void
+pfm_reset_msgq(pfm_context_t *ctx)
+{
+	ctx->ctx_msgq_head = ctx->ctx_msgq_tail = 0;
+	DPRINT(("ctx=%p msgq reset\n", ctx));
+}
+
+
 /* Here we want the physical address of the memory.
  * This is used when initializing the contents of the
  * area and marking the pages as reserved.
@@ -540,7 +876,6 @@
 pfm_kvirt_to_pa(unsigned long adr)
 {
 	__u64 pa = ia64_tpa(adr);
-	//DBprintk(("kv2pa(%lx-->%lx)\n", adr, pa));
 	return pa;
 }
 
@@ -548,17 +883,17 @@
 pfm_rvmalloc(unsigned long size)
 {
 	void *mem;
-	unsigned long adr;
+	unsigned long addr;
 
-	size=PAGE_ALIGN(size);
-	mem=vmalloc(size);
+	size = PAGE_ALIGN(size);
+	mem  = vmalloc(size);
 	if (mem) {
 		//printk("perfmon: CPU%d pfm_rvmalloc(%ld)=%p\n", smp_processor_id(), size, mem);
-		memset(mem, 0, size); /* Clear the ram out, no junk to the user */
-		adr=(unsigned long) mem;
+		memset(mem, 0, size);
+		addr = (unsigned long)mem;
 		while (size > 0) {
-			SetPageReserved(vmalloc_to_page((void *)adr));
-			adr+=PAGE_SIZE;
+			pfm_reserve_page(addr);
+			addr+=PAGE_SIZE;
 			size-=PAGE_SIZE;
 		}
 	}
@@ -568,13 +903,14 @@
 static void
 pfm_rvfree(void *mem, unsigned long size)
 {
-	unsigned long adr;
+	unsigned long addr;
 
 	if (mem) {
-		adr=(unsigned long) mem;
+		DPRINT(("freeing physical buffer @%p size=%lu\n", mem, size));
+		addr = (unsigned long) mem;
 		while ((long) size > 0) {
-			ClearPageReserved(vmalloc_to_page((void*)adr));
-			adr+=PAGE_SIZE;
+			pfm_unreserve_page(addr);
+			addr+=PAGE_SIZE;
 			size-=PAGE_SIZE;
 		}
 		vfree(mem);
@@ -582,201 +918,1489 @@
 	return;
 }
 
+static pfm_context_t *
+pfm_context_alloc(void)
+{
+	pfm_context_t *ctx;
+
+	/* allocate context descriptor */
+	ctx = kmalloc(sizeof(pfm_context_t), GFP_KERNEL);
+	if (ctx) {
+		memset(ctx, 0, sizeof(pfm_context_t));
+		DPRINT(("alloc ctx @%p\n", ctx));
+	}
+	return ctx;
+}
+
+static void
+pfm_context_free(pfm_context_t *ctx)
+{
+	if (ctx) {
+		DPRINT(("free ctx @%p\n", ctx));
+		kfree(ctx);
+	}
+}
+
+static void
+pfm_mask_monitoring(struct task_struct *task)
+{
+	pfm_context_t *ctx = PFM_GET_CTX(task);
+	struct thread_struct *th = &task->thread;
+	unsigned long mask, val;
+	int i;
+
+	DPRINT(("[%d] masking monitoring for [%d]\n", current->pid, task->pid));
+
+	/*
+	 * monitoring can only be masked as a result of a valid
+	 * counter overflow. In UP, it means that the PMU still
+	 * has an owner. Note that the owner can be different
+	 * from the current task. However the PMU state belongs
+	 * to the owner.
+	 * In SMP, a valid overflow only happens when task is
+	 * current. Therefore if we come here, we know that
+	 * the PMU state belongs to the current task, therefore
+	 * we can access the live registers.
+	 *
+	 * So in both cases, the live register contains the owner's
+	 * state. We can ONLY touch the PMU registers and NOT the PSR.
+	 *
+	 * As a consequence to this call, the thread->pmds[] array
+	 * contains stale information which must be ignored
+	 * when context is reloaded AND monitoring is active (see
+	 * pfm_restart).
+	 */
+	mask = ctx->ctx_used_pmds[0];
+	for (i = 0; mask; i++, mask>>=1) {
+		/* skip non used pmds */
+		if ((mask & 0x1) == 0) continue;
+		val = ia64_get_pmd(i);
+
+		if (PMD_IS_COUNTING(i)) {
+			/*
+		 	 * we rebuild the full 64 bit value of the counter
+		 	 */
+			ctx->ctx_pmds[i].val += (val & pmu_conf.ovfl_val);
+		} else {
+			ctx->ctx_pmds[i].val = val;
+		}
+		DPRINT(("pmd[%d]=0x%lx hw_pmd=0x%lx\n",
+			i,
+			ctx->ctx_pmds[i].val,
+			val & pmu_conf.ovfl_val));
+	}
+	/*
+	 * mask monitoring by setting the privilege level to 0
+	 * we cannot use psr.pp/psr.up for this, it is controlled by
+	 * the user
+	 *
+	 * if task is current, modify actual registers, otherwise modify
+	 * thread save state, i.e., what will be restored in pfm_load_regs()
+	 */
+	mask = ctx->ctx_used_monitors[0] >> PMU_FIRST_COUNTER;
+	for(i= PMU_FIRST_COUNTER; mask; i++, mask>>=1) {
+		if ((mask & 0x1) == 0UL) continue;
+		ia64_set_pmc(i, th->pmcs[i] & ~0xfUL);
+		th->pmcs[i] &= ~0xfUL;
+	}
+	/*
+	 * make all of this visible
+	 */
+	ia64_srlz_d();
+}
+
 /*
- * This function gets called from mm/mmap.c:exit_mmap() only when there is a sampling buffer
- * attached to the context AND the current task has a mapping for it, i.e., it is the original
- * creator of the context.
- *
- * This function is used to remember the fact that the vma describing the sampling buffer
- * has now been removed. It can only be called when no other tasks share the same mm context.
+ * must always be done with task == current
  *
+ * context must be in MASKED state when calling
  */
-static void 
-pfm_vm_close(struct vm_area_struct *vma)
+static void
+pfm_restore_monitoring(struct task_struct *task)
 {
-	pfm_smpl_buffer_desc_t *psb = (pfm_smpl_buffer_desc_t *)vma->vm_private_data;
+	pfm_context_t *ctx = PFM_GET_CTX(task);
+	struct thread_struct *th = &task->thread;
+	unsigned long mask;
+	unsigned long psr, val;
+	int i;
 
-	if (psb == NULL) {
-		printk(KERN_DEBUG "perfmon: psb is null in [%d]\n", current->pid);
+	if (task != current) {
+		printk(KERN_ERR "perfmon.%d: invalid task[%d] current[%d]\n", __LINE__, task->pid, current->pid);
 		return;
 	}
+	if (CTX_IS_MASKED(ctx) == 0) {
+		printk(KERN_ERR "perfmon.%d: task[%d] current[%d] invalid state=%d\n", __LINE__,
+			task->pid, current->pid, ctx->ctx_state);
+		return;
+	}
+	psr = pfm_get_psr();
 	/*
-	 * Add PSB to list of buffers to free on release_thread() when no more users
+	 * monitoring is masked via the PMC.
+	 * As we restore their value, we do not want each counter to
+	 * restart right away. We stop monitoring using the PSR,
+	 * restore the PMC (and PMD) and then re-establish the psr
+	 * as it was. Note that there can be no pending overflow at
+	 * this point, because monitoring was MASKED.
 	 *
-	 * This call is safe because, once the count is zero is cannot be modified anymore.
-	 * This is not because there is no more user of the mm context, that the sampling
-	 * buffer is not being used anymore outside of this task. In fact, it can still
-	 * be accessed from within the kernel by another task (such as the monitored task).
-	 *
-	 * Therefore, we only move the psb into the list of buffers to free when we know
-	 * nobody else is using it.
-	 * The linked list if independent of the perfmon context, because in the case of
-	 * multi-threaded processes, the last thread may not have been involved with
-	 * monitoring however it will be the one removing the vma and it should therefore
-	 * also remove the sampling buffer. This buffer cannot be removed until the vma
-	 * is removed.
-	 *
-	 * This function cannot remove the buffer from here, because exit_mmap() must first
-	 * complete. Given that there is no other vma related callback in the generic code,
-	 * we have created our own with the linked list of sampling buffers to free. The list
-	 * is part of the thread structure. In release_thread() we check if the list is
-	 * empty. If not we call into perfmon to free the buffer and psb. That is the only
-	 * way to ensure a safe deallocation of the sampling buffer which works when
-	 * the buffer is shared between distinct processes or with multi-threaded programs.
-	 *
-	 * We need to lock the psb because the refcnt test and flag manipulation must
-	 * looked like an atomic operation vis a vis pfm_context_exit()
+	 * system-wide session are pinned and self-monitoring
+	 */
+	if (ctx->ctx_fl_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
+		/* disable dcr pp */
+		ia64_set_dcr(ia64_get_dcr() & ~IA64_DCR_PP);
+		pfm_clear_psr_pp();
+	} else {
+		pfm_clear_psr_up();
+	}
+	/*
+	 * first, we restore the PMD
+	 */
+	mask = ctx->ctx_used_pmds[0];
+	for (i = 0; mask; i++, mask>>=1) {
+		/* skip non used pmds */
+		if ((mask & 0x1) == 0) continue;
+
+		if (PMD_IS_COUNTING(i)) {
+			/*
+			 * we split the 64bit value according to
+			 * counter width
+			 */
+			val = ctx->ctx_pmds[i].val & pmu_conf.ovfl_val;
+			ctx->ctx_pmds[i].val &= ~pmu_conf.ovfl_val;
+		} else {
+			val = ctx->ctx_pmds[i].val;
+		}
+		ia64_set_pmd(i, val);
+
+		DPRINT(("pmd[%d]=0x%lx hw_pmd=0x%lx\n",
+			i,
+			ctx->ctx_pmds[i].val,
+			val));
+	}
+	/*
+	 * restore the PMCs
+	 */
+	mask = ctx->ctx_used_monitors[0] >> PMU_FIRST_COUNTER;
+	for(i= PMU_FIRST_COUNTER; mask; i++, mask>>=1) {
+		if ((mask & 0x1) == 0UL) continue;
+		th->pmcs[i] = ctx->ctx_pmcs[i];
+		ia64_set_pmc(i, th->pmcs[i]);
+		DPRINT(("[%d] pmc[%d]=0x%lx\n", task->pid, i, th->pmcs[i]));
+	}
+	ia64_srlz_d();
+
+	/*
+	 * now restore PSR
 	 */
-	LOCK_PSB(psb);
+	if (ctx->ctx_fl_system && (PFM_CPUINFO_GET() & PFM_CPUINFO_DCR_PP)) {
+		/* enable dcr pp */
+		ia64_set_dcr(ia64_get_dcr() | IA64_DCR_PP);
+		ia64_srlz_i();
+	}
+	pfm_set_psr_l(psr);
+}
+
+static inline void
+pfm_save_pmds(unsigned long *pmds, unsigned long mask)
+{
+	int i;
 
-	if (psb->psb_refcnt == 0) {
+	ia64_srlz_d();
+
+	for (i=0; mask; i++, mask>>=1) {
+		if (mask & 0x1) pmds[i] = ia64_get_pmd(i);
+	}
+}
+
+/*
+ * reload from thread state (used for ctxw only)
+ */
+static inline void
+pfm_restore_pmds(unsigned long *pmds, unsigned long mask)
+{
+	int i;
+	unsigned long val, ovfl_val = pmu_conf.ovfl_val;
+
+	DPRINT(("mask=0x%lx\n", mask));
+	for (i=0; mask; i++, mask>>=1) {
+		if ((mask & 0x1) == 0) continue;
+		val = PMD_IS_COUNTING(i) ? pmds[i] & ovfl_val : pmds[i];
+		ia64_set_pmd(i, val);
+		DPRINT(("pmd[%d]=0x%lx\n", i, val));
+	}
+	ia64_srlz_d();
+}
+
+/*
+ * propagate PMD from context to thread-state
+ */
+static inline void
+pfm_copy_pmds(struct task_struct *task, pfm_context_t *ctx)
+{
+	struct thread_struct *thread = &task->thread;
+	unsigned long ovfl_val = pmu_conf.ovfl_val;
+	unsigned long mask = ctx->ctx_all_pmds[0];
+	unsigned long val;
+	int i;
+
+	DPRINT(("mask=0x%lx\n", mask));
+
+	for (i=0; mask; i++, mask>>=1) {
 
-		psb->psb_next = current->thread.pfm_smpl_buf_list;
-		current->thread.pfm_smpl_buf_list = psb;
+		val = ctx->ctx_pmds[i].val;
+
+		/*
+		 * We break up the 64 bit value into 2 pieces
+		 * the lower bits go to the machine state in the
+		 * thread (will be reloaded on ctxsw in).
+		 * The upper part stays in the soft-counter.
+		 */
+		if (PMD_IS_COUNTING(i)) {
+			ctx->ctx_pmds[i].val = val & ~ovfl_val;
+			 val &= ovfl_val;
+		}
+		thread->pmds[i] = val;
 
-		DBprintk(("[%d] add smpl @%p size %lu to smpl_buf_list psb_flags=0x%x\n", 
-			current->pid, psb->psb_hdr, psb->psb_size, psb->psb_flags));
+		DPRINT(("pmd[%d]=0x%lx soft_val=0x%lx\n",
+			i,
+			thread->pmds[i],
+			ctx->ctx_pmds[i].val));
 	}
-	DBprintk(("[%d] clearing psb_flags=0x%x smpl @%p size %lu\n", 
-			current->pid, psb->psb_flags, psb->psb_hdr, psb->psb_size));
+}
+
+/*
+ * propagate PMC from context to thread-state
+ */
+static inline void
+pfm_copy_pmcs(struct task_struct *task, pfm_context_t *ctx)
+{
+	struct thread_struct *thread = &task->thread;
+	unsigned long mask = ctx->ctx_all_pmcs[0];
+	int i;
+
+	DPRINT(("mask=0x%lx\n", mask));
+
+	for (i=0; mask; i++, mask>>=1) {
+		/* masking 0 with ovfl_val yields 0 */
+		thread->pmcs[i] = ctx->ctx_pmcs[i];
+		DPRINT(("pmc[%d]=0x%lx\n", i, thread->pmcs[i]));
+	}
+}
+
+
+
+static inline void
+pfm_restore_pmcs(unsigned long *pmcs, unsigned long mask)
+{
+	int i;
+
+	DPRINT(("mask=0x%lx\n", mask));
+	for (i=0; mask; i++, mask>>=1) {
+		if ((mask & 0x1) == 0) continue;
+		ia64_set_pmc(i, pmcs[i]);
+		DPRINT(("pmc[%d]=0x%lx\n", i, pmcs[i]));
+	}
+	ia64_srlz_d();
+}
+
+static inline void
+pfm_restore_ibrs(unsigned long *ibrs, unsigned int nibrs)
+{
+	int i;
+
+	for (i=0; i < nibrs; i++) {
+		ia64_set_ibr(i, ibrs[i]);
+	}
+	ia64_srlz_i();
+}
+
+static inline void
+pfm_restore_dbrs(unsigned long *dbrs, unsigned int ndbrs)
+{
+	int i;
+
+	for (i=0; i < ndbrs; i++) {
+		ia64_set_dbr(i, dbrs[i]);
+	}
+	ia64_srlz_d();
+}
+
+static inline int
+pfm_uuid_cmp(pfm_uuid_t a, pfm_uuid_t b)
+{
+	return memcmp(a, b, sizeof(pfm_uuid_t));
+}
+
+static inline int
+pfm_buf_fmt_exit(pfm_buffer_fmt_t *fmt, struct task_struct *task, void *buf, struct pt_regs *regs)
+{
+	int ret = 0;
+	if (fmt->fmt_exit) ret = (*fmt->fmt_exit)(task, buf, regs);
+	return ret;
+}
+
+static inline int
+pfm_buf_fmt_getsize(pfm_buffer_fmt_t *fmt, struct task_struct *task, unsigned int flags, int cpu, void *arg, unsigned long *size)
+{
+	int ret = 0;
+	if (fmt->fmt_getsize) ret = (*fmt->fmt_getsize)(task, flags, cpu, arg, size);
+	return ret;
+}
+
+
+static inline int
+pfm_buf_fmt_validate(pfm_buffer_fmt_t *fmt, struct task_struct *task, unsigned int flags,
+		     int cpu, void *arg)
+{
+	int ret = 0;
+	if (fmt->fmt_validate) ret = (*fmt->fmt_validate)(task, flags, cpu, arg);
+	return ret;
+}
+
+static inline int
+pfm_buf_fmt_init(pfm_buffer_fmt_t *fmt, struct task_struct *task, void *buf, unsigned int flags,
+		     int cpu, void *arg)
+{
+	int ret = 0;
+	if (fmt->fmt_init) ret = (*fmt->fmt_init)(task, buf, flags, cpu, arg);
+	return ret;
+}
+
+static inline int
+pfm_buf_fmt_restart(pfm_buffer_fmt_t *fmt, struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs)
+{
+	int ret = 0;
+	if (fmt->fmt_restart) ret = (*fmt->fmt_restart)(task, ctrl, buf, regs);
+	return ret;
+}
+
+static inline int
+pfm_buf_fmt_restart_active(pfm_buffer_fmt_t *fmt, struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs)
+{
+	int ret = 0;
+	if (fmt->fmt_restart_active) ret = (*fmt->fmt_restart_active)(task, ctrl, buf, regs);
+	return ret;
+}
+
+
+
+int
+pfm_register_buffer_fmt(pfm_buffer_fmt_t *fmt)
+{
+	pfm_buffer_fmt_t *p;
+	int ret = 0;
+
+	/* some sanity checks */
+	if (fmt == NULL || fmt->fmt_name == NULL) return -EINVAL;
+
+	/* we need at least a handler */
+	if (fmt->fmt_handler == NULL) return -EINVAL;
+
 	/*
-	 * decrement the number vma for the buffer
+	 * XXX: need check validity of fmt_arg_size
 	 */
-	psb->psb_flags &= ~PSB_HAS_VMA;
 
-	UNLOCK_PSB(psb);
+	LOCK_BUF_FMT_LIST();
+	p = pfm_buffer_fmt_list;
+
+
+	while (p) {
+		if (pfm_uuid_cmp(fmt->fmt_uuid, p->fmt_uuid) == 0) break;
+		p = p->fmt_next;
+	}
+
+	if (p) {
+		printk(KERN_ERR "perfmon: duplicate sampling format: %s\n", fmt->fmt_name);
+		ret = -EBUSY;
+	} else {
+		fmt->fmt_prev = NULL;
+		fmt->fmt_next = pfm_buffer_fmt_list;
+		pfm_buffer_fmt_list = fmt;
+		printk(KERN_ERR "perfmon: added sampling format %s\n", fmt->fmt_name);
+	}
+	UNLOCK_BUF_FMT_LIST();
+
+	return ret;
+}
+
+int
+pfm_unregister_buffer_fmt(pfm_uuid_t uuid)
+{
+	pfm_buffer_fmt_t *p;
+	int ret = 0;
+
+	LOCK_BUF_FMT_LIST();
+	p = pfm_buffer_fmt_list;
+	while (p) {
+		if (memcmp(uuid, p->fmt_uuid, sizeof(pfm_uuid_t)) == 0) break;
+		p = p->fmt_next;
+	}
+	if (p) {
+		if (p->fmt_prev)
+			p->fmt_prev->fmt_next = p->fmt_next;
+		else
+			pfm_buffer_fmt_list = p->fmt_next;
+
+		if (p->fmt_next)
+			p->fmt_next->fmt_prev = p->fmt_prev;
+
+		printk(KERN_ERR "perfmon: removed sampling format: %s\n",  p->fmt_name);
+		p->fmt_next = p->fmt_prev = NULL;
+	} else {
+		printk(KERN_ERR "perfmon: cannot unregister format, not found\n");
+		ret = -EINVAL;
+	}
+	UNLOCK_BUF_FMT_LIST();
+
+	return ret;
+
 }
 
 /*
- * This function is called from pfm_destroy_context() and also from pfm_inherit()
- * to explicitly remove the sampling buffer mapping from the user level address space.
+ * find a buffer format based on its uuid
  */
+static pfm_buffer_fmt_t *
+pfm_find_buffer_fmt(pfm_uuid_t uuid, int nolock)
+{
+	pfm_buffer_fmt_t *p;
+
+	LOCK_BUF_FMT_LIST();
+	for (p = pfm_buffer_fmt_list; p ; p = p->fmt_next) {
+		if (pfm_uuid_cmp(uuid, p->fmt_uuid) == 0) break;
+	}
+
+	UNLOCK_BUF_FMT_LIST();
+
+	return p;
+}
+
 static int
-pfm_remove_smpl_mapping(struct task_struct *task)
+pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned int cpu)
+{
+	/*
+	 * validy checks on cpu_mask have been done upstream
+	 */
+	LOCK_PFS();
+
+	DPRINT(("in sys_sessions=%u task_sessions=%u dbregs=%u syswide=%d cpu=%u\n",
+		pfm_sessions.pfs_sys_sessions,
+		pfm_sessions.pfs_task_sessions,
+		pfm_sessions.pfs_sys_use_dbregs,
+		is_syswide,
+		cpu));
+
+	if (is_syswide) {
+		/*
+		 * cannot mix system wide and per-task sessions
+		 */
+		if (pfm_sessions.pfs_task_sessions > 0UL) {
+			DPRINT(("system wide not possible, %u conflicting task_sessions\n",
+			  	pfm_sessions.pfs_task_sessions));
+			goto abort;
+		}
+
+		if (pfm_sessions.pfs_sys_session[cpu]) goto error_conflict;
+
+		DPRINT(("reserving system wide session on CPU%u currently on CPU%u\n", cpu, smp_processor_id()));
+
+		pfm_sessions.pfs_sys_session[cpu] = task;
+
+		pfm_sessions.pfs_sys_sessions++ ;
+
+	} else {
+		if (pfm_sessions.pfs_sys_sessions) goto abort;
+		pfm_sessions.pfs_task_sessions++;
+	}
+
+	DPRINT(("out sys_sessions=%u task_sessions=%u dbregs=%u syswide=%d cpu=%u\n",
+		pfm_sessions.pfs_sys_sessions,
+		pfm_sessions.pfs_task_sessions,
+		pfm_sessions.pfs_sys_use_dbregs,
+		is_syswide,
+		cpu));
+
+	UNLOCK_PFS();
+
+	return 0;
+
+error_conflict:
+	DPRINT(("system wide not possible, conflicting session [%d] on CPU%d\n",
+  		pfm_sessions.pfs_sys_session[cpu]->pid,
+		smp_processor_id()));
+abort:
+	UNLOCK_PFS();
+
+	return -EBUSY;
+
+}
+
+static int
+pfm_unreserve_session(pfm_context_t *ctx, int is_syswide, unsigned int cpu)
 {
-	pfm_context_t *ctx = task->thread.pfm_context;
-	pfm_smpl_buffer_desc_t *psb;
-	int r;
 
 	/*
-	 * some sanity checks first
+	 * validy checks on cpu_mask have been done upstream
 	 */
-	if (ctx == NULL || task->mm == NULL || ctx->ctx_smpl_vaddr == 0 || ctx->ctx_psb == NULL) {
-		printk(KERN_DEBUG "perfmon: invalid context mm=%p\n", task->mm);
-		return -1;
+	LOCK_PFS();
+
+	DPRINT(("in sys_sessions=%u task_sessions=%u dbregs=%u syswide=%d cpu=%u\n",
+		pfm_sessions.pfs_sys_sessions,
+		pfm_sessions.pfs_task_sessions,
+		pfm_sessions.pfs_sys_use_dbregs,
+		is_syswide,
+		cpu));
+
+
+	if (is_syswide) {
+		pfm_sessions.pfs_sys_session[cpu] = NULL;
+		/*
+		 * would not work with perfmon+more than one bit in cpu_mask
+		 */
+		if (ctx && ctx->ctx_fl_using_dbreg) {
+			if (pfm_sessions.pfs_sys_use_dbregs == 0) {
+				printk(KERN_ERR "perfmon: invalid release for ctx %p sys_use_dbregs=0\n", ctx);
+			} else {
+				pfm_sessions.pfs_sys_use_dbregs--;
+			}
+		}
+		pfm_sessions.pfs_sys_sessions--;
+	} else {
+		pfm_sessions.pfs_task_sessions--;
 	}
-	psb = ctx->ctx_psb;
+	DPRINT(("out sys_sessions=%u task_sessions=%u dbregs=%u syswide=%d cpu=%u\n",
+		pfm_sessions.pfs_sys_sessions,
+		pfm_sessions.pfs_task_sessions,
+		pfm_sessions.pfs_sys_use_dbregs,
+		is_syswide,
+		cpu));
+
+	UNLOCK_PFS();
+
+	return 0;
+}
+
+/*
+ * removes virtual mapping of the sampling buffer.
+ * IMPORTANT: cannot be called with interrupts disable, e.g. inside
+ * a PROTECT_CTX() section.
+ */
+static int
+pfm_remove_smpl_mapping(struct task_struct *task, void *vaddr, unsigned long size)
+{
+	int r;
+
+	/* sanity checks */
+	if (task->mm == NULL || size == 0UL || vaddr == NULL) {
+		printk(KERN_ERR "perfmon: pfm_remove_smpl_mapping [%d] invalid context mm=%p\n", task->pid, task->mm);
+		return -EINVAL;
+	}
+
+	DPRINT(("smpl_vaddr=%p size=%lu\n", vaddr, size));
 
+	/*
+	 * does the actual unmapping
+	 */
 	down_write(&task->mm->mmap_sem);
 
-	r = do_munmap(task->mm, ctx->ctx_smpl_vaddr, psb->psb_size);
+	DPRINT(("down_write done smpl_vaddr=%p size=%lu\n", vaddr, size));
+
+	r = do_munmap(task->mm, (unsigned long)vaddr, size);
 
 	up_write(&task->mm->mmap_sem);
 	if (r !=0) {
-		printk(KERN_DEBUG "perfmon: pid %d unable to unmap sampling buffer "
-		       "@0x%lx size=%ld\n", task->pid, ctx->ctx_smpl_vaddr, psb->psb_size);
+		printk(KERN_ERR "perfmon: [%d] unable to unmap sampling buffer @%p size=%lu\n", task->pid, vaddr, size);
 	}
 
-	DBprintk(("[%d] do_unmap(0x%lx, %ld)=%d refcnt=%lu psb_flags=0x%x\n",
-		task->pid, ctx->ctx_smpl_vaddr, psb->psb_size, r, psb->psb_refcnt, psb->psb_flags));
+	DPRINT(("do_unmap(%p, %lu)=%d\n", vaddr, size, r));
 
 	return 0;
 }
 
-static pfm_context_t *
-pfm_context_alloc(void)
+/*
+ * free actual physical storage used by sampling buffer
+ */
+#if 0
+static int
+pfm_free_smpl_buffer(pfm_context_t *ctx)
+{
+	pfm_buffer_fmt_t *fmt;
+
+	if (ctx->ctx_smpl_hdr == NULL) goto invalid_free;
+
+	/*
+	 * we won't use the buffer format anymore
+	 */
+	fmt = ctx->ctx_buf_fmt;
+
+	DPRINT(("sampling buffer @%p size %lu vaddr=%p\n",
+		ctx->ctx_smpl_hdr,
+		ctx->ctx_smpl_size,
+		ctx->ctx_smpl_vaddr));
+
+	pfm_buf_fmt_exit(fmt, current, NULL, NULL);
+
+	/*
+	 * free the buffer
+	 */
+	pfm_rvfree(ctx->ctx_smpl_hdr, ctx->ctx_smpl_size);
+
+	ctx->ctx_smpl_hdr  = NULL;
+	ctx->ctx_smpl_size = 0UL;
+
+	return 0;
+
+invalid_free:
+	printk(KERN_ERR "perfmon: pfm_free_smpl_buffer [%d] no buffer\n", current->pid);
+	return -EINVAL;
+}
+#endif
+
+static inline void
+pfm_exit_smpl_buffer(pfm_buffer_fmt_t *fmt)
+{
+	if (fmt == NULL) return;
+
+	pfm_buf_fmt_exit(fmt, current, NULL, NULL);
+
+}
+
+/*
+ * pfmfs should _never_ be mounted by userland - too much of security hassle,
+ * no real gain from having the whole whorehouse mounted. So we don't need
+ * any operations on the root directory. However, we need a non-trivial
+ * d_name - pfm: will go nicely and kill the special-casing in procfs.
+ */
+static struct vfsmount *pfmfs_mnt;
+#define PFMFS_MAGIC 0xa0b4d889
+
+#ifdef PFM_COMPILED_FOR_2_4
+
+static int
+pfmfs_statfs(struct super_block *sb, struct statfs *buf)
+{
+	buf->f_type = PFMFS_MAGIC;
+	buf->f_bsize = 1024;
+	buf->f_namelen = 255;
+	return 0;
+}
+
+static struct super_operations pfmfs_ops = {
+	statfs:		pfmfs_statfs,
+};
+
+static struct super_block *
+pfmfs_read_super(struct super_block *sb, void *data, int silent)
+{
+	struct inode *root = new_inode(sb);
+	if (!root)
+		return NULL;
+	root->i_mode = S_IFDIR | S_IRUSR | S_IWUSR;
+	root->i_uid = root->i_gid = 0;
+	root->i_atime = root->i_mtime = root->i_ctime = CURRENT_TIME;
+	sb->s_blocksize = 1024;
+	sb->s_blocksize_bits = 10;
+	sb->s_magic = PFMFS_MAGIC;
+	sb->s_op	= &pfmfs_ops;
+	sb->s_root = d_alloc(NULL, &(const struct qstr) { "pfm:", 4, 0 });
+	if (!sb->s_root) {
+		iput(root);
+		return NULL;
+	}
+	sb->s_root->d_sb = sb;
+	sb->s_root->d_parent = sb->s_root;
+	d_instantiate(sb->s_root, root);
+	return sb;
+}
+
+//static DECLARE_FSTYPE(pfm_fs_type, "pfmfs", pfmfs_read_super, FS_NOMOUNT);
+static struct file_system_type pfm_fs_type = {
+	name:		"pfmfs",
+	read_super:	pfmfs_read_super,
+	fs_flags:	FS_NOMOUNT,
+};
+
+#else /* ! COMPILED_FOR_2_4 */
+
+static struct super_block *
+pfmfs_get_sb(struct file_system_type *fs_type, int flags, char *dev_name, void *data)
+{
+	return get_sb_pseudo(fs_type, "pfm:", NULL, PFMFS_MAGIC);
+}
+
+static struct file_system_type pfm_fs_type = {
+	.name     = "pfmfs",
+	.get_sb   = pfmfs_get_sb,
+	.kill_sb  = kill_anon_super,
+};
+#endif /* COMPILED_FOR_2_4 */
+
+static int __init
+init_pfm_fs(void)
+{
+	int err = register_filesystem(&pfm_fs_type);
+	if (!err) {
+		pfmfs_mnt = kern_mount(&pfm_fs_type);
+		err = PTR_ERR(pfmfs_mnt);
+		if (IS_ERR(pfmfs_mnt))
+			unregister_filesystem(&pfm_fs_type);
+		else
+			err = 0;
+	}
+	return err;
+}
+
+static void __exit
+exit_pfm_fs(void)
+{
+	unregister_filesystem(&pfm_fs_type);
+	mntput(pfmfs_mnt);
+}
+
+static loff_t
+pfm_lseek(struct file *file, loff_t offset, int whence)
+{
+	DPRINT(("pfm_lseek called\n"));
+	return -ESPIPE;
+}
+
+static ssize_t
+pfm_do_read(struct file *filp, char *buf, size_t size, loff_t *ppos)
 {
 	pfm_context_t *ctx;
+	pfm_msg_t *msg;
+	ssize_t ret;
+	unsigned long flags;
+  	DECLARE_WAITQUEUE(wait, current);
+	if (PFM_IS_FILE(filp) == 0) {
+		printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", current->pid);
+		return -EINVAL;
+	}
 
-	/* allocate context descriptor */
-	ctx = kmalloc(sizeof(pfm_context_t), GFP_KERNEL);
-	if (ctx) memset(ctx, 0, sizeof(pfm_context_t));
-	
-	return ctx;
+	ctx = (pfm_context_t *)filp->private_data;
+	if (ctx == NULL) {
+		printk(KERN_ERR "perfmon: pfm_read: NULL ctx [%d]\n", current->pid);
+		return -EINVAL;
+	}
+
+	/*
+	 * check even when there is no message
+	 */
+	if (size < sizeof(pfm_msg_t)) {
+		DPRINT(("message is too small ctx=%p (>=%ld)\n", ctx, sizeof(pfm_msg_t)));
+		return -EINVAL;
+	}
+	/*
+	 * seeks are not allowed on message queues
+	 */
+	if (ppos != &filp->f_pos) return -ESPIPE;
+
+	PROTECT_CTX(ctx, flags);
+
+  	/*
+	 * put ourselves on the wait queue
+	 */
+  	add_wait_queue(&ctx->ctx_msgq_wait, &wait);
+
+
+  	for(;;) {
+		/*
+		 * check wait queue
+		 */
+
+  		set_current_state(TASK_INTERRUPTIBLE);
+
+		DPRINT(("head=%d tail=%d\n", ctx->ctx_msgq_head, ctx->ctx_msgq_tail));
+
+		ret = 0;
+		if(PFM_CTXQ_EMPTY(ctx) == 0) break;
+
+		UNPROTECT_CTX(ctx, flags);
+
+		/*
+		 * check non-blocking read
+		 */
+      		ret = -EAGAIN;
+		if(filp->f_flags & O_NONBLOCK) break;
+
+		/*
+		 * check pending signals
+		 */
+		if(signal_pending(current)) {
+			ret = -EINTR;
+			break;
+		}
+      		/*
+		 * no message, so wait
+		 */
+      		schedule();
+
+		PROTECT_CTX(ctx, flags);
+	}
+	DPRINT(("[%d] back to running ret=%ld\n", current->pid, ret));
+  	set_current_state(TASK_RUNNING);
+	remove_wait_queue(&ctx->ctx_msgq_wait, &wait);
+
+	if (ret < 0) goto abort;
+
+	ret = -EINVAL;
+	msg = pfm_get_next_msg(ctx);
+	if (msg == NULL) {
+		printk(KERN_ERR "perfmon: pfm_read no msg for ctx=%p [%d]\n", ctx, current->pid);
+		goto abort_locked;
+	}
+
+	DPRINT(("[%d] fd=%d type=%d\n", current->pid, msg->pfm_gen_msg.msg_ctx_fd, msg->pfm_gen_msg.msg_type));
+
+	ret = -EFAULT;
+  	if(copy_to_user(buf, msg, sizeof(pfm_msg_t)) == 0) ret = sizeof(pfm_msg_t);
+
+abort_locked:
+	UNPROTECT_CTX(ctx, flags);
+abort:
+	return ret;
 }
 
-static void
-pfm_context_free(pfm_context_t *ctx)
+static ssize_t
+pfm_read(struct file *filp, char *buf, size_t size, loff_t *ppos)
+{
+	int oldvar, ret;
+
+	oldvar = pfm_debug_var;
+	pfm_debug_var = pfm_sysctl.debug_pfm_read;
+	ret = pfm_do_read(filp, buf, size, ppos);
+	pfm_debug_var = oldvar;
+	return ret;
+}
+
+static ssize_t
+pfm_write(struct file *file, const char *ubuf,
+			  size_t size, loff_t *ppos)
+{
+	DPRINT(("pfm_write called\n"));
+	return -EINVAL;
+}
+
+static unsigned int
+pfm_poll(struct file *filp, poll_table * wait)
 {
-	if (ctx) kfree(ctx);
+	pfm_context_t *ctx;
+	unsigned long flags;
+	unsigned int mask = 0;
+
+	if (PFM_IS_FILE(filp) == 0) {
+		printk(KERN_ERR "perfmon: pfm_poll: bad magic [%d]\n", current->pid);
+		return 0;
+	}
+
+	ctx = (pfm_context_t *)filp->private_data;
+	if (ctx == NULL) {
+		printk(KERN_ERR "perfmon: pfm_poll: NULL ctx [%d]\n", current->pid);
+		return 0;
+	}
+
+
+	DPRINT(("pfm_poll ctx_fd=%d before poll_wait\n", ctx->ctx_fd));
+
+	poll_wait(filp, &ctx->ctx_msgq_wait, wait);
+
+	PROTECT_CTX(ctx, flags);
+
+	if (PFM_CTXQ_EMPTY(ctx) == 0)
+		mask =  POLLIN | POLLRDNORM;
+
+	UNPROTECT_CTX(ctx, flags);
+
+	DPRINT(("pfm_poll ctx_fd=%d mask=0x%x\n", ctx->ctx_fd, mask));
+
+	return mask;
 }
 
 static int
-pfm_remap_buffer(struct vm_area_struct *vma, unsigned long buf, unsigned long addr, unsigned long size)
+pfm_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
 {
-	unsigned long page;
+	DPRINT(("pfm_ioctl called\n"));
+	return -EINVAL;
+}
 
-	DBprintk(("CPU%d buf=0x%lx addr=0x%lx size=%ld\n", smp_processor_id(), buf, addr, size));
+/*
+ * context is locked when coming here
+ */
+static inline int
+pfm_do_fasync(int fd, struct file *filp, pfm_context_t *ctx, int on)
+{
+	int ret;
 
-	while (size > 0) {
-		page = pfm_kvirt_to_pa(buf);
+	ret = fasync_helper (fd, filp, on, &ctx->ctx_async_queue);
 
-		if (remap_page_range(vma, addr, page, PAGE_SIZE, PAGE_READONLY)) return -ENOMEM;
+	DPRINT(("pfm_fasync called by [%d] on ctx_fd=%d on=%d async_queue=%p ret=%d\n",
+		current->pid,
+		fd,
+		on,
+		ctx->ctx_async_queue, ret));
 
-		addr  += PAGE_SIZE;
-		buf   += PAGE_SIZE;
-		size  -= PAGE_SIZE;
+	return ret;
+}
+
+static int
+pfm_fasync(int fd, struct file *filp, int on)
+{
+	pfm_context_t *ctx;
+	unsigned long flags;
+	int ret;
+
+	if (PFM_IS_FILE(filp) == 0) {
+		printk(KERN_ERR "perfmon: pfm_fasync bad magic [%d]\n", current->pid);
+		return -EBADF;
 	}
-	return 0;
+
+	ctx = (pfm_context_t *)filp->private_data;
+	if (ctx == NULL) {
+		printk(KERN_ERR "perfmon: pfm_fasync NULL ctx [%d]\n", current->pid);
+		return -EBADF;
+	}
+
+
+	PROTECT_CTX(ctx, flags);
+
+	ret = pfm_do_fasync(fd, filp, ctx, on);
+
+	DPRINT(("pfm_fasync called by [%d] on ctx_fd=%d on=%d async_queue=%p ret=%d\n",
+		current->pid,
+		fd,
+		on,
+		ctx->ctx_async_queue, ret));
+
+	UNPROTECT_CTX(ctx, flags);
+
+	return ret;
 }
 
+#ifdef CONFIG_SMP
 /*
- * counts the number of PMDS to save per entry.
- * This code is generic enough to accommodate more than 64 PMDS when they become available
+ * this function is exclusively called from pfm_close().
+ * The context is not protected at that time, nor are interrupts
+ * on the remote CPU. That's necessary to avoid deadlocks.
  */
-static unsigned long
-pfm_smpl_entry_size(unsigned long *which, unsigned long size)
+static void
+pfm_syswide_force_stop(void *info)
 {
-	unsigned long i, res = 0;
+	pfm_context_t   *ctx = (pfm_context_t *)info;
+	struct pt_regs *regs = ia64_task_regs(current);
+	struct task_struct *owner;
 
-	for (i=0; i < size; i++, which++) res += hweight64(*which);
+	if (ctx->ctx_cpu != smp_processor_id()) {
+		printk(KERN_ERR "perfmon: pfm_syswide_force_stop for CPU%d  but on CPU%d\n",
+			ctx->ctx_cpu,
+			smp_processor_id());
+		return;
+	}
+	owner = GET_PMU_OWNER();
+	if (owner != ctx->ctx_task) {
+		printk(KERN_ERR "perfmon: pfm_syswide_force_stop CPU%d unexpected owner [%d] instead of [%d]\n",
+			smp_processor_id(),
+			owner->pid, ctx->ctx_task->pid);
+		return;
+	}
+	if (GET_PMU_CTX() != ctx) {
+		printk(KERN_ERR "perfmon: pfm_syswide_force_stop CPU%d unexpected ctx %p instead of %p\n",
+			smp_processor_id(),
+			GET_PMU_CTX(), ctx);
+		return;
+	}
 
-	DBprintk(("weight=%ld\n", res));
+	DPRINT(("[%d] on CPU%d forcing system wide stop for [%d]\n", current->pid, smp_processor_id(), ctx->ctx_task->pid));
+	/*
+	 * Update local PMU
+	 */
+	ia64_set_dcr(ia64_get_dcr() & ~IA64_DCR_PP);
+	ia64_srlz_i();
+	/*
+	 * update local cpuinfo
+	 */
+	PFM_CPUINFO_CLEAR(PFM_CPUINFO_DCR_PP);
+	PFM_CPUINFO_CLEAR(PFM_CPUINFO_SYST_WIDE);
+	PFM_CPUINFO_CLEAR(PFM_CPUINFO_EXCL_IDLE);
+
+	pfm_clear_psr_pp();
+
+	/*
+	 * also stop monitoring in the local interrupted task
+	 */
+	ia64_psr(regs)->pp = 0;
+
+	SET_PMU_OWNER(NULL, NULL);
+}
+
+static void
+pfm_syswide_cleanup_other_cpu(pfm_context_t *ctx)
+{
+	int ret;
 
-	return res;
+	DPRINT(("[%d] calling CPU%d for cleanup\n", current->pid, ctx->ctx_cpu));
+	ret = smp_call_function_single(ctx->ctx_cpu, pfm_syswide_force_stop, ctx, 0, 1);
+	DPRINT(("[%d] called CPU%d for cleanup ret=%d\n", current->pid, ctx->ctx_cpu, ret));
 }
+#endif /* CONFIG_SMP */
 
 /*
- * Allocates the sampling buffer and remaps it into caller's address space
+ * called either on explicit close() or from exit_files().
+ *
+ * IMPORTANT: we get called ONLY when the refcnt on the file gets to zero (fput()),i.e,
+ * last task to access the file. Nobody else can access the file at this point.
+ *
+ * When called from exit_files(), the VMA has been freed because exit_mm()
+ * is executed before exit_files().
+ *
+ * When called from exit_files(), the current task is not yet ZOMBIE but we will
+ * flush the PMU state to the context. This means * that when we see the context
+ * state as TERMINATED we are guranteed to have the latest PMU state available,
+ * even if the task itself is in the middle of being ctxsw out.
  */
+static int pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs);
 static int
-pfm_smpl_buffer_alloc(pfm_context_t *ctx, unsigned long *which_pmds, unsigned long entries, 
-		      void **user_vaddr)
+pfm_close(struct inode *inode, struct file *filp)
 {
-	struct mm_struct *mm = current->mm;
-	struct vm_area_struct *vma = NULL;
-	unsigned long size, regcount;
-	void *smpl_buf;
-	pfm_smpl_buffer_desc_t *psb;
+	pfm_context_t *ctx;
+	struct task_struct *task;
+	struct pt_regs *regs;
+  	DECLARE_WAITQUEUE(wait, current);
+	unsigned long flags;
+	unsigned long smpl_buf_size = 0UL;
+	void *smpl_buf_vaddr = NULL;
+	void *smpl_buf_addr = NULL;
+	int free_possible = 1;
 
+	{ u64 psr = pfm_get_psr();
+	  BUG_ON((psr & IA64_PSR_I) == 0UL);
+	}
 
-	/* note that regcount might be 0, in this case only the header for each
-	 * entry will be recorded.
+	DPRINT(("pfm_close called private=%p\n", filp->private_data));
+
+	if (!inode) {
+		printk(KERN_ERR "pfm_close: NULL inode\n");
+		return 0;
+	}
+
+	if (PFM_IS_FILE(filp) == 0) {
+		printk(KERN_ERR "perfmon: pfm_close: bad magic [%d]\n", current->pid);
+		return -EBADF;
+	}
+
+	ctx = (pfm_context_t *)filp->private_data;
+	if (ctx == NULL) {
+		printk(KERN_ERR "perfmon: pfm_close: NULL ctx [%d]\n", current->pid);
+		return -EBADF;
+	}
+
+	PROTECT_CTX(ctx, flags);
+
+	/*
+	 * remove our file from the async queue, if we use it
 	 */
-	regcount = pfm_smpl_entry_size(which_pmds, 1);
+	if (filp->f_flags & FASYNC) {
+		DPRINT(("[%d] before async_queue=%p\n", current->pid, ctx->ctx_async_queue));
+		pfm_do_fasync (-1, filp, ctx, 0);
+		DPRINT(("[%d] after async_queue=%p\n", current->pid, ctx->ctx_async_queue));
+	}
 
-	if ((sizeof(perfmon_smpl_hdr_t)+ entries*sizeof(perfmon_smpl_entry_t)) <= entries) {
-		DBprintk(("requested entries %lu is too big\n", entries));
-		return -EINVAL;
+	task = PFM_CTX_TASK(ctx);
+
+	DPRINT(("[%d] ctx_state=%d\n", current->pid, ctx->ctx_state));
+
+	if (CTX_IS_UNLOADED(ctx) || CTX_IS_TERMINATED(ctx)) {
+		goto doit;
+	}
+
+	regs = ia64_task_regs(task);
+
+	/*
+	 * context still loaded/masked and self monitoring,
+	 * we stop/unload and we destroy right here
+	 *
+	 * We always go here for system-wide sessions
+	 */
+	if (task == current) {
+#ifdef CONFIG_SMP
+		/*
+		 * the task IS the owner but it migrated to another CPU: that's bad
+		 * but we must handle this cleanly. Unfortunately, the kernel does
+		 * not provide a mechanism to block migration (while the context is loaded).
+		 *
+		 * We need to release the resource on the ORIGINAL cpu.
+		 */
+		if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+
+			DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+
+			UNPROTECT_CTX(ctx, flags);
+
+			pfm_syswide_cleanup_other_cpu(ctx);
+
+			PROTECT_CTX(ctx, flags);
+
+			/*
+			 * short circuit pfm_context_unload();
+			 */
+			task->thread.pfm_context = NULL;
+			ctx->ctx_task            = NULL;
+
+			CTX_UNLOADED(ctx);
+
+			pfm_unreserve_session(ctx, 1 , ctx->ctx_cpu);
+		} else
+#endif /* CONFIG_SMP */
+		{
+
+			DPRINT(("forcing unload on [%d]\n", current->pid));
+			/*
+		 	* stop and unload, returning with state UNLOADED
+		 	* and session unreserved.
+		 	*/
+			pfm_context_unload(ctx, NULL, 0, regs);
+
+			CTX_TERMINATED(ctx);
+
+			DPRINT(("[%d] ctx_state=%d\n", current->pid, ctx->ctx_state));
+		}
+		goto doit;
+	}
+
+	/*
+	 * The task is currently blocked or will block after an overflow.
+	 * we must force it to wakeup to get out of the
+	 * MASKED state and transition to the unloaded state by itself
+	 */
+	if (CTX_IS_MASKED(ctx) && CTX_OVFL_NOBLOCK(ctx) == 0) {
+
+		/*
+		 * set a "partial" zombie state to be checked
+		 * upon return from down() in pfm_handle_work().
+		 *
+		 * We cannot use the ZOMBIE state, because it is checked
+		 * by pfm_load_regs() which is called upon wakeup from down().
+		 * In such cas, it would free the context and then we would
+		 * return to pfm_handle_work() which would access the
+		 * stale context. Instead, we set a flag invisible to pfm_load_regs()
+		 * but visible to pfm_handle_work().
+		 *
+		 * For some window of time, we have a zombie context with
+		 * ctx_state = MASKED  and not ZOMBIE
+		 */
+		ctx->ctx_fl_going_zombie = 1;
+
+		/*
+		 * force task to wake up from MASKED state
+		 */
+		up(&ctx->ctx_restart_sem);
+
+		DPRINT(("waking up ctx_state=%d for [%d]\n", ctx->ctx_state, current->pid));
+
+		/*
+		 * put ourself to sleep waiting for the other
+		 * task to report completion
+		 *
+		 * the context is protected by mutex, therefore there
+		 * is no risk of being notified of completion before
+		 * begin actually on the waitq.
+		 */
+  		set_current_state(TASK_INTERRUPTIBLE);
+  		add_wait_queue(&ctx->ctx_zombieq, &wait);
+
+		UNPROTECT_CTX(ctx, flags);
+
+		/*
+		 * XXX: check for signals :
+		 * 	- ok of explicit close
+		 * 	- not ok when coming from exit_files()
+		 */
+      		schedule();
+
+		DPRINT(("woken up ctx_state=%d for [%d]\n", ctx->ctx_state, current->pid));
+
+		PROTECT_CTX(ctx, flags);
+
+		remove_wait_queue(&ctx->ctx_zombieq, &wait);
+  		set_current_state(TASK_RUNNING);
+
+		/*
+		 * context is terminated at this point
+		 */
+		DPRINT(("after zombie wakeup ctx_state=%d for [%d]\n", ctx->ctx_state, current->pid));
+	}
+	else {
+#ifdef CONFIG_SMP
+		/*
+	 	 * switch context to zombie state
+	 	 */
+		CTX_ZOMBIE(ctx);
+
+		DPRINT(("zombie ctx for [%d]\n", task->pid));
+		/*
+		 * cannot free the context on the spot. deferred until
+		 * the task notices the ZOMBIE state
+		 */
+		free_possible = 0;
+#else
+		pfm_context_unload(ctx, NULL, 0, regs);
+#endif
+	}
+
+doit:	/* cannot assume task is defined from now on */
+	/*
+	 * the context is still attached to a task (possibly current)
+	 * we cannot destroy it right now
+	 */
+	/*
+	 * remove virtual mapping, if any. will be NULL when
+	 * called from exit_files().
+	 */
+	if (ctx->ctx_smpl_vaddr) {
+		smpl_buf_vaddr = ctx->ctx_smpl_vaddr;
+		smpl_buf_size  = ctx->ctx_smpl_size;
+		ctx->ctx_smpl_vaddr = NULL;
+	}
+
+	/*
+	 * we must fre the sampling buffer right here because
+	 * we cannot rely on it being cleaned up later by the
+	 * monitored task. It is not possible to free vmalloc'ed
+	 * memory in pfm_load_regs(). Instead, we remove the buffer
+	 * now. should there be subsequent PMU overflow originally
+	 * meant for sampling, the will be converted to spurious
+	 * and that's fine because the monitoring tools is gone anyway.
+	 */
+	if (ctx->ctx_smpl_hdr) {
+		smpl_buf_addr = ctx->ctx_smpl_hdr;
+		smpl_buf_size = ctx->ctx_smpl_size;
+		/* no more sampling */
+		ctx->ctx_smpl_hdr = NULL;
+	}
+
+
+	DPRINT(("[%d] ctx_state=%d free_possible=%d vaddr=%p addr=%p size=%lu\n",
+		current->pid,
+		ctx->ctx_state,
+		free_possible,
+		smpl_buf_vaddr,
+		smpl_buf_addr,
+		smpl_buf_size));
+
+	if (smpl_buf_addr) pfm_exit_smpl_buffer(ctx->ctx_buf_fmt);
+
+	/*
+	 * UNLOADED and TERMINATED mean that the session has already been
+	 * unreserved.
+	 */
+	if (CTX_IS_ZOMBIE(ctx)) {
+		pfm_unreserve_session(ctx, ctx->ctx_fl_system , ctx->ctx_cpu);
+	}
+
+	/*
+	 * disconnect file descriptor from context must be done
+	 * before we unlock.
+	 */
+	filp->private_data = NULL;
+
+	/*
+	 * if we free on the spot, the context is now completely unreacheable
+	 * from the callers side. The monitored task side is also cut, so we
+	 * can freely cut.
+	 *
+	 * If we have a deferred free, only the caller side is disconnected.
+	 */
+	UNPROTECT_CTX(ctx, flags);
+
+	/*
+	 * if there was a mapping, then we systematically remove it
+	 * at this point. Cannot be done inside critical section
+	 * because some VM function reenables interrupts.
+	 *
+	 * All memory free operations (especially for vmalloc'ed memory)
+	 * MUST be done with interrupts ENABLED.
+	 */
+	if (smpl_buf_vaddr) pfm_remove_smpl_mapping(current, smpl_buf_vaddr, smpl_buf_size);
+	if (smpl_buf_addr)  pfm_rvfree(smpl_buf_addr, smpl_buf_size);
+
+	/*
+	 * return the memory used by the context
+	 */
+	if (free_possible) pfm_context_free(ctx);
+
+	return 0;
+}
+
+static int
+pfm_no_open(struct inode *irrelevant, struct file *dontcare)
+{
+	DPRINT(("pfm_no_open called\n"));
+	return -ENXIO;
+}
+
+static struct file_operations pfm_file_ops = {
+	.llseek   = pfm_lseek,
+	.read     = pfm_read,
+	.write    = pfm_write,
+	.poll     = pfm_poll,
+	.ioctl    = pfm_ioctl,
+	.open     = pfm_no_open,	/* special open code to disallow open via /proc */
+	.fasync   = pfm_fasync,
+	.release  = pfm_close
+};
+
+static int
+pfmfs_delete_dentry(struct dentry *dentry)
+{
+	return 1;
+}
+static struct dentry_operations pfmfs_dentry_operations = {
+	d_delete:	pfmfs_delete_dentry,
+};
+
+
+static int
+pfm_alloc_fd(struct file **cfile)
+{
+	int fd, ret = 0;
+	struct file *file = NULL;
+	struct inode * inode;
+	char name[32];
+	struct qstr this;
+
+	fd = get_unused_fd();
+	if (fd < 0) return -ENFILE;
+
+	ret = -ENFILE;
+
+	file = get_empty_filp();
+	if (!file) goto out;
+
+	/*
+	 * allocate a new inode
+	 */
+	inode = new_inode(pfmfs_mnt->mnt_sb);
+	if (!inode) goto out;
+
+	DPRINT(("new inode ino=%ld @%p\n", inode->i_ino, inode));
+
+	inode->i_sb   = pfmfs_mnt->mnt_sb;
+	inode->i_mode = S_IFCHR|S_IRUGO;
+	inode->i_sock = 0;
+	inode->i_uid  = current->fsuid;
+	inode->i_gid  = current->fsgid;
+
+	sprintf(name, "[%lu]", inode->i_ino);
+	this.name = name;
+	this.len  = strlen(name);
+	this.hash = inode->i_ino;
+
+	ret = -ENOMEM;
+
+	/*
+	 * allocate a new dcache entry
+	 */
+	file->f_dentry = d_alloc(pfmfs_mnt->mnt_sb->s_root, &this);
+	if (!file->f_dentry) goto out;
+
+	file->f_dentry->d_op = &pfmfs_dentry_operations;
+
+	d_add(file->f_dentry, inode);
+	file->f_vfsmnt = mntget(pfmfs_mnt);
+
+	file->f_op    = &pfm_file_ops;
+	file->f_mode  = FMODE_READ;
+	file->f_flags = O_RDONLY;
+	file->f_pos   = 0;
+
+	/*
+	 * may have to delay until context is attached?
+	 */
+	fd_install(fd, file);
+
+	/*
+	 * the file structure we will use
+	 */
+	*cfile = file;
+
+	return fd;
+out:
+	if (file) put_filp(file);
+	put_unused_fd(fd);
+	return ret;
+}
+
+static void
+pfm_free_fd(int fd, struct file *file)
+{
+	if (file) put_filp(file);
+	put_unused_fd(fd);
+}
+
+/*
+ * This function gets called from mm/mmap.c:exit_mmap() only when there is a sampling buffer
+ * attached to the context AND the current task has a mapping for it, i.e., it is the original
+ * creator of the context.
+ *
+ * This function is used to remember the fact that the vma describing the sampling buffer
+ * has now been removed. It can only be called when no other tasks share the same mm context.
+ *
+ */
+static void
+pfm_vm_close(struct vm_area_struct *vma)
+{
+	pfm_context_t *ctx = (pfm_context_t *)vma->vm_private_data;
+	unsigned long flags;
+
+	PROTECT_CTX(ctx, flags);
+	ctx->ctx_smpl_vaddr = NULL;
+	UNPROTECT_CTX(ctx, flags);
+	DPRINT(("[%d] clearing vaddr for ctx %p\n", current->pid, ctx));
+}
+
+static int
+pfm_remap_buffer(struct vm_area_struct *vma, unsigned long buf, unsigned long addr, unsigned long size)
+{
+	unsigned long page;
+
+	DPRINT(("CPU%d buf=0x%lx addr=0x%lx size=%ld\n", smp_processor_id(), buf, addr, size));
+
+	while (size > 0) {
+		page = pfm_kvirt_to_pa(buf);
+
+		if (pfm_remap_page_range(vma, addr, page, PAGE_SIZE, PAGE_READONLY)) return -ENOMEM;
+
+		addr  += PAGE_SIZE;
+		buf   += PAGE_SIZE;
+		size  -= PAGE_SIZE;
 	}
+	return 0;
+}
+
+/*
+ * allocate a sampling buffer and remaps it into the user address space of the task
+ */
+static int
+pfm_smpl_buffer_alloc(struct task_struct *task, pfm_context_t *ctx, unsigned long rsize, void **user_vaddr)
+{
+	struct mm_struct *mm = task->mm;
+	struct vm_area_struct *vma = NULL;
+	unsigned long size;
+	void *smpl_buf;
+
 
 	/*
-	 * 1 buffer hdr and for each entry a header + regcount PMDs to save
+	 * the fixed header + requested size and align to page boundary
 	 */
-	size = PAGE_ALIGN(  sizeof(perfmon_smpl_hdr_t)
-			  + entries * (sizeof(perfmon_smpl_entry_t) + regcount*sizeof(u64)));
+	size = PAGE_ALIGN(rsize);
 
-	DBprintk(("sampling buffer size=%lu bytes\n", size));
+	DPRINT(("sampling buffer rsize=%lu size=%lu bytes\n", rsize, size));
 
 	/*
 	 * check requested size to avoid Denial-of-service attacks
-	 * XXX: may have to refine this test	
+	 * XXX: may have to refine this test
 	 * Check against address space limit.
 	 *
-	 * if ((mm->total_vm << PAGE_SHIFT) + len> current->rlim[RLIMIT_AS].rlim_cur) 
+	 * if ((mm->total_vm << PAGE_SHIFT) + len> task->rlim[RLIMIT_AS].rlim_cur)
 	 * 	return -ENOMEM;
 	 */
-	if (size > current->rlim[RLIMIT_MEMLOCK].rlim_cur) return -EAGAIN;
+	if (size > task->rlim[RLIMIT_MEMLOCK].rlim_cur) return -EAGAIN;
 
 	/*
 	 * We do the easy to undo allocations first.
@@ -785,69 +2409,40 @@
 	 */
 	smpl_buf = pfm_rvmalloc(size);
 	if (smpl_buf == NULL) {
-		DBprintk(("Can't allocate sampling buffer\n"));
+		DPRINT(("Can't allocate sampling buffer\n"));
 		return -ENOMEM;
 	}
 
-	DBprintk(("smpl_buf @%p\n", smpl_buf));
-
-	/* allocate sampling buffer descriptor now */
-	psb = kmalloc(sizeof(*psb), GFP_KERNEL);
-	if (psb == NULL) {
-		DBprintk(("Can't allocate sampling buffer descriptor\n"));
-		goto error_kmalloc;
-	}
+	DPRINT(("[%d]  smpl_buf @%p\n", current->pid, smpl_buf));
 
 	/* allocate vma */
 	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
 	if (!vma) {
-		DBprintk(("Cannot allocate vma\n"));
+		DPRINT(("Cannot allocate vma\n"));
 		goto error_kmem;
 	}
 	/*
 	 * partially initialize the vma for the sampling buffer
 	 *
 	 * The VM_DONTCOPY flag is very important as it ensures that the mapping
-	 * will never be inherited for any child process (via fork()) which is always 
+	 * will never be inherited for any child process (via fork()) which is always
 	 * what we want.
 	 */
 	vma->vm_mm	     = mm;
 	vma->vm_flags	     = VM_READ| VM_MAYREAD |VM_RESERVED|VM_DONTCOPY;
 	vma->vm_page_prot    = PAGE_READONLY; /* XXX may need to change */
-	vma->vm_ops	     = &pfm_vm_ops; /* necesarry to get the close() callback */
+	vma->vm_ops	     = &pfm_vm_ops;
 	vma->vm_pgoff	     = 0;
 	vma->vm_file	     = NULL;
-	vma->vm_private_data = psb;	/* information needed by the pfm_vm_close() function */
+	vma->vm_private_data = ctx;	/* information needed by the pfm_vm_close() function */
 
 	/*
 	 * Now we have everything we need and we can initialize
 	 * and connect all the data structures
 	 */
 
-	psb->psb_hdr	 = smpl_buf;
-	psb->psb_addr    = ((char *)smpl_buf)+sizeof(perfmon_smpl_hdr_t); /* first entry */
-	psb->psb_size    = size; /* aligned size */
-	psb->psb_index   = 0;
-	psb->psb_entries = entries;
-	psb->psb_refcnt  = 1;
-	psb->psb_flags   = PSB_HAS_VMA;
-
-	spin_lock_init(&psb->psb_lock);
-
-	/*
-	 * XXX: will need to do cacheline alignment to avoid false sharing in SMP mode and
-	 * multitask monitoring.
-	 */
-	psb->psb_entry_size = sizeof(perfmon_smpl_entry_t) + regcount*sizeof(u64);
-
-	DBprintk(("psb @%p entry_size=%ld hdr=%p addr=%p refcnt=%lu psb_flags=0x%x\n", 
-		  (void *)psb,psb->psb_entry_size, (void *)psb->psb_hdr, 
-		  (void *)psb->psb_addr, psb->psb_refcnt, psb->psb_flags));
-
-	/* initialize some of the fields of user visible buffer header */
-	psb->psb_hdr->hdr_version    = PFM_SMPL_VERSION;
-	psb->psb_hdr->hdr_entry_size = psb->psb_entry_size;
-	psb->psb_hdr->hdr_pmds[0]    = which_pmds[0];
+	ctx->ctx_smpl_hdr   = smpl_buf;
+	ctx->ctx_smpl_size  = size; /* aligned size */
 
 	/*
 	 * Let's do the difficult operations next.
@@ -855,24 +2450,23 @@
 	 * now we atomically find some area in the address space and
 	 * remap the buffer in it.
 	 */
-	down_write(&current->mm->mmap_sem);
-
+	down_write(&task->mm->mmap_sem);
 
 	/* find some free area in address space, must have mmap sem held */
 	vma->vm_start = get_unmapped_area(NULL, 0, size, 0, MAP_PRIVATE|MAP_ANONYMOUS);
 	if (vma->vm_start == 0UL) {
-		DBprintk(("Cannot find unmapped area for size %ld\n", size));
-		up_write(&current->mm->mmap_sem);
+		DPRINT(("Cannot find unmapped area for size %ld\n", size));
+		up_write(&task->mm->mmap_sem);
 		goto error;
 	}
 	vma->vm_end = vma->vm_start + size;
 
-	DBprintk(("entries=%ld aligned size=%ld, unmapped @0x%lx\n", entries, size, vma->vm_start));
+	DPRINT(("aligned size=%ld, hdr=%p mapped @0x%lx\n", size, ctx->ctx_smpl_hdr, vma->vm_start));
 
-	/* can only be applied to current, need to have the mm semaphore held when called */
+	/* can only be applied to current task, need to have the mm semaphore held when called */
 	if (pfm_remap_buffer(vma, (unsigned long)smpl_buf, vma->vm_start, size)) {
-		DBprintk(("Can't remap buffer\n"));
-		up_write(&current->mm->mmap_sem);
+		DPRINT(("Can't remap buffer\n"));
+		up_write(&task->mm->mmap_sem);
 		goto error;
 	}
 
@@ -884,412 +2478,385 @@
 
 	mm->total_vm  += size >> PAGE_SHIFT;
 
-	up_write(&current->mm->mmap_sem);
-
-	/* store which PMDS to record */
-	ctx->ctx_smpl_regs[0] = which_pmds[0];
-
-
-	/* link to perfmon context */
-	ctx->ctx_psb        = psb;
+	up_write(&task->mm->mmap_sem);
 
 	/*
-	 * keep track of user level virtual address 
+	 * keep track of user level virtual address
 	 */
-	ctx->ctx_smpl_vaddr = *(unsigned long *)user_vaddr = vma->vm_start;
+	ctx->ctx_smpl_vaddr = (void *)vma->vm_start;
+	*(unsigned long *)user_vaddr = vma->vm_start;
 
 	return 0;
 
 error:
 	kmem_cache_free(vm_area_cachep, vma);
 error_kmem:
-	kfree(psb);
-error_kmalloc:
 	pfm_rvfree(smpl_buf, size);
+
 	return -ENOMEM;
 }
 
+/*
+ * XXX: do something better here
+ */
 static int
-pfm_reserve_session(struct task_struct *task, int is_syswide, unsigned long cpu_mask)
+pfm_bad_permissions(struct task_struct *task)
 {
-	unsigned long m, undo_mask;
-	unsigned int n, i;
-
-	/*
-	 * validy checks on cpu_mask have been done upstream
-	 */
-	LOCK_PFS();
-
-	if (is_syswide) {
-		/* 
-		 * cannot mix system wide and per-task sessions
-		 */
-		if (pfm_sessions.pfs_task_sessions > 0UL) {
-			DBprintk(("system wide not possible, %u conflicting task_sessions\n", 
-			  	pfm_sessions.pfs_task_sessions));
-			goto abort;
-		}
+	/* stolen from bad_signal() */
+	return (current->session != task->session)
+	    && (current->euid ^ task->suid) && (current->euid ^ task->uid)
+	    && (current->uid ^ task->suid) && (current->uid ^ task->uid);
+}
 
-		m = cpu_mask; undo_mask = 0UL; n = 0;
-		DBprintk(("cpu_mask=0x%lx\n", cpu_mask));
-		for(i=0; m; i++, m>>=1) {
+static int
+pfarg_is_sane(struct task_struct *task, pfarg_context_t *pfx)
+{
+	int ctx_flags;
 
-			if ((m & 0x1) == 0UL) continue;
+	/* valid signal */
 
-			if (pfm_sessions.pfs_sys_session[i]) goto undo;
+	ctx_flags = pfx->ctx_flags;
 
-			DBprintk(("reserving CPU%d currently on CPU%d\n", i, smp_processor_id()));
+	if (ctx_flags & PFM_FL_SYSTEM_WIDE) {
 
-			pfm_sessions.pfs_sys_session[i] = task;
-			undo_mask |= 1UL << i;
-			n++;
+		/*
+		 * cannot block in this mode
+		 */
+		if (ctx_flags & PFM_FL_NOTIFY_BLOCK) {
+			DPRINT(("cannot use blocking mode when in system wide monitoring\n"));
+			return -EINVAL;
 		}
-		pfm_sessions.pfs_sys_sessions += n;
 	} else {
-		if (pfm_sessions.pfs_sys_sessions) goto abort;
-		pfm_sessions.pfs_task_sessions++;
 	}
-	DBprintk(("task_sessions=%u sys_session[%d]=%d", 
-		  pfm_sessions.pfs_task_sessions, 
-		  smp_processor_id(), pfm_sessions.pfs_sys_session[smp_processor_id()] ? 1 : 0));
-	UNLOCK_PFS();
-	return 0;
-undo:
-	DBprintk(("system wide not possible, conflicting session [%d] on CPU%d\n",
-  		pfm_sessions.pfs_sys_session[i]->pid, i));
-
-	for(i=0; undo_mask; i++, undo_mask >>=1) {
-		pfm_sessions.pfs_sys_session[i] = NULL;
-	}
-abort:
-	UNLOCK_PFS();
-
-	return -EBUSY;
+	/* probably more to add here */
 
+	return 0;
 }
 
 static int
-pfm_unreserve_session(struct task_struct *task, int is_syswide, unsigned long cpu_mask)
+pfm_setup_buffer_fmt(struct task_struct *task, pfm_context_t *ctx, unsigned int ctx_flags,
+		     unsigned int cpu, pfarg_context_t *arg)
 {
-	pfm_context_t *ctx;
-	unsigned long m;
-	unsigned int n, i;
+	pfm_buffer_fmt_t *fmt = NULL;
+	unsigned long size = 0UL;
+	void *uaddr = NULL;
+	void *fmt_arg = NULL;
+	int ret = 0;
+#define PFM_CTXARG_BUF_ARG(a)	(pfm_buffer_fmt_t *)(a+1)
 
-	ctx = task ? task->thread.pfm_context : NULL;
+	/* invoke and lock buffer format, if found */
+	fmt = pfm_find_buffer_fmt(arg->ctx_smpl_buf_id, 0);
+	if (fmt == NULL) {
+		DPRINT(("[%d] cannot find buffer format\n", task->pid));
+		return -EINVAL;
+	}
 
 	/*
-	 * validy checks on cpu_mask have been done upstream
+	 * buffer argument MUST be contiguous to pfarg_context_t
 	 */
-	LOCK_PFS();
+	if (fmt->fmt_arg_size) fmt_arg = PFM_CTXARG_BUF_ARG(arg);
 
-	DBprintk(("[%d] sys_sessions=%u task_sessions=%u dbregs=%u syswide=%d cpu_mask=0x%lx\n",
-		task->pid,
-		pfm_sessions.pfs_sys_sessions,
-		pfm_sessions.pfs_task_sessions,
-		pfm_sessions.pfs_sys_use_dbregs,
-		is_syswide,
-		cpu_mask));
+	ret = pfm_buf_fmt_validate(fmt, task, ctx_flags, cpu, fmt_arg);
 
+	DPRINT(("[%d] after validate(0x%x,%d,%p)=%d\n", task->pid, ctx_flags, cpu, fmt_arg, ret));
 
-	if (is_syswide) {
-		m = cpu_mask; n = 0;
-		for(i=0; m; i++, m>>=1) {
-			if ((m & 0x1) == 0UL) continue;
-			pfm_sessions.pfs_sys_session[i] = NULL;
-			n++;
-		}
-		/* 
-		 * would not work with perfmon+more than one bit in cpu_mask
+	if (ret) goto error;
+
+	/* link buffer format and context */
+	ctx->ctx_buf_fmt = fmt;
+
+	/*
+	 * check if buffer format wants to use perfmon buffer allocation/mapping service
+	 */
+	ret = pfm_buf_fmt_getsize(fmt, task, ctx_flags, cpu, fmt_arg, &size);
+	if (ret) goto error;
+
+	if (size) {
+		/*
+		 * buffer is always remapped into the caller's address space
 		 */
-		if (ctx && ctx->ctx_fl_using_dbreg) {
-			if (pfm_sessions.pfs_sys_use_dbregs == 0) {
-				printk(KERN_DEBUG "perfmon: invalid release for [%d] "
-				       "sys_use_dbregs=0\n", task->pid);
-			} else {
-				pfm_sessions.pfs_sys_use_dbregs--;
-			}
-		}
-		pfm_sessions.pfs_sys_sessions -= n;
+		ret = pfm_smpl_buffer_alloc(current, ctx, size, &uaddr);
+		if (ret) goto error;
 
-		DBprintk(("CPU%d sys_sessions=%u\n", 
-			smp_processor_id(), pfm_sessions.pfs_sys_sessions));
-	} else {
-		pfm_sessions.pfs_task_sessions--;
-		DBprintk(("[%d] task_sessions=%u\n", 
-			task->pid, pfm_sessions.pfs_task_sessions));
+		/* keep track of user address of buffer */
+		arg->ctx_smpl_vaddr = uaddr;
 	}
+	ret = pfm_buf_fmt_init(fmt, task, ctx->ctx_smpl_hdr, ctx_flags, cpu, fmt_arg);
 
-	UNLOCK_PFS();
-
-	return 0;
+error:
+	return ret;
 }
 
-/*
- * XXX: do something better here
- */
-static int
-pfm_bad_permissions(struct task_struct *task)
+static void
+pfm_reset_pmu_state(pfm_context_t *ctx)
 {
-	/* stolen from bad_signal() */
-	return (current->session != task->session)
-	    && (current->euid ^ task->suid) && (current->euid ^ task->uid)
-	    && (current->uid ^ task->suid) && (current->uid ^ task->uid);
-}
+	int i;
 
+	/*
+	 * install reset values for PMC.
+	 */
+	for (i=1; PMC_IS_LAST(i) == 0; i++) {
+		if (PMC_IS_IMPL(i) == 0) continue;
+		ctx->ctx_pmcs[i] = PMC_DFL_VAL(i);
+		DPRINT(("pmc[%d]=0x%lx\n", i, ctx->ctx_pmcs[i]));
+	}
+	/*
+	 * PMD registers are set to 0UL when the context in memset()
+	 */
 
-static int
-pfx_is_sane(struct task_struct *task, pfarg_context_t *pfx)
-{
-	unsigned long smpl_pmds = pfx->ctx_smpl_regs[0];
-	int ctx_flags;
-	int cpu;
+	/*
+	 * On context switched restore, we must restore ALL pmc and ALL pmd even
+	 * when they are not actively used by the task. In UP, the incoming process
+	 * may otherwise pick up left over PMC, PMD state from the previous process.
+	 * As opposed to PMD, stale PMC can cause harm to the incoming
+	 * process because they may change what is being measured.
+	 * Therefore, we must systematically reinstall the entire
+	 * PMC state. In SMP, the same thing is possible on the
+	 * same CPU but also on between 2 CPUs.
+	 *
+	 * The problem with PMD is information leaking especially
+	 * to user level when psr.sp=0
+	 *
+	 * There is unfortunately no easy way to avoid this problem
+	 * on either UP or SMP. This definitively slows down the
+	 * pfm_load_regs() function.
+	 */
 
-	/* valid signal */
+	 /*
+	  * bitmask of all PMCs accessible to this context
+	  *
+	  * PMC0 is treated differently.
+	  */
+	ctx->ctx_all_pmcs[0] = pmu_conf.impl_pmcs[0] & ~0x1;
 
-	/* cannot send to process 1, 0 means do not notify */
-	if (pfx->ctx_notify_pid == 1) {
-		DBprintk(("invalid notify_pid %d\n", pfx->ctx_notify_pid));
-		return -EINVAL;
-	}
-	ctx_flags = pfx->ctx_flags;
+	/*
+	 * bitmask of all PMDs that are accesible to this context
+	 */
+	ctx->ctx_all_pmds[0] = pmu_conf.impl_pmds[0];
 
-	if ((ctx_flags & PFM_FL_INHERIT_MASK) == (PFM_FL_INHERIT_ONCE|PFM_FL_INHERIT_ALL)) {
-		DBprintk(("invalid inherit mask 0x%x\n",ctx_flags & PFM_FL_INHERIT_MASK));
-		return -EINVAL;
-	}
+	DPRINT(("<%d> all_pmcs=0x%lx all_pmds=0x%lx\n", ctx->ctx_fd, ctx->ctx_all_pmcs[0],ctx->ctx_all_pmds[0]));
 
-	if (ctx_flags & PFM_FL_SYSTEM_WIDE) {
-		DBprintk(("cpu_mask=0x%lx\n", pfx->ctx_cpu_mask));
-		/*
-		 * cannot block in this mode 
-		 */
-		if (ctx_flags & PFM_FL_NOTIFY_BLOCK) {
-			DBprintk(("cannot use blocking mode when in system wide monitoring\n"));
-			return -EINVAL;
-		}
-		/*
-		 * must only have one bit set in the CPU mask
-		 */
-		if (hweight64(pfx->ctx_cpu_mask) != 1UL) {
-			DBprintk(("invalid CPU mask specified\n"));
-			return -EINVAL;
-		}
-		/*
-		 * and it must be a valid CPU
-		 */
-		cpu = ffz(~pfx->ctx_cpu_mask);
-#ifdef CONFIG_SMP
-		if (cpu_online(cpu) == 0) {
-#else
-		if (cpu != 0) {
-#endif
-			DBprintk(("CPU%d is not online\n", cpu));
-			return -EINVAL;
-		}
+	/*
+	 * useful in case of re-enable after disable
+	 */
+	ctx->ctx_used_ibrs[0] = 0UL;
+	ctx->ctx_used_dbrs[0] = 0UL;
+}
 
-		/*
-		 * check for pre-existing pinning, if conflicting reject
-		 */
-		if (task->cpus_allowed != ~0UL && (task->cpus_allowed & (1UL<<cpu)) == 0) {
-			DBprintk(("[%d] pinned on 0x%lx, mask for CPU%d \n", task->pid, 
-				task->cpus_allowed, cpu));
-			return -EINVAL;
-		}
+static int
+pfm_ctx_getsize(void *arg, size_t *sz)
+{
+	pfarg_context_t *req = (pfarg_context_t *)arg;
+	pfm_buffer_fmt_t *fmt;
 
-	} else {
-		/*
-		 * must provide a target for the signal in blocking mode even when
-		 * no counter is configured with PFM_FL_REG_OVFL_NOTIFY
-		 */
-		if ((ctx_flags & PFM_FL_NOTIFY_BLOCK) && pfx->ctx_notify_pid == 0) {
-			DBprintk(("must have notify_pid when blocking for [%d]\n", task->pid));
-			return -EINVAL;
-		}
-#if 0
-		if ((ctx_flags & PFM_FL_NOTIFY_BLOCK) && pfx->ctx_notify_pid == task->pid) {
-			DBprintk(("cannot notify self when blocking for [%d]\n", task->pid));
-			return -EINVAL;
-		}
-#endif
-	}
-	/* verify validity of smpl_regs */
-	if ((smpl_pmds & pmu_conf.impl_pmds[0]) != smpl_pmds) {
-		DBprintk(("invalid smpl_regs 0x%lx\n", smpl_pmds));
+	*sz = 0;
+
+	if (!pfm_uuid_cmp(req->ctx_smpl_buf_id, pfm_null_uuid)) return 0;
+
+	/* no buffer locking here, will be called again */
+	fmt = pfm_find_buffer_fmt(req->ctx_smpl_buf_id, 1);
+	if (fmt == NULL) {
+		DPRINT(("cannot find buffer format\n"));
 		return -EINVAL;
 	}
-	/* probably more to add here */
+	/* get just enough to copy in user parameters */
+	*sz = fmt->fmt_arg_size;
+	DPRINT(("arg_size=%lu\n", *sz));
 
 	return 0;
 }
 
+
+
+/*
+ * cannot attach if :
+ * 	- kernel task
+ * 	- task not owned by caller
+ * 	- task incompatible with context mode
+ */
 static int
-pfm_context_create(struct task_struct *task, pfm_context_t *ctx, void *req, int count, 
-		   struct pt_regs *regs)
+pfm_task_incompatible(pfm_context_t *ctx, struct task_struct *task)
 {
-	pfarg_context_t tmp;
-	void *uaddr = NULL;
-	int ret;
-	int ctx_flags;
-	pid_t notify_pid;
+	/*
+	 * no kernel task or task not owner by caller
+	 */
+	if (task->mm == NULL) {
+		DPRINT(("[%d] task [%d] has not memory context (kernel thread)\n", current->pid, task->pid));
+		return -EPERM;
+	}
+	if (pfm_bad_permissions(task)) {
+		DPRINT(("[%d] no permission to attach to  [%d]\n", current->pid, task->pid));
+		return -EPERM;
+	}
+	/*
+	 * cannot block in self-monitoring mode
+	 */
+	if (CTX_OVFL_NOBLOCK(ctx) == 0 && task == current) {
+		DPRINT(("cannot load a blocking context on self for [%d]\n", task->pid));
+		return -EINVAL;
+	}
 
-	/* a context has already been defined */
-	if (ctx) return -EBUSY;
+	if (task->state == TASK_ZOMBIE) {
+		DPRINT(("[%d] cannot attach to  zombie task [%d]\n", current->pid, task->pid));
+		return -EBUSY;
+	}
 
 	/*
-	 * not yet supported
+	 * always ok for self
 	 */
-	if (task != current) return -EINVAL;
+	if (task == current) return 0;
 
-	if (__copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
+	if (task->state != TASK_STOPPED) {
+		DPRINT(("[%d] cannot attach to non-stopped task [%d] state=%ld\n", current->pid, task->pid, task->state));
+		return -EBUSY;
+	}
+	/*
+	 * make sure the task is off any CPU
+	 */
+	pfm_wait_task_inactive(task);
 
-	ret = pfx_is_sane(task, &tmp);
-	if (ret < 0) return ret;
+	/* more to come... */
 
-	ctx_flags = tmp.ctx_flags;
+	return 0;
+}
 
-	ret = pfm_reserve_session(task, ctx_flags & PFM_FL_SYSTEM_WIDE, tmp.ctx_cpu_mask);
-	if (ret) goto abort;
+static int
+pfm_get_task(pfm_context_t *ctx, pid_t pid, struct task_struct **task)
+{
+	struct task_struct *p = current;
+	int ret;
 
-	ret = -ENOMEM;
+	/* XXX: need to add more checks here */
+	if (pid < 2) return -EPERM;
 
-	ctx = pfm_context_alloc();
-	if (!ctx) goto error;
+	if (pid != current->pid) {
 
-	/* record the creator (important for inheritance) */
-	ctx->ctx_owner = current;
+		read_lock(&tasklist_lock);
 
-	notify_pid = tmp.ctx_notify_pid;
+		p = find_task_by_pid(pid);
 
-	spin_lock_init(&ctx->ctx_lock);
+		/* make sure task cannot go away while we operate on it */
+		if (p) get_task_struct(p);
 
-	if (notify_pid == current->pid) {
+		read_unlock(&tasklist_lock);
 
-		ctx->ctx_notify_task = current;
-		task->thread.pfm_context = ctx;
+		if (p == NULL) return -ESRCH;
+	}
 
-	} else if (notify_pid!=0) {
-		struct task_struct *notify_task;
+	ret = pfm_task_incompatible(ctx, p);
+	if (ret == 0) {
+		*task = p;
+	} else if (p != current) {
+		pfm_put_task(p);
+	}
+	return ret;
+}
 
-		read_lock(&tasklist_lock);
 
-		notify_task = find_task_by_pid(notify_pid);
 
-		if (notify_task) {
+static int
+pfm_context_create(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
+{
+	pfarg_context_t *req = (pfarg_context_t *)arg;
+	struct file *filp;
+	int ctx_flags;
+	int ret;
 
-			ret = -EPERM;
+	/* let's check the arguments first */
+	ret = pfarg_is_sane(current, req);
+	if (ret < 0) return ret;
 
-			/*
-			 * check if we can send this task a signal
-			 */
-			if (pfm_bad_permissions(notify_task)) {
-				read_unlock(&tasklist_lock);
-				goto buffer_error;
-			}
+	ctx_flags = req->ctx_flags;
 
-			/* 
-		 	 * make visible
-		 	 * must be done inside critical section
-		 	 *
-		 	 * if the initialization does not go through it is still
-		 	 * okay because child will do the scan for nothing which
-		 	 * won't hurt.
-		 	 */
-			task->thread.pfm_context = ctx;
+	ret = -ENOMEM;
 
-			/*
-			 * will cause task to check on exit for monitored
-			 * processes that would notify it. see release_thread()
-			 * Note: the scan MUST be done in release thread, once the
-			 * task has been detached from the tasklist otherwise you are
-			 * exposed to race conditions.
-			 */
-			atomic_add(1, &ctx->ctx_notify_task->thread.pfm_notifiers_check);
+	ctx = pfm_context_alloc();
+	if (!ctx) goto error;
 
-			ctx->ctx_notify_task = notify_task;
-		}
-		read_unlock(&tasklist_lock);
-	}
+	req->ctx_fd = ctx->ctx_fd = pfm_alloc_fd(&filp);
+	if (req->ctx_fd < 0) goto error_file;
 
 	/*
-	 * notification process does not exist
+	 * attach context to file
 	 */
-	if (notify_pid != 0 && ctx->ctx_notify_task == NULL) {
-		ret = -EINVAL;
-		goto buffer_error;
-	}
-
-	if (tmp.ctx_smpl_entries) {
-		DBprintk(("sampling entries=%lu\n",tmp.ctx_smpl_entries));
-
-		ret = pfm_smpl_buffer_alloc(ctx, tmp.ctx_smpl_regs, 
-						 tmp.ctx_smpl_entries, &uaddr);
-		if (ret<0) goto buffer_error;
+	filp->private_data = ctx;
 
-		tmp.ctx_smpl_vaddr = uaddr;
+	/*
+	 * does the user want to sample?
+	 */
+	if (pfm_uuid_cmp(req->ctx_smpl_buf_id, pfm_null_uuid)) {
+		ret = pfm_setup_buffer_fmt(current, ctx, ctx_flags, 0, req);
+		if (ret) goto buffer_error;
 	}
-	/* initialization of context's flags */
-	ctx->ctx_fl_inherit   = ctx_flags & PFM_FL_INHERIT_MASK;
-	ctx->ctx_fl_block     = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0;
-	ctx->ctx_fl_system    = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0;
-	ctx->ctx_fl_excl_idle = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0;
-	ctx->ctx_fl_unsecure  = (ctx_flags & PFM_FL_UNSECURE) ? 1: 0;
-	ctx->ctx_fl_frozen    = 0;
-	ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_NONE;
 
 	/*
-	 * setting this flag to 0 here means, that the creator or the task that the
-	 * context is being attached are granted access. Given that a context can only
-	 * be created for the calling process this, in effect only allows the creator
-	 * to access the context. See pfm_protect() for more.
+	 * init context protection lock
 	 */
-	ctx->ctx_fl_protected = 0;
-
-	/* for system wide mode only (only 1 bit set) */
-	ctx->ctx_cpu = ffz(~tmp.ctx_cpu_mask);
-
-	atomic_set(&ctx->ctx_last_cpu,-1); /* SMP only, means no CPU */
+	spin_lock_init(&ctx->ctx_lock);
 
-	sema_init(&ctx->ctx_restart_sem, 0); /* init this semaphore to locked */
+	/*
+	 * context is unloaded
+	 */
+	CTX_UNLOADED(ctx);
 
-	if (__copy_to_user(req, &tmp, sizeof(tmp))) {
-		ret = -EFAULT;
-		goto buffer_error;
-	}
+	/*
+	 * initialization of context's flags
+	 */
+	ctx->ctx_fl_block       = (ctx_flags & PFM_FL_NOTIFY_BLOCK) ? 1 : 0;
+	ctx->ctx_fl_system      = (ctx_flags & PFM_FL_SYSTEM_WIDE) ? 1: 0;
+	ctx->ctx_fl_unsecure	= (ctx_flags & PFM_FL_UNSECURE) ? 1: 0;
+	ctx->ctx_fl_is_sampling = ctx->ctx_buf_fmt ? 1 : 0; /* assume record() is defined */
+	ctx->ctx_fl_no_msg      = (ctx_flags & PFM_FL_OVFL_NO_MSG) ? 1: 0;
+	/*
+	 * will move to set properties
+	 * ctx->ctx_fl_excl_idle   = (ctx_flags & PFM_FL_EXCL_IDLE) ? 1: 0;
+	 */
 
-	DBprintk(("context=%p, pid=%d notify_task=%p\n",
-			(void *)ctx, task->pid, ctx->ctx_notify_task));
+	/*
+	 * init restart semaphore to locked
+	 */
+	sema_init(&ctx->ctx_restart_sem, 0);
 
-	DBprintk(("context=%p, pid=%d flags=0x%x inherit=%d block=%d system=%d excl_idle=%d unsecure=%d\n", 
-			(void *)ctx, task->pid, ctx_flags, ctx->ctx_fl_inherit, 
-			ctx->ctx_fl_block, ctx->ctx_fl_system, 
-			ctx->ctx_fl_excl_idle,
-			ctx->ctx_fl_unsecure));
+	/*
+	 * activation is used in SMP only
+	 */
+	ctx->ctx_last_activation = PFM_INVALID_ACTIVATION;
+	SET_LAST_CPU(ctx, -1);
 
 	/*
-	 * when no notification is required, we can make this visible at the last moment
+	 * initialize notification message queue
 	 */
-	if (notify_pid == 0) task->thread.pfm_context = ctx;
+	ctx->ctx_msgq_head = ctx->ctx_msgq_tail = 0;
+	init_waitqueue_head(&ctx->ctx_msgq_wait);
+	init_waitqueue_head(&ctx->ctx_zombieq);
+
+	DPRINT(("ctx=%p flags=0x%x system=%d notify_block=%d excl_idle=%d unsecure=%d no_msg=%d ctx_fd=%d \n",
+		ctx,
+		ctx_flags,
+		ctx->ctx_fl_system,
+		ctx->ctx_fl_block,
+		ctx->ctx_fl_excl_idle,
+		ctx->ctx_fl_unsecure,
+		ctx->ctx_fl_no_msg,
+		ctx->ctx_fd));
+
 	/*
-	 * pin task to CPU and force reschedule on exit to ensure
-	 * that when back to user level the task runs on the designated
-	 * CPU.
+	 * initialize soft PMU state
 	 */
-	if (ctx->ctx_fl_system) {
-		ctx->ctx_saved_cpus_allowed = task->cpus_allowed;
-		set_cpus_allowed(task, tmp.ctx_cpu_mask);
-		DBprintk(("[%d] rescheduled allowed=0x%lx\n", task->pid, task->cpus_allowed));
-	}
+	pfm_reset_pmu_state(ctx);
 
 	return 0;
 
 buffer_error:
+	pfm_free_fd(ctx->ctx_fd, filp);
+
+	if (ctx->ctx_buf_fmt) {
+		pfm_buf_fmt_exit(ctx->ctx_buf_fmt, current, NULL, regs);
+	}
+error_file:
 	pfm_context_free(ctx);
-error:
-	pfm_unreserve_session(task, ctx_flags & PFM_FL_SYSTEM_WIDE , tmp.ctx_cpu_mask);
-abort:
-	/* make sure we don't leave anything behind */
-	task->thread.pfm_context = NULL;
 
+error:
 	return ret;
 }
 
@@ -1313,6 +2880,46 @@
 }
 
 static void
+pfm_reset_regs_masked(pfm_context_t *ctx, unsigned long *ovfl_regs, int flag)
+{
+	unsigned long mask = ovfl_regs[0];
+	unsigned long reset_others = 0UL;
+	unsigned long val;
+	int i, is_long_reset = (flag == PFM_PMD_LONG_RESET);
+
+	DPRINT_ovfl(("ovfl_regs=0x%lx flag=%d\n", ovfl_regs[0], flag));
+
+	if (flag == PFM_PMD_NO_RESET) return;
+
+	/*
+	 * now restore reset value on sampling overflowed counters
+	 */
+	mask >>= PMU_FIRST_COUNTER;
+	for(i = PMU_FIRST_COUNTER; mask; i++, mask >>= 1) {
+		if (mask & 0x1) {
+			ctx->ctx_pmds[i].val = val = pfm_new_counter_value(ctx->ctx_pmds+ i, is_long_reset);
+			reset_others |= ctx->ctx_pmds[i].reset_pmds[0];
+
+			DPRINT_ovfl((" %s reset ctx_pmds[%d]=%lx\n",
+				  is_long_reset ? "long" : "short", i, val));
+		}
+	}
+
+	/*
+	 * Now take care of resetting the other registers
+	 */
+	for(i = 0; reset_others; i++, reset_others >>= 1) {
+
+		if ((reset_others & 0x1) == 0) continue;
+
+		ctx->ctx_pmds[i].val = val = pfm_new_counter_value(ctx->ctx_pmds + i, is_long_reset);
+
+		DPRINT_ovfl(("%s reset_others pmd[%d]=%lx\n",
+			  is_long_reset ? "long" : "short", i, val));
+	}
+}
+
+static void
 pfm_reset_regs(pfm_context_t *ctx, unsigned long *ovfl_regs, int flag)
 {
 	unsigned long mask = ovfl_regs[0];
@@ -1320,19 +2927,27 @@
 	unsigned long val;
 	int i, is_long_reset = (flag == PFM_PMD_LONG_RESET);
 
+	DPRINT_ovfl(("ovfl_regs=0x%lx flag=%d\n", ovfl_regs[0], flag));
+
+	if (flag == PFM_PMD_NO_RESET) return;
+
+	if (CTX_IS_MASKED(ctx)) {
+		pfm_reset_regs_masked(ctx, ovfl_regs, flag);
+		return;
+	}
+
 	/*
 	 * now restore reset value on sampling overflowed counters
 	 */
 	mask >>= PMU_FIRST_COUNTER;
 	for(i = PMU_FIRST_COUNTER; mask; i++, mask >>= 1) {
 		if (mask & 0x1) {
-			val = pfm_new_counter_value(ctx->ctx_soft_pmds + i, is_long_reset);
-			reset_others |= ctx->ctx_soft_pmds[i].reset_pmds[0];
+			val = pfm_new_counter_value(ctx->ctx_pmds+ i, is_long_reset);
+			reset_others |= ctx->ctx_pmds[i].reset_pmds[0];
 
-			DBprintk_ovfl(("[%d] %s reset soft_pmd[%d]=%lx\n", current->pid,
+			DPRINT_ovfl((" %s reset ctx_pmds[%d]=%lx\n",
 				  is_long_reset ? "long" : "short", i, val));
 
-			/* upper part is ignored on rval */
 			pfm_write_soft_counter(ctx, i, val);
 		}
 	}
@@ -1344,71 +2959,86 @@
 
 		if ((reset_others & 0x1) == 0) continue;
 
-		val = pfm_new_counter_value(ctx->ctx_soft_pmds + i, is_long_reset);
+		val = pfm_new_counter_value(ctx->ctx_pmds + i, is_long_reset);
 
 		if (PMD_IS_COUNTING(i)) {
 			pfm_write_soft_counter(ctx, i, val);
 		} else {
 			ia64_set_pmd(i, val);
 		}
-		DBprintk_ovfl(("[%d] %s reset_others pmd[%d]=%lx\n", current->pid,
+		DPRINT_ovfl(("%s reset_others pmd[%d]=%lx\n",
 			  is_long_reset ? "long" : "short", i, val));
 	}
 	ia64_srlz_d();
 }
 
 static int
-pfm_write_pmcs(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
+pfm_write_pmcs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
-	struct thread_struct *th = &task->thread;
-	pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg;
-	unsigned long value, reset_pmds;
+	struct thread_struct *thread = NULL;
+	pfarg_reg_t *req = (pfarg_reg_t *)arg;
+	unsigned long value;
+	unsigned long smpl_pmds, reset_pmds;
 	unsigned int cnum, reg_flags, flags;
-	int i;
+	int i, can_access_pmu = 0, is_loaded;
+	int is_monitor, is_counting;
 	int ret = -EINVAL;
+#define PFM_CHECK_PMC_PM(x, y, z) ((x)->ctx_fl_system ^ PMC_PM(y, z))
 
-	/* we don't quite support this right now */
-	if (task != current) return -EINVAL;
+	if (CTX_IS_DEAD(ctx)) return -EINVAL;
 
-	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
+	is_loaded = CTX_IS_LOADED(ctx);
 
-	/* XXX: ctx locking may be required here */
+	if (is_loaded) {
+		thread = &ctx->ctx_task->thread;
+		can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task? 1 : 0;
+		/*
+		 * In system wide and when the context is loaded, access can only happen
+		 * when the caller is running on the CPU being monitored by the session.
+		 * It does not have to be the owner (ctx_task) of the context per se.
+		 */
+		if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+			DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+			return -EBUSY;
+		}
+	}
 
 	for (i = 0; i < count; i++, req++) {
 
-		if (__copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
-
-		cnum       = tmp.reg_num;
-		reg_flags  = tmp.reg_flags;
-		value      = tmp.reg_value;
-		reset_pmds = tmp.reg_reset_pmds[0];
+		cnum       = req->reg_num;
+		reg_flags  = req->reg_flags;
+		value      = req->reg_value;
+		smpl_pmds  = req->reg_smpl_pmds[0];
+		reset_pmds = req->reg_reset_pmds[0];
 		flags      = 0;
 
-		/* 
+		is_counting = PMC_IS_COUNTING(cnum);
+		is_monitor  = PMC_IS_MONITOR(cnum);
+
+		/*
 		 * we reject all non implemented PMC as well
 		 * as attempts to modify PMC[0-3] which are used
 		 * as status registers by the PMU
 		 */
 		if (!PMC_IS_IMPL(cnum) || cnum < 4) {
-			DBprintk(("pmc[%u] is unimplemented or invalid\n", cnum));
+			DPRINT(("pmc%u is unimplemented or invalid\n", cnum));
 			goto error;
 		}
 		/*
-		 * A PMC used to configure monitors must be:
-		 * 	- system-wide session: privileged monitor
-		 * 	- per-task : user monitor
-		 * any other configuration is rejected.
-		 */
-		if (PMC_IS_MONITOR(cnum) || PMC_IS_COUNTING(cnum)) {
-			DBprintk(("pmc[%u].pm=%ld\n", cnum, PMC_PM(cnum, value))); 
-
-			if (ctx->ctx_fl_system ^ PMC_PM(cnum, value)) {
-				DBprintk(("pmc_pm=%ld fl_system=%d\n", PMC_PM(cnum, value), ctx->ctx_fl_system));
-				goto error;
-			}
+		 * If the PMC is a monitor, then if the value is not the default:
+		 * 	- system-wide session: PMCx.pm=1 (privileged monitor)
+		 * 	- per-task           : PMCx.pm=0 (user monitor)
+		 */
+		if ((is_monitor || is_counting) && value != PMC_DFL_VAL(i) && PFM_CHECK_PMC_PM(ctx, cnum, value)) {
+			DPRINT(("pmc%u pmc_pm=%ld fl_system=%d\n",
+				cnum,
+				PMC_PM(cnum, value),
+				ctx->ctx_fl_system));
+			goto error;
 		}
 
-		if (PMC_IS_COUNTING(cnum)) {
+
+		if (is_counting) {
 			pfm_monitor_t *p = (pfm_monitor_t *)&value;
 			/*
 		 	 * enforce generation of overflow interrupt. Necessary on all
@@ -1417,33 +3047,35 @@
 			p->pmc_oi = 1;
 
 			if (reg_flags & PFM_REGFL_OVFL_NOTIFY) {
-				/*
-			 	 * must have a target for the signal
-			 	 */
-				if (ctx->ctx_notify_task == NULL) {
-					DBprintk(("cannot set ovfl_notify: no notify_task\n"));
-					goto error;
-				}
 				flags |= PFM_REGFL_OVFL_NOTIFY;
 			}
 
 			if (reg_flags & PFM_REGFL_RANDOM) flags |= PFM_REGFL_RANDOM;
 
+			/* verify validity of smpl_pmds */
+			if ((smpl_pmds & pmu_conf.impl_pmds[0]) != smpl_pmds) {
+				DPRINT(("invalid smpl_pmds 0x%lx for pmc%u\n", smpl_pmds, cnum));
+				goto error;
+			}
+
 			/* verify validity of reset_pmds */
 			if ((reset_pmds & pmu_conf.impl_pmds[0]) != reset_pmds) {
-				DBprintk(("invalid reset_pmds 0x%lx for pmc%u\n", reset_pmds, cnum));
+				DPRINT(("invalid reset_pmds 0x%lx for pmc%u\n", reset_pmds, cnum));
 				goto error;
 			}
-		} else if (reg_flags & (PFM_REGFL_OVFL_NOTIFY|PFM_REGFL_RANDOM)) {
-				DBprintk(("cannot set ovfl_notify or random on pmc%u\n", cnum));
+		} else {
+			if (reg_flags & (PFM_REGFL_OVFL_NOTIFY|PFM_REGFL_RANDOM)) {
+				DPRINT(("cannot set ovfl_notify or random on pmc%u\n", cnum));
 				goto error;
+			}
+			/* eventid on non-counting monitors are ignored */
 		}
 
 		/*
 		 * execute write checker, if any
 		 */
 		if (PMC_WR_FUNC(cnum)) {
-			ret = PMC_WR_FUNC(cnum)(task, cnum, &value, regs);
+			ret = PMC_WR_FUNC(cnum)(ctx->ctx_task, ctx, cnum, &value, regs);
 			if (ret) goto error;
 			ret = -EINVAL;
 		}
@@ -1451,297 +3083,538 @@
 		/*
 		 * no error on this register
 		 */
-		PFM_REG_RETFLAG_SET(tmp.reg_flags, 0);
-
-		/*
-		 * update register return value, abort all if problem during copy.
-		 * we only modify the reg_flags field. no check mode is fine because
-		 * access has been verified upfront in sys_perfmonctl().
-		 *
-		 * If this fails, then the software state is not modified
-		 */
-		if (__put_user(tmp.reg_flags, &req->reg_flags)) return -EFAULT;
+		PFM_REG_RETFLAG_SET(req->reg_flags, 0);
 
 		/*
 		 * Now we commit the changes to the software state
 		 */
 
-		/* 
-		 * full flag update each time a register is programmed
+		/*
+		 * update overflow information
 		 */
-		ctx->ctx_soft_pmds[cnum].flags = flags;
+		if (is_counting) {
+			/*
+		 	 * full flag update each time a register is programmed
+		 	 */
+			ctx->ctx_pmds[cnum].flags = flags;
 
-		if (PMC_IS_COUNTING(cnum)) {
-			ctx->ctx_soft_pmds[cnum].reset_pmds[0] = reset_pmds;
+			ctx->ctx_pmds[cnum].reset_pmds[0] = reset_pmds;
+			ctx->ctx_pmds[cnum].smpl_pmds[0]  = smpl_pmds;
+			ctx->ctx_pmds[cnum].eventid       = req->reg_smpl_eventid;
 
-			/* mark all PMDS to be accessed as used */
+			/*
+			 * Mark all PMDS to be accessed as used.
+			 *
+			 * We do not keep track of PMC because we have to
+			 * systematically restore ALL of them.
+			 *
+			 * We do not update the used_monitors mask, because
+			 * if we have not programmed them, then will be in
+			 * a quiescent state, therefore we will not need to
+			 * mask/restore then when context is MASKED.
+			 */
 			CTX_USED_PMD(ctx, reset_pmds);
+			CTX_USED_PMD(ctx, smpl_pmds);
+			/*
+		 	 * make sure we do not try to reset on
+		 	 * restart because we have established new values
+		 	 */
+			if (CTX_IS_MASKED(ctx)) ctx->ctx_ovfl_regs[0] &= ~1UL << cnum;
 		}
-
 		/*
 		 * Needed in case the user does not initialize the equivalent
-		 * PMD. Clearing is done in reset_pmu() so there is no possible
-		 * leak here.
+		 * PMD. Clearing is done indirectly via pfm_reset_pmu_state() so there is no
+		 * possible leak here.
 		 */
 		CTX_USED_PMD(ctx, pmu_conf.pmc_desc[cnum].dep_pmd[0]);
 
-		/* 
-		 * keep copy the pmc, used for register reload
+		/*
+		 * keep track of the monitor PMC that we are using.
+		 * we save the value of the pmc in ctx_pmcs[] and if
+		 * the monitoring is not stopped for the context we also
+		 * place it in the saved state area so that it will be
+		 * picked up later by the context switch code.
+		 *
+		 * The value in ctx_pmcs[] can only be changed in pfm_write_pmcs().
+		 *
+		 * The value in t->pmc[] may be modified on overflow, i.e.,  when
+		 * monitoring needs to be stopped.
 		 */
-		th->pmc[cnum] = value;
+		if (is_monitor) CTX_USED_MONITOR(ctx, 1UL << cnum);
 
-		ia64_set_pmc(cnum, value);
+		/*
+		 * update context state
+		 */
+		ctx->ctx_pmcs[cnum] = value;
 
-		DBprintk(("[%d] pmc[%u]=0x%lx flags=0x%x used_pmds=0x%lx\n", 
-			  task->pid, cnum, value, 
-			  ctx->ctx_soft_pmds[cnum].flags, 
-			  ctx->ctx_used_pmds[0]));
+		if (is_loaded) {
+			/*
+			 * write thread state
+			 */
+			if (ctx->ctx_fl_system == 0) thread->pmcs[cnum] = value;
+
+			/*
+			 * write hardware register if we can
+			 */
+			if (can_access_pmu) {
+				ia64_set_pmc(cnum, value);
+			}
+#ifdef CONFIG_SMP
+			else {
+				/*
+				 * per-task SMP only here
+				 *
+			 	 * we are guaranteed that the task is not running on the other CPU,
+			 	 * we indicate that this PMD will need to be reloaded if the task
+			 	 * is rescheduled on the CPU it ran last on.
+			 	 */
+				ctx->ctx_reload_pmcs[0] |= 1UL << cnum;
+			}
+#endif
+		}
 
+		DPRINT(("pmc[%u]=0x%lx loaded=%d access_pmu=%d all_pmcs=0x%lx used_pmds=0x%lx eventid=%ld smpl_pmds=0x%lx reset_pmds=0x%lx reloads_pmcs=0x%lx used_monitors=0x%lx ovfl_regs=0x%lx\n",
+			  cnum,
+			  value,
+			  is_loaded,
+			  can_access_pmu,
+			  ctx->ctx_all_pmcs[0],
+			  ctx->ctx_used_pmds[0],
+			  ctx->ctx_pmds[cnum].eventid,
+			  smpl_pmds,
+			  reset_pmds,
+			  ctx->ctx_reload_pmcs[0],
+			  ctx->ctx_used_monitors[0],
+			  ctx->ctx_ovfl_regs[0]));
 	}
 
-	return 0;
+	/*
+	 * make sure the changes are visible
+	 */
+	if (can_access_pmu) ia64_srlz_d();
 
+	return 0;
 error:
-	PFM_REG_RETFLAG_SET(tmp.reg_flags, PFM_REG_RETFL_EINVAL);
+	PFM_REG_RETFLAG_SET(req->reg_flags, PFM_REG_RETFL_EINVAL);
 
-	if (__put_user(tmp.reg_flags, &req->reg_flags)) ret = -EFAULT;
+	req->reg_flags = PFM_REG_RETFL_EINVAL;
 
-	DBprintk(("[%d] pmc[%u]=0x%lx error %d\n", task->pid, cnum, value, ret));
+	DPRINT(("pmc[%u]=0x%lx error %d\n", cnum, value, ret));
 
 	return ret;
 }
 
 static int
-pfm_write_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
+pfm_write_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
-	pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg;
+	struct thread_struct *thread = NULL;
+	pfarg_reg_t *req = (pfarg_reg_t *)arg;
 	unsigned long value, hw_value;
 	unsigned int cnum;
-	int i;
+	int i, can_access_pmu = 0;
+	int is_counting, is_loaded;
 	int ret = -EINVAL;
 
-	/* we don't quite support this right now */
-	if (task != current) return -EINVAL;
-
-	/* 
-	 * Cannot do anything before PMU is enabled 
-	 */
-	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
-	preempt_disable();
+	if (CTX_IS_DEAD(ctx)) return -EINVAL;
 
-	/* XXX: ctx locking may be required here */
+	is_loaded = CTX_IS_LOADED(ctx);
 
+	/*
+	 * on both UP and SMP, we can only write to the PMC when the task is
+	 * the owner of the local PMU.
+	 */
+	if (is_loaded) {
+		thread = &ctx->ctx_task->thread;
+		can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task ? 1 : 0;
+		/*
+		 * In system wide and when the context is loaded, access can only happen
+		 * when the caller is running on the CPU being monitored by the session.
+		 * It does not have to be the owner (ctx_task) of the context per se.
+		 */
+		if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+			DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+			return -EBUSY;
+		}
+	}
 
 	for (i = 0; i < count; i++, req++) {
 
-		if (__copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
-
-		cnum  = tmp.reg_num;
-		value = tmp.reg_value;
+		cnum  = req->reg_num;
+		value = req->reg_value;
 
 		if (!PMD_IS_IMPL(cnum)) {
-			DBprintk(("pmd[%u] is unimplemented or invalid\n", cnum));
+			DPRINT(("pmd[%u] is unimplemented or invalid\n", cnum));
 			goto abort_mission;
 		}
+		is_counting = PMD_IS_COUNTING(cnum);
 
 		/*
 		 * execute write checker, if any
 		 */
 		if (PMD_WR_FUNC(cnum)) {
 			unsigned long v = value;
-			ret = PMD_WR_FUNC(cnum)(task, cnum, &v, regs);
+
+			ret = PMD_WR_FUNC(cnum)(ctx->ctx_task, ctx, cnum, &v, regs);
 			if (ret) goto abort_mission;
+
 			value = v;
-			ret = -EINVAL;
+			ret   = -EINVAL;
 		}
-		hw_value = value;
+
 		/*
 		 * no error on this register
 		 */
-		PFM_REG_RETFLAG_SET(tmp.reg_flags, 0);
-
-		if (__put_user(tmp.reg_flags, &req->reg_flags)) return -EFAULT;
+		PFM_REG_RETFLAG_SET(req->reg_flags, 0);
 
 		/*
 		 * now commit changes to software state
 		 */
+		hw_value = value;
 
-		/* update virtualized (64bits) counter */
-		if (PMD_IS_COUNTING(cnum)) {
-			ctx->ctx_soft_pmds[cnum].lval = value;
-			ctx->ctx_soft_pmds[cnum].val  = value & ~pmu_conf.ovfl_val;
+		/*
+		 * update virtualized (64bits) counter
+		 */
+		if (is_counting) {
+			/*
+			 * write context state
+			 */
+			ctx->ctx_pmds[cnum].lval = value;
 
-			hw_value = value & pmu_conf.ovfl_val;
+			/*
+			 * when context is load we use the split value
+			 */
+			if (is_loaded) {
+				hw_value = value &  pmu_conf.ovfl_val;
+				value    = value & ~pmu_conf.ovfl_val;
+			}
 
-			ctx->ctx_soft_pmds[cnum].long_reset  = tmp.reg_long_reset;
-			ctx->ctx_soft_pmds[cnum].short_reset = tmp.reg_short_reset;
+			/*
+			 * update sampling periods
+			 */
+			ctx->ctx_pmds[cnum].long_reset  = req->reg_long_reset;
+			ctx->ctx_pmds[cnum].short_reset = req->reg_short_reset;
 
-			ctx->ctx_soft_pmds[cnum].seed = tmp.reg_random_seed;
-			ctx->ctx_soft_pmds[cnum].mask = tmp.reg_random_mask;
+			/*
+			 * update randomization parameters
+			 */
+			ctx->ctx_pmds[cnum].seed = req->reg_random_seed;
+			ctx->ctx_pmds[cnum].mask = req->reg_random_mask;
 		}
 
-		/* keep track of what we use */
-		CTX_USED_PMD(ctx, pmu_conf.pmd_desc[(cnum)].dep_pmd[0]);
+		/*
+		 * update context value
+		 */
+		ctx->ctx_pmds[cnum].val  = value;
+
+		/*
+		 * Keep track of what we use
+		 *
+		 * We do not keep track of PMC because we have to
+		 * systematically restore ALL of them.
+		 */
+		CTX_USED_PMD(ctx, PMD_PMD_DEP(cnum));
 
-		/* mark this register as used as well */
+		/*
+		 * mark this PMD register used as well
+		 */
 		CTX_USED_PMD(ctx, RDEP(cnum));
 
-		/* writes to unimplemented part is ignored, so this is safe */
-		ia64_set_pmd(cnum, hw_value);
+		/*
+		 * make sure we do not try to reset on
+		 * restart because we have established new values
+		 */
+		if (is_counting && CTX_IS_MASKED(ctx)) {
+			ctx->ctx_ovfl_regs[0] &= ~1UL << cnum;
+		}
 
-		/* to go away */
-		ia64_srlz_d();
+		if (is_loaded) {
+			/*
+		 	 * write thread state
+		 	 */
+			if (ctx->ctx_fl_system == 0) thread->pmds[cnum] = hw_value;
+
+			/*
+			 * write hardware register if we can
+			 */
+			if (can_access_pmu) {
+				ia64_set_pmd(cnum, hw_value);
+			} else {
+#ifdef CONFIG_SMP
+				/*
+			 	 * we are guaranteed that the task is not running on the other CPU,
+			 	 * we indicate that this PMD will need to be reloaded if the task
+			 	 * is rescheduled on the CPU it ran last on.
+			 	 */
+				ctx->ctx_reload_pmds[0] |= 1UL << cnum;
+#endif
+			}
+		}
 
-		DBprintk(("[%d] pmd[%u]: value=0x%lx hw_value=0x%lx soft_pmd=0x%lx  short_reset=0x%lx "
-			  "long_reset=0x%lx hw_pmd=%lx notify=%c used_pmds=0x%lx reset_pmds=0x%lx\n",
-				task->pid, cnum,
-				value, hw_value,
-				ctx->ctx_soft_pmds[cnum].val,
-				ctx->ctx_soft_pmds[cnum].short_reset,
-				ctx->ctx_soft_pmds[cnum].long_reset,
-				ia64_get_pmd(cnum) & pmu_conf.ovfl_val,
-				PMC_OVFL_NOTIFY(ctx, cnum) ? 'Y':'N',
-				ctx->ctx_used_pmds[0],
-				ctx->ctx_soft_pmds[cnum].reset_pmds[0]));
+		DPRINT(("pmd[%u]=0x%lx loaded=%d access_pmu=%d, hw_value=0x%lx ctx_pmd=0x%lx  short_reset=0x%lx "
+			  "long_reset=0x%lx notify=%c used_pmds=0x%lx reset_pmds=0x%lx reload_pmds=0x%lx all_pmds=0x%lx ovfl_regs=0x%lx\n",
+			cnum,
+			value,
+			is_loaded,
+			can_access_pmu,
+			hw_value,
+			ctx->ctx_pmds[cnum].val,
+			ctx->ctx_pmds[cnum].short_reset,
+			ctx->ctx_pmds[cnum].long_reset,
+			PMC_OVFL_NOTIFY(ctx, cnum) ? 'Y':'N',
+			ctx->ctx_used_pmds[0],
+			ctx->ctx_pmds[cnum].reset_pmds[0],
+			ctx->ctx_reload_pmds[0],
+			ctx->ctx_all_pmds[0],
+			ctx->ctx_ovfl_regs[0]));
 	}
-	preempt_enable();
+
+	/*
+	 * make changes visible
+	 */
+	if (can_access_pmu) ia64_srlz_d();
+
 	return 0;
 
 abort_mission:
-	preempt_enable();
-
 	/*
 	 * for now, we have only one possibility for error
 	 */
-	PFM_REG_RETFLAG_SET(tmp.reg_flags, PFM_REG_RETFL_EINVAL);
+	PFM_REG_RETFLAG_SET(req->reg_flags, PFM_REG_RETFL_EINVAL);
 
 	/*
 	 * we change the return value to EFAULT in case we cannot write register return code.
 	 * The caller first must correct this error, then a resubmission of the request will
 	 * eventually yield the EINVAL.
 	 */
-	if (__put_user(tmp.reg_flags, &req->reg_flags)) ret = -EFAULT;
+	req->reg_flags = PFM_REG_RETFL_EINVAL;
 
-	DBprintk(("[%d] pmc[%u]=0x%lx ret %d\n", task->pid, cnum, value, ret));
+	DPRINT(("pmd[%u]=0x%lx ret %d\n", cnum, value, ret));
 
 	return ret;
 }
 
+/*
+ * By the way of PROTECT_CONTEXT(), interrupts are masked while we are in this function.
+ * Therefore we know, we do not have to worry about the PMU overflow interrupt. If an
+ * interrupt is delivered during the call, it will be kept pending until we leave, making
+ * it appears as if it had been generated at the UNPROTECT_CONTEXT(). At least we are
+ * guaranteed to return consistent data to the user, it may simply be old. It is not
+ * trivial to treat the overflow while inside the call because you may end up in
+ * some module sampling buffer code causing deadlocks.
+ */
 static int
-pfm_read_pmds(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
+pfm_read_pmds(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
-	struct thread_struct *th = &task->thread;
-	unsigned long val, lval;
+	struct thread_struct *thread = NULL;
+	unsigned long val = 0UL, lval ;
 	pfarg_reg_t *req = (pfarg_reg_t *)arg;
 	unsigned int cnum, reg_flags = 0;
-	int i, ret = 0;
-
-#if __GNUC__ < 3
-	int foo;
-#endif
+	int i, is_loaded, can_access_pmu = 0;
+	int ret = -EINVAL;
 
-	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
+	if (CTX_IS_ZOMBIE(ctx)) return -EINVAL;
 
 	/*
-	 * XXX: MUST MAKE SURE WE DON"T HAVE ANY PENDING OVERFLOW BEFORE READING
-	 * This is required when the monitoring has been stoppped by user or kernel.
-	 * If it is still going on, then that's fine because we a re not guaranteed
-	 * to return an accurate value in this case.
+	 * access is possible when loaded only for
+	 * self-monitoring tasks or in UP mode
 	 */
+	is_loaded = CTX_IS_LOADED(ctx);
 
-	/* XXX: ctx locking may be required here */
+	if (is_loaded) {
+		thread = &ctx->ctx_task->thread;
+		/*
+		 * this can be true when not self-monitoring only in UP
+		 */
+		can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task? 1 : 0;
 
-	DBprintk(("ctx_last_cpu=%d for [%d]\n", atomic_read(&ctx->ctx_last_cpu), task->pid));
+		if (can_access_pmu) ia64_srlz_d();
+		/*
+		 * In system wide and when the context is loaded, access can only happen
+		 * when the caller is running on the CPU being monitored by the session.
+		 * It does not have to be the owner (ctx_task) of the context per se.
+		 */
+		if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+			DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+			return -EBUSY;
+		}
+	}
+	DPRINT(("enter loaded=%d access_pmu=%d ctx_state=%d\n",
+		is_loaded,
+		can_access_pmu,
+		ctx->ctx_state));
+
+	/*
+	 * on both UP and SMP, we can only read the PMD from the hardware register when
+	 * the task is the owner of the local PMU.
+	 */
 
 	for (i = 0; i < count; i++, req++) {
-		int me;
-#if __GNUC__ < 3
-		foo = __get_user(cnum, &req->reg_num);
-		if (foo) return -EFAULT;
-		foo = __get_user(reg_flags, &req->reg_flags);
-		if (foo) return -EFAULT;
-#else
-		if (__get_user(cnum, &req->reg_num)) return -EFAULT;
-		if (__get_user(reg_flags, &req->reg_flags)) return -EFAULT;
-#endif
-		lval = 0UL;
 
-		if (!PMD_IS_IMPL(cnum)) goto abort_mission;
+		lval        = 0UL;
+		cnum        = req->reg_num;
+		reg_flags   = req->reg_flags;
+
+		if (!PMD_IS_IMPL(cnum)) goto error;
 		/*
 		 * we can only read the register that we use. That includes
-		 * the one we explicitly initialize AND the one we want included
+		 * the one we explicitely initialize AND the one we want included
 		 * in the sampling buffer (smpl_regs).
 		 *
 		 * Having this restriction allows optimization in the ctxsw routine
 		 * without compromising security (leaks)
 		 */
-		if (!CTX_IS_USED_PMD(ctx, cnum)) goto abort_mission;
+		if (!CTX_IS_USED_PMD(ctx, cnum)) goto error;
 
 		/*
 		 * If the task is not the current one, then we check if the
 		 * PMU state is still in the local live register due to lazy ctxsw.
 		 * If true, then we read directly from the registers.
 		 */
-		me = get_cpu();
-		if (atomic_read(&ctx->ctx_last_cpu) == me){
-			ia64_srlz_d();
+		if (can_access_pmu){
 			val = ia64_get_pmd(cnum);
-			DBprintk(("reading pmd[%u]=0x%lx from hw\n", cnum, val));
 		} else {
-			val = th->pmd[cnum];
+			/*
+			 * context has been saved
+			 * if context is zombie, then task does not exist anymore.
+			 * In this case, we use the full value saved in the context (pfm_flush_regs()).
+			 */
+			val = CTX_IS_LOADED(ctx) ? thread->pmds[cnum] : 0UL;
 		}
 
-
 		if (PMD_IS_COUNTING(cnum)) {
 			/*
-			 * XXX: need to check for overflow
+			 * XXX: need to check for overflow when loaded
 			 */
 			val &= pmu_conf.ovfl_val;
-			val += ctx->ctx_soft_pmds[cnum].val;
+			val += ctx->ctx_pmds[cnum].val;
 
-			lval = ctx->ctx_soft_pmds[cnum].lval;
-		} 
+			lval = ctx->ctx_pmds[cnum].lval;
+		}
 
 		/*
 		 * execute read checker, if any
 		 */
 		if (PMD_RD_FUNC(cnum)) {
 			unsigned long v = val;
-			ret = PMD_RD_FUNC(cnum)(task, cnum, &v, regs);
+			ret = PMD_RD_FUNC(cnum)(ctx->ctx_task, ctx, cnum, &v, regs);
+			if (ret) goto error;
 			val = v;
+			ret = -EINVAL;
 		}
 
-		PFM_REG_RETFLAG_SET(reg_flags, ret);
-
-		put_cpu();
+		PFM_REG_RETFLAG_SET(reg_flags, 0);
 
-		DBprintk(("read pmd[%u] ret=%d value=0x%lx pmc=0x%lx\n", 
-					cnum, ret, val, ia64_get_pmc(cnum)));
+		DPRINT(("pmd[%u]=0x%lx loaded=%d access_pmu=%d ctx_state=%d\n",
+			cnum,
+			val,
+			is_loaded,
+			can_access_pmu,
+			ctx->ctx_state));
 
 		/*
 		 * update register return value, abort all if problem during copy.
 		 * we only modify the reg_flags field. no check mode is fine because
 		 * access has been verified upfront in sys_perfmonctl().
 		 */
-		if (__put_user(cnum, &req->reg_num)) return -EFAULT;
-		if (__put_user(val, &req->reg_value)) return -EFAULT;
-		if (__put_user(reg_flags, &req->reg_flags)) return -EFAULT;
-		if (__put_user(lval, &req->reg_last_reset_value)) return -EFAULT;
+		req->reg_value            = val;
+		req->reg_flags            = reg_flags;
+		req->reg_last_reset_val   = lval;
 	}
 
 	return 0;
 
-abort_mission:
+error:
 	PFM_REG_RETFLAG_SET(reg_flags, PFM_REG_RETFL_EINVAL);
-	/* 
-	 * XXX: if this fails, we stick with the original failure, flag not updated!
+
+	req->reg_flags = PFM_REG_RETFL_EINVAL;
+
+	DPRINT(("error pmd[%u]=0x%lx\n", cnum, val));
+
+	return ret;
+}
+
+long
+pfm_mod_write_pmcs(struct task_struct *task, pfarg_reg_t *req, unsigned int nreq, struct pt_regs *regs)
+{
+	pfm_context_t *ctx;
+
+	if (task == NULL || req == NULL) return -EINVAL;
+
+ 	ctx = task->thread.pfm_context;
+
+	if (ctx == NULL) return -EINVAL;
+
+	/*
+	 * for now limit to current task, which is enough when calling
+	 * from overflow handler
 	 */
-	__put_user(reg_flags, &req->reg_flags);
+	if (task != current) return -EBUSY;
 
-	return -EINVAL;
+	return pfm_write_pmcs(ctx, req, nreq, regs);
+}
+
+long
+pfm_mod_read_pmds(struct task_struct *task, pfarg_reg_t *req, unsigned int nreq, struct pt_regs *regs)
+{
+	pfm_context_t *ctx;
+
+	if (task == NULL || req == NULL) return -EINVAL;
+
+ 	//ctx = task->thread.pfm_context;
+ 	ctx = GET_PMU_CTX();
+
+	if (ctx == NULL) return -EINVAL;
+
+	/*
+	 * for now limit to current task, which is enough when calling
+	 * from overflow handler
+	 */
+	if (task != current && ctx->ctx_fl_system == 0) return -EBUSY;
+
+	return pfm_read_pmds(ctx, req, nreq, regs);
+}
+
+long
+pfm_mod_fast_read_pmds(struct task_struct *task, unsigned long mask[4], unsigned long *addr, struct pt_regs *regs)
+{
+	pfm_context_t *ctx;
+	unsigned long m, val;
+	unsigned int j;
+
+	if (task == NULL || addr == NULL) return -EINVAL;
+
+ 	//ctx = task->thread.pfm_context;
+ 	ctx = GET_PMU_CTX();
+
+	if (ctx == NULL) return -EINVAL;
+
+	/*
+	 * for now limit to current task, which is enough when calling
+	 * from overflow handler
+	 */
+	if (task != current && ctx->ctx_fl_system == 0) return -EBUSY;
+
+	m = mask[0];
+	for (j=0; m; m >>=1, j++) {
+
+		if ((m & 0x1) == 0) continue;
+
+		if (!(PMD_IS_IMPL(j)  && CTX_IS_USED_PMD(ctx, j)) ) return -EINVAL;
+
+		if (PMD_IS_COUNTING(j)) {
+			val = pfm_read_soft_counter(ctx, j);
+		} else {
+			val = ia64_get_pmd(j);
+		}
+
+		*addr++ = val;
+
+		/* XXX: should call read checker routine? */
+		DPRINT(("single_read_pmd[%u]=0x%lx\n", j, val));
+	}
+	return 0;
 }
 
-#ifdef PFM_PMU_USES_DBR
 /*
  * Only call this function when a process it trying to
  * write the debug registers (reading is always allowed)
@@ -1752,7 +3625,9 @@
 	pfm_context_t *ctx = task->thread.pfm_context;
 	int ret = 0;
 
-	DBprintk(("called for [%d]\n", task->pid));
+	if (pmu_conf.use_rr_dbregs == 0) return 0;
+
+	DPRINT(("called for [%d]\n", task->pid));
 
 	/*
 	 * do it only once
@@ -1780,9 +3655,9 @@
 	else
 		pfm_sessions.pfs_ptrace_use_dbregs++;
 
-	DBprintk(("ptrace_use_dbregs=%u  sys_use_dbregs=%u by [%d] ret = %d\n", 
-		  pfm_sessions.pfs_ptrace_use_dbregs, 
-		  pfm_sessions.pfs_sys_use_dbregs, 
+	DPRINT(("ptrace_use_dbregs=%u  sys_use_dbregs=%u by [%d] ret = %d\n",
+		  pfm_sessions.pfs_ptrace_use_dbregs,
+		  pfm_sessions.pfs_sys_use_dbregs,
 		  task->pid, ret));
 
 	UNLOCK_PFS();
@@ -1803,10 +3678,11 @@
 {
 	int ret;
 
+	if (pmu_conf.use_rr_dbregs == 0) return 0;
+
 	LOCK_PFS();
 	if (pfm_sessions.pfs_ptrace_use_dbregs == 0) {
-		printk(KERN_DEBUG "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n",
-		       task->pid);
+		printk(KERN_ERR "perfmon: invalid release for [%d] ptrace_use_dbregs=0\n", task->pid);
 		ret = -1;
 	}  else {
 		pfm_sessions.pfs_ptrace_use_dbregs--;
@@ -1816,388 +3692,275 @@
 
 	return ret;
 }
-#else /* PFM_PMU_USES_DBR is true */
-/*
- * in case, the PMU does not use the debug registers, these two functions are nops.
- * The first function is called from arch/ia64/kernel/ptrace.c.
- * The second function is called from arch/ia64/kernel/process.c.
- */
-int
-pfm_use_debug_registers(struct task_struct *task)
-{
-	return 0;
-}
-
-int
-pfm_release_debug_registers(struct task_struct *task)
-{
-	return 0;
-}
-#endif /* PFM_PMU_USES_DBR */
 
 static int
-pfm_restart(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
-	 struct pt_regs *regs)
+pfm_restart(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
-	void *sem = &ctx->ctx_restart_sem;
-
-	/* 
-	 * Cannot do anything before PMU is enabled 
-	 */
-	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
-
-	if (task == current) {
-		DBprintk(("restarting self %d frozen=%d ovfl_regs=0x%lx\n", 
-			task->pid, 
-			ctx->ctx_fl_frozen,
-			ctx->ctx_ovfl_regs[0]));
-
-		preempt_disable();
-		pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_PMD_LONG_RESET);
-
-		ctx->ctx_ovfl_regs[0] = 0UL;
-
-		/*
-		 * We ignore block/don't block because we never block
-		 * for a self-monitoring process.
-		 */
-		ctx->ctx_fl_frozen = 0;
-
-		if (CTX_HAS_SMPL(ctx)) {
-			ctx->ctx_psb->psb_hdr->hdr_count = 0;
-			ctx->ctx_psb->psb_index = 0;
-		}
-
-		/* simply unfreeze */
-		pfm_unfreeze_pmu();
+	struct task_struct *task;
+	pfm_buffer_fmt_t *fmt;
+	pfm_ovfl_ctrl_t rst_ctrl;
+	int is_loaded;
+	int ret = 0;
 
-		preempt_enable();
+	fmt       = ctx->ctx_buf_fmt;
+	is_loaded = CTX_IS_LOADED(ctx);
 
-		return 0;
-	} 
-	/* restart on another task */
+	if (is_loaded && CTX_HAS_SMPL(ctx) && fmt->fmt_restart_active) goto proceed;
 
 	/*
-	 * if blocking, then post the semaphore.
-	 * if non-blocking, then we ensure that the task will go into
-	 * pfm_overflow_must_block() before returning to user mode. 
-	 * We cannot explicitly reset another task, it MUST always
-	 * be done by the task itself. This works for system wide because
-	 * the tool that is controlling the session is doing "self-monitoring".
-	 *
-	 * XXX: what if the task never goes back to user?
-	 *
+	 * restarting a terminated context is a nop
 	 */
-	if (CTX_OVFL_NOBLOCK(ctx) == 0) {
-		DBprintk(("unblocking %d \n", task->pid));
-		up(sem);
-	} else {
-		struct thread_info *info = (struct thread_info *) ((char *) task + IA64_TASK_SIZE);
-		task->thread.pfm_ovfl_block_reset = 1;
-		ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_RESET;
-		set_bit(TIF_NOTIFY_RESUME, &info->flags);
+	if (unlikely(CTX_IS_TERMINATED(ctx))) {
+		DPRINT(("context is terminated, nothing to do\n"));
+		return 0;
 	}
-#if 0
+
+
 	/*
-	 * in case of non blocking mode, then it's just a matter of
-	 * of reseting the sampling buffer (if any) index. The PMU
-	 * is already active.
+	 * LOADED, UNLOADED, ZOMBIE
 	 */
+	if (CTX_IS_MASKED(ctx) == 0) return -EBUSY;
 
+proceed:
 	/*
-	 * must reset the header count first
-	 */
-	if (CTX_HAS_SMPL(ctx)) {
-		DBprintk(("resetting sampling indexes for %d \n", task->pid));
-		ctx->ctx_psb->psb_hdr->hdr_count = 0;
-		ctx->ctx_psb->psb_index = 0;
+ 	 * In system wide and when the context is loaded, access can only happen
+ 	 * when the caller is running on the CPU being monitored by the session.
+ 	 * It does not have to be the owner (ctx_task) of the context per se.
+ 	 */
+	if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+		DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+		return -EBUSY;
 	}
-#endif
-	return 0;
-}
 
-static int
-pfm_stop(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
-	 struct pt_regs *regs)
-{
-	/* we don't quite support this right now */
-	if (task != current) return -EINVAL;
+	task = PFM_CTX_TASK(ctx);
 
-	/* 
-	 * Cannot do anything before PMU is enabled 
+	/* sanity check */
+	if (unlikely(task == NULL)) {
+		printk(KERN_ERR "perfmon: [%d] pfm_restart no task\n", current->pid);
+		return -EINVAL;
+	}
+
+	/*
+	 * this test is always true in system wide mode
 	 */
-	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
+	if (task == current) {
 
-	DBprintk(("[%d] fl_system=%d owner=%p current=%p\n",
-				current->pid,
-				ctx->ctx_fl_system, PMU_OWNER(),
-				current));
+		fmt = ctx->ctx_buf_fmt;
 
-	preempt_disable();
-	/* simply stop monitoring but not the PMU */
-	if (ctx->ctx_fl_system) {
+		DPRINT(("restarting self %d ovfl=0x%lx\n",
+			task->pid,
+			ctx->ctx_ovfl_regs[0]));
 
-		/* disable dcr pp */
-		ia64_set_dcr(ia64_get_dcr() & ~IA64_DCR_PP);
+		if (CTX_HAS_SMPL(ctx)) {
 
-		/* stop monitoring */
-		pfm_clear_psr_pp();
+			prefetch(ctx->ctx_smpl_hdr);
 
-		ia64_srlz_i();
+			rst_ctrl.stop_monitoring = 0;
+			rst_ctrl.reset_pmds      = PFM_PMD_NO_RESET;
 
-		PFM_CPUINFO_CLEAR(PFM_CPUINFO_DCR_PP);
+			if (is_loaded)
+				ret = pfm_buf_fmt_restart_active(fmt, task, &rst_ctrl, ctx->ctx_smpl_hdr, regs);
+			else
+				ret = pfm_buf_fmt_restart(fmt, task, &rst_ctrl, ctx->ctx_smpl_hdr, regs);
 
-		ia64_psr(regs)->pp = 0;
 
-	} else {
+		} else {
+			rst_ctrl.stop_monitoring = 0;
+			rst_ctrl.reset_pmds      = PFM_PMD_LONG_RESET;
+		}
 
-		/* stop monitoring */
-		pfm_clear_psr_up();
+		if (ret == 0) {
+			if (rst_ctrl.reset_pmds)
+				pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, rst_ctrl.reset_pmds);
 
-		ia64_srlz_i();
+			if (rst_ctrl.stop_monitoring == 0) {
+				DPRINT(("resuming monitoring for [%d]\n", task->pid));
 
+				if (CTX_IS_MASKED(ctx)) pfm_restore_monitoring(task);
+			} else {
+				DPRINT(("keeping monitoring stopped for [%d]\n", task->pid));
+
+				// cannot use pfm_stop_monitoring(task, regs);
+			}
+		}
 		/*
-		 * clear user level psr.up
+		 * clear overflowed PMD mask to remove any stale information
 		 */
-		ia64_psr(regs)->up = 0;
-	}
-	preempt_enable();
-	return 0;
-}
+		ctx->ctx_ovfl_regs[0] = 0UL;
 
-static int
-pfm_disable(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
-	   struct pt_regs *regs)
-{	
-	/* we don't quite support this right now */
-	if (task != current) return -EINVAL;
+		/*
+		 * back to LOADED state
+		 */
+		CTX_LOADED(ctx);
 
-	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
+		return 0;
+	}
+	/* restart another task */
 
-	preempt_disable();
 	/*
-	 * stop monitoring, freeze PMU, and save state in context
-	 * this call will clear IA64_THREAD_PM_VALID for per-task sessions.
+	 * if blocking, then post the semaphore.
+	 * if non-blocking, then we ensure that the task will go into
+	 * pfm_handle_work() before returning to user mode.
+	 * We cannot explicitely reset another task, it MUST always
+	 * be done by the task itself. This works for system wide because
+	 * the tool that is controlling the session is doing "self-monitoring".
+	 *
+	 * XXX: what if the task never goes back to user?
+	 *
 	 */
-	pfm_flush_regs(task);
-
-	if (ctx->ctx_fl_system) {	
-		ia64_psr(regs)->pp = 0;
+	if (CTX_OVFL_NOBLOCK(ctx) == 0) {
+		DPRINT(("unblocking [%d] \n", task->pid));
+		up(&ctx->ctx_restart_sem);
 	} else {
-		ia64_psr(regs)->up = 0;
-	}
-	/* 
-	 * goes back to default behavior: no user level control
-	 * no need to change live psr.sp because useless at the kernel level
-	 */
-	ia64_psr(regs)->sp = 1;
+		DPRINT(("[%d] armed exit trap\n", task->pid));
 
-	DBprintk(("enabling psr.sp for [%d]\n", current->pid));
-
-	ctx->ctx_flags.state = PFM_CTX_DISABLED;
-	preempt_enable();
-
-	return 0;
-}
-
-static int
-pfm_context_destroy(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
-	 struct pt_regs *regs)
-{
-	/* we don't quite support this right now */
-	if (task != current) return -EINVAL;
+		ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_RESET;
 
-	/*
-	 * if context was never enabled, then there is not much
-	 * to do
-	 */
-	if (!CTX_IS_ENABLED(ctx)) goto skipped_stop;
 
-	/*
-	 * Disable context: stop monitoring, flush regs to software state (useless here), 
-	 * and freeze PMU
-	 * 
-	 * The IA64_THREAD_PM_VALID is cleared by pfm_flush_regs() called from pfm_disable()
-	 */
-	pfm_disable(task, ctx, arg, count, regs);
+		PFM_SET_WORK_PENDING(task, 1);
 
-	if (ctx->ctx_fl_system) {	
-		ia64_psr(regs)->pp = 0;
-	} else {
-		ia64_psr(regs)->up = 0;
-	}
+		pfm_set_task_notify(task);
 
-skipped_stop:
-	/*
-	 * remove sampling buffer mapping, if any
-	 */
-	if (ctx->ctx_smpl_vaddr) {
-		pfm_remove_smpl_mapping(task);
-		ctx->ctx_smpl_vaddr = 0UL;
+		/*
+		 * XXX: send reschedule if task runs on another CPU
+		 */
 	}
-	/* now free context and related state */
-	pfm_context_exit(task);
-
 	return 0;
 }
 
-/*
- * does nothing at the moment
- */
 static int
-pfm_context_unprotect(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
-	 struct pt_regs *regs)
+pfm_debug(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
-	return 0;
-}
+	unsigned int m = *(unsigned int *)arg;
 
-static int
-pfm_protect_context(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
-	 struct pt_regs *regs)
-{
-	DBprintk(("context from [%d] is protected\n", task->pid));
-	/*
-	 * from now on, only the creator of the context has access to it
-	 */
-	ctx->ctx_fl_protected = 1;
-
-	/*
-	 * reinforce secure monitoring: cannot toggle psr.up
-	 */
-	if (ctx->ctx_fl_unsecure == 0) ia64_psr(regs)->sp = 1;
+	pfm_sysctl.debug = m == 0 ? 0 : 1;
 
-	return 0;
-}
+	pfm_debug_var = pfm_sysctl.debug;
 
-static int
-pfm_debug(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
-	 struct pt_regs *regs)
-{
-	unsigned int mode = *(unsigned int *)arg;
+	printk(KERN_ERR "perfmon debugging %s (timing reset)\n", pfm_sysctl.debug ? "on" : "off");
 
-	pfm_sysctl.debug = mode == 0 ? 0 : 1;
 
-	printk(KERN_INFO "perfmon debugging %s\n", pfm_sysctl.debug ? "on" : "off");
+	if (m==0) {
+		memset(pfm_stats, 0, sizeof(pfm_stats));
+		for(m=0; m < NR_CPUS; m++) pfm_stats[m].pfm_ovfl_intr_cycles_min = ~0UL;
+	}
 
 	return 0;
 }
 
-#ifdef PFM_PMU_USES_DBR
-
-typedef struct {
-	unsigned long ibr_mask:56;
-	unsigned long ibr_plm:4;
-	unsigned long ibr_ig:3;
-	unsigned long ibr_x:1;
-} ibr_mask_reg_t;
-
-typedef struct {
-	unsigned long dbr_mask:56;
-	unsigned long dbr_plm:4;
-	unsigned long dbr_ig:2;
-	unsigned long dbr_w:1;
-	unsigned long dbr_r:1;
-} dbr_mask_reg_t;
-
-typedef union {
-	unsigned long  val;
-	ibr_mask_reg_t ibr;
-	dbr_mask_reg_t dbr;
-} dbreg_t;
 
 static int
-pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, struct pt_regs *regs)
+pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
-	struct thread_struct *thread = &task->thread;
-	pfm_context_t *ctx = task->thread.pfm_context;
-	pfarg_dbreg_t tmp, *req = (pfarg_dbreg_t *)arg;
+	struct thread_struct *thread = NULL;
+	pfarg_dbreg_t *req = (pfarg_dbreg_t *)arg;
 	dbreg_t dbreg;
 	unsigned int rnum;
 	int first_time;
-	int i, ret = 0;
+	int ret = 0;
+	int i, can_access_pmu = 0, is_loaded;
+
+	if (pmu_conf.use_rr_dbregs == 0) return -EINVAL;
+
+	if (CTX_IS_DEAD(ctx)) return -EINVAL;
+
+	is_loaded = CTX_IS_LOADED(ctx);
+	/*
+	 * on both UP and SMP, we can only write to the PMC when the task is
+	 * the owner of the local PMU.
+	 */
+	if (is_loaded) {
+		thread = &ctx->ctx_task->thread;
+		can_access_pmu = GET_PMU_OWNER() == ctx->ctx_task ? 1 : 0;
+		/*
+		 * In system wide and when the context is loaded, access can only happen
+		 * when the caller is running on the CPU being monitored by the session.
+		 * It does not have to be the owner (ctx_task) of the context per se.
+		 */
+		if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+			DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+			return -EBUSY;
+		}
+	}
 
 	/*
 	 * we do not need to check for ipsr.db because we do clear ibr.x, dbr.r, and dbr.w
 	 * ensuring that no real breakpoint can be installed via this call.
+	 *
+	 * IMPORTANT: regs can be NULL in this function
 	 */
 
 	first_time = ctx->ctx_fl_using_dbreg == 0;
 
 	/*
+	 * don't bother if we are loaded and task is being debugged
+	 */
+	if (is_loaded && (thread->flags & IA64_THREAD_DBG_VALID) != 0) {
+		DPRINT(("debug registers already in use for [%d]\n", ctx->ctx_task->pid));
+		return -EBUSY;
+	}
+
+	/*
 	 * check for debug registers in system wide mode
 	 *
+	 * We make the reservation even when context is not loaded
+	 * to make sure we get our slot. Note that the PFM_LOAD_CONTEXT
+	 * may still fail if the task has DBG_VALID set.
 	 */
 	LOCK_PFS();
-	if (ctx->ctx_fl_system && first_time) {
-		if (pfm_sessions.pfs_ptrace_use_dbregs) 
+
+	if (first_time && ctx->ctx_fl_system) {
+		if (pfm_sessions.pfs_ptrace_use_dbregs)
 			ret = -EBUSY;
 		else
 			pfm_sessions.pfs_sys_use_dbregs++;
 	}
+
 	UNLOCK_PFS();
 
 	if (ret != 0) return ret;
 
-	if (ctx->ctx_fl_system) {
-		/* we mark ourselves as owner  of the debug registers */
-		ctx->ctx_fl_using_dbreg = 1;
-		DBprintk(("system-wide setting fl_using_dbreg for [%d]\n", task->pid));
-	} else if (first_time) {
-			ret= -EBUSY;
-			if ((thread->flags & IA64_THREAD_DBG_VALID) != 0) {
-				DBprintk(("debug registers already in use for [%d]\n", task->pid));
-				goto abort_mission;
-			}
-			/* we mark ourselves as owner  of the debug registers */
-			ctx->ctx_fl_using_dbreg = 1;
-
-			DBprintk(("setting fl_using_dbreg for [%d]\n", task->pid));
-			/* 
-			 * Given debug registers cannot be used for both debugging 
-			 * and performance monitoring at the same time, we reuse
-			 * the storage area to save and restore the registers on ctxsw.
-			 */
-			memset(task->thread.dbr, 0, sizeof(task->thread.dbr));
-			memset(task->thread.ibr, 0, sizeof(task->thread.ibr));
-	}
+	/*
+	 * mark ourself as user of the debug registers for
+	 * perfmon purposes.
+	 */
+	ctx->ctx_fl_using_dbreg = 1;
 
-	if (first_time) {
-		DBprintk(("[%d] clearing ibrs,dbrs\n", task->pid));
-		/*
-	 	 * clear hardware registers to make sure we don't
-	 	 * pick up stale state. 
-		 *
-		 * for a system wide session, we do not use
-		 * thread.dbr, thread.ibr because this process
-		 * never leaves the current CPU and the state
-		 * is shared by all processes running on it
-	 	 */
-		for (i=0; i < (int) pmu_conf.num_ibrs; i++) {
+	/*
+ 	 * clear hardware registers to make sure we don't
+ 	 * pick up stale state.
+	 *
+	 * for a system wide session, we do not use
+	 * thread.dbr, thread.ibr because this process
+	 * never leaves the current CPU and the state
+	 * is shared by all processes running on it
+ 	 */
+	if (first_time && can_access_pmu) {
+		DPRINT(("[%d] clearing ibrs, dbrs\n", ctx->ctx_task->pid));
+		for (i=0; i < pmu_conf.num_ibrs; i++) {
 			ia64_set_ibr(i, 0UL);
+			ia64_srlz_i();
 		}
 		ia64_srlz_i();
-		for (i=0; i < (int) pmu_conf.num_dbrs; i++) {
+		for (i=0; i < pmu_conf.num_dbrs; i++) {
 			ia64_set_dbr(i, 0UL);
+			ia64_srlz_d();
 		}
 		ia64_srlz_d();
 	}
 
-	ret = -EFAULT;
-
 	/*
 	 * Now install the values into the registers
 	 */
 	for (i = 0; i < count; i++, req++) {
-		
-		if (__copy_from_user(&tmp, req, sizeof(tmp))) goto abort_mission;
-		
-		rnum      = tmp.dbreg_num;
-		dbreg.val = tmp.dbreg_value;
-		
+
+		rnum      = req->dbreg_num;
+		dbreg.val = req->dbreg_value;
+
 		ret = -EINVAL;
 
-		if ((mode == 0 && !IBR_IS_IMPL(rnum)) || ((mode == 1) && !DBR_IS_IMPL(rnum))) {
-			DBprintk(("invalid register %u val=0x%lx mode=%d i=%d count=%d\n", 
+		if ((mode == PFM_CODE_RR && !IBR_IS_IMPL(rnum)) || ((mode == PFM_DATA_RR) && !DBR_IS_IMPL(rnum))) {
+			DPRINT(("invalid register %u val=0x%lx mode=%d i=%d count=%d\n",
 				  rnum, dbreg.val, mode, i, count));
 
 			goto abort_mission;
@@ -2207,22 +3970,13 @@
 		 * make sure we do not install enabled breakpoint
 		 */
 		if (rnum & 0x1) {
-			if (mode == 0) 
+			if (mode == PFM_CODE_RR)
 				dbreg.ibr.ibr_x = 0;
 			else
 				dbreg.dbr.dbr_r = dbreg.dbr.dbr_w = 0;
 		}
 
-		/*
-		 * clear return flags and copy back to user
-		 *
-		 * XXX: fix once EAGAIN is implemented
-		 */
-		ret = -EFAULT;
-
-		PFM_REG_RETFLAG_SET(tmp.dbreg_flags, 0);
-
-		if (__copy_to_user(req, &tmp, sizeof(tmp))) goto abort_mission;
+		PFM_REG_RETFLAG_SET(req->dbreg_flags, 0);
 
 		/*
 		 * Debug registers, just like PMC, can only be modified
@@ -2234,24 +3988,24 @@
 		 * by the fact that when perfmon uses debug registers, ptrace()
 		 * won't be able to modify them concurrently.
 		 */
-		if (mode == 0) {
+		if (mode == PFM_CODE_RR) {
 			CTX_USED_IBR(ctx, rnum);
 
-			ia64_set_ibr(rnum, dbreg.val);
-			ia64_srlz_i();
+			if (can_access_pmu) ia64_set_ibr(rnum, dbreg.val);
 
-			thread->ibr[rnum] = dbreg.val;
+			ctx->ctx_ibrs[rnum] = dbreg.val;
 
-			DBprintk(("write ibr%u=0x%lx used_ibrs=0x%lx\n", rnum, dbreg.val, ctx->ctx_used_ibrs[0]));
+			DPRINT(("write ibr%u=0x%lx used_ibrs=0x%x is_loaded=%d access_pmu=%d\n",
+				rnum, dbreg.val, ctx->ctx_used_ibrs[0], is_loaded, can_access_pmu));
 		} else {
 			CTX_USED_DBR(ctx, rnum);
 
-			ia64_set_dbr(rnum, dbreg.val);
-			ia64_srlz_d();
+			if (can_access_pmu) ia64_set_dbr(rnum, dbreg.val);
 
-			thread->dbr[rnum] = dbreg.val;
+			ctx->ctx_dbrs[rnum] = dbreg.val;
 
-			DBprintk(("write dbr%u=0x%lx used_dbrs=0x%lx\n", rnum, dbreg.val, ctx->ctx_used_dbrs[0]));
+			DPRINT(("write dbr%u=0x%lx used_dbrs=0x%x is_loaded=%d access_pmu=%d\n",
+				rnum, dbreg.val, ctx->ctx_used_dbrs[0], is_loaded, can_access_pmu));
 		}
 	}
 
@@ -2272,720 +4026,1177 @@
 	/*
 	 * install error return flag
 	 */
-	if (ret != -EFAULT) {
-		/*
-		 * XXX: for now we can only come here on EINVAL
-		 */
-		PFM_REG_RETFLAG_SET(tmp.dbreg_flags, PFM_REG_RETFL_EINVAL);
-		if (__put_user(tmp.dbreg_flags, &req->dbreg_flags)) ret = -EFAULT;
-	}
+	PFM_REG_RETFLAG_SET(req->dbreg_flags, PFM_REG_RETFL_EINVAL);
+
 	return ret;
 }
 
 static int
-pfm_write_ibrs(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
-	 struct pt_regs *regs)
-{	
-	/* we don't quite support this right now */
-	if (task != current) return -EINVAL;
-
-	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
-
-	return pfm_write_ibr_dbr(0, task, arg, count, regs);
+pfm_write_ibrs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
+{
+	return pfm_write_ibr_dbr(PFM_CODE_RR, ctx, arg, count, regs);
 }
 
 static int
-pfm_write_dbrs(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
-	 struct pt_regs *regs)
-{	
-	/* we don't quite support this right now */
-	if (task != current) return -EINVAL;
-
-	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
-
-	return pfm_write_ibr_dbr(1, task, arg, count, regs);
+pfm_write_dbrs(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
+{
+	return pfm_write_ibr_dbr(PFM_DATA_RR, ctx, arg, count, regs);
 }
 
-#endif /* PFM_PMU_USES_DBR */
-
 static int
-pfm_get_features(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
+pfm_get_features(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
-	pfarg_features_t tmp;
-
-	memset(&tmp, 0, sizeof(tmp));
-
-	tmp.ft_version      = PFM_VERSION;
-	tmp.ft_smpl_version = PFM_SMPL_VERSION;
-
-	if (__copy_to_user(arg, &tmp, sizeof(tmp))) return -EFAULT;
+	pfarg_features_t *req = (pfarg_features_t *)arg;
 
+	req->ft_version = PFM_VERSION;
 	return 0;
 }
 
 static int
-pfm_start(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
-	  struct pt_regs *regs)
+pfm_stop(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
-	/* we don't quite support this right now */
-	if (task != current) return -EINVAL;
+	struct pt_regs *tregs;
 
-	/* 
-	 * Cannot do anything before PMU is enabled 
-	 */
-	if (!CTX_IS_ENABLED(ctx)) return -EINVAL;
 
-	DBprintk(("[%d] fl_system=%d owner=%p current=%p\n",
-				current->pid,
-				ctx->ctx_fl_system, PMU_OWNER(),
-				current));
+	if (CTX_IS_LOADED(ctx) == 0 && CTX_IS_MASKED(ctx) == 0) return -EINVAL;
 
-	if (PMU_OWNER() != task) {
-		printk(KERN_DEBUG "perfmon: pfm_start task [%d] not pmu owner\n", task->pid);
-		return -EINVAL;
+	/*
+ 	 * In system wide and when the context is loaded, access can only happen
+ 	 * when the caller is running on the CPU being monitored by the session.
+ 	 * It does not have to be the owner (ctx_task) of the context per se.
+ 	 */
+	if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+		DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+		return -EBUSY;
 	}
 
-	preempt_disable();
+	/*
+	 * in system mode, we need to update the PMU directly
+	 * and the user level state of the caller, which may not
+	 * necessarily be the creator of the context.
+	 */
 	if (ctx->ctx_fl_system) {
-		
-		PFM_CPUINFO_SET(PFM_CPUINFO_DCR_PP);
+		/*
+		 * Update local PMU first
+		 *
+		 * disable dcr pp
+		 */
+		ia64_set_dcr(ia64_get_dcr() & ~IA64_DCR_PP);
+		ia64_srlz_i();
 
-		/* set user level psr.pp */
-		ia64_psr(regs)->pp = 1;
+		/*
+		 * update local cpuinfo
+		 */
+		PFM_CPUINFO_CLEAR(PFM_CPUINFO_DCR_PP);
 
-		/* start monitoring at kernel level */
-		pfm_set_psr_pp();
+		/*
+		 * stop monitoring, does srlz.i
+		 */
+		pfm_clear_psr_pp();
 
-		/* enable dcr pp */
-		ia64_set_dcr(ia64_get_dcr()|IA64_DCR_PP);
+		/*
+		 * stop monitoring in the caller
+		 */
+		ia64_psr(regs)->pp = 0;
 
-		ia64_srlz_i();
+		return 0;
+	}
+	/*
+	 * per-task mode
+	 */
 
+	if (ctx->ctx_task == current) {
+		/* stop monitoring  at kernel level */
+		pfm_clear_psr_up();
+
+		/*
+	 	 * stop monitoring at the user level
+	 	 */
+		ia64_psr(regs)->up = 0;
 	} else {
-		if ((task->thread.flags & IA64_THREAD_PM_VALID) == 0) {
-			preempt_enable();
-			printk(KERN_DEBUG "perfmon: pfm_start task flag not set for [%d]\n",
-			       task->pid);
-			return -EINVAL;
-		}
-		/* set user level psr.up */
-		ia64_psr(regs)->up = 1;
+		tregs = ia64_task_regs(ctx->ctx_task);
 
-		/* start monitoring at kernel level */
-		pfm_set_psr_up();
+		/*
+	 	 * stop monitoring at the user level
+	 	 */
+		ia64_psr(tregs)->up = 0;
 
-		ia64_srlz_i();
+		/*
+		 * monitoring disabled in kernel at next reschedule
+		 */
+		ctx->ctx_saved_psr &= ~IA64_PSR_UP;
+		printk("pfm_stop: current [%d] task=[%d]\n", current->pid, ctx->ctx_task->pid);
 	}
-
-	preempt_enable();
 	return 0;
 }
 
+
 static int
-pfm_enable(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
-	   struct pt_regs *regs)
+pfm_start(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
-	int me;
+	struct pt_regs *tregs;
 
-	/* we don't quite support this right now */
-	if (task != current) return -EINVAL;
+	if (CTX_IS_LOADED(ctx) == 0) return -EINVAL;
 
-	me = get_cpu();  /* make sure we're not migrated or preempted */
-
-	if (ctx->ctx_fl_system == 0 && PMU_OWNER()  && PMU_OWNER() != current) 
-		pfm_lazy_save_regs(PMU_OWNER());
-
-	/* reset all registers to stable quiet state */
-	pfm_reset_pmu(task);
+	/*
+ 	 * In system wide and when the context is loaded, access can only happen
+ 	 * when the caller is running on the CPU being monitored by the session.
+ 	 * It does not have to be the owner (ctx_task) of the context per se.
+ 	 */
+	if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+		DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+		return -EBUSY;
+	}
 
-	/* make sure nothing starts */
+	/*
+	 * in system mode, we need to update the PMU directly
+	 * and the user level state of the caller, which may not
+	 * necessarily be the creator of the context.
+	 */
 	if (ctx->ctx_fl_system) {
-		ia64_psr(regs)->pp = 0;
-		ia64_psr(regs)->up = 0; /* just to make sure! */
 
-		/* make sure monitoring is stopped */
-		pfm_clear_psr_pp();
-		ia64_srlz_i();
+		/*
+		 * set user level psr.pp for the caller
+		 */
+		ia64_psr(regs)->pp = 1;
 
-		PFM_CPUINFO_CLEAR(PFM_CPUINFO_DCR_PP);
-		PFM_CPUINFO_SET(PFM_CPUINFO_SYST_WIDE);
-		if (ctx->ctx_fl_excl_idle) PFM_CPUINFO_SET(PFM_CPUINFO_EXCL_IDLE);
-	} else {
 		/*
-		 * needed in case the task was a passive task during
-		 * a system wide session and now wants to have its own
-		 * session
+		 * now update the local PMU and cpuinfo
 		 */
-		ia64_psr(regs)->pp = 0; /* just to make sure! */
-		ia64_psr(regs)->up = 0;
+		PFM_CPUINFO_SET(PFM_CPUINFO_DCR_PP);
 
-		/* make sure monitoring is stopped */
-		pfm_clear_psr_up();
+		/*
+		 * start monitoring at kernel level
+		 */
+		pfm_set_psr_pp();
+
+		/* enable dcr pp */
+		ia64_set_dcr(ia64_get_dcr()|IA64_DCR_PP);
 		ia64_srlz_i();
 
-		DBprintk(("clearing psr.sp for [%d]\n", current->pid));
+		return 0;
+	}
+
+	/*
+	 * per-process mode
+	 */
 
-		/* allow user level control  */
-		ia64_psr(regs)->sp = 0;
+	if (ctx->ctx_task == current) {
 
-		/* PMU state will be saved/restored on ctxsw */
-		task->thread.flags |= IA64_THREAD_PM_VALID;
-	}
+		/* start monitoring at kernel level */
+		pfm_set_psr_up();
 
-	SET_PMU_OWNER(task);
+		/*
+		 * activate monitoring at user level
+		 */
+		ia64_psr(regs)->up = 1;
 
-	ctx->ctx_flags.state = PFM_CTX_ENABLED;
-	atomic_set(&ctx->ctx_last_cpu, me);
+	} else {
+		tregs = ia64_task_regs(ctx->ctx_task);
 
-	/* simply unfreeze */
-	pfm_unfreeze_pmu();
+		/*
+		 * start monitoring at the kernel level the next
+		 * time the task is scheduled
+		 */
+		ctx->ctx_saved_psr |= IA64_PSR_UP;
 
-	put_cpu();
+		/*
+		 * activate monitoring at user level
+		 */
+		ia64_psr(tregs)->up = 1;
+	}
 
 	return 0;
 }
 
 static int
-pfm_get_pmc_reset(struct task_struct *task, pfm_context_t *ctx, void *arg, int count, 
-	   struct pt_regs *regs)
+pfm_get_pmc_reset(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
-	pfarg_reg_t tmp, *req = (pfarg_reg_t *)arg;
+	pfarg_reg_t *req = (pfarg_reg_t *)arg;
 	unsigned int cnum;
-	int i, ret = -EINVAL;
+	int i;
+	int ret = -EINVAL;
 
 	for (i = 0; i < count; i++, req++) {
 
-		if (__copy_from_user(&tmp, req, sizeof(tmp))) return -EFAULT;
-
-		cnum = tmp.reg_num;
+		cnum = req->reg_num;
 
 		if (!PMC_IS_IMPL(cnum)) goto abort_mission;
 
-		tmp.reg_value = PMC_DFL_VAL(cnum);
-
-		PFM_REG_RETFLAG_SET(tmp.reg_flags, 0);
+		req->reg_value = PMC_DFL_VAL(cnum);
 
-		DBprintk(("pmc_reset_val pmc[%u]=0x%lx\n", cnum, tmp.reg_value)); 
+		PFM_REG_RETFLAG_SET(req->reg_flags, 0);
 
-		if (__copy_to_user(req, &tmp, sizeof(tmp))) return -EFAULT;
+		DPRINT(("pmc_reset_val pmc[%u]=0x%lx\n", cnum, req->reg_value));
 	}
 	return 0;
-abort_mission:
-	PFM_REG_RETFLAG_SET(tmp.reg_flags, PFM_REG_RETFL_EINVAL);
-	if (__copy_to_user(req, &tmp, sizeof(tmp))) ret = -EFAULT;
 
+abort_mission:
+	PFM_REG_RETFLAG_SET(req->reg_flags, PFM_REG_RETFL_EINVAL);
 	return ret;
 }
 
-/*
- * functions MUST be listed in the increasing order of their index (see permfon.h)
- */
-static pfm_cmd_desc_t pfm_cmd_tab[]={
-/* 0  */{ NULL, 0, 0, 0}, /* not used */
-/* 1  */{ pfm_write_pmcs, PFM_CMD_PID|PFM_CMD_CTX|PFM_CMD_ARG_RW, PFM_CMD_ARG_MANY, sizeof(pfarg_reg_t)}, 
-/* 2  */{ pfm_write_pmds, PFM_CMD_PID|PFM_CMD_CTX|PFM_CMD_ARG_RW, PFM_CMD_ARG_MANY, sizeof(pfarg_reg_t)},
-/* 3  */{ pfm_read_pmds,PFM_CMD_PID|PFM_CMD_CTX|PFM_CMD_ARG_RW, PFM_CMD_ARG_MANY, sizeof(pfarg_reg_t)}, 
-/* 4  */{ pfm_stop, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
-/* 5  */{ pfm_start, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
-/* 6  */{ pfm_enable, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
-/* 7  */{ pfm_disable, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
-/* 8  */{ pfm_context_create, PFM_CMD_PID|PFM_CMD_ARG_RW, 1, sizeof(pfarg_context_t)},
-/* 9  */{ pfm_context_destroy, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
-/* 10 */{ pfm_restart, PFM_CMD_PID|PFM_CMD_CTX|PFM_CMD_NOCHK, 0, 0},
-/* 11 */{ pfm_protect_context, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
-/* 12 */{ pfm_get_features, PFM_CMD_ARG_RW, 0, 0},
-/* 13 */{ pfm_debug, 0, 1, sizeof(unsigned int)},
-/* 14 */{ pfm_context_unprotect, PFM_CMD_PID|PFM_CMD_CTX, 0, 0},
-/* 15 */{ pfm_get_pmc_reset, PFM_CMD_ARG_RW, PFM_CMD_ARG_MANY, sizeof(pfarg_reg_t)},
-/* 16 */{ NULL, 0, 0, 0}, /* not used */
-/* 17 */{ NULL, 0, 0, 0}, /* not used */
-/* 18 */{ NULL, 0, 0, 0}, /* not used */
-/* 19 */{ NULL, 0, 0, 0}, /* not used */
-/* 20 */{ NULL, 0, 0, 0}, /* not used */
-/* 21 */{ NULL, 0, 0, 0}, /* not used */
-/* 22 */{ NULL, 0, 0, 0}, /* not used */
-/* 23 */{ NULL, 0, 0, 0}, /* not used */
-/* 24 */{ NULL, 0, 0, 0}, /* not used */
-/* 25 */{ NULL, 0, 0, 0}, /* not used */
-/* 26 */{ NULL, 0, 0, 0}, /* not used */
-/* 27 */{ NULL, 0, 0, 0}, /* not used */
-/* 28 */{ NULL, 0, 0, 0}, /* not used */
-/* 29 */{ NULL, 0, 0, 0}, /* not used */
-/* 30 */{ NULL, 0, 0, 0}, /* not used */
-/* 31 */{ NULL, 0, 0, 0}, /* not used */
-#ifdef PFM_PMU_USES_DBR
-/* 32 */{ pfm_write_ibrs, PFM_CMD_PID|PFM_CMD_CTX|PFM_CMD_ARG_RW, PFM_CMD_ARG_MANY, sizeof(pfarg_dbreg_t)},
-/* 33 */{ pfm_write_dbrs, PFM_CMD_PID|PFM_CMD_CTX|PFM_CMD_ARG_RW, PFM_CMD_ARG_MANY, sizeof(pfarg_dbreg_t)}
-#endif
-};
-#define PFM_CMD_COUNT	ARRAY_SIZE(pfm_cmd_tab)
-
 static int
-check_task_state(struct task_struct *task)
+pfm_context_load(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
+	struct task_struct *task;
+	struct thread_struct *thread;
+	struct pfm_context_t *old;
+#ifndef CONFIG_SMP
+	struct task_struct *owner_task = NULL;
+#endif
+	pfarg_load_t *req = (pfarg_load_t *)arg;
+	unsigned long *pmcs_source, *pmds_source;
+	int the_cpu;
 	int ret = 0;
-#ifdef CONFIG_SMP
-	/* We must wait until the state has been completely
-	 * saved. There can be situations where the reader arrives before
-	 * after the task is marked as STOPPED but before pfm_save_regs()
-	 * is completed.
-	 */
-	if (task->state != TASK_ZOMBIE && task->state != TASK_STOPPED) return -EBUSY;
-	DBprintk(("before wait_task_inactive [%d] state %ld\n", task->pid, task->state));
-	wait_task_inactive(task);
-	DBprintk(("after wait_task_inactive [%d] state %ld\n", task->pid, task->state));
-#else
-	if (task->state != TASK_ZOMBIE && task->state != TASK_STOPPED) {
-		DBprintk(("warning [%d] not in stable state %ld\n", task->pid, task->state));
-		ret = -EBUSY;
+
+	/*
+	 * can only load from unloaded or terminated state
+	 */
+	if (CTX_IS_UNLOADED(ctx) == 0 && CTX_IS_TERMINATED(ctx) == 0) {
+		DPRINT(("[%d] cannot load to [%d], invalid ctx_state=%d\n",
+			current->pid,
+			req->load_pid,
+			ctx->ctx_state));
+		return -EINVAL;
 	}
-#endif
-	return ret;
-}
 
-asmlinkage long
-sys_perfmonctl (pid_t pid, int cmd, void *arg, int count, long arg5, long arg6, long arg7, 
-		long arg8, long stack)
-{
-	struct pt_regs *regs = (struct pt_regs *)&stack;
-	struct task_struct *task = current;
-	pfm_context_t *ctx;
-	size_t sz;
-	int ret, narg;
+	DPRINT(("load_pid [%d]\n", req->load_pid));
 
-	/* 
-	 * reject any call if perfmon was disabled at initialization time
+	if (CTX_OVFL_NOBLOCK(ctx) == 0 && req->load_pid == current->pid) {
+		DPRINT(("cannot use blocking mode on self for [%d]\n", current->pid));
+		return -EINVAL;
+	}
+
+	ret = pfm_get_task(ctx, req->load_pid, &task);
+	if (ret) {
+		DPRINT(("load_pid [%d] get_task=%d\n", req->load_pid, ret));
+		return ret;
+	}
+
+	ret = -EINVAL;
+
+	/*
+	 * system wide is self monitoring only
 	 */
-	if (PFM_IS_DISABLED()) return -ENOSYS;
+	if (ctx->ctx_fl_system && task != current) {
+		DPRINT(("system wide is self monitoring only current=%d load_pid=%d\n",
+			current->pid,
+			req->load_pid));
+		goto error;
+	}
 
-	DBprintk(("cmd=%d idx=%d valid=%d narg=0x%x\n", cmd, PFM_CMD_IDX(cmd), 
-		  PFM_CMD_IS_VALID(cmd), PFM_CMD_NARG(cmd)));
+	thread = &task->thread;
 
-	if (PFM_CMD_IS_VALID(cmd) == 0) return -EINVAL;
+	ret = -EBUSY;
 
-	/* ingore arguments when command has none */
-	narg = PFM_CMD_NARG(cmd);
-	if ((narg == PFM_CMD_ARG_MANY  && count == 0) || (narg > 0 && narg != count)) return -EINVAL;
+	/*
+	 * cannot load a context which is using range restrictions,
+	 * into a task that is being debugged.
+	 */
+	if (ctx->ctx_fl_using_dbreg && (thread->flags & IA64_THREAD_DBG_VALID)) {
+		DPRINT(("load_pid [%d] task is debugged, cannot load range restrictions\n", req->load_pid));
+		goto error;
+	}
 
-	sz = PFM_CMD_ARG_SIZE(cmd);
+	/*
+	 * SMP system-wide monitoring implies self-monitoring.
+	 *
+	 * The programming model expects the task to
+	 * be pinned on a CPU throughout the session.
+	 * Here we take note of the current CPU at the
+	 * time the context is loaded. No call from
+	 * another CPU will be allowed.
+	 *
+	 * The pinning via shed_setaffinity()
+	 * must be done by the calling task prior
+	 * to this call.
+	 *
+	 * systemwide: keep track of CPU this session is supposed to run on
+	 */
+	the_cpu = ctx->ctx_cpu = smp_processor_id();
 
-	if (PFM_CMD_READ_ARG(cmd) && !access_ok(VERIFY_READ, arg, sz*count)) return -EFAULT;
+	/*
+	 * now reserve the session
+	 */
+	ret = pfm_reserve_session(current, ctx->ctx_fl_system, the_cpu);
+	if (ret) goto error;
+
+	ret = -EBUSY;
+	/*
+	 * task is necessarily stopped at this point.
+	 *
+	 * If the previous context was zombie, then it got removed in
+	 * pfm_save_regs(). Therefore we should not see it here.
+	 * If we see a context, then this is an active context
+	 *
+	 * XXX: needs to be atomic
+	 */
+	DPRINT(("[%d] before cmpxchg() old_ctx=%p new_ctx=%p\n",
+		current->pid, 
+		thread->pfm_context, ctx));
 
-	if (PFM_CMD_RW_ARG(cmd) && !access_ok(VERIFY_WRITE, arg, sz*count)) return -EFAULT;
+	old = ia64_cmpxchg("acq", &thread->pfm_context, NULL, ctx, sizeof(pfm_context_t *));
+	if (old != NULL) {
+		DPRINT(("load_pid [%d] already has a context\n", req->load_pid));
+		goto error_unres;
+	}
 
-	if (PFM_CMD_USE_PID(cmd))  {
-		/* 
-		 * XXX: may need to fine tune this one
-		 */
-		if (pid < 2) return -EPERM;
+	pfm_reset_msgq(ctx);
 
-		if (pid != current->pid) {
+	CTX_LOADED(ctx);
 
-			ret = -ESRCH;
+	/*
+	 * link context to task
+	 */
+	ctx->ctx_task = task;
 
-			read_lock(&tasklist_lock);
+	if (ctx->ctx_fl_system) {
 
-			task = find_task_by_pid(pid);
+		/*
+		 * we load as stopped
+		 */
+		PFM_CPUINFO_SET(PFM_CPUINFO_SYST_WIDE);
+		PFM_CPUINFO_CLEAR(PFM_CPUINFO_DCR_PP);
 
-			if (task) get_task_struct(task);
+		if (ctx->ctx_fl_excl_idle) PFM_CPUINFO_SET(PFM_CPUINFO_EXCL_IDLE);
+	} else {
+		thread->flags |= IA64_THREAD_PM_VALID;
+	}
 
-			read_unlock(&tasklist_lock);
+	/*
+	 * propagate into thread-state
+	 */
+	pfm_copy_pmds(task, ctx);
+	pfm_copy_pmcs(task, ctx);
 
-			if (!task) goto abort_call;
+	pmcs_source = thread->pmcs;
+	pmds_source = thread->pmds;
 
-			ret = -EPERM;
+	/*
+	 * always the case for system-wide
+	 */
+	if (task == current) {
 
-			if (pfm_bad_permissions(task)) goto abort_call;
+		if (ctx->ctx_fl_system == 0) {
 
-			if (PFM_CMD_CHK(cmd)) {
-				ret = check_task_state(task);
-				if (ret != 0) goto abort_call;
-			}
+			/* allow user level control */
+			ia64_psr(regs)->sp = 0;
+			DPRINT(("clearing psr.sp for [%d]\n", task->pid));
+
+			SET_LAST_CPU(ctx, smp_processor_id());
+			INC_ACTIVATION();
+			SET_ACTIVATION(ctx);
+#ifndef CONFIG_SMP
+			/*
+			 * push the other task out, if any
+			 */
+			owner_task = GET_PMU_OWNER();
+			if (owner_task) pfm_lazy_save_regs(owner_task);
+#endif
 		}
-	} 
+		/*
+		 * load all PMD from ctx to PMU (as opposed to thread state)
+		 * restore all PMC from ctx to PMU
+		 */
+		pfm_restore_pmds(pmds_source, ctx->ctx_all_pmds[0]);
+		pfm_restore_pmcs(pmcs_source, ctx->ctx_all_pmcs[0]);
 
-	ctx = task->thread.pfm_context;
+		ctx->ctx_reload_pmcs[0] = 0UL;
+		ctx->ctx_reload_pmds[0] = 0UL;
 
-	if (PFM_CMD_USE_CTX(cmd)) {
-		ret = -EINVAL;
-	       if (ctx == NULL) {
-			DBprintk(("no context for task %d\n", task->pid));
-			goto abort_call;
-	       }
-	       ret = -EPERM;
-	       /*
-		* we only grant access to the context if:
-		* 	- the caller is the creator of the context (ctx_owner)
-		*  OR   - the context is attached to the caller AND The context IS NOT 
-		*  	  in protected mode
-		*/
-	       if (ctx->ctx_owner != current && (ctx->ctx_fl_protected || task != current)) {
-				DBprintk(("context protected, no access for [%d]\n", task->pid));
-				goto abort_call;
-	       }
+		/*
+		 * guaranteed safe by earlier check against DBG_VALID
+		 */
+		if (ctx->ctx_fl_using_dbreg) {
+			pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf.num_ibrs);
+			pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf.num_dbrs);
+		}
+		/*
+		 * set new ownership
+		 */
+		SET_PMU_OWNER(task, ctx);
+
+		DPRINT(("context loaded on PMU for [%d]\n", task->pid));
+	} else {
+		/*
+		 * when not current, task MUST be stopped, so this is safe
+		 */
+		regs = ia64_task_regs(task);
+
+		/* force a full reload */
+		ctx->ctx_last_activation = PFM_INVALID_ACTIVATION;
+		SET_LAST_CPU(ctx, -1);
+
+		/* initial saved psr (stopped) */
+		ctx->ctx_saved_psr = pfm_get_psr() & ~(IA64_PSR_PP|IA64_PSR_UP);
+		ia64_psr(regs)->up = ia64_psr(regs)->pp = 0;
+
+		if (ctx->ctx_fl_unsecure) {
+			ia64_psr(regs)->sp = 0;
+			DPRINT(("context unsecured for [%d]\n", task->pid));
+		}
 	}
 
-	ret = (*pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_func)(task, ctx, arg, count, regs);
+	ret = 0;
 
-abort_call:
-	if (task && task != current) put_task_struct(task);
+error_unres:
+	if (ret) pfm_unreserve_session(ctx, ctx->ctx_fl_system, the_cpu);
+error:
+	/*
+	 * release task, there is now a link with the context
+	 */
+	if (ctx->ctx_fl_system == 0 && task != current) pfm_put_task(task);
 
 	return ret;
 }
 
 /*
- * send SIGPROF to register task, must be invoked when it
- * is safe to send a signal, e.g., not holding any runqueue
- * related locks.
+ * in this function, we do not need to increase the use count
+ * for the task via get_task_struct(), because we hold the
+ * context lock. If the task were to disappear while having
+ * a context attached, it would go through pfm_exit_thread()
+ * which also grabs the context lock  and would therefore be blocked
+ * until we are here.
  */
+static void pfm_flush_pmds(struct task_struct *, pfm_context_t *ctx);
+
 static int
-pfm_notify_user(pfm_context_t *ctx)
+pfm_context_unload(pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs)
 {
-	struct siginfo si;
-	int ret;
+	struct task_struct *task = ctx->ctx_task;
+	struct pt_regs *tregs;
 
-	if (ctx->ctx_notify_task == NULL) {
-		DBprintk(("[%d] no notifier\n", current->pid));
-		return -EINVAL;
+	DPRINT(("ctx_state=%d task [%d]\n", ctx->ctx_state, task ? task->pid : -1));
+
+	/*
+	 * unload only when necessary
+	 */
+	if (CTX_IS_TERMINATED(ctx) || CTX_IS_UNLOADED(ctx)) {
+		DPRINT(("[%d] ctx_state=%d, nothing to do\n", current->pid, ctx->ctx_state));
+		return 0;
 	}
 
-	si.si_errno    = 0;
-	si.si_addr     = NULL;
-	si.si_pid      = current->pid; /* who is sending */
-	si.si_signo    = SIGPROF;
-	si.si_code     = PROF_OVFL;
+	/*
+	 * In system wide and when the context is loaded, access can only happen
+	 * when the caller is running on the CPU being monitored by the session.
+	 * It does not have to be the owner (ctx_task) of the context per se.
+	 */
+	if (ctx->ctx_fl_system && ctx->ctx_cpu != smp_processor_id()) {
+		DPRINT(("[%d] should be running on CPU%d\n", current->pid, ctx->ctx_cpu));
+		return -EBUSY;
+	}
+
+	/*
+	 * clear psr and dcr bits
+	 */
+	pfm_stop(ctx, NULL, 0, regs);
 
-	si.si_pfm_ovfl[0] = ctx->ctx_ovfl_regs[0];
+	CTX_UNLOADED(ctx);
 
 	/*
-	 * when the target of the signal is not ourself, we have to be more
-	 * careful. The notify_task may being cleared by the target task itself
-	 * in release_thread(). We must ensure mutual exclusion here such that
-	 * the signal is delivered (even to a dying task) safely.
+	 * in system mode, we need to update the PMU directly
+	 * and the user level state of the caller, which may not
+	 * necessarily be the creator of the context.
 	 */
+	if (ctx->ctx_fl_system) {
 
-	if (ctx->ctx_notify_task != current) {
 		/*
-		 * grab the notification lock for this task
-		 * This guarantees that the sequence: test + send_signal
-		 * is atomic with regards to the ctx_notify_task field.
-		 *
-		 * We need a spinlock and not just an atomic variable for this.
+		 * Update cpuinfo
 		 *
+		 * local PMU is taken care of in pfm_stop()
 		 */
-		spin_lock(&ctx->ctx_lock);
+		PFM_CPUINFO_CLEAR(PFM_CPUINFO_SYST_WIDE);
+		PFM_CPUINFO_CLEAR(PFM_CPUINFO_EXCL_IDLE);
 
 		/*
-		 * now notify_task cannot be modified until we're done
-		 * if NULL, they it got modified while we were in the handler
+		 * save PMDs in context
+		 * release ownership
 		 */
-		if (ctx->ctx_notify_task == NULL) {
+		pfm_flush_pmds(current, ctx);
 
-			spin_unlock(&ctx->ctx_lock);
+		/*
+		 * at this point we are done with the PMU
+		 * so we can unreserve the resource.
+		 */
+		pfm_unreserve_session(ctx, 1 , ctx->ctx_cpu);
 
-			/*
-			 * If we've lost the notified task, then we will run
-			 * to completion wbut keep the PMU frozen. Results
-			 * will be incorrect anyway. We do not kill task
-			 * to leave it possible to attach perfmon context
-			 * to already running task.
-			 */
-			printk("perfmon: pfm_notify_user() lost notify_task\n");
-			DBprintk_ovfl(("notification task has disappeared !\n"));
+		/*
+		 * disconnect context from task
+		 */
+		task->thread.pfm_context = NULL;
+		/*
+		 * disconnect task from context
+		 */
+		ctx->ctx_task = NULL;
 
-			/* we cannot afford to block now */
-			ctx->ctx_fl_block = 0;
+		/*
+		 * There is nothing more to cleanup here.
+		 */
+		return 0;
+	}
 
-			return  -EINVAL;
-		}
+	/*
+	 * per-task mode
+	 */
+	tregs = task == current ? regs : ia64_task_regs(task);
 
+	if (task == current || ctx->ctx_fl_unsecure) {
 		/*
-		 * required by send_sig_info() to make sure the target
-		 * task does not disappear on us.
+		 * cancel user level control
 		 */
-		read_lock(&tasklist_lock);
+		ia64_psr(regs)->sp = 1;
+		DPRINT(("setting psr.sp for [%d]\n", task->pid));
+
 	}
 	/*
- 	 * in this case, we don't stop the task, we let it go on. It will
- 	 * necessarily go to the signal handler (if any) when it goes back to
- 	 * user mode.
- 	 */
-	DBprintk_ovfl(("[%d] sending notification to [%d]\n", 
-			current->pid, ctx->ctx_notify_task->pid));
+	 * save PMDs to context
+	 * release ownership
+	 */
+	pfm_flush_pmds(task, ctx);
 
-	/* 
-	 * this call is safe in an interrupt handler, so does read_lock() on tasklist_lock
+	/*
+	 * at this point we are done with the PMU
+	 * so we can unreserve the resource.
 	 */
-	ret = send_sig_info(SIGPROF, &si, ctx->ctx_notify_task);
-	if (ret) {
-		printk("perfmon: send_sig_info(process %d, SIGPROF)=%d\n", 
-				ctx->ctx_notify_task->pid, ret);
-	}
+	pfm_unreserve_session(ctx, 0 , ctx->ctx_cpu);
 
 	/*
-	 * now undo the protections in order
+	 * reset activation counter and psr
 	 */
-	if (ctx->ctx_notify_task != current) {
-		read_unlock(&tasklist_lock);
-		spin_unlock(&ctx->ctx_lock);
+	ctx->ctx_last_activation = PFM_INVALID_ACTIVATION;
+	SET_LAST_CPU(ctx, -1);
+
+	/*
+	 * PMU state will not be restored
+	 */
+	task->thread.flags &= ~IA64_THREAD_PM_VALID;
+
+	/*
+	 * break links between context and task
+	 */
+	task->thread.pfm_context  = NULL;
+	ctx->ctx_task             = NULL;
+
+	PFM_SET_WORK_PENDING(task, 0);
+	ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_NONE;
+
+	DPRINT(("disconnected [%d] from context\n", task->pid));
+
+	return 0;
+}
+
+static void
+pfm_force_cleanup(pfm_context_t *ctx, struct pt_regs *regs)
+{
+	struct task_struct *task = ctx->ctx_task;
+
+	ia64_psr(regs)->up = 0;
+	ia64_psr(regs)->sp = 1;
+
+	if (GET_PMU_OWNER() == task) {
+		DPRINT(("cleared ownership for [%d]\n", ctx->ctx_task->pid));
+		SET_PMU_OWNER(NULL, NULL);
 	}
-	return ret;
+
+	/*
+	 * disconnect the task from the context and vice-versa
+	 */
+	PFM_SET_WORK_PENDING(task, 0);
+
+	task->thread.pfm_context  = NULL;
+	task->thread.flags       &= ~IA64_THREAD_PM_VALID;
+
+	DPRINT(("context <%d> force cleanup for [%d] by [%d]\n", ctx->ctx_fd, task->pid, current->pid));
 }
 
+
+/*
+ * called only from exit_thread(): task == current
+ */
 void
-pfm_ovfl_block_reset(void)
+pfm_exit_thread(struct task_struct *task)
 {
-	struct thread_struct *th = &current->thread;
-	pfm_context_t *ctx = current->thread.pfm_context;
-	unsigned int reason;
+	pfm_context_t *ctx;
+	unsigned long flags;
+	struct pt_regs *regs = ia64_task_regs(task);
 	int ret;
+	int free_ok = 0;
+
+	ctx = PFM_GET_CTX(task);
+
+	PROTECT_CTX(ctx, flags);
+
+	DPRINT(("state=%d task [%d]\n", ctx->ctx_state, task->pid));
 
 	/*
-	 * clear the flag, to make sure we won't get here
-	 * again
+	 * come here only if attached
 	 */
-	th->pfm_ovfl_block_reset = 0;
-	clear_thread_flag(TIF_NOTIFY_RESUME);
+	if (unlikely(CTX_IS_UNLOADED(ctx))) {
+		printk(KERN_ERR "perfmon: pfm_exit_thread [%d] ctx unloaded\n", task->pid);
+		goto skip_all;
+	}
+
+	if (CTX_IS_LOADED(ctx) || CTX_IS_MASKED(ctx)) {
+
+		ret = pfm_context_unload(ctx, NULL, 0, regs);
+		if (ret) {
+			printk(KERN_ERR "perfmon: pfm_exit_thread [%d] state=%d unload failed %d\n", task->pid, ctx->ctx_state, ret);
+		}
+		CTX_TERMINATED(ctx);
+		DPRINT(("ctx terminated by [%d]\n", task->pid));
+
+		pfm_end_notify_user(ctx);
+
+	} else if (CTX_IS_ZOMBIE(ctx)) {
+		pfm_clear_psr_up();
+
+		BUG_ON(ctx->ctx_smpl_hdr);
+
+		pfm_force_cleanup(ctx, regs);
+
+		free_ok = 1;
+	}
+	{ u64 psr = pfm_get_psr();
+	  BUG_ON(psr & (IA64_PSR_UP|IA64_PSR_PP));
+	}
+skip_all:
+	UNPROTECT_CTX(ctx, flags);
 
 	/*
-	 * do some sanity checks first
+	 * All memory free operations (especially for vmalloc'ed memory)
+	 * MUST be done with interrupts ENABLED.
 	 */
-	if (!ctx) {
-		printk(KERN_ERR "perfmon: [%d] has no PFM context\n", current->pid);
-		return;
+	if (free_ok) pfm_context_free(ctx);
+}
+
+/*
+ * functions MUST be listed in the increasing order of their index (see permfon.h)
+ */
+#define PFM_CMD(name, flags, arg_count, arg_type, getsz) { name, #name, flags, arg_count, sizeof(arg_type), getsz }
+#define PFM_CMD_S(name, flags) { name, #name, flags, 0, 0, NULL }
+#define PFM_CMD_PCLRWS	(PFM_CMD_FD|PFM_CMD_ARG_RW|PFM_CMD_STOP)
+#define PFM_CMD_PCLRW	(PFM_CMD_FD|PFM_CMD_ARG_RW)
+#define PFM_CMD_NONE	{ NULL, "no-cmd", 0, 0, 0, NULL}
+
+static pfm_cmd_desc_t pfm_cmd_tab[]={
+/* 0  */PFM_CMD_NONE,
+/* 1  */PFM_CMD(pfm_write_pmcs, PFM_CMD_PCLRWS, PFM_CMD_ARG_MANY, pfarg_reg_t, NULL),
+/* 2  */PFM_CMD(pfm_write_pmds, PFM_CMD_PCLRWS, PFM_CMD_ARG_MANY, pfarg_reg_t, NULL),
+/* 3  */PFM_CMD(pfm_read_pmds, PFM_CMD_PCLRWS, PFM_CMD_ARG_MANY, pfarg_reg_t, NULL),
+/* 4  */PFM_CMD_S(pfm_stop, PFM_CMD_PCLRWS),
+/* 5  */PFM_CMD_S(pfm_start, PFM_CMD_PCLRWS),
+/* 6  */PFM_CMD_NONE,
+/* 7  */PFM_CMD_NONE,
+/* 8  */PFM_CMD(pfm_context_create, PFM_CMD_ARG_RW, 1, pfarg_context_t, pfm_ctx_getsize),
+/* 9  */PFM_CMD_NONE,
+/* 10 */PFM_CMD_S(pfm_restart, PFM_CMD_PCLRW),
+/* 11 */PFM_CMD_NONE,
+/* 12 */PFM_CMD(pfm_get_features, PFM_CMD_ARG_RW, 1, pfarg_features_t, NULL),
+/* 13 */PFM_CMD(pfm_debug, 0, 1, unsigned int, NULL),
+/* 14 */PFM_CMD_NONE,
+/* 15 */PFM_CMD(pfm_get_pmc_reset, PFM_CMD_ARG_RW, PFM_CMD_ARG_MANY, pfarg_reg_t, NULL),
+/* 16 */PFM_CMD(pfm_context_load, PFM_CMD_PCLRWS, 1, pfarg_load_t, NULL),
+/* 17 */PFM_CMD_S(pfm_context_unload, PFM_CMD_PCLRWS),
+/* 18 */PFM_CMD_NONE,
+/* 19 */PFM_CMD_NONE,
+/* 20 */PFM_CMD_NONE,
+/* 21 */PFM_CMD_NONE,
+/* 22 */PFM_CMD_NONE,
+/* 23 */PFM_CMD_NONE,
+/* 24 */PFM_CMD_NONE,
+/* 25 */PFM_CMD_NONE,
+/* 26 */PFM_CMD_NONE,
+/* 27 */PFM_CMD_NONE,
+/* 28 */PFM_CMD_NONE,
+/* 29 */PFM_CMD_NONE,
+/* 30 */PFM_CMD_NONE,
+/* 31 */PFM_CMD_NONE,
+/* 32 */PFM_CMD(pfm_write_ibrs, PFM_CMD_PCLRWS, PFM_CMD_ARG_MANY, pfarg_dbreg_t, NULL),
+/* 33 */PFM_CMD(pfm_write_dbrs, PFM_CMD_PCLRWS, PFM_CMD_ARG_MANY, pfarg_dbreg_t, NULL)
+};
+#define PFM_CMD_COUNT	(sizeof(pfm_cmd_tab)/sizeof(pfm_cmd_desc_t))
+
+static int
+pfm_check_task_state(pfm_context_t *ctx, int cmd, unsigned long flags)
+{
+	struct task_struct *task;
+
+	task = PFM_CTX_TASK(ctx);
+	if (task == NULL) {
+		DPRINT(("context %d no task, state=%d\n", ctx->ctx_fd, ctx->ctx_state));
+		return 0;
 	}
+
+	DPRINT(("context %d state=%d [%d] task_state=%ld must_stop=%d\n",
+				ctx->ctx_fd,
+				ctx->ctx_state,
+				task->pid,
+				task->state, PFM_CMD_STOPPED(cmd)));
+
 	/*
-	 * extract reason for being here and clear
+	 * self-monitoring always ok.
+	 *
+	 * for system-wide the caller can either be the creator of the
+	 * context (to one to which the context is attached to) OR
+	 * a task running on the same CPU as the session.
 	 */
-	reason = ctx->ctx_fl_trap_reason;
-	ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_NONE;
+	if (task == current || ctx->ctx_fl_system) return 0;
+
+	/*
+	 * context is UNLOADED, MASKED, TERMINATED we are safe to go
+	 */
+	if (CTX_IS_LOADED(ctx) == 0) return 0;
 
-	DBprintk(("[%d] reason=%d\n", current->pid, reason));
+	if (CTX_IS_ZOMBIE(ctx)) return -EINVAL;
 
 	/*
-	 * just here for a reset (non-blocking context only)
+	 * context is loaded, we must make sure the task is stopped
+	 * We could lift this restriction for UP but it would mean that
+	 * the user has no guarantee the task would not run between
+	 * two successive calls to perfmonctl(). That's probably OK.
+	 * If this user wants to ensure the task does not run, then
+	 * the task must be stopped.
 	 */
-	if (reason == PFM_TRAP_REASON_RESET) goto non_blocking;
+	if (PFM_CMD_STOPPED(cmd) && task->state != TASK_STOPPED) {
+		DPRINT(("[%d] task not in stopped state\n", task->pid));
+		return -EBUSY;
+	}
+
+	UNPROTECT_CTX(ctx, flags);
+
+	pfm_wait_task_inactive(task);
+
+	PROTECT_CTX(ctx, flags);
+	return 0;
+}
+
+/*
+ * system-call entry point (must return long)
+ */
+asmlinkage long
+sys_perfmonctl (int fd, int cmd, void *arg, int count, long arg5, long arg6, long arg7,
+		long arg8, long stack)
+{
+	struct pt_regs *regs = (struct pt_regs *)&stack;
+	struct file *file = NULL;
+	pfm_context_t *ctx = NULL;
+	unsigned long flags = 0UL;
+	void *args_k = NULL;
+	long ret; /* will expand int return types */
+	size_t base_sz, sz, xtra_sz = 0;
+	int narg, completed_args = 0, call_made = 0;
+#define PFM_MAX_ARGSIZE	4096
 
 	/*
-	 * first notify user. This can fail if notify_task has disappeared.
+	 * reject any call if perfmon was disabled at initialization time
 	 */
-	if (reason == PFM_TRAP_REASON_SIG || reason == PFM_TRAP_REASON_BLOCKSIG) {
-		ret = pfm_notify_user(ctx);
-		if (ret) return;
+	if (PFM_IS_DISABLED()) return -ENOSYS;
+
+	if (unlikely(PFM_CMD_IS_VALID(cmd) == 0)) {
+		DPRINT(("[%d] invalid cmd=%d\n", current->pid, cmd));
+		return -EINVAL;
 	}
 
+	DPRINT(("cmd=%s idx=%d valid=%d narg=0x%x argsz=%lu count=%d\n",
+		PFM_CMD_NAME(cmd),
+		PFM_CMD_IDX(cmd),
+		PFM_CMD_IS_VALID(cmd),
+		PFM_CMD_NARG(cmd),
+		PFM_CMD_ARG_SIZE(cmd), count));
+
 	/*
-	 * came here just to signal (non-blocking)
+	 * check if number of arguments matches what the command expects
 	 */
-	if (reason == PFM_TRAP_REASON_SIG) return;
+	narg = PFM_CMD_NARG(cmd);
+	if ((narg == PFM_CMD_ARG_MANY && count <= 0) || (narg > 0 && narg != count))
+		return -EINVAL;
 
-	DBprintk(("[%d] before sleeping\n", current->pid));
+	/* get single argument size */
+	base_sz = PFM_CMD_ARG_SIZE(cmd);
 
+restart_args:
+	sz = xtra_sz + base_sz*count;
 	/*
-	 * may go through without blocking on SMP systems
-	 * if restart has been received already by the time we call down()
+	 * limit abuse to min page size
 	 */
-	ret = down_interruptible(&ctx->ctx_restart_sem);
+	if (unlikely(sz > PFM_MAX_ARGSIZE)) {
+		printk(KERN_ERR "perfmon: [%d] argument too big %lu\n", current->pid, sz);
+		return -E2BIG;
+	}
 
-	DBprintk(("[%d] after sleeping ret=%d\n", current->pid, ret));
+	/*
+	 * allocate default-sized argument buffer
+	 */
+	if (count && args_k == NULL) {
+		args_k = kmalloc(PFM_MAX_ARGSIZE, GFP_KERNEL);
+		if (args_k == NULL) return -ENOMEM;
+	}
+
+	ret = -EFAULT;
 
 	/*
-	 * in case of interruption of down() we don't restart anything
+	 * copy arguments
+	 *
+	 * assume sz = 0 for command without parameters
 	 */
-	if (ret >= 0) {
+	if (sz && copy_from_user(args_k, arg, sz)) {
+		DPRINT(("[%d] cannot copy_from_user %lu bytes @%p\n", current->pid, sz, arg));
+		goto error_args;
+	}
 
-non_blocking:
-		/* we reactivate on context switch */
-		ctx->ctx_fl_frozen = 0;
+	/*
+	 * check if command supports extra parameters
+	 */
+	if (completed_args == 0 && PFM_CMD_GETSIZE(cmd)) {
 		/*
-		 * the ovfl_sem is cleared by the restart task and this is safe because we always
-		 * use the local reference
+		 * get extra parameters size (based on main argument)
 		 */
+		ret = PFM_CMD_GETSIZE(cmd)(args_k, &xtra_sz);
+		if (ret) goto error_args;
 
-		pfm_reset_regs(ctx, ctx->ctx_ovfl_regs, PFM_PMD_LONG_RESET);
+		completed_args = 1;
 
-		ctx->ctx_ovfl_regs[0] = 0UL;
+		DPRINT(("[%d] restart_args sz=%lu xtra_sz=%lu\n", current->pid, sz, xtra_sz));
+
+		/* retry if necessary */
+		if (xtra_sz) goto restart_args;
+	}
+
+	if (PFM_CMD_USE_FD(cmd))  {
+
+		ret = -EBADF;
+
+		file = fget(fd);
+		if (file == NULL) {
+			DPRINT(("[%d] invalid fd %d\n", current->pid, fd));
+			goto error_args;
+		}
+		if (PFM_IS_FILE(file) == 0) {
+			DPRINT(("[%d] fd %d not related to perfmon\n", current->pid, fd));
+			goto error_args;
+		}
+
+
+		ctx = (pfm_context_t *)file->private_data;
+		if (ctx == NULL) {
+			DPRINT(("[%d] no context for fd %d\n", current->pid, fd));
+			goto error_args;
+		}
+
+		PROTECT_CTX(ctx, flags);
 
 		/*
-		 * Unlock sampling buffer and reset index atomically
-		 * XXX: not really needed when blocking
+		 * check task is stopped
 		 */
-		if (CTX_HAS_SMPL(ctx)) {
-			ctx->ctx_psb->psb_hdr->hdr_count = 0;
-			ctx->ctx_psb->psb_index = 0;
-		}
+		ret = pfm_check_task_state(ctx, cmd, flags);
+		if (ret) goto abort_locked;
+	}
 
-		pfm_unfreeze_pmu();
+	ret = (*pfm_cmd_tab[PFM_CMD_IDX(cmd)].cmd_func)(ctx, args_k, count, regs);
+
+	call_made = 1;
+
+abort_locked:
+	if (ctx) {
+		DPRINT(("[%d] context unlocked\n", current->pid));
+		UNPROTECT_CTX(ctx, flags);
+		fput(file);
+	}
 
-		/* state restored, can go back to work (user mode) */
+	/* copy argument back to user, if needed */
+	if (call_made && PFM_CMD_RW_ARG(cmd) && copy_to_user(arg, args_k, base_sz*count)) ret = -EFAULT;
+
+error_args:
+	if (args_k) kfree(args_k);
+
+	return ret;
+}
+
+static void
+pfm_resume_after_ovfl(pfm_context_t *ctx, unsigned long ovfl_regs, struct pt_regs *regs)
+{
+	pfm_buffer_fmt_t *fmt = ctx->ctx_buf_fmt;
+	pfm_ovfl_ctrl_t rst_ctrl;
+	int ret = 0;
+
+	/*
+	 * Unlock sampling buffer and reset index atomically
+	 * XXX: not really needed when blocking
+	 */
+	if (CTX_HAS_SMPL(ctx)) {
+
+		rst_ctrl.stop_monitoring = 1;
+		rst_ctrl.reset_pmds      = PFM_PMD_NO_RESET;
+
+		/* XXX: check return value */
+		if (fmt->fmt_restart)
+			ret = (*fmt->fmt_restart)(current, &rst_ctrl, ctx->ctx_smpl_hdr, regs);
+	} else {
+		rst_ctrl.stop_monitoring = 0;
+		rst_ctrl.reset_pmds      = PFM_PMD_LONG_RESET;
+	}
+
+	if (ret == 0) {
+		if (rst_ctrl.reset_pmds != PFM_PMD_NO_RESET)
+			pfm_reset_regs(ctx, &ovfl_regs, rst_ctrl.reset_pmds);
+
+		if (rst_ctrl.stop_monitoring == 0) {
+			DPRINT(("resuming monitoring\n"));
+			if (CTX_IS_MASKED(ctx)) pfm_restore_monitoring(current);
+		} else {
+			DPRINT(("stopping monitoring\n"));
+			//pfm_stop_monitoring(current, regs);
+		}
+		CTX_LOADED(ctx);
 	}
 }
 
+
 /*
- * This function will record an entry in the sampling if it is not full already.
- * Return:
- * 	0 : buffer is not full (did not BECOME full: still space or was already full)
- * 	1 : buffer is full (recorded the last entry)
+ * context MUST BE LOCKED when calling
+ * can only be called for current
  */
-static int
-pfm_record_sample(struct task_struct *task, pfm_context_t *ctx, unsigned long ovfl_mask, struct pt_regs *regs)
+static void
+pfm_context_force_terminate(pfm_context_t *ctx, struct pt_regs *regs)
 {
-	pfm_smpl_buffer_desc_t *psb = ctx->ctx_psb;
-	unsigned long *e, m, idx;
-	perfmon_smpl_entry_t *h;
-	int j;
-
+	if (ctx->ctx_fl_system) {
+		printk(KERN_ERR "perfmon: pfm_context_force_terminate [%d] is system-wide\n", current->pid);
+		return;
+	}
+	/*
+	 * we stop the whole thing, we do no need to flush
+	 * we know we WERE masked
+	 */
+	pfm_clear_psr_up();
+	ia64_psr(regs)->up = 0;
+	ia64_psr(regs)->sp = 1;
 
-	idx = ia64_fetch_and_add(1, &psb->psb_index);
-	DBprintk_ovfl(("recording index=%ld entries=%ld\n", idx-1, psb->psb_entries));
+	/*
+	 * disconnect the task from the context and vice-versa
+	 */
+	current->thread.pfm_context  = NULL;
+	current->thread.flags       &= ~IA64_THREAD_PM_VALID;
+	ctx->ctx_task = NULL;
 
 	/*
-	 * XXX: there is a small chance that we could run out on index before resetting
-	 * but index is unsigned long, so it will take some time.....
-	 * We use > instead of == because fetch_and_add() is off by one (see below)
-	 *
-	 * This case can happen in non-blocking mode or with multiple processes.
-	 * For non-blocking, we need to reload and continue.
- 	 */
-	if (idx > psb->psb_entries) return 0;
+	 * switch to terminated state
+	 */
+	CTX_TERMINATED(ctx);
 
-	/* first entry is really entry 0, not 1 caused by fetch_and_add */
-	idx--;
+	DPRINT(("context <%d> terminated for [%d]\n", ctx->ctx_fd, current->pid));
 
-	h = (perfmon_smpl_entry_t *)(((char *)psb->psb_addr) + idx*(psb->psb_entry_size));
+	/*
+	 * and wakeup controlling task, indicating we are now disconnected
+	 */
+	wake_up_interruptible(&ctx->ctx_zombieq);
 
 	/*
-	 * initialize entry header
+	 * given that context is still locked, the controlling
+	 * task will only get access when we return from
+	 * pfm_handle_work().
 	 */
-	h->pid  = current->pid;
-	h->cpu  = get_cpu();
-	h->last_reset_value = ovfl_mask ? ctx->ctx_soft_pmds[ffz(~ovfl_mask)].lval : 0UL;
-	h->ip   = regs ? regs->cr_iip | ((regs->cr_ipsr >> 41) & 0x3): 0x0UL;
-	h->regs = ovfl_mask; 			/* which registers overflowed */
+}
+
+static int pfm_ovfl_notify_user(pfm_context_t *ctx, unsigned long ovfl_pmds);
+
+void
+pfm_handle_work(void)
+{
+	pfm_context_t *ctx;
+	struct pt_regs *regs;
+	unsigned long flags;
+	unsigned long ovfl_regs;
+	unsigned int reason;
+	int ret;
 
-	/* guaranteed to monotonically increase on each cpu */
-	h->stamp  = pfm_get_stamp();
+	ctx = PFM_GET_CTX(current);
+	if (ctx == NULL) {
+		printk(KERN_ERR "perfmon: [%d] has no PFM context\n", current->pid);
+		return;
+	}
+
+	PROTECT_CTX(ctx, flags);
+
+	PFM_SET_WORK_PENDING(current, 0);
 
-	/* position for first pmd */
-	e = (unsigned long *)(h+1);
+	pfm_clear_task_notify();
+
+	regs = ia64_task_regs(current);
 
 	/*
-	 * selectively store PMDs in increasing index number
+	 * extract reason for being here and clear
 	 */
-	m = ctx->ctx_smpl_regs[0];
-	for (j=0; m; m >>=1, j++) {
+	reason = ctx->ctx_fl_trap_reason;
+	ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_NONE;
 
-		if ((m & 0x1) == 0) continue;
+	DPRINT(("[%d] reason=%d\n", current->pid, reason));
 
-		if (PMD_IS_COUNTING(j)) {
-			*e  =  pfm_read_soft_counter(ctx, j);
-		} else {
-			*e = ia64_get_pmd(j); /* slow */
-		}
-		DBprintk_ovfl(("e=%p pmd%d =0x%lx\n", (void *)e, j, *e));
-		e++;
-	}
-	pfm_stats[h->cpu].pfm_recorded_samples_count++;
+	/*
+	 * must be done before we check non-blocking mode
+	 */
+	if (ctx->ctx_fl_going_zombie || CTX_IS_ZOMBIE(ctx)) goto do_zombie;
+
+	ovfl_regs = ctx->ctx_ovfl_regs[0];
+
+	//if (CTX_OVFL_NOBLOCK(ctx)) goto skip_blocking;
+	if (reason == PFM_TRAP_REASON_RESET) goto skip_blocking;
+
+	UNPROTECT_CTX(ctx, flags);
+
+	DPRINT(("before block sleeping\n"));
 
 	/*
-	 * make the new entry visible to user, needs to be atomic
+	 * may go through without blocking on SMP systems
+	 * if restart has been received already by the time we call down()
 	 */
-	ia64_fetch_and_add(1, &psb->psb_hdr->hdr_count);
+	ret = down_interruptible(&ctx->ctx_restart_sem);
 
-	DBprintk_ovfl(("index=%ld entries=%ld hdr_count=%ld\n", 
-				idx, psb->psb_entries, psb->psb_hdr->hdr_count));
-	/* 
-	 * sampling buffer full ? 
+	DPRINT(("after block sleeping ret=%d\n", ret));
+
+	PROTECT_CTX(ctx, flags);
+
+	if (ctx->ctx_fl_going_zombie) {
+do_zombie:
+		DPRINT(("context is zombie, bailing out\n"));
+		pfm_context_force_terminate(ctx, regs);
+		goto nothing_to_do;
+	}
+	/*
+	 * in case of interruption of down() we don't restart anything
 	 */
-	if (idx == (psb->psb_entries-1)) {
-		DBprintk_ovfl(("sampling buffer full\n"));
-		/*
-		 * XXX: must reset buffer in blocking mode and lost notified
-		 */
-		pfm_stats[h->cpu].pfm_full_smpl_buffer_count++;
-		put_cpu();
-		return 1;
+	if (ret < 0) goto nothing_to_do;
+
+skip_blocking:
+	pfm_resume_after_ovfl(ctx, ovfl_regs, regs);
+	ctx->ctx_ovfl_regs[0] = 0UL;
+
+nothing_to_do:
+
+	UNPROTECT_CTX(ctx, flags);
+}
+
+static int
+pfm_notify_user(pfm_context_t *ctx, pfm_msg_t *msg)
+{
+	if (CTX_IS_ZOMBIE(ctx)) {
+		DPRINT(("ignoring overflow notification, owner is zombie\n"));
+		return 0;
 	}
-	put_cpu();
+
+	DPRINT(("[%d] waking up somebody\n", current->pid));
+
+	if (msg) wake_up_interruptible(&ctx->ctx_msgq_wait);
+
+	/*
+	 * safe, we are not in intr handler, nor in ctxsw when
+	 * we come here
+	 */
+	kill_fasync (&ctx->ctx_async_queue, SIGIO, POLL_IN);
+
 	return 0;
 }
 
+static int
+pfm_ovfl_notify_user(pfm_context_t *ctx, unsigned long ovfl_pmds)
+{
+	pfm_msg_t *msg = NULL;
+
+	if (ctx->ctx_fl_no_msg == 0) {
+		msg = pfm_get_new_msg(ctx);
+		if (msg == NULL) {
+			printk(KERN_ERR "perfmon: pfm_ovfl_notify_user no more notification msgs\n");
+			return -1;
+		}
+
+		msg->pfm_ovfl_msg.msg_type         = PFM_MSG_OVFL;
+		msg->pfm_ovfl_msg.msg_ctx_fd       = ctx->ctx_fd;
+		msg->pfm_ovfl_msg.msg_tstamp       = ia64_get_itc(); /* relevant on UP only */
+		msg->pfm_ovfl_msg.msg_active_set   = 0;
+		msg->pfm_ovfl_msg.msg_ovfl_pmds[0] = ovfl_pmds;
+		msg->pfm_ovfl_msg.msg_ovfl_pmds[1] = msg->pfm_ovfl_msg.msg_ovfl_pmds[2] = msg->pfm_ovfl_msg.msg_ovfl_pmds[3] = 0UL;
+
+	}
+
+	DPRINT(("ovfl msg: msg=%p no_msg=%d fd=%d pid=%d ovfl_pmds=0x%lx\n",
+		msg,
+		ctx->ctx_fl_no_msg,
+		ctx->ctx_fd,
+		current->pid,
+		ovfl_pmds));
+
+	return pfm_notify_user(ctx, msg);
+}
+
+static int
+pfm_end_notify_user(pfm_context_t *ctx)
+{
+	pfm_msg_t *msg;
+
+	msg = pfm_get_new_msg(ctx);
+	if (msg == NULL) {
+		printk(KERN_ERR "perfmon: pfm_end_notify_user no more notification msgs\n");
+		return -1;
+	}
+
+	msg->pfm_end_msg.msg_type    = PFM_MSG_END;
+	msg->pfm_end_msg.msg_ctx_fd  = ctx->ctx_fd;
+	msg->pfm_ovfl_msg.msg_tstamp = ia64_get_itc(); /* relevant on UP only */
+
+	DPRINT(("end msg: msg=%p no_msg=%d ctx_fd=%d pid=%d\n",
+		msg,
+		ctx->ctx_fl_no_msg,
+		ctx->ctx_fd, current->pid));
+
+	return pfm_notify_user(ctx, msg);
+}
+
 /*
  * main overflow processing routine.
- * it can be called from the interrupt path or explicitly during the context switch code
- * Arguments:
- *	mode: 0=coming from PMU interrupt, 1=coming from ctxsw 
- *	
- * Return:
- *	new value of pmc[0]. if 0x0 then unfreeze, else keep frozen
+ * it can be called from the interrupt path or explicitely during the context switch code
  */
-static unsigned long
-pfm_overflow_handler(int mode, struct task_struct *task, pfm_context_t *ctx, u64 pmc0, struct pt_regs *regs)
+static void
+pfm_overflow_handler(struct task_struct *task, pfm_context_t *ctx, u64 pmc0, struct pt_regs *regs)
 {
-	struct thread_struct *t;
+	pfm_ovfl_arg_t ovfl_arg;
 	unsigned long mask;
 	unsigned long old_val;
-	unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL;
-	int i;
-	int ret = 1;
-	/*
-	 * It is never safe to access the task for which the overflow interrupt is destinated
-	 * using the current variable as the interrupt may occur in the middle of a context switch
-	 * where current does not hold the task that is running yet.
-	 *
-	 * For monitoring, however, we do need to get access to the task which caused the overflow
-	 * to account for overflow on the counters.
-	 *
-	 * We accomplish this by maintaining a current owner of the PMU per CPU. During context
-	 * switch the ownership is changed in a way such that the reflected owner is always the
-	 * valid one, i.e. the one that caused the interrupt.
-	 */
+	unsigned long ovfl_notify = 0UL, ovfl_pmds = 0UL, smpl_pmds = 0UL;
+	pfm_ovfl_ctrl_t	ovfl_ctrl;
+	unsigned int i, j, has_smpl, first_pmd = ~0U;
+	int must_notify = 0;
 
-	preempt_disable();
-
-	t   = &task->thread;
+	if (unlikely(CTX_IS_ZOMBIE(ctx))) goto stop_monitoring;
 
 	/*
-	 * XXX: debug test
-	 * Don't think this could happen given upfront tests
-	 */
-	if ((t->flags & IA64_THREAD_PM_VALID) == 0 && ctx->ctx_fl_system == 0) {
-		printk(KERN_DEBUG "perfmon: Spurious overflow interrupt: process %d not "
-		       "using perfmon\n", task->pid);
-		preempt_enable_no_resched();
-		return 0x1;
-	}
-	/*
 	 * sanity test. Should never happen
 	 */
-	if ((pmc0 & 0x1) == 0) {
-		printk(KERN_DEBUG "perfmon: pid %d pmc0=0x%lx assumption error for freeze bit\n",
-		       task->pid, pmc0);
-		preempt_enable_no_resched();
-		return 0x0;
-	}
+	if (unlikely((pmc0 & 0x1) == 0)) goto sanity_check;
 
 	mask = pmc0 >> PMU_FIRST_COUNTER;
 
-	DBprintk_ovfl(("pmc0=0x%lx pid=%d iip=0x%lx, %s"
-		  " mode used_pmds=0x%lx used_pmcs=0x%lx reload_pmcs=0x%lx\n", 
-			pmc0, task->pid, (regs ? regs->cr_iip : 0), 
+	DPRINT_ovfl(("pmc0=0x%lx pid=%d iip=0x%lx, %s"
+		     "used_pmds=0x%lx reload_pmcs=0x%lx\n",
+			pmc0,
+			task ? task->pid: -1,
+			(regs ? regs->cr_iip : 0),
 			CTX_OVFL_NOBLOCK(ctx) ? "nonblocking" : "blocking",
 			ctx->ctx_used_pmds[0],
-			ctx->ctx_used_pmcs[0],
 			ctx->ctx_reload_pmcs[0]));
 
+	has_smpl = CTX_HAS_SMPL(ctx);
+
 	/*
-	 * First we update the virtual counters
+	 * first we update the virtual counters
+	 * assume there was a prior ia64_srlz_d() issued
 	 */
 	for (i = PMU_FIRST_COUNTER; mask ; i++, mask >>= 1) {
 
 		/* skip pmd which did not overflow */
 		if ((mask & 0x1) == 0) continue;
 
-		DBprintk_ovfl(("pmd[%d] overflowed hw_pmd=0x%lx soft_pmd=0x%lx\n", 
-			  i, ia64_get_pmd(i), ctx->ctx_soft_pmds[i].val));
+		DPRINT_ovfl(("pmd[%d] overflowed hw_pmd=0x%lx ctx_pmd=0x%lx\n",
+					i, ia64_get_pmd(i), ctx->ctx_pmds[i].val));
 
 		/*
 		 * Note that the pmd is not necessarily 0 at this point as qualified events
@@ -2993,250 +5204,350 @@
 		 * taken into consideration here but will be with any read of the pmd via
 		 * pfm_read_pmds().
 		 */
-		old_val = ctx->ctx_soft_pmds[i].val;
-		ctx->ctx_soft_pmds[i].val += 1 + pmu_conf.ovfl_val;
+		old_val               = ctx->ctx_pmds[i].val;
+		ctx->ctx_pmds[i].val += 1 + pmu_conf.ovfl_val;
 
 		/*
 		 * check for overflow condition
 		 */
-		if (old_val > ctx->ctx_soft_pmds[i].val) {
+		if (likely(old_val > ctx->ctx_pmds[i].val)) {
 
 			ovfl_pmds |= 1UL << i;
 
-			if (PMC_OVFL_NOTIFY(ctx, i)) {
-				ovfl_notify |= 1UL << i;
+			/*
+			 * keep track of pmds of interest for samples
+			 */
+			if (has_smpl) {
+				if (first_pmd == ~0U) first_pmd = i;
+				smpl_pmds |= ctx->ctx_pmds[i].smpl_pmds[0];
 			}
+
+			if (PMC_OVFL_NOTIFY(ctx, i)) ovfl_notify |= 1UL << i;
 		}
-		DBprintk_ovfl(("soft_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx ovfl_pmds=0x%lx ovfl_notify=0x%lx\n", 
-			  i, ctx->ctx_soft_pmds[i].val, old_val, 
-			  ia64_get_pmd(i) & pmu_conf.ovfl_val, ovfl_pmds, ovfl_notify));
+
+		DPRINT_ovfl(("ctx_pmd[%d].val=0x%lx old_val=0x%lx pmd=0x%lx ovfl_pmds=0x%lx ovfl_notify=0x%lx first_pmd=%u smpl_pmds=0x%lx\n",
+					i, ctx->ctx_pmds[i].val, old_val,
+					ia64_get_pmd(i) & pmu_conf.ovfl_val, ovfl_pmds, ovfl_notify, first_pmd, smpl_pmds));
 	}
 
+	ovfl_ctrl.notify_user     = ovfl_notify ? 1 : 0;
+	ovfl_ctrl.reset_pmds      = ovfl_pmds && ovfl_notify == 0UL ? 1 : 0;
+	ovfl_ctrl.block           = ovfl_notify ? 1 : 0;
+	ovfl_ctrl.stop_monitoring = ovfl_notify ? 1 : 0;
+
 	/*
-	 * check for sampling buffer
-	 *
-	 * if present, record sample only when a 64-bit counter has overflowed.
-	 * We propagate notification ONLY when buffer becomes full.
+	 * when a overflow is detected, check for sampling buffer, if present, invoke
+	 * record() callback.
 	 */
-	if(CTX_HAS_SMPL(ctx) && ovfl_pmds) {
-		ret = pfm_record_sample(task, ctx, ovfl_pmds, regs);
-		if (ret == 1) {
-			/*
-			 * Sampling buffer became full
-			 * If no notication was requested, then we reset buffer index
-			 * and reset registers (done below) and resume.
-			 * If notification requested, then defer reset until pfm_restart()
-			 */
-			if (ovfl_notify == 0UL) {
-				ctx->ctx_psb->psb_hdr->hdr_count = 0UL;
-				ctx->ctx_psb->psb_index		 = 0UL;
+	if (ovfl_pmds && has_smpl) {
+		unsigned long start_cycles;
+		int this_cpu = smp_processor_id();
+
+		ovfl_arg.ovfl_pmds[0]   = ovfl_pmds;
+		ovfl_arg.ovfl_notify[0] = ovfl_notify;
+		ovfl_arg.ovfl_ctrl      = ovfl_ctrl;
+		ovfl_arg.smpl_pmds[0]   = smpl_pmds;
+
+		prefetch(ctx->ctx_smpl_hdr);
+
+		ovfl_arg.pmd_value      = ctx->ctx_pmds[first_pmd].val;
+		ovfl_arg.pmd_last_reset = ctx->ctx_pmds[first_pmd].lval;
+		ovfl_arg.pmd_eventid    = ctx->ctx_pmds[first_pmd].eventid;
+
+		/*
+		 * copy values of pmds of interest. Sampling format may copy them
+		 * into sampling buffer.
+		 */
+		if (smpl_pmds) {
+			for(i=0, j=0; smpl_pmds; i++, smpl_pmds >>=1) {
+				if ((smpl_pmds & 0x1) == 0) continue;
+				ovfl_arg.smpl_pmds_values[j++] = PMD_IS_COUNTING(i) ?  pfm_read_soft_counter(ctx, i) : ia64_get_pmd(i);
 			}
-		} else {
-			/*
-			 * sample recorded in buffer, no need to notify user
-			 */
-			ovfl_notify = 0UL;
 		}
-	}
 
-	/*
-	 * No overflow requiring a user level notification
-	 */
-	if (ovfl_notify == 0UL) {
-		if (ovfl_pmds) 
-			pfm_reset_regs(ctx, &ovfl_pmds, PFM_PMD_SHORT_RESET);
-		preempt_enable_no_resched();
-		return 0x0UL;
-	}
+		pfm_stats[this_cpu].pfm_smpl_handler_calls++;
+		start_cycles = ia64_get_itc();
 
-	/* 
-	 * keep track of what to reset when unblocking 
-	 */
-	ctx->ctx_ovfl_regs[0]  = ovfl_pmds; 
+		/*
+		 * call custom buffer format record (handler) routine
+		 */
+		(*ctx->ctx_buf_fmt->fmt_handler)(task, ctx->ctx_smpl_hdr, &ovfl_arg, regs);
 
-	DBprintk_ovfl(("block=%d notify [%d] current [%d]\n", 
-		ctx->ctx_fl_block,
-		ctx->ctx_notify_task ? ctx->ctx_notify_task->pid: -1, 
-		current->pid ));
+		pfm_stats[this_cpu].pfm_smpl_handler_cycles += ia64_get_itc() - start_cycles;
 
-	/* 
-	 * ctx_notify_task could already be NULL, checked in pfm_notify_user() 
-	 */
-	if (CTX_OVFL_NOBLOCK(ctx) == 0 && ctx->ctx_notify_task != task) {
-		ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_BLOCKSIG;
-	} else {
-		ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_SIG;
+		ovfl_pmds   = ovfl_arg.ovfl_pmds[0];
+		ovfl_notify = ovfl_arg.ovfl_notify[0];
+		ovfl_ctrl   = ovfl_arg.ovfl_ctrl;
+	}
+
+	if (ovfl_pmds && ovfl_ctrl.reset_pmds) {
+		pfm_reset_regs(ctx, &ovfl_pmds, ovfl_ctrl.reset_pmds);
 	}
-	/*
-	 * we cannot block in system wide mode and we do not go
-	 * through the PMU ctxsw code. Therefore we can generate
-	 * the notification here. In system wide mode, the current
-	 * task maybe different from the task controlling the session
-	 * on this CPU, therefore owner can be different from current.
-	 *
-	 * In per-process mode, this function gets called from 
-	 * the interrupt handler or pfm_load_regs(). The mode argument
-	 * tells where we are coming from. When coming from the interrupt
-	 * handler, it is safe to notify (send signal) right here because
-	 * we do not hold any runqueue locks needed by send_sig_info(). 
-	 *
-	 * However when coming from ctxsw, we cannot send the signal here.
-	 * It must be deferred until we are sure we do not hold any runqueue
-	 * related locks. The current task maybe different from the owner
-	 * only in UP mode. The deferral is implemented using the 
-	 * TIF_NOTIFY_RESUME mechanism. In this case, the pending work
-	 * is checked when the task is about to leave the kernel (see
-	 * entry.S). As of this version of perfmon, a kernel only
-	 * task cannot be monitored in per-process mode. Therefore,
-	 * when this function gets called from pfm_load_regs(), we know
-	 * we have a user level task which will eventually either exit
-	 * or leave the kernel, and thereby go through the checkpoint
-	 * for TIF_*.
-	 */
-	if (ctx->ctx_fl_system || mode == 0) {
-		pfm_notify_user(ctx);
-		ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_NONE;
-	} else {
-		struct thread_info *info;
 
+	if (ovfl_notify && ovfl_ctrl.notify_user) {
 		/*
-		 * given that TIF_NOTIFY_RESUME is not specific to
-		 * perfmon, we need to have a second level check to
-		 * verify the source of the notification.
+		 * keep track of what to reset when unblocking
 		 */
-		task->thread.pfm_ovfl_block_reset = 1;
+		ctx->ctx_ovfl_regs[0] = ovfl_pmds;
+
+		if (CTX_OVFL_NOBLOCK(ctx) == 0 && ovfl_ctrl.block) {
+
+			ctx->ctx_fl_trap_reason = PFM_TRAP_REASON_BLOCK;
+
+			/*
+			 * set the perfmon specific checking pending work
+			 */
+			PFM_SET_WORK_PENDING(task, 1);
+
+			/*
+			 * when coming from ctxsw, current still points to the
+			 * previous task, therefore we must work with task and not current.
+			 */
+			pfm_set_task_notify(task);
+		}
 		/*
-		 * when coming from ctxsw, current still points to the
-		 * previous task, therefore we must work with task and not current.
+		 * defer until state is changed (shorten spin window). the context is locked
+		 * anyway, so the signal receiver would come spin for nothing.
 		 */
-		info = ((struct thread_info *) ((char *) task + IA64_TASK_SIZE));
-		set_bit(TIF_NOTIFY_RESUME, &info->flags);
+		must_notify = 1;
 	}
 
+	DPRINT_ovfl(("current [%d] owner [%d] pending=%ld reason=%u ovfl_pmds=0x%lx ovfl_notify=0x%lx stopped=%d\n",
+			current->pid,
+			GET_PMU_OWNER() ? GET_PMU_OWNER()->pid : -1,
+			PFM_GET_WORK_PENDING(task),
+			ctx->ctx_fl_trap_reason,
+			ovfl_pmds,
+			ovfl_notify,
+			ovfl_ctrl.stop_monitoring ? 1 : 0));
+	/*
+	 * in case monitoring must be stopped, we toggle the psr bits
+	 */
+	if (ovfl_ctrl.stop_monitoring) {
+		pfm_mask_monitoring(task);
+		CTX_MASKED(ctx);
+	}
 	/*
-	 * keep the PMU frozen until either pfm_restart() or 
-	 * task completes (non-blocking or notify_task gone).
+	 * send notification now
 	 */
-	ctx->ctx_fl_frozen = 1;
+	if (must_notify) pfm_ovfl_notify_user(ctx, ovfl_notify);
 
-	DBprintk_ovfl(("current [%d] owner [%d] mode=%d return pmc0=0x%x must_block=%ld reason=%d\n",
-		current->pid, 
-		PMU_OWNER() ? PMU_OWNER()->pid : -1,
-		mode,
-		ctx->ctx_fl_frozen ? 0x1 : 0x0, 
-		t->pfm_ovfl_block_reset,
-		ctx->ctx_fl_trap_reason));
+	return;
 
-	preempt_enable_no_resched();
-	return 0x1UL;
+
+sanity_check:
+	printk(KERN_ERR "perfmon: CPU%d overflow handler [%d] pmc0=0x%lx\n",
+			smp_processor_id(),
+			task ? task->pid : -1,
+			pmc0);
+	return;
+
+stop_monitoring:
+	/*
+	 * in SMP, zombie context is never restored but reclaimed in pfm_load_regs().
+	 * Moreover, zombies are also reclaimed in pfm_save_regs(). Therefore we can
+	 * come here as zombie only if the task is the current task. In which case, we
+	 * can access the PMU  hardware directly.
+	 *
+	 * Note that zombies do have PM_VALID set. So here we do the minimal.
+	 *
+	 * In case the context was zombified it could not be reclaimed at the time
+	 * the monitoring program exited. At this point, the PMU reservation has been
+	 * returned, the sampiing buffer has been freed. We must convert this call
+	 * into a spurious interrupt. However, we must also avoid infinite overflows
+	 * by stopping monitoring for this task. We can only come here for a per-task
+	 * context. All we need to do is to stop monitoring using the psr bits which
+	 * are always task private. By re-enabling secure montioring, we ensure that
+	 * the monitored task will not be able to re-activate monitoring.
+	 * The task will eventually be context switched out, at which point the context
+	 * will be reclaimed (that includes releasing ownership of the PMU).
+	 *
+	 * So there might be a window of time where the number of per-task session is zero
+	 * yet one PMU might have a owner and get at most one overflow interrupt for a zombie
+	 * context. This is safe because if a per-task session comes in, it will push this one
+	 * out and by the virtue on pfm_save_regs(), this one will disappear. If a system wide
+	 * session is force on that CPU, given that we use task pinning, pfm_save_regs() will
+	 * also push our zombie context out.
+	 *
+	 * Overall pretty hairy stuff....
+	 */
+	DPRINT(("ctx is zombie for [%d], converted to spurious\n", task ? task->pid: -1));
+	pfm_clear_psr_up();
+	ia64_psr(regs)->up = 0;
+	ia64_psr(regs)->sp = 1;
+	return;
 }
 
-static irqreturn_t
-pfm_interrupt_handler(int irq, void *arg, struct pt_regs *regs)
+static int
+pfm_do_interrupt_handler(int irq, void *arg, struct pt_regs *regs)
 {
-	u64 pmc0;
 	struct task_struct *task;
 	pfm_context_t *ctx;
+	unsigned long flags;
+	u64 pmc0;
+	int this_cpu = smp_processor_id();
+	int retval = 0;
 
-	pfm_stats[get_cpu()].pfm_ovfl_intr_count++;
+	pfm_stats[this_cpu].pfm_ovfl_intr_count++;
 
 	/*
-	 * if an alternate handler is registered, just bypass the default one
-	 */
-	if (pfm_alternate_intr_handler) {
-		(*pfm_alternate_intr_handler->handler)(irq, arg, regs);
-		put_cpu();
-		return IRQ_HANDLED;
-	}
-
-	/* 
 	 * srlz.d done before arriving here
-	 *
-	 * This is slow
 	 */
-	pmc0 = ia64_get_pmc(0); 
+	pmc0 = ia64_get_pmc(0);
+
+	task = GET_PMU_OWNER();
+	ctx  = GET_PMU_CTX();
 
 	/*
 	 * if we have some pending bits set
-	 * assumes : if any PM[0].bit[63-1] is set, then PMC[0].fr = 1
+	 * assumes : if any PMC0.bit[63-1] is set, then PMC0.fr = 1
 	 */
-	if ((pmc0 & ~0x1UL)!=0UL && (task=PMU_OWNER())!= NULL) {
-		/* 
+	if (PMC0_HAS_OVFL(pmc0) && task) {
+		/*
 		 * we assume that pmc0.fr is always set here
 		 */
-		ctx = task->thread.pfm_context;
 
 		/* sanity check */
-		if (!ctx) {
-			printk(KERN_DEBUG "perfmon: Spurious overflow interrupt: process %d has "
-			       "no PFM context\n", task->pid);
-			put_cpu();
-			return IRQ_HANDLED;
-		}
+		if (!ctx) goto report_spurious;
 
-		/* 
-		 * assume PMC[0].fr = 1 at this point 
-		 */
-		pmc0 = pfm_overflow_handler(0, task, ctx, pmc0, regs);
-		/*
-		 * we can only update pmc0 when the overflow
-		 * is for the current context or we are in system
-		 * wide mode. In UP (per-task) the current
-		 * task may not be the one owning the PMU,
-		 * same thing for system-wide.
-		 */
-		if (task == current || ctx->ctx_fl_system) {
-			/*
-		 	 * We always clear the overflow status bits and either unfreeze
-		 	 * or keep the PMU frozen.
-		 	 */
-			ia64_set_pmc(0, pmc0);
-			ia64_srlz_d();
-		} else {
-			task->thread.pmc[0] = pmc0;
+		if (ctx->ctx_fl_system == 0 && (task->thread.flags & IA64_THREAD_PM_VALID) == 0) {
+			printk("perfmon: current [%d] owner = [%d] PMVALID=0 state=%d\n", current->pid, task->pid, ctx->ctx_state);
+			goto report_spurious;
 		}
+
+		PROTECT_CTX_NOPRINT(ctx, flags);
+
+		pfm_overflow_handler(task, ctx, pmc0, regs);
+
+		UNPROTECT_CTX_NOPRINT(ctx, flags);
+
 	} else {
-		pfm_stats[smp_processor_id()].pfm_spurious_ovfl_intr_count++;
+		pfm_stats[this_cpu].pfm_spurious_ovfl_intr_count++;
+		retval = -1;
+	}
+	/*
+	 * keep it unfrozen at all times
+	 */
+	pfm_unfreeze_pmu();
+
+	return retval;
+
+report_spurious:
+	printk(KERN_INFO "perfmon: spurious overflow interrupt on CPU%d: process %d has no PFM context\n",
+		this_cpu, task->pid);
+	pfm_unfreeze_pmu();
+	return -1;
+}
+
+static pfm_irq_handler_t
+pfm_interrupt_handler(int irq, void *arg, struct pt_regs *regs)
+{
+	unsigned long m;
+	unsigned long min, max;
+	int this_cpu;
+	int ret;
+
+	this_cpu = smp_processor_id();
+	min      = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min;
+	max      = pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max;
+
+	m = ia64_get_itc();
+
+	ret = pfm_do_interrupt_handler(irq, arg, regs);
+
+	m = ia64_get_itc() - m;
+
+	/*
+	 * don't measure spurious interrupts
+	 */
+	if (ret == 0) {
+		if (m < min) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_min = m;
+		if (m > max) pfm_stats[this_cpu].pfm_ovfl_intr_cycles_max = m;
+		pfm_stats[this_cpu].pfm_ovfl_intr_cycles += m;
 	}
-	put_cpu_no_resched();
-	return IRQ_HANDLED;
+	PFM_IRQ_HANDLER_RET();
 }
 
+
 /* for debug only */
 static int
 pfm_proc_info(char *page)
 {
 	char *p = page;
+	pfm_buffer_fmt_t *b;
+	unsigned long psr;
 	int i;
 
-	p += sprintf(p, "fastctxsw              : %s\n", pfm_sysctl.fastctxsw > 0 ? "Yes": "No");
-	p += sprintf(p, "ovfl_mask              : 0x%lx\n", pmu_conf.ovfl_val);
+		p += sprintf(p, "model                     : %s\n", pmu_conf.pmu_name);
+		p += sprintf(p, "fastctxsw                 : %s\n", pfm_sysctl.fastctxsw > 0 ? "Yes": "No");
+		p += sprintf(p, "ovfl_mask                 : 0x%lx\n", pmu_conf.ovfl_val);
 
 	for(i=0; i < NR_CPUS; i++) {
-		if (cpu_online(i) == 0) continue;
-		p += sprintf(p, "CPU%-2d overflow intrs   : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_count);
-		p += sprintf(p, "CPU%-2d spurious intrs   : %lu\n", i, pfm_stats[i].pfm_spurious_ovfl_intr_count);
-		p += sprintf(p, "CPU%-2d recorded samples : %lu\n", i, pfm_stats[i].pfm_recorded_samples_count);
-		p += sprintf(p, "CPU%-2d smpl buffer full : %lu\n", i, pfm_stats[i].pfm_full_smpl_buffer_count);
-		p += sprintf(p, "CPU%-2d syst_wide        : %d\n", i, per_cpu(pfm_syst_info, i) & PFM_CPUINFO_SYST_WIDE ? 1 : 0);
-		p += sprintf(p, "CPU%-2d dcr_pp           : %d\n", i, per_cpu(pfm_syst_info, i) & PFM_CPUINFO_DCR_PP ? 1 : 0);
-		p += sprintf(p, "CPU%-2d exclude idle     : %d\n", i, per_cpu(pfm_syst_info, i) & PFM_CPUINFO_EXCL_IDLE ? 1 : 0);
-		p += sprintf(p, "CPU%-2d owner            : %d\n", i, pmu_owners[i].owner ? pmu_owners[i].owner->pid: -1);
+		if (cpu_is_online(i) == 0) continue;
+		p += sprintf(p, "CPU%-2d overflow intrs      : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_count);
+		p += sprintf(p, "CPU%-2d overflow cycles     : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_cycles);
+		p += sprintf(p, "CPU%-2d overflow min        : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_cycles_min);
+		p += sprintf(p, "CPU%-2d overflow max        : %lu\n", i, pfm_stats[i].pfm_ovfl_intr_cycles_max);
+		p += sprintf(p, "CPU%-2d smpl handler calls  : %lu\n", i, pfm_stats[i].pfm_smpl_handler_calls);
+		p += sprintf(p, "CPU%-2d smpl handler cycles : %lu\n", i, pfm_stats[i].pfm_smpl_handler_cycles);
+		p += sprintf(p, "CPU%-2d spurious intrs      : %lu\n", i, pfm_stats[i].pfm_spurious_ovfl_intr_count);
+		p += sprintf(p, "CPU%-2d sysupdt count       : %lu\n", i, pfm_stats[i].pfm_sysupdt_count);
+		p += sprintf(p, "CPU%-2d sysupdt cycles      : %lu\n", i, pfm_stats[i].pfm_sysupdt_cycles);
+		p += sprintf(p, "CPU%-2d syst_wide           : %d\n" , i, pfm_get_cpu_data(pfm_syst_info, i) & PFM_CPUINFO_SYST_WIDE ? 1 : 0);
+		p += sprintf(p, "CPU%-2d dcr_pp              : %d\n" , i, pfm_get_cpu_data(pfm_syst_info, i) & PFM_CPUINFO_DCR_PP ? 1 : 0);
+		p += sprintf(p, "CPU%-2d exclude idle        : %d\n" , i, pfm_get_cpu_data(pfm_syst_info, i) & PFM_CPUINFO_EXCL_IDLE ? 1 : 0);
+		p += sprintf(p, "CPU%-2d owner               : %d\n" , i, pfm_get_cpu_data(pmu_owner, i) ? pfm_get_cpu_data(pmu_owner, i)->pid: -1);
+		p += sprintf(p, "CPU%-2d context             : %p\n" , i, pfm_get_cpu_data(pmu_ctx, i));
+		p += sprintf(p, "CPU%-2d activations         : %lu\n", i, pfm_get_cpu_data(pmu_activation_number,i));
+	}
+
+	if (hweight64(PFM_CPU_ONLINE_MAP) == 1)
+	{
+		psr = pfm_get_psr();
+		ia64_srlz_d();
+		p += sprintf(p, "CPU%-2d psr                 : 0x%lx\n", smp_processor_id(), psr);
+		p += sprintf(p, "CPU%-2d pmc0                : 0x%lx\n", smp_processor_id(), ia64_get_pmc(0));
+		for(i=4; i < 8; i++) {
+   			p += sprintf(p, "CPU%-2d pmc%u                : 0x%lx\n", smp_processor_id(), i, ia64_get_pmc(i));
+   			p += sprintf(p, "CPU%-2d pmd%u                : 0x%lx\n", smp_processor_id(), i, ia64_get_pmd(i));
+  		}
 	}
 
 	LOCK_PFS();
-
-	p += sprintf(p, "proc_sessions          : %u\n"
-			"sys_sessions           : %u\n"
-			"sys_use_dbregs         : %u\n"
-			"ptrace_use_dbregs      : %u\n", 
-			pfm_sessions.pfs_task_sessions, 
+		p += sprintf(p, "proc_sessions             : %u\n"
+			"sys_sessions              : %u\n"
+			"sys_use_dbregs            : %u\n"
+			"ptrace_use_dbregs         : %u\n",
+			pfm_sessions.pfs_task_sessions,
 			pfm_sessions.pfs_sys_sessions,
 			pfm_sessions.pfs_sys_use_dbregs,
 			pfm_sessions.pfs_ptrace_use_dbregs);
-
 	UNLOCK_PFS();
 
+	LOCK_BUF_FMT_LIST();
+
+	for (b = pfm_buffer_fmt_list; b ; b = b->fmt_next) {
+		p += sprintf(p, "format                    : %02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x-%02x %s\n",
+				b->fmt_uuid[0],
+				b->fmt_uuid[1],
+				b->fmt_uuid[2],
+				b->fmt_uuid[3],
+				b->fmt_uuid[4],
+				b->fmt_uuid[5],
+				b->fmt_uuid[6],
+				b->fmt_uuid[7],
+				b->fmt_uuid[8],
+				b->fmt_uuid[9],
+				b->fmt_uuid[10],
+				b->fmt_uuid[11],
+				b->fmt_uuid[12],
+				b->fmt_uuid[13],
+				b->fmt_uuid[14],
+				b->fmt_uuid[15],
+				b->fmt_name);
+	}
+	UNLOCK_BUF_FMT_LIST();
+
 	return p - page;
 }
 
@@ -3258,30 +5569,27 @@
 }
 
 /*
- * we come here as soon as PFM_CPUINFO_SYST_WIDE is set. This happens
+ * we come here as soon as local_cpu_data->pfm_syst_wide is set. this happens
  * during pfm_enable() hence before pfm_start(). We cannot assume monitoring
- * is active or inactive based on mode. We must rely on the value in 
- * cpu_data(i)->pfm_syst_info
+ * is active or inactive based on mode. We must rely on the value in
+ * local_cpu_data->pfm_syst_info
  */
 void
-pfm_syst_wide_update_task(struct task_struct *task, unsigned long info, int is_ctxswin)
+pfm_do_syst_wide_update_task(struct task_struct *task, unsigned long info, int is_ctxswin)
 {
 	struct pt_regs *regs;
 	unsigned long dcr;
 	unsigned long dcr_pp;
 
-	preempt_disable();
 	dcr_pp = info & PFM_CPUINFO_DCR_PP ? 1 : 0;
 
 	/*
-	 * pid 0 is guaranteed to be the idle task. There is one such task with pid 0 
+	 * pid 0 is guaranteed to be the idle task. There is one such task with pid 0
 	 * on every CPU, so we can rely on the pid to identify the idle task.
 	 */
 	if ((info & PFM_CPUINFO_EXCL_IDLE) == 0 || task->pid) {
-		regs = (struct pt_regs *)((unsigned long) task + IA64_STK_OFFSET);
-		regs--;
+		regs = ia64_task_regs(task);
 		ia64_psr(regs)->pp = is_ctxswin ? dcr_pp : 0;
-		preempt_enable();
 		return;
 	}
 	/*
@@ -3289,43 +5597,89 @@
 	 */
 	if (dcr_pp) {
 		dcr = ia64_get_dcr();
-		/* 
-		 * context switching in? 
+		/*
+		 * context switching in?
 		 */
 		if (is_ctxswin) {
 			/* mask monitoring for the idle task */
 			ia64_set_dcr(dcr & ~IA64_DCR_PP);
 			pfm_clear_psr_pp();
 			ia64_srlz_i();
-			preempt_enable();
 			return;
 		}
-		/* 
+		/*
 		 * context switching out
-		 * restore monitoring for next task 
+		 * restore monitoring for next task
 		 *
-		 * Due to inlining this odd if-then-else construction generates 
+		 * Due to inlining this odd if-then-else construction generates
 		 * better code.
 		 */
 		ia64_set_dcr(dcr |IA64_DCR_PP);
 		pfm_set_psr_pp();
 		ia64_srlz_i();
 	}
-	preempt_enable();
 }
 
 void
-pfm_save_regs (struct task_struct *task)
+pfm_syst_wide_update_task(struct task_struct *task, unsigned long info, int is_ctxswin)
+{
+	unsigned long start, end;
+	pfm_stats[smp_processor_id()].pfm_sysupdt_count++;
+	start = ia64_get_itc();
+	pfm_do_syst_wide_update_task(task, info, is_ctxswin);
+	end = ia64_get_itc();
+	pfm_stats[smp_processor_id()].pfm_sysupdt_cycles += end-start;
+}
+
+#ifdef CONFIG_SMP
+void
+pfm_save_regs(struct task_struct *task)
 {
 	pfm_context_t *ctx;
-	unsigned long mask;
+	struct thread_struct *t;
+	unsigned long flags;
 	u64 psr;
-	int i;
 
-	preempt_disable();
+	ctx = PFM_GET_CTX(task);
+	if (ctx == NULL) goto save_error;
+	t = &task->thread;
+
+	/*
+ 	 * we always come here with interrupts ALREADY disabled by
+ 	 * the scheduler. So we simply need to protect against concurrent
+	 * access, not CPU concurrency.
+	 */
+	flags = pfm_protect_ctx_ctxsw(ctx);
+
+	if (CTX_IS_ZOMBIE(ctx)) {
+		struct pt_regs *regs = ia64_task_regs(task);
+
+		pfm_clear_psr_up();
+
+		DPRINT(("ctx zombie, forcing cleanup for [%d]\n", task->pid));
+
+		pfm_force_cleanup(ctx, regs);
+
+		BUG_ON(ctx->ctx_smpl_hdr);
 
-	ctx = task->thread.pfm_context;
+		pfm_unprotect_ctx_ctxsw(ctx, flags);
 
+		pfm_context_free(ctx);
+		return;
+	}
+
+	/*
+	 * sanity check
+	 */
+	if (ctx->ctx_last_activation != GET_ACTIVATION()) {
+		DPRINT(("ctx_activation=%lu activation=%lu state=%d: no save\n",
+				ctx->ctx_last_activation,
+				GET_ACTIVATION(), ctx->ctx_state));
+
+		pfm_unprotect_ctx_ctxsw(ctx, flags);
+
+		return;
+	}
 
 	/*
 	 * save current PSR: needed because we modify it
@@ -3334,1018 +5688,623 @@
 
 	/*
 	 * stop monitoring:
-	 * This is the last instruction which can generate an overflow
+	 * This is the last instruction which may generate an overflow
 	 *
 	 * We do not need to set psr.sp because, it is irrelevant in kernel.
 	 * It will be restored from ipsr when going back to user level
 	 */
 	pfm_clear_psr_up();
-	ia64_srlz_i();
 
+	/*
+	 * keep a copy of the saved psr (for reload)
+	 */
 	ctx->ctx_saved_psr = psr;
 
-#ifdef CONFIG_SMP
 	/*
-	 * We do not use a lazy scheme in SMP because
-	 * of the new scheduler which masks interrupts
-	 * during low-level context switch. So we save
-	 * all the PMD register we use and restore on
-	 * ctxsw in.
-	 *
 	 * release ownership of this PMU.
-	 * must be done before we save the registers.
+	 * PM interrupts are masked, so nothing
+	 * can happen.
 	 */
-	SET_PMU_OWNER(NULL);
+	SET_PMU_OWNER(NULL, NULL);
 
 	/*
-	 * save PMDs
-	 */
-	ia64_srlz_d();
-
-	mask = ctx->ctx_used_pmds[0];
-	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) task->thread.pmd[i] =ia64_get_pmd(i);
-	}
-
-	/* 
-	 * save pmc0 
+	 * we systematically save the PMD as we have no
+	 * guarantee we will be schedule at that same
+	 * CPU again.
 	 */
-	task->thread.pmc[0] = ia64_get_pmc(0);
+	pfm_save_pmds(t->pmds, ctx->ctx_used_pmds[0]);
 
-	/* 
-	 * force a full reload 
+	/*
+	 * save pmc0 ia64_srlz_d() done in pfm_save_pmds()
+	 * we will need it on the restore path to check
+	 * for pending overflow.
 	 */
-	atomic_set(&ctx->ctx_last_cpu, -1);
-#endif
-	preempt_enable();
-}
-
-static void
-pfm_lazy_save_regs (struct task_struct *task)
-{
-	pfm_context_t *ctx;
-	struct thread_struct *t;
-	unsigned long mask;
-	int i;
-
-	preempt_disable();
-	DBprintk(("on [%d] by [%d]\n", task->pid, current->pid));
-
-	t   = &task->thread;
-	ctx = task->thread.pfm_context;
+	t->pmcs[0] = ia64_get_pmc(0);
 
 	/*
-	 * do not own the PMU
+	 * unfreeze PMU if had pending overflows
 	 */
-	SET_PMU_OWNER(NULL);
-
-	ia64_srlz_d();
+	if (t->pmcs[0] & ~1UL) pfm_unfreeze_pmu();
 
 	/*
-	 * XXX needs further optimization.
-	 * Also must take holes into account
+	 * finally, unmask interrupts and allow context
+	 * access.
+	 * Any pended overflow interrupt may be delivered
+	 * here and will be treated as spurious because we
+	 * have have no PMU owner anymore.
 	 */
-	mask = ctx->ctx_used_pmds[0];
-	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) t->pmd[i] =ia64_get_pmd(i);
-	}
+	pfm_unprotect_ctx_ctxsw(ctx, flags);
 
-	/* save pmc0 */
-	t->pmc[0] = ia64_get_pmc(0);
+	return;
 
-	/* not owned by this CPU */
-	atomic_set(&ctx->ctx_last_cpu, -1);
-	preempt_enable();
+save_error:
+	printk(KERN_ERR "perfmon: pfm_save_regs CPU%d [%d] NULL context PM_VALID=%ld\n",
+		smp_processor_id(), task->pid,
+		task->thread.flags & IA64_THREAD_PM_VALID);
 }
 
+#else /* !CONFIG_SMP */
+
+/*
+ * in 2.5, interrupts are masked when we come here
+ */
 void
-pfm_load_regs (struct task_struct *task)
+pfm_save_regs(struct task_struct *task)
 {
-	struct thread_struct *t;
 	pfm_context_t *ctx;
-	struct task_struct *owner;
-	unsigned long mask;
 	u64 psr;
-	int i;
-
-	preempt_disable();
-
-	owner = PMU_OWNER();
-	ctx   = task->thread.pfm_context;
-	t     = &task->thread;
-
-	if (ctx == NULL) {
-		preempt_enable();
-		printk("perfmon: pfm_load_regs: null ctx for [%d]\n", task->pid);
-		return;
-	}
 
-	/*
-	 * we restore ALL the debug registers to avoid picking up 
-	 * stale state.
-	 *
-	 * This must be done even when the task is still the owner
-	 * as the registers may have been modified via ptrace()
-	 * (not perfmon) by the previous task. 
-	 *
-	 * XXX: dealing with this in a lazy fashion requires modifications
-	 * to the way the the debug registers are managed. This is will done
-	 * in the next version of perfmon.
-	 */
-	if (ctx->ctx_fl_using_dbreg) {
-		for (i=0; i < (int) pmu_conf.num_ibrs; i++) {
-			ia64_set_ibr(i, t->ibr[i]);
-		}
-		ia64_srlz_i();
-		for (i=0; i < (int) pmu_conf.num_dbrs; i++) {
-			ia64_set_dbr(i, t->dbr[i]);
-		}
-		ia64_srlz_d();
-	}
+	ctx = PFM_GET_CTX(task);
+	if (ctx == NULL) goto save_error;
 
 	/*
-	 * if we were the last user, then nothing to do except restore psr
-	 * this path cannot be used in SMP
+	 * save current PSR: needed because we modify it
 	 */
-	if (owner == task) {
-		if ((unsigned int) atomic_read(&ctx->ctx_last_cpu) != smp_processor_id())
-			DBprintk(("invalid last_cpu=%d for [%d]\n", 
-				atomic_read(&ctx->ctx_last_cpu), task->pid));
-
-		psr = ctx->ctx_saved_psr;
-		pfm_set_psr_l(psr);
-		preempt_enable();
-		return;
-	}
+	psr = pfm_get_psr();
 
 	/*
-	 * someone else is still using the PMU, first push it out and
-	 * then we'll be able to install our stuff !
+	 * stop monitoring:
+	 * This is the last instruction which may generate an overflow
 	 *
-	 * not possible in SMP
+	 * We do not need to set psr.sp because, it is irrelevant in kernel.
+	 * It will be restored from ipsr when going back to user level
 	 */
-	if (owner) pfm_lazy_save_regs(owner);
+	pfm_clear_psr_up();
 
 	/*
-	 * To avoid leaking information to the user level when psr.sp=0,
-	 * we must reload ALL implemented pmds (even the ones we don't use).
-	 * In the kernel we only allow PFM_READ_PMDS on registers which
-	 * we initialized or requested (sampling) so there is no risk there.
-	 *
-	 * As an optimization, we will only reload the PMD that we use when 
-	 * the context is in protected mode, i.e. psr.sp=1 because then there
-	 * is no leak possible.
+	 * keep a copy of the saved psr (for reload)
 	 */
-	mask = pfm_sysctl.fastctxsw || ctx->ctx_fl_protected ?  ctx->ctx_used_pmds[0] : ctx->ctx_reload_pmds[0];
-	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) ia64_set_pmd(i, t->pmd[i] & pmu_conf.ovfl_val);
-	}
+	ctx->ctx_saved_psr = psr;
 
-	/* 
-	 * PMC0 is never set in the mask because it is always restored
-	 * separately.  
-	 *
-	 * ALL PMCs are systematically reloaded, unused registers
-	 * get their default (PAL reset) values to avoid picking up 
-	 * stale configuration.
-	 */	
-	mask = ctx->ctx_reload_pmcs[0];
-	for (i=0; mask; i++, mask>>=1) {
-		if (mask & 0x1) ia64_set_pmc(i, t->pmc[i]);
+	psr = pfm_get_psr();
+	if (psr & IA64_PSR_UP) {
+		printk(KERN_ERR " perfmon: pfm_save_regs: psr.up set current [%d] owner [%d] psr=0x%lx\n", current->pid, GET_PMU_OWNER()->pid, psr);
 	}
-
-	/*
-	 * manually invoke core interrupt handler
-	 * if the task had a pending overflow when it was ctxsw out.
-	 * Side effect on ctx_fl_frozen is possible.
-	 */
-	if (t->pmc[0] & ~0x1) {
-		t->pmc[0] = pfm_overflow_handler(1, task, ctx, t->pmc[0], NULL);
+	if (psr & IA64_PSR_I) {
+		printk(KERN_ERR " perfmon: pfm_save_regs: psr.i set current [%d] owner [%d] psr=0x%lx\n", current->pid, GET_PMU_OWNER()->pid, psr);
 	}
 
-	/*
-	 * unfreeze PMU if possible
-	 */
-	if (ctx->ctx_fl_frozen == 0) pfm_unfreeze_pmu();
-
-	atomic_set(&ctx->ctx_last_cpu, smp_processor_id());
-
-	SET_PMU_OWNER(task);
-
-	/*
-	 * restore the psr we changed in pfm_save_regs()
-	 */
-	psr = ctx->ctx_saved_psr;
-	preempt_enable();
-	pfm_set_psr_l(psr);
+	return;
+save_error:
+	printk(KERN_ERR "perfmon: pfm_save_regs CPU%d [%d] NULL context PM_VALID=%ld\n",
+		smp_processor_id(), task->pid,
+		task->thread.flags & IA64_THREAD_PM_VALID);
 }
 
-/*
- * XXX: make this routine able to work with non current context
- */
 static void
-pfm_reset_pmu(struct task_struct *task)
+pfm_lazy_save_regs (struct task_struct *task)
 {
-	struct thread_struct *t = &task->thread;
-	pfm_context_t *ctx = t->pfm_context;
-	int i;
+	pfm_context_t *ctx;
+	struct thread_struct *t;
+	unsigned long flags;
+	unsigned long psr;
 
-	if (task != current) {
-		printk("perfmon: invalid task in pfm_reset_pmu()\n");
-		return;
+#if 1
+	psr = pfm_get_psr();
+	if (psr & IA64_PSR_UP) {
+		printk(KERN_ERR " perfmon: pfm_lazy_save_regs: psr.up set current [%d] owner [%d] psr=0x%lx\n", current->pid, task->pid, psr);
+		pfm_clear_psr_up();
 	}
-	preempt_disable();
+#endif
 
-	/* Let's make sure the PMU is frozen */
-	pfm_freeze_pmu();
+	ctx = PFM_GET_CTX(task);
+	t   = &task->thread;
 
-	/*
-	 * install reset values for PMC. We skip PMC0 (done above)
-	 * XX: good up to 64 PMCS
-	 */
-	for (i=1; (pmu_conf.pmc_desc[i].type & PFM_REG_END) == 0; i++) {
-		if ((pmu_conf.pmc_desc[i].type & PFM_REG_IMPL) == 0) continue;
-		ia64_set_pmc(i, PMC_DFL_VAL(i));
-		/*
-		 * When restoring context, we must restore ALL pmcs, even the ones 
-		 * that the task does not use to avoid leaks and possibly corruption
-		 * of the sesion because of configuration conflicts. So here, we 
-		 * initialize the entire set used in the context switch restore routine.
-	 	 */
-		t->pmc[i] = PMC_DFL_VAL(i);
-		DBprintk(("pmc[%d]=0x%lx\n", i, t->pmc[i]));
-	}
+	DPRINT(("on [%d] used_pmds=0x%lx\n", task->pid, ctx->ctx_used_pmds[0]));
 
 	/*
-	 * clear reset values for PMD. 
-	 * XXX: good up to 64 PMDS.
+	 * we need to mask PMU overflow here to
+	 * make sure that we maintain pmc0 until
+	 * we save it. overflow interrupts are
+	 * treated as spurious if there is no
+	 * owner.
+	 *
+	 * XXX: I don't think this is necessary
 	 */
-	for (i=0; (pmu_conf.pmd_desc[i].type & PFM_REG_END) == 0; i++) {
-		if ((pmu_conf.pmd_desc[i].type & PFM_REG_IMPL) == 0) continue;
-		ia64_set_pmd(i, 0UL);
-		t->pmd[i] = 0UL;
-	}
+	PROTECT_CTX(ctx,flags);
 
 	/*
-	 * On context switched restore, we must restore ALL pmc and ALL pmd even
-	 * when they are not actively used by the task. In UP, the incoming process 
-	 * may otherwise pick up left over PMC, PMD state from the previous process.
-	 * As opposed to PMD, stale PMC can cause harm to the incoming
-	 * process because they may change what is being measured. 
-	 * Therefore, we must systematically reinstall the entire
-	 * PMC state. In SMP, the same thing is possible on the 
-	 * same CPU but also on between 2 CPUs. 
-	 *
-	 * The problem with PMD is information leaking especially
-	 * to user level when psr.sp=0
+	 * release ownership of this PMU.
+	 * must be done before we save the registers.
 	 *
-	 * There is unfortunately no easy way to avoid this problem
-	 * on either UP or SMP. This definitively slows down the
-	 * pfm_load_regs() function. 
+	 * after this call any PMU interrupt is treated
+	 * as spurious.
 	 */
-	
-	 /*
-	  * We must include all the PMC in this mask to make sure we don't
-	  * see any side effect of a stale state, such as opcode matching
-	  * or range restrictions, for instance.
-	  *
-	  * We never directly restore PMC0 so we do not include it in the mask.
-	  */
-	ctx->ctx_reload_pmcs[0] = pmu_conf.impl_pmcs[0] & ~0x1;
+	SET_PMU_OWNER(NULL, NULL);
+
 	/*
-	 * We must include all the PMD in this mask to avoid picking
-	 * up stale value and leak information, especially directly
-	 * at the user level when psr.sp=0
+	 * save all the pmds we use
 	 */
-	ctx->ctx_reload_pmds[0] = pmu_conf.impl_pmds[0];
+	pfm_save_pmds(t->pmds, ctx->ctx_used_pmds[0]);
 
-	/* 
-	 * Keep track of the pmds we want to sample
-	 * XXX: may be we don't need to save/restore the DEAR/IEAR pmds
-	 * but we do need the BTB for sure. This is because of a hardware
-	 * buffer of 1 only for non-BTB pmds.
-	 *
-	 * We ignore the unimplemented pmds specified by the user
+	/*
+	 * save pmc0 ia64_srlz_d() done in pfm_save_pmds()
+	 * it is needed to check for pended overflow
+	 * on the restore path
 	 */
-	ctx->ctx_used_pmds[0] = ctx->ctx_smpl_regs[0];
-	ctx->ctx_used_pmcs[0] = 1; /* always save/restore PMC[0] */
+	t->pmcs[0] = ia64_get_pmc(0);
 
 	/*
-	 * useful in case of re-enable after disable
+	 * unfreeze PMU if had pending overflows
 	 */
-	ctx->ctx_used_ibrs[0] = 0UL;
-	ctx->ctx_used_dbrs[0] = 0UL;
+	if (t->pmcs[0] & ~1UL) pfm_unfreeze_pmu();
 
-	ia64_srlz_d();
-	preempt_enable();
+	/*
+	 * now get can unmask PMU interrupts, they will
+	 * be treated as purely spurious and we will not
+	 * lose any information
+	 */
+	UNPROTECT_CTX(ctx,flags);
 }
+#endif /* CONFIG_SMP */
 
-/*
- * This function is called when a thread exits (from exit_thread()).
- * This is a simplified pfm_save_regs() that simply flushes the current
- * register state into the save area taking into account any pending
- * overflow. This time no notification is sent because the task is dying
- * anyway. The inline processing of overflows avoids loosing some counts.
- * The PMU is frozen on exit from this call and is to never be reenabled
- * again for this task.
- *
- */
+#ifdef CONFIG_SMP
 void
-pfm_flush_regs (struct task_struct *task)
+pfm_load_regs (struct task_struct *task)
 {
 	pfm_context_t *ctx;
-	u64 pmc0;
-	unsigned long mask2, val;
-	int i;
+	struct thread_struct *t;
+	struct task_struct *owner;
+	unsigned long pmc_mask = 0UL, pmd_mask = 0UL;
+	unsigned long flags;
+	u64 psr;
 
-	ctx = task->thread.pfm_context;
+	ctx = PFM_GET_CTX(task);
+	if (unlikely(ctx == NULL)) {
+		printk(KERN_ERR "perfmon: pfm_load_regs() null context\n");
+		return;
+	}
 
-	if (ctx == NULL) return;
+	owner = GET_PMU_OWNER();
+	t     = &task->thread;
+
+#if 1
+	psr = pfm_get_psr();
+	BUG_ON(psr & IA64_PSR_UP);
+	psr = pfm_get_psr();
+	BUG_ON(psr & IA64_PSR_I);
+#endif
 
-	/* 
-	 * that's it if context already disabled
-	 */
-	if (ctx->ctx_flags.state == PFM_CTX_DISABLED) return;
 
-	preempt_disable();
 	/*
-	 * stop monitoring:
-	 * This is the only way to stop monitoring without destroying overflow
-	 * information in PMC[0].
-	 * This is the last instruction which can cause overflow when monitoring
-	 * in kernel.
-	 * By now, we could still have an overflow interrupt in-flight.
+	 * possible on unload
 	 */
-	if (ctx->ctx_fl_system) {
+	if (unlikely((t->flags & IA64_THREAD_PM_VALID) == 0)) {
+		DPRINT(("[%d] PM_VALID=0, nothing to do\n", task->pid));
+		return;
+	}
 
+	/*
+ 	 * we always come here with interrupts ALREADY disabled by
+ 	 * the scheduler. So we simply need to protect against concurrent
+	 * access, not CPU concurrency.
+	 */
+	flags = pfm_protect_ctx_ctxsw(ctx);
 
-		/* disable dcr pp */
-		ia64_set_dcr(ia64_get_dcr() & ~IA64_DCR_PP);
+	if (unlikely(CTX_IS_ZOMBIE(ctx))) {
+		struct pt_regs *regs = ia64_task_regs(task);
 
-		/* stop monitoring */
-		pfm_clear_psr_pp();
+		BUG_ON(ctx->ctx_smpl_hdr);
 
-		ia64_srlz_i();
+		DPRINT(("ctx zombie, forcing cleanup for [%d]\n", task->pid));
 
-		PFM_CPUINFO_CLEAR(PFM_CPUINFO_SYST_WIDE);
-		PFM_CPUINFO_CLEAR(PFM_CPUINFO_DCR_PP);
-		PFM_CPUINFO_CLEAR(PFM_CPUINFO_EXCL_IDLE);
-	} else  {
+		pfm_force_cleanup(ctx, regs);
 
-		/* stop monitoring */
-		pfm_clear_psr_up();
+		pfm_unprotect_ctx_ctxsw(ctx, flags);
 
-		ia64_srlz_i();
+		/*
+		 * this one (kmalloc'ed) is fine with interrupts disabled
+		 */
+		pfm_context_free(ctx);
 
-		/* no more save/restore on ctxsw */
-		current->thread.flags &= ~IA64_THREAD_PM_VALID;
+		return;
 	}
 
 	/*
-	 * Mark the PMU as not owned
-	 * This will cause the interrupt handler to do nothing in case an overflow
-	 * interrupt was in-flight
-	 * This also guarantees that pmc0 will contain the final state
-	 * It virtually gives us full control on overflow processing from that point
-	 * on.
-	 * It must be an atomic operation.
+	 * we restore ALL the debug registers to avoid picking up
+	 * stale state.
+	 *
+	 * This must be done even when the task is still the owner
+	 * as the registers may have been modified via ptrace()
+	 * (not perfmon) by the previous task.
+	 */
+	if (ctx->ctx_fl_using_dbreg) {
+		pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf.num_ibrs);
+		pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf.num_dbrs);
+	}
+	/*
+	 * retrieve saved psr
 	 */
-	SET_PMU_OWNER(NULL);
+	psr = ctx->ctx_saved_psr;
 
 	/*
-	 * read current overflow status:
-	 *
-	 * we are guaranteed to read the final stable state
+	 * if we were the last user of the PMU on that CPU,
+	 * then nothing to do except restore psr
 	 */
-	ia64_srlz_d();
-	pmc0 = ia64_get_pmc(0); /* slow */
+	if (GET_LAST_CPU(ctx) == smp_processor_id() && ctx->ctx_last_activation == GET_ACTIVATION()) {
 
+		/*
+		 * retrieve partial reload masks (due to user modifications)
+		 */
+		pmc_mask = ctx->ctx_reload_pmcs[0];
+		pmd_mask = ctx->ctx_reload_pmds[0];
+
+		if (pmc_mask || pmd_mask) DPRINT(("partial reload [%d] pmd_mask=0x%lx pmc_mask=0x%lx\n", task->pid, pmd_mask, pmc_mask));
+	} else {
+		/*
+	 	 * To avoid leaking information to the user level when psr.sp=0,
+	 	 * we must reload ALL implemented pmds (even the ones we don't use).
+	 	 * In the kernel we only allow PFM_READ_PMDS on registers which
+	 	 * we initialized or requested (sampling) so there is no risk there.
+	 	 */
+		pmd_mask = pfm_sysctl.fastctxsw ?  ctx->ctx_used_pmds[0] : ctx->ctx_all_pmds[0];
+
+		/*
+	 	 * ALL accessible PMCs are systematically reloaded, unused registers
+	 	 * get their default (from pfm_reset_pmu_state()) values to avoid picking
+	 	 * up stale configuration.
+	 	 *
+	 	 * PMC0 is never in the mask. It is always restored separately.
+	 	 */
+		pmc_mask = ctx->ctx_all_pmcs[0];
+
+		DPRINT(("full reload for [%d] owner=%d activation=%lu last_activation=%lu last_cpu=%d pmd_mask=0x%lx pmc_mask=0x%lx\n",
+			task->pid, owner ? owner->pid : -1,
+			GET_ACTIVATION(), ctx->ctx_last_activation,
+			GET_LAST_CPU(ctx), pmd_mask, pmc_mask));
+
+	}
 	/*
-	 * freeze PMU:
+	 * when context is MASKED, we will restore PMC with plm=0
+	 * and PMD with stale information, but that's ok, nothing
+	 * will be captured.
 	 *
-	 * This destroys the overflow information. This is required to make sure
-	 * next process does not start with monitoring on if not requested
+	 * XXX: optimize here
 	 */
-	pfm_freeze_pmu();
+	if (pmd_mask) pfm_restore_pmds(t->pmds, pmd_mask);
+	if (pmc_mask) pfm_restore_pmcs(t->pmcs, pmc_mask);
 
 	/*
-	 * We don't need to restore psr, because we are on our way out
+	 * check for pending overflow at the time the state
+	 * was saved.
 	 */
+	if (unlikely(PMC0_HAS_OVFL(t->pmcs[0]))) {
+		struct pt_regs *regs = ia64_task_regs(task);
+		pfm_overflow_handler(task, ctx, t->pmcs[0], regs);
+	}
 
 	/*
-	 * This loop flushes the PMD into the PFM context.
-	 * It also processes overflow inline.
-	 *
-	 * IMPORTANT: No notification is sent at this point as the process is dying.
-	 * The implicit notification will come from a SIGCHILD or a return from a
-	 * waitpid().
-	 *
+	 * we clear PMC0, to ensure that any in flight interrupt
+	 * will not be attributed to the new context we are installing
+	 * because the actual overflow has been processed above already.
+	 * No real effect until we unmask interrupts at the end of the
+	 * function.
 	 */
-
-	if ((unsigned int) atomic_read(&ctx->ctx_last_cpu) != smp_processor_id())
-		printk(KERN_DEBUG "perfmon: [%d] last_cpu=%d\n",
-		       task->pid, atomic_read(&ctx->ctx_last_cpu));
+	pfm_unfreeze_pmu();
 
 	/*
-	 * we save all the used pmds
-	 * we take care of overflows for pmds used as counters
+	 * we just did a reload, so we reset the partial reload fields
 	 */
-	mask2 = ctx->ctx_used_pmds[0];
-	for (i = 0; mask2; i++, mask2>>=1) {
+	ctx->ctx_reload_pmcs[0] = 0UL;
+	ctx->ctx_reload_pmds[0] = 0UL;
 
-		/* skip non used pmds */
-		if ((mask2 & 0x1) == 0) continue;
-
-		val = ia64_get_pmd(i);
+	SET_LAST_CPU(ctx, smp_processor_id());
 
-		if (PMD_IS_COUNTING(i)) {
-			DBprintk(("[%d] pmd[%d] soft_pmd=0x%lx hw_pmd=0x%lx\n", 
-				task->pid, 
-				i, 
-				ctx->ctx_soft_pmds[i].val, 
-				val & pmu_conf.ovfl_val));
+	/*
+	 * dump activation value for this PMU
+	 */
+	INC_ACTIVATION();
+	/*
+	 * record current activation for this context
+	 */
+	SET_ACTIVATION(ctx);
 
-			/* collect latest results */
-			ctx->ctx_soft_pmds[i].val += val & pmu_conf.ovfl_val;
+	/*
+	 * establish new ownership. Interrupts
+	 * are still masked at this point.
+	 */
+	SET_PMU_OWNER(task, ctx);
 
-			/*
-			 * now everything is in ctx_soft_pmds[] and we need
-			 * to clear the saved context from save_regs() such that
-			 * pfm_read_pmds() gets the correct value
-			 */
-			task->thread.pmd[i] = 0;
+	/*
+	 * restore the psr we changed
+	 */
+	pfm_set_psr_l(psr);
 
-			/* 
-			 * take care of overflow inline
-			 */
-			if (pmc0 & (1UL << i)) {
-				ctx->ctx_soft_pmds[i].val += 1 + pmu_conf.ovfl_val;
-				DBprintk(("[%d] pmd[%d] overflowed soft_pmd=0x%lx\n",
-					task->pid, i, ctx->ctx_soft_pmds[i].val));
-			}
-		} else {
-			DBprintk(("[%d] pmd[%d] hw_pmd=0x%lx\n", task->pid, i, val));
-			/* 
-			 * not a counter, just save value as is
-			 */
-			task->thread.pmd[i] = val;
-		}
-	}
-	/* 
-	 * indicates that context has been saved
+	/*
+	 * allow concurrent access to context
 	 */
-	atomic_set(&ctx->ctx_last_cpu, -1);
-	preempt_enable();
+	pfm_unprotect_ctx_ctxsw(ctx, flags);
 }
-
-
+#else /*  !CONFIG_SMP */
 /*
- * task is the newly created task, pt_regs for new child
+ * reload PMU state for UP kernels
+ * in 2.5 we come here with interrupts disabled
  */
-int
-pfm_inherit(struct task_struct *task, struct pt_regs *regs)
+void
+pfm_load_regs (struct task_struct *task)
 {
+	struct thread_struct *t;
 	pfm_context_t *ctx;
-	pfm_context_t *nctx;
-	struct thread_struct *thread;
-	unsigned long m;
-	int i;
+	struct task_struct *owner;
+	unsigned long pmd_mask, pmc_mask;
+	u64 psr;
 
-	/*
-	 * the new task was copied from parent and therefore points
-	 * to the parent's context at this point
-	 */
-	ctx    = task->thread.pfm_context;
-	thread = &task->thread;
+	owner      = GET_PMU_OWNER();
+	ctx        = PFM_GET_CTX(task);
+	t          = &task->thread;
 
-	preempt_disable();
-	/*
-	 * for secure sessions, make sure child cannot mess up 
-	 * the monitoring session.
-	 */
-	if (ctx->ctx_fl_unsecure == 0) {
-		ia64_psr(regs)->sp = 1;
-	 	DBprintk(("enabling psr.sp for [%d]\n", task->pid));
-	} else {
-	 	DBprintk(("psr.sp=%d [%d]\n", ia64_psr(regs)->sp, task->pid));
+#if 1
+	psr = pfm_get_psr();
+	if (psr & IA64_PSR_UP) {
+		printk(KERN_ERR " perfmon: pfm_load_regs: psr.up set current [%d] owner [%d] psr=0x%lx\n", current->pid, owner->pid, psr);
 	}
+	psr = pfm_get_psr();
+	if (psr & IA64_PSR_I) {
+		printk(KERN_ERR " perfmon: pfm_load_regs: psr.i set current [%d] owner [%d] psr=0x%lx\n", current->pid, owner->pid, psr);
+	}
+#endif
 
 	/*
-	 * if there was a virtual mapping for the sampling buffer
-	 * the mapping is NOT inherited across fork() (see VM_DONTCOPY), 
-	 * so we don't have to explicitly remove it here. 
-	 *
+	 * we restore ALL the debug registers to avoid picking up
+	 * stale state.
 	 *
-	 * Part of the clearing of fields is also done in
-	 * copy_thread() because the fiels are outside the
-	 * pfm_context structure and can affect tasks not
-	 * using perfmon.
+	 * This must be done even when the task is still the owner
+	 * as the registers may have been modified via ptrace()
+	 * (not perfmon) by the previous task.
 	 */
-
-	/* clear pending notification */
-	task->thread.pfm_ovfl_block_reset = 0;
+	if (ctx->ctx_fl_using_dbreg) {
+		pfm_restore_ibrs(ctx->ctx_ibrs, pmu_conf.num_ibrs);
+		pfm_restore_dbrs(ctx->ctx_dbrs, pmu_conf.num_dbrs);
+	}
 
 	/*
-	 * clear cpu pinning restriction for child
+	 * retrieved save psr
 	 */
-	if (ctx->ctx_fl_system) {
-		set_cpus_allowed(task, ctx->ctx_saved_cpus_allowed);
-
-	 	DBprintk(("setting cpus_allowed for [%d] to 0x%lx from 0x%lx\n", 
-			task->pid,
-			ctx->ctx_saved_cpus_allowed, 
-			current->cpus_allowed));
-	}
+	psr = ctx->ctx_saved_psr;
 
 	/*
-	 * takes care of easiest case first
+	 * short path, our state is still there, just
+	 * need to restore psr and we go
+	 *
+	 * we do not touch either PMC nor PMD. the psr is not touched
+	 * by the overflow_handler. So we are safe w.r.t. to interrupt
+	 * concurrency even without interrupt masking.
 	 */
-	if (CTX_INHERIT_MODE(ctx) == PFM_FL_INHERIT_NONE) {
-
-		DBprintk(("removing PFM context for [%d]\n", task->pid));
-
-		task->thread.pfm_context = NULL;
-
-		/* 
-		 * we must clear psr.up because the new child does
-		 * not have a context and the PM_VALID flag is cleared
-		 * in copy_thread().
-		 *
-		 * we do not clear psr.pp because it is always
-		 * controlled by the system wide logic and we should
-		 * never be here when system wide is running anyway
-		 */
-	 	ia64_psr(regs)->up = 0;
-
-		preempt_enable();
-
-		/* copy_thread() clears IA64_THREAD_PM_VALID */
-		return 0;
+	if (likely(owner == task)) {
+		pfm_set_psr_l(psr);
+		return;
 	}
-	nctx = pfm_context_alloc();
-	if (nctx == NULL) return -ENOMEM;
-
-	/* copy content */
-	*nctx = *ctx;
 
+	DPRINT(("reload for [%d] owner=%d\n", task->pid, owner ? owner->pid : -1));
 
-	if (CTX_INHERIT_MODE(ctx) == PFM_FL_INHERIT_ONCE) {
-		nctx->ctx_fl_inherit = PFM_FL_INHERIT_NONE;
-		DBprintk(("downgrading to INHERIT_NONE for [%d]\n", task->pid));
-	}
 	/*
-	 * task is not yet visible in the tasklist, so we do 
-	 * not need to lock the newly created context.
-	 * However, we must grab the tasklist_lock to ensure
-	 * that the ctx_owner or ctx_notify_task do not disappear
-	 * while we increment their check counters.
+	 * someone else is still using the PMU, first push it out and
+	 * then we'll be able to install our stuff !
+	 *
+	 * Upon return, there will be no owner for the current PMU
 	 */
-	read_lock(&tasklist_lock);
-
-	if (nctx->ctx_notify_task) 
-		atomic_inc(&nctx->ctx_notify_task->thread.pfm_notifiers_check);
-
-	if (nctx->ctx_owner)
-		atomic_inc(&nctx->ctx_owner->thread.pfm_owners_check);
-
-	read_unlock(&tasklist_lock);
-
-
-	LOCK_PFS();
-	pfm_sessions.pfs_task_sessions++;
-	UNLOCK_PFS();
-
-	/* initialize counters in new context */
-	m = nctx->ctx_used_pmds[0] >> PMU_FIRST_COUNTER;
-	for(i = PMU_FIRST_COUNTER ; m ; m>>=1, i++) {
-		if ((m & 0x1) && pmu_conf.pmd_desc[i].type == PFM_REG_COUNTING) {
-			nctx->ctx_soft_pmds[i].val = nctx->ctx_soft_pmds[i].lval & ~pmu_conf.ovfl_val;
-			thread->pmd[i]	      	   = nctx->ctx_soft_pmds[i].lval & pmu_conf.ovfl_val;
-		} else {
-			thread->pmd[i]	      	   = 0UL; /* reset to initial state */
-		}
-	}
+	if (owner) pfm_lazy_save_regs(owner);
 
-	nctx->ctx_fl_frozen      = 0;
-	nctx->ctx_ovfl_regs[0]   = 0UL;
-	nctx->ctx_fl_trap_reason = PFM_TRAP_REASON_NONE;
-	atomic_set(&nctx->ctx_last_cpu, -1);
+	/*
+	 * To avoid leaking information to the user level when psr.sp=0,
+	 * we must reload ALL implemented pmds (even the ones we don't use).
+	 * In the kernel we only allow PFM_READ_PMDS on registers which
+	 * we initialized or requested (sampling) so there is no risk there.
+	 */
+	pmd_mask = pfm_sysctl.fastctxsw ?  ctx->ctx_used_pmds[0] : ctx->ctx_all_pmds[0];
 
 	/*
-	 * here nctx->ctx_psb == ctx->ctx_psb
+	 * ALL accessible PMCs are systematically reloaded, unused registers
+	 * get their default (from pfm_reset_pmu_state()) values to avoid picking
+	 * up stale configuration.
 	 *
-	 * increment reference count to sampling
-	 * buffer, if any. Note that this is independent
-	 * from the virtual mapping. The latter is never
-	 * inherited while the former will be if context
-	 * is setup to something different from PFM_FL_INHERIT_NONE
+	 * PMC0 is never in the mask. It is always restored separately
 	 */
-	if (nctx->ctx_psb) {
-		LOCK_PSB(nctx->ctx_psb);
+	pmc_mask = ctx->ctx_all_pmcs[0];
 
-		nctx->ctx_psb->psb_refcnt++;
+	pfm_restore_pmds(t->pmds, pmd_mask);
+	pfm_restore_pmcs(t->pmcs, pmc_mask);
 
-	 	DBprintk(("updated smpl @ %p refcnt=%lu psb_flags=0x%x\n", 
-			ctx->ctx_psb->psb_hdr,
-			ctx->ctx_psb->psb_refcnt,
-			ctx->ctx_psb->psb_flags));
-
-		UNLOCK_PSB(nctx->ctx_psb);
-
-		/*
-	 	 * remove any pointer to sampling buffer mapping
-	 	 */
-		nctx->ctx_smpl_vaddr = 0;
+	/*
+	 * Check for pending overflow when state was last saved.
+	 * invoked handler is overflow status bits set.
+	 *
+	 * Any PMU overflow in flight at this point, will still
+	 * be treated as spurious because we have no declared
+	 * owner. Note that the first level interrupt handler
+	 * DOES NOT TOUCH any PMC except PMC0 for which we have
+	 * a copy already.
+	 */
+	if (unlikely(PMC0_HAS_OVFL(t->pmcs[0]))) {
+		struct pt_regs *regs = ia64_task_regs(task);
+		pfm_overflow_handler(task, ctx, t->pmcs[0], regs);
 	}
 
-	sema_init(&nctx->ctx_restart_sem, 0); /* reset this semaphore to locked */
-
 	/*
-	 * propagate kernel psr in new context (used for first ctxsw in
+	 * we clear PMC0, to ensure that any in flight interrupt
+	 * will not be attributed to the new context we are installing
+	 * because the actual overflow has been processed above already.
+	 *
+	 * This is an atomic operation.
 	 */
-	nctx->ctx_saved_psr = pfm_get_psr();
+	pfm_unfreeze_pmu();
 
 	/*
-	 * propagate kernel psr in new context (used for first ctxsw in
+	 * establish new ownership. If there was an in-flight
+	 * overflow interrupt, it will be treated as spurious
+	 * before and after the call, because no overflow
+	 * status bit can possibly be set. No new overflow
+	 * can be generated because, at this point, psr.up
+	 * is still cleared.
 	 */
-	nctx->ctx_saved_psr = pfm_get_psr();
-
-	/* link with new task */
-	thread->pfm_context = nctx;
-
-	DBprintk(("nctx=%p for process [%d]\n", (void *)nctx, task->pid));
+	SET_PMU_OWNER(task, ctx);
 
 	/*
-	 * the copy_thread routine automatically clears
-	 * IA64_THREAD_PM_VALID, so we need to reenable it, if it was used by the caller
+	 * restore the psr. This is the point at which
+	 * new overflow interrupts can be generated again.
 	 */
-	if (current->thread.flags & IA64_THREAD_PM_VALID) {
-		DBprintk(("setting PM_VALID for [%d]\n", task->pid));
-		thread->flags |= IA64_THREAD_PM_VALID;
-	}
-
-	preempt_enable();
+	pfm_set_psr_l(psr);
 
-	return 0;
 }
+#endif /* CONFIG_SMP */
 
-/* 
- *
- * We cannot touch any of the PMU registers at this point as we may
- * not be running on the same CPU the task was last run on.  Therefore
- * it is assumed that the PMU has been stopped appropriately in
- * pfm_flush_regs() called from exit_thread(). 
- *
- * The function is called in the context of the parent via a release_thread()
- * and wait4(). The task is not in the tasklist anymore.
+/*
+ * this function assumes monitoring is stopped
  */
-void
-pfm_context_exit(struct task_struct *task)
+static void
+pfm_flush_pmds(struct task_struct *task, pfm_context_t *ctx)
 {
-	pfm_context_t *ctx = task->thread.pfm_context;
+	u64 pmc0;
+	unsigned long mask2, val, pmd_val;
+	int i, can_access_pmu = 0;
+	int is_self;
 
 	/*
-	 * check sampling buffer
+	 * is the caller the task being monitored (or which initiated the
+	 * session for system wide measurements)
 	 */
-	preempt_disable();
-	if (ctx->ctx_psb) {
-		pfm_smpl_buffer_desc_t *psb = ctx->ctx_psb;
-
-		LOCK_PSB(psb);
-
-		DBprintk(("sampling buffer from [%d] @%p size %ld refcnt=%lu psb_flags=0x%x\n",
-			task->pid,
-			psb->psb_hdr, psb->psb_size, psb->psb_refcnt, psb->psb_flags));
+	is_self = ctx->ctx_task == task ? 1 : 0;
 
+#ifdef CONFIG_SMP
+	if (task == current) {
+#else
+	/*
+	 * in UP, the state can still be in the registers
+	 */
+	if (task == current || GET_PMU_OWNER() == task) {
+#endif
+		can_access_pmu = 1;
 		/*
-		 * in the case where we are the last user, we may be able to free
-		 * the buffer
+		 * Mark the PMU as not owned
+		 * This will cause the interrupt handler to do nothing in case an overflow
+		 * interrupt was in-flight
+		 * This also guarantees that pmc0 will contain the final state
+		 * It virtually gives us full control on overflow processing from that point
+		 * on.
 		 */
-		psb->psb_refcnt--;
-
-		if (psb->psb_refcnt == 0) {
-
-			/*
-			 * The flag is cleared in pfm_vm_close(). which gets 
-			 * called from do_exit() via exit_mm(). 
-			 * By the time we come here, the task has no more mm context.
-			 *
-			 * We can only free the psb and buffer here after the vm area
-			 * describing the buffer has been removed. This normally happens 
-			 * as part of do_exit() but the entire mm context is ONLY removed
-			 * once its reference counts goes to zero. This is typically
-			 * the case except for multi-threaded (several tasks) processes.
-			 *
-			 * See pfm_vm_close() and pfm_cleanup_smpl_buf() for more details.
-			 */
-			if ((psb->psb_flags & PSB_HAS_VMA) == 0) {
-
-				DBprintk(("cleaning sampling buffer from [%d] @%p size %ld\n",
-					task->pid,
-					psb->psb_hdr, psb->psb_size));
-
-				/* 
-				 * free the buffer and psb 
-				 */
-				pfm_rvfree(psb->psb_hdr, psb->psb_size);
-				kfree(psb);
-				psb = NULL;
-			} 
-		} 
-		/* psb may have been deleted */
-		if (psb) UNLOCK_PSB(psb);
-	} 
-
-	DBprintk(("cleaning [%d] pfm_context @%p notify_task=%p check=%d mm=%p\n", 
-		task->pid, ctx, 
-		ctx->ctx_notify_task, 
-		atomic_read(&task->thread.pfm_notifiers_check), task->mm));
-
-	/*
-	 * To avoid getting the notified task or owner task scan the entire process 
-	 * list when they exit, we decrement notifiers_check and owners_check respectively.
-	 *
-	 * Of course, there is race condition between decreasing the value and the 
-	 * task exiting. The danger comes from the fact that, in both cases, we have a 
-	 * direct pointer to a task structure thereby bypassing the tasklist. 
-	 * We must make sure that, if we have task!= NULL, the target task is still 
-	 * present and is identical to the initial task specified 
-	 * during pfm_context_create(). It may already be detached from the tasklist but 
-	 * that's okay. Note that it is okay if we miss the deadline and the task scans 
-	 * the list for nothing, it will affect performance but not correctness. 
-	 * The correctness is ensured by using the ctx_lock which prevents the 
-	 * notify_task from changing the fields in our context.
-	 * Once holdhing this lock, if we see task!= NULL, then it will stay like
-	 * that until we release the lock. If it is NULL already then we came too late.
-	 */
-	LOCK_CTX(ctx);
-
-	if (ctx->ctx_notify_task != NULL) {
-		DBprintk(("[%d], [%d] atomic_sub on [%d] notifiers=%u\n", current->pid,
-			task->pid,
-			ctx->ctx_notify_task->pid, 
-			atomic_read(&ctx->ctx_notify_task->thread.pfm_notifiers_check)));
-
-		atomic_dec(&ctx->ctx_notify_task->thread.pfm_notifiers_check);
-	}
-
-	if (ctx->ctx_owner != NULL) {
-		DBprintk(("[%d], [%d] atomic_sub on [%d] owners=%u\n", 
-			 current->pid, 
-			 task->pid,
-			 ctx->ctx_owner->pid, 
-			 atomic_read(&ctx->ctx_owner->thread.pfm_owners_check)));
-
-		atomic_dec(&ctx->ctx_owner->thread.pfm_owners_check);
-	}
-
-	UNLOCK_CTX(ctx);
-	preempt_enable();
+		SET_PMU_OWNER(NULL, NULL);
 
-	pfm_unreserve_session(task, ctx->ctx_fl_system, 1UL << ctx->ctx_cpu);
-
-	if (ctx->ctx_fl_system) {
 		/*
-	 	 * remove any CPU pinning
-	 	 */
-		set_cpus_allowed(task, ctx->ctx_saved_cpus_allowed);
-	} 
-
-	pfm_context_free(ctx);
-	/* 
-	 *  clean pfm state in thread structure,
-	 */
-	task->thread.pfm_context          = NULL;
-	task->thread.pfm_ovfl_block_reset = 0;
-
-	/* pfm_notifiers is cleaned in pfm_cleanup_notifiers() */
-}
-
-/*
- * function invoked from release_thread when pfm_smpl_buf_list is not NULL
- */
-int
-pfm_cleanup_smpl_buf(struct task_struct *task)
-{
-	pfm_smpl_buffer_desc_t *tmp, *psb = task->thread.pfm_smpl_buf_list;
+		 * read current overflow status:
+		 *
+		 * we are guaranteed to read the final stable state
+		 */
+		ia64_srlz_d();
+		pmc0 = ia64_get_pmc(0); /* slow */
 
-	if (psb == NULL) {
-		printk(KERN_DEBUG "perfmon: psb is null in [%d]\n", current->pid);
-		return -1;
+		/*
+		 * reset freeze bit, overflow status information destroyed
+		 */
+		pfm_unfreeze_pmu();
+	} else {
+		pmc0 = task->thread.pmcs[0];
+		/*
+		 * clear whatever overflow status bits there were
+		 */
+		task->thread.pmcs[0] &= ~0x1;
 	}
+
 	/*
-	 * Walk through the list and free the sampling buffer and psb
+	 * we save all the used pmds
+	 * we take care of overflows for counting PMDs
+	 *
+	 * XXX: sampling situation is not taken into account here
 	 */
-	while (psb) {
-		DBprintk(("[%d] freeing smpl @%p size %ld\n", current->pid, psb->psb_hdr, psb->psb_size));
-
-		pfm_rvfree(psb->psb_hdr, psb->psb_size);
-		tmp = psb->psb_next;
-		kfree(psb);
-		psb = tmp;
-	}
-
-	/* just in case */
-	task->thread.pfm_smpl_buf_list = NULL;
-
-	return 0;
-}
-
-/*
- * function invoked from release_thread to make sure that the ctx_owner field does not
- * point to an unexisting task.
- */
-void
-pfm_cleanup_owners(struct task_struct *task)
-{
-	struct task_struct *g, *p;
-	pfm_context_t *ctx;
-
-	DBprintk(("called by [%d] for [%d]\n", current->pid, task->pid));
+	mask2 = ctx->ctx_used_pmds[0];
+	for (i = 0; mask2; i++, mask2>>=1) {
 
-	read_lock(&tasklist_lock);
+		/* skip non used pmds */
+		if ((mask2 & 0x1) == 0) continue;
 
-	do_each_thread(g, p) {
 		/*
-		 * It is safe to do the 2-step test here, because thread.ctx
-		 * is cleaned up only in release_thread() and at that point
-		 * the task has been detached from the tasklist which is an
-		 * operation which uses the write_lock() on the tasklist_lock
-		 * so it cannot run concurrently to this loop. So we have the
-		 * guarantee that if we find p and it has a perfmon ctx then
-		 * it is going to stay like this for the entire execution of this
-		 * loop.
+		 * can access PMU always true in system wide mode
 		 */
-		ctx = p->thread.pfm_context;
+		val = pmd_val = can_access_pmu ? ia64_get_pmd(i) : task->thread.pmds[i];
 
-		//DBprintk(("[%d] scanning task [%d] ctx=%p\n", task->pid, p->pid, ctx));
+		if (PMD_IS_COUNTING(i)) {
+			DPRINT(("[%d] pmd[%d] ctx_pmd=0x%lx hw_pmd=0x%lx\n",
+				task->pid,
+				i,
+				ctx->ctx_pmds[i].val,
+				val & pmu_conf.ovfl_val));
 
-		if (ctx && ctx->ctx_owner == task) {
-			DBprintk(("trying for owner [%d] in [%d]\n", task->pid, p->pid));
 			/*
-			 * the spinlock is required to take care of a race condition
-			 * with the send_sig_info() call. We must make sure that 
-			 * either the send_sig_info() completes using a valid task,
-			 * or the notify_task is cleared before the send_sig_info()
-			 * can pick up a stale value. Note that by the time this
-			 * function is executed the 'task' is already detached from the
-			 * tasklist. The problem is that the notifiers have a direct
-			 * pointer to it. It is okay to send a signal to a task in this
-			 * stage, it simply will have no effect. But it is better than sending
-			 * to a completely destroyed task or worse to a new task using the same
-			 * task_struct address.
+			 * we rebuild the full 64 bit value of the counter
 			 */
-			LOCK_CTX(ctx);
-
-			ctx->ctx_owner = NULL;
-
-			UNLOCK_CTX(ctx);
-
-			DBprintk(("done for notifier [%d] in [%d]\n", task->pid, p->pid));
-		}
-	} while_each_thread(g, p);
-
-	read_unlock(&tasklist_lock);
-
-	atomic_set(&task->thread.pfm_owners_check, 0);
-}
-
-
-/*
- * function called from release_thread to make sure that the ctx_notify_task is not pointing
- * to an unexisting task
- */
-void
-pfm_cleanup_notifiers(struct task_struct *task)
-{
-	struct task_struct *g, *p;
-	pfm_context_t *ctx;
-
-	DBprintk(("called by [%d] for [%d]\n", current->pid, task->pid));
-
-	read_lock(&tasklist_lock);
+			val = ctx->ctx_pmds[i].val + (val & pmu_conf.ovfl_val);
 
-	do_each_thread(g, p) {
-		/*
-		 * It is safe to do the 2-step test here, because thread.ctx is cleaned up
-		 * only in release_thread() and at that point the task has been detached
-		 * from the tasklist which is an operation which uses the write_lock() on
-		 * the tasklist_lock so it cannot run concurrently to this loop. So we
-		 * have the guarantee that if we find p and it has a perfmon ctx then it
-		 * is going to stay like this for the entire execution of this loop.
-		 */
-		ctx = p->thread.pfm_context;
-
-		//DBprintk(("[%d] scanning task [%d] ctx=%p\n", task->pid, p->pid, ctx));
-
-		if (ctx && ctx->ctx_notify_task == task) {
-			DBprintk(("trying for notifier [%d] in [%d]\n", task->pid, p->pid));
 			/*
-			 * the spinlock is required to take care of a race condition
-			 * with the send_sig_info() call. We must make sure that 
-			 * either the send_sig_info() completes using a valid task,
-			 * or the notify_task is cleared before the send_sig_info()
-			 * can pick up a stale value. Note that by the time this
-			 * function is executed the 'task' is already detached from the
-			 * tasklist. The problem is that the notifiers have a direct
-			 * pointer to it. It is okay to send a signal to a task in this
-			 * stage, it simply will have no effect. But it is better than sending
-			 * to a completely destroyed task or worse to a new task using the same
-			 * task_struct address.
+			 * now everything is in ctx_pmds[] and we need
+			 * to clear the saved context from save_regs() such that
+			 * pfm_read_pmds() gets the correct value
 			 */
-			LOCK_CTX(ctx);
-
-			ctx->ctx_notify_task = NULL;
-
-			UNLOCK_CTX(ctx);
+			pmd_val = 0UL;
 
-			DBprintk(("done for notifier [%d] in [%d]\n", task->pid, p->pid));
+			/*
+			 * take care of overflow inline
+			 */
+			if (pmc0 & (1UL << i)) {
+				val += 1 + pmu_conf.ovfl_val;
+				DPRINT(("[%d] pmd[%d] overflowed\n", task->pid, i));
+			}
 		}
-	} while_each_thread(g, p);
 
-	read_unlock(&tasklist_lock);
+		DPRINT(("[%d] is_self=%d ctx_pmd[%d]=0x%lx  pmd_val=0x%lx\n", task->pid, is_self, i, val, pmd_val));
 
-	atomic_set(&task->thread.pfm_notifiers_check, 0);
+		if (is_self) task->thread.pmds[i] = pmd_val;
+		ctx->ctx_pmds[i].val = val;
+	}
 }
 
 static struct irqaction perfmon_irqaction = {
-	.handler =	pfm_interrupt_handler,
-	.flags   =	SA_INTERRUPT,
-	.name    =	"perfmon"
+	.handler = pfm_interrupt_handler,
+	.flags   = SA_INTERRUPT,
+	.name    = "perfmon"
 };
 
-int
-pfm_install_alternate_syswide_subsystem(pfm_intr_handler_desc_t *hdl)
-{
-	int ret;
-
-
-	/* some sanity checks */
-	if (hdl == NULL || hdl->handler == NULL) {
-		return -EINVAL;
-	}
-
-	/* do the easy test first */
-	if (pfm_alternate_intr_handler) {
-		return -EBUSY;
-	}
-
-	preempt_disable();
-	/* reserve our session */
-	ret = pfm_reserve_session(NULL, 1, cpu_online_map);
-	if (ret) {
-		preempt_enable();
-		return ret;
-	}
-
-	if (pfm_alternate_intr_handler) {
-		preempt_enable();
-		printk(KERN_DEBUG "perfmon: install_alternate, intr_handler not NULL "
-		       "after reserve\n");
-		return -EINVAL;
-	}
-
-	pfm_alternate_intr_handler = hdl;
-
-	preempt_enable();
-	return 0;
-}
-
-int
-pfm_remove_alternate_syswide_subsystem(pfm_intr_handler_desc_t *hdl)
-{
-	if (hdl == NULL)
-		return -EINVAL;
-
-	/* cannot remove someone else's handler! */
-	if (pfm_alternate_intr_handler != hdl) 
-		return -EINVAL;
-
-	preempt_disable();
-	pfm_alternate_intr_handler = NULL;
-
-	/* 
-	 * XXX: assume cpu_online_map has not changed since reservation 
-	 */
-	pfm_unreserve_session(NULL, 1, cpu_online_map);
-
-	preempt_enable();
-
-	return 0;
-}
-
 /*
  * perfmon initialization routine, called from the initcall() table
  */
+static int init_pfm_fs(void);
+
 int __init
 pfm_init(void)
 {
 	unsigned int n, n_counters, i;
 
-	pmu_conf.disabled = 1;
+	printk("perfmon: version %u.%u IRQ %u\n",
+		PFM_VERSION_MAJ,
+		PFM_VERSION_MIN,
+		IA64_PERFMON_VECTOR);
 
-	printk(KERN_INFO "perfmon: version %u.%u IRQ %u\n", PFM_VERSION_MAJ, PFM_VERSION_MIN,
-	       IA64_PERFMON_VECTOR);
+	/*
+	 * PMU type sanity check
+	 * XXX: maybe better to implement autodetection (but then we have a larger kernel)
+	 */
+	if (local_cpu_data->family != pmu_conf.pmu_family) {
+		printk(KERN_INFO "perfmon: disabled, kernel only supports %s PMU family\n", pmu_conf.pmu_name);
+		return -ENODEV;
+	}
 
 	/*
 	 * compute the number of implemented PMD/PMC from the
@@ -4369,7 +6328,22 @@
 	pmu_conf.num_pmds      = n;
 	pmu_conf.num_counters  = n_counters;
 
-	printk(KERN_INFO "perfmon: %u PMCs, %u PMDs, %u counters (%lu bits)\n",
+	/*
+	 * sanity checks on the number of debug registers
+	 */
+	if (pmu_conf.use_rr_dbregs) {
+		if (pmu_conf.num_ibrs > IA64_NUM_DBG_REGS) {
+			printk(KERN_INFO "perfmon: unsupported number of code debug registers (%u)\n", pmu_conf.num_ibrs);
+			return -1;
+		}
+		if (pmu_conf.num_dbrs > IA64_NUM_DBG_REGS) {
+			printk(KERN_INFO "perfmon: unsupported number of data debug registers (%u)\n", pmu_conf.num_ibrs);
+			return -1;
+		}
+	}
+
+	printk("perfmon: %s PMU detected, %u PMCs, %u PMDs, %u counters (%lu bits)\n",
+	       pmu_conf.pmu_name,
 	       pmu_conf.num_pmcs,
 	       pmu_conf.num_pmds,
 	       pmu_conf.num_counters,
@@ -4382,7 +6356,7 @@
 	}
 
 	/*
-	 * for now here for debug purposes
+	 * create /proc/perfmon (mostly for debugging purposes)
 	 */
 	perfmon_dir = create_proc_read_entry ("perfmon", 0, 0, perfmon_read_entry, NULL);
 	if (perfmon_dir == NULL) {
@@ -4391,7 +6365,7 @@
 	}
 
 	/*
-	 * create /proc/perfmon
+	 * create /proc/sys/kernel/perfmon (for debugging purposes)
 	 */
 	pfm_sysctl_header = register_sysctl_table(pfm_sysctl_root, 0);
 
@@ -4399,21 +6373,34 @@
 	 * initialize all our spinlocks
 	 */
 	spin_lock_init(&pfm_sessions.pfs_lock);
+	spin_lock_init(&pfm_smpl_fmt_lock);
+
+	init_pfm_fs();
+
+	for(i=0; i < NR_CPUS; i++) pfm_stats[i].pfm_ovfl_intr_cycles_min = ~0UL;
 
 	/* we are all set */
-	pmu_conf.disabled = 0;
+	pmu_conf.enabled = 1;
 
 	return 0;
 }
+
 __initcall(pfm_init);
 
 void
-pfm_init_percpu(void)
+pfm_init_percpu (void)
 {
 	int i;
-	int me = get_cpu();
 
-	if (me == 0)
+	/*
+	 * make sure no measurement is active
+	 * (may inherit programmed PMCs from EFI).
+	 */
+	pfm_clear_psr_pp();
+	pfm_clear_psr_up();
+
+
+	if (smp_processor_id() == 0)
 		register_percpu_irq(IA64_PERFMON_VECTOR, &perfmon_irqaction);
 
 	ia64_set_pmv(IA64_PERFMON_VECTOR);
@@ -4426,28 +6413,102 @@
 	 *
 	 * At this point, pmu_conf has not yet been initialized
 	 *
-	 * On McKinley, this code is ineffective until PMC4 is initialized.
+	 * On McKinley, this code is ineffective until PMC4 is initialized
+	 * but that's all right because we take care of pmc0 later.
+	 *
+	 * XXX: potential problems with pmc1.
 	 */
 	for (i=1; PMC_IS_LAST(i) == 0;  i++) {
 		if (PMC_IS_IMPL(i) == 0) continue;
 		ia64_set_pmc(i, PMC_DFL_VAL(i));
 	}
 
-	for (i=0; PMD_IS_LAST(i); i++) {
+	for (i=0; PMD_IS_LAST(i) == 0; i++) {
 		if (PMD_IS_IMPL(i) == 0) continue;
 		ia64_set_pmd(i, 0UL);
 	}
-	put_cpu();
-	pfm_freeze_pmu();
+
+	/*
+	 * we run with the PMU not frozen at all times
+	 */
+	pfm_unfreeze_pmu();
+}
+
+/*
+ * used for debug purposes only
+ */
+void
+dump_pmu_state(void)
+{
+	struct task_struct *task;
+	struct thread_struct *t;
+	pfm_context_t *ctx;
+	unsigned long psr;
+	int i;
+
+	printk("current [%d] %s\n", current->pid, current->comm);
+
+	task = GET_PMU_OWNER();
+	ctx  = GET_PMU_CTX();
+
+	printk("owner [%d] ctx=%p\n", task ? task->pid : -1, ctx);
+
+	psr = pfm_get_psr();
+
+	printk("psr.pp=%ld psr.up=%ld\n", (psr >> IA64_PSR_PP_BIT) &0x1UL, (psr >> IA64_PSR_PP_BIT)&0x1UL);
+
+	t = &current->thread;
+
+	for (i=1; PMC_IS_LAST(i) == 0; i++) {
+		if (PMC_IS_IMPL(i) == 0) continue;
+		printk("pmc[%d]=0x%lx tpmc=0x%lx\n", i, ia64_get_pmc(i), t->pmcs[i]);
+	}
+
+	for (i=1; PMD_IS_LAST(i) == 0; i++) {
+		if (PMD_IS_IMPL(i) == 0) continue;
+		printk("pmd[%d]=0x%lx tpmd=0x%lx\n", i, ia64_get_pmd(i), t->pmds[i]);
+	}
+	if (ctx) {
+		printk("ctx_state=%d vaddr=%p addr=%p fd=%d ctx_task=[%d] saved_psr=0x%lx\n",
+				ctx->ctx_state,
+				ctx->ctx_smpl_vaddr,
+				ctx->ctx_smpl_hdr,
+				ctx->ctx_msgq_head,
+				ctx->ctx_msgq_tail,
+				ctx->ctx_saved_psr);
+	}
 }
 
-#else /* !CONFIG_PERFMON */
+/*
+ * called from process.c:copy_thread(). task is new child.
+ */
+void
+pfm_inherit(struct task_struct *task, struct pt_regs *regs)
+{
+	struct thread_struct *thread;
+
+	DPRINT(("perfmon: pfm_inherit clearing state for [%d] current [%d]\n", task->pid, current->pid));
+
+	thread = &task->thread;
+
+	/*
+	 * cut links inherited from parent (current)
+	 */
+	thread->pfm_context = NULL;
+
+	PFM_SET_WORK_PENDING(task, 0);
 
+	/*
+	 * restore default psr settings
+	 */
+	ia64_psr(regs)->pp = ia64_psr(regs)->up = 0;
+	ia64_psr(regs)->sp = 1;
+}
+#else  /* !CONFIG_PERFMON */
 asmlinkage long
-sys_perfmonctl (int pid, int cmd, void *req, int count, long arg5, long arg6, 
-		long arg7, long arg8, long stack)
+sys_perfmonctl (int fd, int cmd, void *arg, int count, long arg5, long arg6, long arg7,
+		long arg8, long stack)
 {
 	return -ENOSYS;
 }
-
-#endif /* !CONFIG_PERFMON */
+#endif /* CONFIG_PERFMON */
diff -Nru a/arch/ia64/kernel/perfmon_default_smpl.c b/arch/ia64/kernel/perfmon_default_smpl.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/kernel/perfmon_default_smpl.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,309 @@
+/*
+ * Copyright (C) 2002-2003 Hewlett-Packard Co
+ *               Stephane Eranian <eranian@hpl.hp.com>
+ *
+ * This file implements the default sampling buffer format
+ * for the Linux/ia64 perfmon-2 subsystem.
+ */
+#include <linux/kernel.h>
+#include <linux/types.h>
+#include <linux/module.h>
+#include <linux/config.h>
+#include <linux/init.h>
+#include <asm/delay.h>
+#include <linux/smp.h>
+
+#include <asm/perfmon.h>
+#include <asm/perfmon_default_smpl.h>
+
+MODULE_AUTHOR("Stephane Eranian <eranian@hpl.hp.com>");
+MODULE_DESCRIPTION("perfmon default sampling format");
+MODULE_LICENSE("GPL");
+
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "debug");
+
+MODULE_PARM(debug_ovfl, "i");
+MODULE_PARM_DESC(debug_ovfl, "debug ovfl");
+
+
+#define DEFAULT_DEBUG 1
+
+#ifdef DEFAULT_DEBUG
+#define DPRINT(a) \
+	do { \
+		if (unlikely(debug >0)) { printk("%s.%d: CPU%d ", __FUNCTION__, __LINE__, smp_processor_id()); printk a; } \
+	} while (0)
+
+#define DPRINT_ovfl(a) \
+	do { \
+		if (unlikely(debug_ovfl >0)) { printk("%s.%d: CPU%d ", __FUNCTION__, __LINE__, smp_processor_id()); printk a; } \
+	} while (0)
+
+#else
+#define DPRINT(a)
+#define DPRINT_ovfl(a)
+#endif
+
+static int debug, debug_ovfl;
+
+static int
+default_validate(struct task_struct *task, unsigned int flags, int cpu, void *data)
+{
+	pfm_default_smpl_arg_t *arg = (pfm_default_smpl_arg_t*)data;
+	int ret = 0;
+
+	if (data == NULL) {
+		DPRINT(("[%d] no argument passed\n", task->pid));
+		return -EINVAL;
+	}
+
+	DPRINT(("[%d] validate flags=0x%x CPU%d\n", task->pid, flags, cpu));
+
+	/*
+	 * must hold at least the buffer header + one minimally sized entry
+	 */
+	if (arg->buf_size < PFM_DEFAULT_SMPL_MIN_BUF_SIZE) return -EINVAL;
+
+	DPRINT(("buf_size=%lu\n", arg->buf_size));
+
+	return ret;
+}
+
+static int
+default_get_size(struct task_struct *task, unsigned int flags, int cpu, void *data, unsigned long *size)
+{
+	pfm_default_smpl_arg_t *arg = (pfm_default_smpl_arg_t *)data;
+
+	/*
+	 * size has been validated in default_validate
+	 */
+	*size = arg->buf_size;
+
+	return 0;
+}
+
+static int
+default_init(struct task_struct *task, void *buf, unsigned int flags, int cpu, void *data)
+{
+	pfm_default_smpl_hdr_t *hdr;
+	pfm_default_smpl_arg_t *arg = (pfm_default_smpl_arg_t *)data;
+
+	hdr = (pfm_default_smpl_hdr_t *)buf;
+
+	hdr->hdr_version      = PFM_DEFAULT_SMPL_VERSION;
+	hdr->hdr_buf_size     = arg->buf_size;
+	hdr->hdr_cur_pos      = (void *)((unsigned long)buf)+sizeof(*hdr);
+	hdr->hdr_last_pos     = (void *)((unsigned long)buf)+arg->buf_size;
+	hdr->hdr_overflows    = 0UL;
+	hdr->hdr_count        = 0UL;
+
+	DPRINT(("[%d] buffer=%p buf_size=%lu hdr_size=%lu hdr_version=%u\n",
+		task->pid,
+		buf,
+		hdr->hdr_buf_size,
+		sizeof(*hdr),
+		hdr->hdr_version));
+
+	return 0;
+}
+
+static int
+default_handler(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg, struct pt_regs *regs)
+{
+	pfm_default_smpl_hdr_t *hdr;
+	pfm_default_smpl_entry_t *ent;
+	void *cur, *last;
+	unsigned long *e;
+	unsigned long ovfl_mask;
+	unsigned long ovfl_notify;
+	unsigned long stamp;
+	unsigned int npmds, i;
+
+	/*
+	 * some time stamp
+	 */
+	stamp = ia64_get_itc();
+
+	if (unlikely(buf == NULL || arg == NULL|| regs == NULL || task == NULL)) {
+		DPRINT(("[%d] invalid arguments buf=%p arg=%p\n", task->pid, buf, arg));
+		return -EINVAL;
+	}
+
+	hdr         = (pfm_default_smpl_hdr_t *)buf;
+	cur         = hdr->hdr_cur_pos;
+	last        = hdr->hdr_last_pos;
+	ovfl_mask   = arg->ovfl_pmds[0];
+	ovfl_notify = arg->ovfl_notify[0];
+
+	/*
+	 * check for space against largest possibly entry.
+	 * We may waste space at the end of the buffer.
+	 */
+	if ((last - cur) < PFM_DEFAULT_MAX_ENTRY_SIZE) goto full;
+
+	npmds = hweight64(arg->smpl_pmds[0]);
+
+	ent = (pfm_default_smpl_entry_t *)cur;
+
+	prefetch(arg->smpl_pmds_values);
+
+	/* position for first pmd */
+	e = (unsigned long *)(ent+1);
+
+	hdr->hdr_count++;
+
+	DPRINT_ovfl(("[%d] count=%lu cur=%p last=%p free_bytes=%lu ovfl_pmds=0x%lx ovfl_notify=0x%lx npmds=%u\n",
+			task->pid,
+			hdr->hdr_count,
+			cur, last,
+			last-cur,
+			ovfl_mask,
+			ovfl_notify, npmds));
+
+	/*
+	 * current = task running at the time of the overflow.
+	 *
+	 * per-task mode:
+	 * 	- this is ususally the task being monitored.
+	 * 	  Under certain conditions, it might be a different task
+	 *
+	 * system-wide:
+	 * 	- this is not necessarily the task controlling the session
+	 */
+	ent->pid            = current->pid;
+	ent->cpu            = smp_processor_id();
+	ent->last_reset_val = arg->pmd_last_reset; //pmd[0].reg_last_reset_val;
+
+	/*
+	 * where did the fault happen (includes slot number)
+	 */
+	ent->ip = regs->cr_iip | ((regs->cr_ipsr >> 41) & 0x3);
+
+	/*
+	 * which registers overflowed
+	 */
+	ent->ovfl_pmds = ovfl_mask;
+	ent->tstamp    = stamp;
+	ent->set       = arg->active_set;
+	ent->reserved1 = 0;
+
+	/*
+	 * selectively store PMDs in increasing index number
+	 */
+	if (npmds) {
+		unsigned long *val = arg->smpl_pmds_values;
+		for(i=0; i < npmds; i++) {
+			*e++ = *val++;
+		}
+	}
+
+	/*
+	 * update position for next entry
+	 */
+	hdr->hdr_cur_pos = cur + sizeof(*ent) + (npmds << 3);
+
+	/*
+	 * keep same ovfl_pmds, ovfl_notify
+	 */
+	arg->ovfl_ctrl.notify_user     = 0;
+	arg->ovfl_ctrl.block           = 0;
+	arg->ovfl_ctrl.stop_monitoring = 0;
+	arg->ovfl_ctrl.reset_pmds      = 1;
+
+	return 0;
+full:
+	DPRINT_ovfl(("sampling buffer full free=%lu, count=%lu, ovfl_notify=0x%lx\n", last-cur, hdr->hdr_count, ovfl_notify));
+
+	/*
+	 * increment number of buffer overflow.
+	 * important to detect duplicate set of samples.
+	 */
+	hdr->hdr_overflows++;
+
+	/*
+	 * if no notification is needed, then we just reset the buffer index.
+	 */
+	if (ovfl_notify == 0UL) {
+		hdr->hdr_count = 0UL;
+		arg->ovfl_ctrl.notify_user     = 0;
+		arg->ovfl_ctrl.block           = 0;
+		arg->ovfl_ctrl.stop_monitoring = 0;
+		arg->ovfl_ctrl.reset_pmds      = 1;
+	} else {
+		/* keep same ovfl_pmds, ovfl_notify */
+		arg->ovfl_ctrl.notify_user     = 1;
+		arg->ovfl_ctrl.block           = 1;
+		arg->ovfl_ctrl.stop_monitoring = 1;
+		arg->ovfl_ctrl.reset_pmds      = 0;
+	}
+	return 0;
+}
+
+static int
+default_restart(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs)
+{
+	pfm_default_smpl_hdr_t *hdr;
+
+	hdr = (pfm_default_smpl_hdr_t *)buf;
+
+	hdr->hdr_count   = 0UL;
+	hdr->hdr_cur_pos = (void *)((unsigned long)buf)+sizeof(*hdr);
+
+	ctrl->stop_monitoring = 0;
+	ctrl->reset_pmds      = PFM_PMD_LONG_RESET;
+
+	return 0;
+}
+
+static int
+default_exit(struct task_struct *task, void *buf, struct pt_regs *regs)
+{
+	DPRINT(("[%d] exit(%p)\n", task->pid, buf));
+	return 0;
+}
+
+static pfm_buffer_fmt_t default_fmt={
+	.fmt_name 	= "default_format",
+	.fmt_uuid	= PFM_DEFAULT_SMPL_UUID,
+	.fmt_arg_size	= sizeof(pfm_default_smpl_arg_t),
+	.fmt_validate	= default_validate,
+	.fmt_getsize	= default_get_size,
+	.fmt_init	= default_init,
+	.fmt_handler	= default_handler,
+	.fmt_restart	= default_restart,
+	.fmt_exit	= default_exit,
+};
+
+static int __init
+pfm_default_smpl_init_module(void)
+{
+	int ret;
+
+	ret = pfm_register_buffer_fmt(&default_fmt);
+	if (ret == 0) {
+		printk("perfmon_default_smpl: %s v%u.%u registered\n",
+			default_fmt.fmt_name,
+			PFM_DEFAULT_SMPL_VERSION_MAJ,
+			PFM_DEFAULT_SMPL_VERSION_MIN);
+	} else {
+		printk("perfmon_default_smpl: %s cannot register ret=%d\n",
+			default_fmt.fmt_name,
+			ret);
+	}
+
+	return ret;
+}
+
+static void __exit
+pfm_default_smpl_cleanup_module(void)
+{
+	int ret;
+	ret = pfm_unregister_buffer_fmt(default_fmt.fmt_uuid);
+
+	printk("perfmon_default_smpl: unregister %s=%d\n", default_fmt.fmt_name, ret);
+}
+
+module_init(pfm_default_smpl_init_module);
+module_exit(pfm_default_smpl_cleanup_module);
+
diff -Nru a/arch/ia64/kernel/perfmon_generic.h b/arch/ia64/kernel/perfmon_generic.h
--- a/arch/ia64/kernel/perfmon_generic.h	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/kernel/perfmon_generic.h	Wed Jun 18 23:42:07 2003
@@ -1,17 +1,19 @@
 /*
- * This file contains the architected PMU register description tables
+ * This file contains the generic PMU register description tables
  * and pmc checker used by perfmon.c.
  *
- * Copyright (C) 2002  Hewlett Packard Co
+ * Copyright (C) 2002-2003  Hewlett Packard Co
  *               Stephane Eranian <eranian@hpl.hp.com>
  */
+
+
 #define RDEP(x)	(1UL<<(x))
 
 #if defined(CONFIG_ITANIUM) || defined (CONFIG_MCKINLEY)
 #error "This file should not be used when CONFIG_ITANIUM or CONFIG_MCKINLEY is defined"
 #endif
 
-static pfm_reg_desc_t pmc_gen_desc[PMU_MAX_PMCS]={
+static pfm_reg_desc_t pfm_gen_pmc_desc[PMU_MAX_PMCS]={
 /* pmc0  */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc1  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc2  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
@@ -23,7 +25,7 @@
 	    { PFM_REG_END     , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
 };
 
-static pfm_reg_desc_t pmd_gen_desc[PMU_MAX_PMDS]={
+static pfm_reg_desc_t pfm_gen_pmd_desc[PMU_MAX_PMDS]={
 /* pmd0  */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}},
 /* pmd1  */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}},
 /* pmd2  */ { PFM_REG_NOTIMPL , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}},
@@ -39,10 +41,13 @@
  * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
  */
 static pmu_config_t pmu_conf={
-	.disabled = 1,
-	.ovfl_val = (1UL << 32) - 1,
-	.num_ibrs = 8,
-	.num_dbrs = 8,
-	.pmd_desc = pfm_gen_pmd_desc,
-	.pmc_desc = pfm_gen_pmc_desc
+	.pmu_name   = "Generic",
+	.pmu_family = 0xff, /* any */
+	.enabled    = 0,
+	.ovfl_val   = (1UL << 32) - 1,
+	.num_ibrs   = 0, /* does not use */
+	.num_dbrs   = 0, /* does not use */
+	.pmd_desc   = pfm_gen_pmd_desc,
+	.pmc_desc   = pfm_gen_pmc_desc
 };
+
diff -Nru a/arch/ia64/kernel/perfmon_itanium.h b/arch/ia64/kernel/perfmon_itanium.h
--- a/arch/ia64/kernel/perfmon_itanium.h	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/kernel/perfmon_itanium.h	Wed Jun 18 23:42:09 2003
@@ -2,7 +2,7 @@
  * This file contains the Itanium PMU register description tables
  * and pmc checker used by perfmon.c.
  *
- * Copyright (C) 2002  Hewlett Packard Co
+ * Copyright (C) 2002-2003  Hewlett Packard Co
  *               Stephane Eranian <eranian@hpl.hp.com>
  */
 
@@ -12,8 +12,8 @@
 #error "This file is only valid when CONFIG_ITANIUM is defined"
 #endif
 
-static int pfm_ita_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
-static int pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, struct pt_regs *regs);
+static int pfm_ita_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
+static int pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs);
 
 static pfm_reg_desc_t pfm_ita_pmc_desc[PMU_MAX_PMCS]={
 /* pmc0  */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
@@ -59,52 +59,53 @@
  * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
  */
 static pmu_config_t pmu_conf={
-	.disabled = 1,
-	.ovfl_val = (1UL << 32) - 1,
-	.num_ibrs = 8,
-	.num_dbrs = 8,
-	.pmd_desc = pfm_ita_pmd_desc,
-	.pmc_desc = pfm_ita_pmc_desc
+	.pmu_name      = "Itanium",
+	.pmu_family    = 0x7,
+	.enabled       = 0,
+	.ovfl_val      = (1UL << 32) - 1,
+	.pmd_desc      = pfm_ita_pmd_desc,
+	.pmc_desc      = pfm_ita_pmc_desc,
+	.num_ibrs      = 8,
+	.num_dbrs      = 8,
+	.use_rr_dbregs = 1 /* debug register are use for range retrictions */
 };
 
-
 static int
-pfm_ita_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
+pfm_ita_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
 {
-	pfm_context_t *ctx = task->thread.pfm_context;
 	int ret;
 
 	/*
 	 * we must clear the (instruction) debug registers if pmc13.ta bit is cleared
-	 * before they are written (fl_using_dbreg==0) to avoid picking up stale information. 
+	 * before they are written (fl_using_dbreg==0) to avoid picking up stale information.
 	 */
 	if (cnum == 13 && ((*val & 0x1) == 0UL) && ctx->ctx_fl_using_dbreg == 0) {
 
 		/* don't mix debug with perfmon */
-		if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
+		if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
 
-		/* 
+		/*
 		 * a count of 0 will mark the debug registers as in use and also
 		 * ensure that they are properly cleared.
 		 */
-		ret = pfm_write_ibr_dbr(1, task, NULL, 0, regs);
+		ret = pfm_write_ibr_dbr(1, ctx, NULL, 0, regs);
 		if (ret) return ret;
 	}
 
 	/*
 	 * we must clear the (data) debug registers if pmc11.pt bit is cleared
-	 * before they are written (fl_using_dbreg==0) to avoid picking up stale information. 
+	 * before they are written (fl_using_dbreg==0) to avoid picking up stale information.
 	 */
 	if (cnum == 11 && ((*val >> 28)& 0x1) == 0 && ctx->ctx_fl_using_dbreg == 0) {
 
 		/* don't mix debug with perfmon */
-		if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
+		if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
 
-		/* 
+		/*
 		 * a count of 0 will mark the debug registers as in use and also
 		 * ensure that they are properly cleared.
 		 */
-		ret = pfm_write_ibr_dbr(0, task, NULL, 0, regs);
+		ret = pfm_write_ibr_dbr(0, ctx, NULL, 0, regs);
 		if (ret) return ret;
 	}
 	return 0;
diff -Nru a/arch/ia64/kernel/perfmon_mckinley.h b/arch/ia64/kernel/perfmon_mckinley.h
--- a/arch/ia64/kernel/perfmon_mckinley.h	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/kernel/perfmon_mckinley.h	Wed Jun 18 23:42:08 2003
@@ -2,7 +2,7 @@
  * This file contains the McKinley PMU register description tables
  * and pmc checker used by perfmon.c.
  *
- * Copyright (C) 2002  Hewlett Packard Co
+ * Copyright (C) 2002-2003  Hewlett Packard Co
  *               Stephane Eranian <eranian@hpl.hp.com>
  */
 
@@ -12,9 +12,8 @@
 #error "This file is only valid when CONFIG_MCKINLEY is defined"
 #endif
 
-static int pfm_mck_reserved(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
-static int pfm_mck_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
-static int pfm_write_ibr_dbr(int mode, struct task_struct *task, void *arg, int count, struct pt_regs *regs);
+static int pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs);
+static int pfm_write_ibr_dbr(int mode, pfm_context_t *ctx, void *arg, int count, struct pt_regs *regs);
 
 static pfm_reg_desc_t pfm_mck_pmc_desc[PMU_MAX_PMCS]={
 /* pmc0  */ { PFM_REG_CONTROL , 0, 0x1UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
@@ -22,17 +21,17 @@
 /* pmc2  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc3  */ { PFM_REG_CONTROL , 0, 0x0UL, -1UL, NULL, NULL, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc4  */ { PFM_REG_COUNTING, 6, 0x0000000000800000UL, 0xfffff7fUL, NULL, pfm_mck_pmc_check, {RDEP(4),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc5  */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL,  pfm_mck_reserved, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc6  */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL,  pfm_mck_reserved, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc7  */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL,  pfm_mck_reserved, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc8  */ { PFM_REG_CONFIG  , 0, 0xffffffff3fffffffUL, 0xffffffff3fffffffUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc9  */ { PFM_REG_CONFIG  , 0, 0xffffffff3ffffffcUL, 0xffffffff3fffffffUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc10 */ { PFM_REG_MONITOR , 4, 0x0UL, 0xffffUL, NULL, pfm_mck_reserved, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc11 */ { PFM_REG_MONITOR , 6, 0x0UL, 0x30f01cf, NULL,  pfm_mck_reserved, {RDEP(2)|RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc12 */ { PFM_REG_MONITOR , 6, 0x0UL, 0xffffUL, NULL,  pfm_mck_reserved, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc5  */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL,  pfm_mck_pmc_check, {RDEP(5),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc6  */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL,  pfm_mck_pmc_check, {RDEP(6),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc7  */ { PFM_REG_COUNTING, 6, 0x0UL, 0xfffff7fUL, NULL,  pfm_mck_pmc_check, {RDEP(7),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc8  */ { PFM_REG_CONFIG  , 0, 0xffffffff3fffffffUL, 0xffffffff3ffffffbUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc9  */ { PFM_REG_CONFIG  , 0, 0xffffffff3ffffffcUL, 0xffffffff3ffffffbUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc10 */ { PFM_REG_MONITOR , 4, 0x0UL, 0xffffUL, NULL, pfm_mck_pmc_check, {RDEP(0)|RDEP(1),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc11 */ { PFM_REG_MONITOR , 6, 0x0UL, 0x30f01cf, NULL,  pfm_mck_pmc_check, {RDEP(2)|RDEP(3)|RDEP(17),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc12 */ { PFM_REG_MONITOR , 6, 0x0UL, 0xffffUL, NULL,  pfm_mck_pmc_check, {RDEP(8)|RDEP(9)|RDEP(10)|RDEP(11)|RDEP(12)|RDEP(13)|RDEP(14)|RDEP(15)|RDEP(16),0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc13 */ { PFM_REG_CONFIG  , 0, 0x00002078fefefefeUL, 0x1e00018181818UL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 /* pmc14 */ { PFM_REG_CONFIG  , 0, 0x0db60db60db60db6UL, 0x2492UL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
-/* pmc15 */ { PFM_REG_CONFIG  , 0, 0x00000000fffffff0UL, 0xfUL, NULL, pfm_mck_reserved, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
+/* pmc15 */ { PFM_REG_CONFIG  , 0, 0x00000000fffffff0UL, 0xfUL, NULL, pfm_mck_pmc_check, {0UL,0UL, 0UL, 0UL}, {0UL,0UL, 0UL, 0UL}},
 	    { PFM_REG_END     , 0, 0x0UL, -1UL, NULL, NULL, {0,}, {0,}}, /* end marker */
 };
 
@@ -62,20 +61,22 @@
  * impl_pmcs, impl_pmds are computed at runtime to minimize errors!
  */
 static pmu_config_t pmu_conf={
-	.disabled = 1,
-	.ovfl_val = (1UL << 47) - 1,
-	.num_ibrs = 8,
-	.num_dbrs = 8,
-	.pmd_desc = pfm_mck_pmd_desc,
-	.pmc_desc = pfm_mck_pmc_desc
+	.pmu_name      = "Itanium 2",
+	.pmu_family    = 0x1f,
+	.enabled       = 0,
+	.ovfl_val      = (1UL << 47) - 1,
+	.pmd_desc      = pfm_mck_pmd_desc,
+	.pmc_desc      = pfm_mck_pmc_desc,
+	.num_ibrs       = 8,
+	.num_dbrs       = 8,
+	.use_rr_dbregs = 1 /* debug register are use for range retrictions */
 };
 
-
 /*
  * PMC reserved fields must have their power-up values preserved
  */
 static int
-pfm_mck_reserved(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
+pfm_mck_reserved(unsigned int cnum, unsigned long *val, struct pt_regs *regs)
 {
 	unsigned long tmp1, tmp2, ival = *val;
 
@@ -87,52 +88,56 @@
 
 	*val = tmp1 | tmp2;
 
-	DBprintk(("pmc[%d]=0x%lx, mask=0x%lx, reset=0x%lx, val=0x%lx\n", 
-		  cnum, ival, PMC_RSVD_MASK(cnum), PMC_DFL_VAL(cnum), *val)); 
+	DPRINT(("pmc[%d]=0x%lx, mask=0x%lx, reset=0x%lx, val=0x%lx\n",
+		  cnum, ival, PMC_RSVD_MASK(cnum), PMC_DFL_VAL(cnum), *val));
 	return 0;
 }
 
+/*
+ * task can be NULL if the context is unloaded
+ */
 static int
-pfm_mck_pmc_check(struct task_struct *task, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
+pfm_mck_pmc_check(struct task_struct *task, pfm_context_t *ctx, unsigned int cnum, unsigned long *val, struct pt_regs *regs)
 {
-	struct thread_struct *th = &task->thread;
-	pfm_context_t *ctx = task->thread.pfm_context;
 	int ret = 0, check_case1 = 0;
 	unsigned long val8 = 0, val14 = 0, val13 = 0;
 
 	/* first preserve the reserved fields */
-	pfm_mck_reserved(task, cnum, val, regs);
+	pfm_mck_reserved(cnum, val, regs);
+
+	/* sanitfy check */
+	if (ctx == NULL) return -EINVAL;
 
 	/*
-	 * we must clear the debug registers if any pmc13.ena_dbrpX bit is enabled 
-	 * before they are written (fl_using_dbreg==0) to avoid picking up stale information. 
+	 * we must clear the debug registers if any pmc13.ena_dbrpX bit is enabled
+	 * before they are written (fl_using_dbreg==0) to avoid picking up stale information.
 	 */
 	if (cnum == 13 && (*val & (0xfUL << 45)) && ctx->ctx_fl_using_dbreg == 0) {
 
 		/* don't mix debug with perfmon */
-		if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
+		if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
 
-		/* 
+		/*
 		 * a count of 0 will mark the debug registers as in use and also
 		 * ensure that they are properly cleared.
 		 */
-		ret = pfm_write_ibr_dbr(1, task, NULL, 0, regs);
+		ret = pfm_write_ibr_dbr(1, ctx, NULL, 0, regs);
 		if (ret) return ret;
 	}
-	/* 
-	 * we must clear the (instruction) debug registers if any pmc14.ibrpX bit is enabled 
-	 * before they are (fl_using_dbreg==0) to avoid picking up stale information. 
+	/*
+	 * we must clear the (instruction) debug registers if any pmc14.ibrpX bit is enabled
+	 * before they are (fl_using_dbreg==0) to avoid picking up stale information.
 	 */
 	if (cnum == 14 && ((*val & 0x2222) != 0x2222) && ctx->ctx_fl_using_dbreg == 0) {
 
 		/* don't mix debug with perfmon */
-		if ((task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
+		if (task && (task->thread.flags & IA64_THREAD_DBG_VALID) != 0) return -EINVAL;
 
-		/* 
+		/*
 		 * a count of 0 will mark the debug registers as in use and also
 		 * ensure that they are properly cleared.
 		 */
-		ret = pfm_write_ibr_dbr(0, task, NULL, 0, regs);
+		ret = pfm_write_ibr_dbr(0, ctx, NULL, 0, regs);
 		if (ret) return ret;
 
 	}
@@ -141,17 +146,17 @@
 		case  4: *val |= 1UL << 23; /* force power enable bit */
 			 break;
 		case  8: val8 = *val;
-			 val13 = th->pmc[13];
-			 val14 = th->pmc[14];
+			 val13 = ctx->ctx_pmcs[13];
+			 val14 = ctx->ctx_pmcs[14];
 			 check_case1 = 1;
 			 break;
-		case 13: val8  = th->pmc[8];
+		case 13: val8  = ctx->ctx_pmcs[8];
 			 val13 = *val;
-			 val14 = th->pmc[14];
+			 val14 = ctx->ctx_pmcs[14];
 			 check_case1 = 1;
 			 break;
-		case 14: val8  = th->pmc[13];
-			 val13 = th->pmc[13];
+		case 14: val8  = ctx->ctx_pmcs[13];
+			 val13 = ctx->ctx_pmcs[13];
 			 val14 = *val;
 			 check_case1 = 1;
 			 break;
@@ -165,7 +170,7 @@
 		   && ((((val14>>1) & 0x3) == 0x2 || ((val14>>1) & 0x3) == 0x0)
 		       ||(((val14>>4) & 0x3) == 0x2 || ((val14>>4) & 0x3) == 0x0));
 
-		if (ret) printk(KERN_DEBUG "perfmon: failure check_case1\n");
+		if (ret) printk("perfmon: failure check_case1\n");
 	}
 
 	return ret ? -EINVAL : 0;
diff -Nru a/arch/ia64/kernel/process.c b/arch/ia64/kernel/process.c
--- a/arch/ia64/kernel/process.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/kernel/process.c	Wed Jun 18 23:42:07 2003
@@ -25,7 +25,6 @@
 
 #include <asm/delay.h>
 #include <asm/elf.h>
-#include <asm/perfmon.h>
 #include <asm/pgalloc.h>
 #include <asm/processor.h>
 #include <asm/sal.h>
@@ -33,16 +32,15 @@
 #include <asm/unwind.h>
 #include <asm/user.h>
 
-#ifdef CONFIG_IA64_SGI_SN
-#include <asm/sn/idle.h>
-#endif
-
 #ifdef CONFIG_PERFMON
 # include <asm/perfmon.h>
 #endif
 
 #include "sigframe.h"
 
+void (*ia64_mark_idle)(int);
+
+
 void
 ia64_do_show_stack (struct unw_frame_info *info, void *arg)
 {
@@ -64,13 +62,7 @@
 }
 
 void
-show_trace_task (struct task_struct *task)
-{
-	show_stack(task);
-}
-
-void
-show_stack (struct task_struct *task)
+show_stack (struct task_struct *task, unsigned long *sp)
 {
 	if (!task)
 		unw_init_running(ia64_do_show_stack, 0);
@@ -85,7 +77,7 @@
 void
 dump_stack (void)
 {
-	show_stack(NULL);
+	show_stack(NULL, NULL);
 }
 
 void
@@ -103,6 +95,7 @@
 	       regs->ar_rnat, regs->ar_bspstore, regs->pr);
 	printk("ldrs: %016lx ccv : %016lx fpsr: %016lx\n",
 	       regs->loadrs, regs->ar_ccv, regs->ar_fpsr);
+	printk("csd : %016lx ssd : %016lx\n", regs->ar_csd, regs->ar_ssd);
 	printk("b0  : %016lx b6  : %016lx b7  : %016lx\n", regs->b0, regs->b6, regs->b7);
 	printk("f6  : %05lx%016lx f7  : %05lx%016lx\n",
 	       regs->f6.u.bits[1], regs->f6.u.bits[0],
@@ -110,6 +103,9 @@
 	printk("f8  : %05lx%016lx f9  : %05lx%016lx\n",
 	       regs->f8.u.bits[1], regs->f8.u.bits[0],
 	       regs->f9.u.bits[1], regs->f9.u.bits[0]);
+	printk("f10 : %05lx%016lx f11 : %05lx%016lx\n",
+	       regs->f10.u.bits[1], regs->f10.u.bits[0],
+	       regs->f11.u.bits[1], regs->f11.u.bits[0]);
 
 	printk("r1  : %016lx r2  : %016lx r3  : %016lx\n", regs->r1, regs->r2, regs->r3);
 	printk("r8  : %016lx r9  : %016lx r10 : %016lx\n", regs->r8, regs->r9, regs->r10);
@@ -135,24 +131,22 @@
 			       ((i == sof - 1) || (i % 3) == 2) ? "\n" : " ");
 		}
 	} else
-		show_stack(NULL);
+		show_stack(NULL, NULL);
 }
 
 void
 do_notify_resume_user (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
 {
-#ifdef CONFIG_FSYS
 	if (fsys_mode(current, &scr->pt)) {
 		/* defer signal-handling etc. until we return to privilege-level 0.  */
 		if (!ia64_psr(&scr->pt)->lp)
 			ia64_psr(&scr->pt)->lp = 1;
 		return;
 	}
-#endif
 
 #ifdef CONFIG_PERFMON
-	if (current->thread.pfm_ovfl_block_reset)
-		pfm_ovfl_block_reset();
+	if (current->thread.pfm_needs_checking)
+		pfm_handle_work();
 #endif
 
 	/* deal with pending signal delivery */
@@ -175,6 +169,8 @@
 void __attribute__((noreturn))
 cpu_idle (void *unused)
 {
+	void (*mark_idle)(int) = ia64_mark_idle;
+
 	/* endless idle loop with no priority at all */
 	while (1) {
 		void (*idle)(void) = pm_idle;
@@ -187,15 +183,13 @@
 #endif
 
 		while (!need_resched()) {
-#ifdef CONFIG_IA64_SGI_SN
-			snidle();
-#endif
+			if (mark_idle)
+				(*mark_idle)(1);
 			(*idle)();
 		}
 
-#ifdef CONFIG_IA64_SGI_SN
-		snidleoff();
-#endif
+		if (mark_idle)
+			(*mark_idle)(0);
 
 #ifdef CONFIG_SMP
 		normal_xtp();
@@ -379,7 +373,7 @@
 #	define THREAD_FLAGS_TO_SET	0
 	p->thread.flags = ((current->thread.flags & ~THREAD_FLAGS_TO_CLEAR)
 			   | THREAD_FLAGS_TO_SET);
-	p->thread.last_fph_cpu = -1;
+	ia64_drop_fpu(p);	/* don't pick up stale state from a CPU's fph */
 #ifdef CONFIG_IA32_SUPPORT
 	/*
 	 * If we're cloning an IA32 task then save the IA32 extra
@@ -390,16 +384,8 @@
 #endif
 
 #ifdef CONFIG_PERFMON
-	/*
-	 * reset notifiers and owner check (may not have a perfmon context)
-	 */
-	atomic_set(&p->thread.pfm_notifiers_check, 0);
-	atomic_set(&p->thread.pfm_owners_check, 0);
-	/* clear list of sampling buffer to free for new task */
-	p->thread.pfm_smpl_buf_list = NULL;
-
 	if (current->thread.pfm_context)
-		retval = pfm_inherit(p, child_ptregs);
+		pfm_inherit(p, child_ptregs);
 #endif
 	return retval;
 }
@@ -472,6 +458,8 @@
 	dst[52] = pt->ar_pfs;	/* UNW_AR_PFS is == to pt->cr_ifs for interrupt frames */
 	unw_get_ar(info, UNW_AR_LC, &dst[53]);
 	unw_get_ar(info, UNW_AR_EC, &dst[54]);
+	unw_get_ar(info, UNW_AR_CSD, &dst[55]);
+	unw_get_ar(info, UNW_AR_SSD, &dst[56]);
 }
 
 void
@@ -579,7 +567,8 @@
 kernel_thread (int (*fn)(void *), void *arg, unsigned long flags)
 {
 	struct task_struct *parent = current;
-	int result, tid;
+	int result; 
+	pid_t tid;
 
 	tid = clone(flags | CLONE_VM | CLONE_UNTRACED, 0);
 	if (parent != current) {
@@ -606,41 +595,9 @@
 {
 	/* drop floating-point and debug-register state if it exists: */
 	current->thread.flags &= ~(IA64_THREAD_FPH_VALID | IA64_THREAD_DBG_VALID);
-
-#ifndef CONFIG_SMP
-	if (ia64_get_fpu_owner() == current)
-		ia64_set_fpu_owner(0);
-#endif
+	ia64_drop_fpu(current);
 }
 
-#ifdef CONFIG_PERFMON
-/*
- * by the time we get here, the task is detached from the tasklist. This is important
- * because it means that no other tasks can ever find it as a notified task, therfore there
- * is no race condition between this code and let's say a pfm_context_create().
- * Conversely, the pfm_cleanup_notifiers() cannot try to access a task's pfm context if this
- * other task is in the middle of its own pfm_context_exit() because it would already be out of
- * the task list. Note that this case is very unlikely between a direct child and its parents
- * (if it is the notified process) because of the way the exit is notified via SIGCHLD.
- */
-
-void
-release_thread (struct task_struct *task)
-{
-	if (task->thread.pfm_context)
-		pfm_context_exit(task);
-
-	if (atomic_read(&task->thread.pfm_notifiers_check) > 0)
-		pfm_cleanup_notifiers(task);
-
-	if (atomic_read(&task->thread.pfm_owners_check) > 0)
-		pfm_cleanup_owners(task);
-
-	if (task->thread.pfm_smpl_buf_list)
-		pfm_cleanup_smpl_buf(task);
-}
-#endif
-
 /*
  * Clean up state associated with current thread.  This is called when
  * the thread calls exit().
@@ -648,14 +605,11 @@
 void
 exit_thread (void)
 {
-#ifndef CONFIG_SMP
-	if (ia64_get_fpu_owner() == current)
-		ia64_set_fpu_owner(0);
-#endif
+	ia64_drop_fpu(current);
 #ifdef CONFIG_PERFMON
        /* if needed, stop monitoring and flush state to perfmon context */
-	if (current->thread.pfm_context) 
-		pfm_flush_regs(current);
+	if (current->thread.pfm_context)
+		pfm_exit_thread(current);
 
 	/* free debug register resources */
 	if (current->thread.flags & IA64_THREAD_DBG_VALID)
@@ -739,30 +693,4 @@
 	if (pm_power_off)
 		pm_power_off();
 	machine_halt();
-}
-
-void __init
-init_task_struct_cache (void)
-{
-}
-
-struct task_struct *
-dup_task_struct(struct task_struct *orig)
-{
-	struct task_struct *tsk;
-
-	tsk = (void *) __get_free_pages(GFP_KERNEL, KERNEL_STACK_SIZE_ORDER);
-	if (!tsk)
-		return NULL;
-
-	memcpy(tsk, orig, sizeof(struct task_struct) + sizeof(struct thread_info));
-	tsk->thread_info = (struct thread_info *) ((char *) tsk + IA64_TASK_SIZE);
-	atomic_set(&tsk->usage, 2);
-	return tsk;
-}
-
-void
-free_task_struct (struct task_struct *tsk)
-{
-	free_pages((unsigned long) tsk, KERNEL_STACK_SIZE_ORDER);
 }
diff -Nru a/arch/ia64/kernel/ptrace.c b/arch/ia64/kernel/ptrace.c
--- a/arch/ia64/kernel/ptrace.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/kernel/ptrace.c	Wed Jun 18 23:42:09 2003
@@ -200,14 +200,20 @@
  */
 static unsigned long
 get_rnat (struct pt_regs *pt, struct switch_stack *sw,
-	  unsigned long *krbs, unsigned long *urnat_addr)
+	  unsigned long *krbs, unsigned long *urnat_addr, unsigned long *urbs_end)
 {
-	unsigned long rnat0 = 0, rnat1 = 0, urnat = 0, *slot0_kaddr, umask = 0UL;
+	unsigned long rnat0 = 0, rnat1 = 0, urnat = 0, *slot0_kaddr, umask = 0, mask, m;
 	unsigned long *kbsp, *ubspstore, *rnat0_kaddr, *rnat1_kaddr, shift;
-	long num_regs;
+	long num_regs, nbits;
 
 	kbsp = (unsigned long *) sw->ar_bspstore;
 	ubspstore = (unsigned long *) pt->ar_bspstore;
+
+	if (urbs_end < urnat_addr)
+		nbits = ia64_rse_num_regs(urnat_addr - 63, urbs_end);
+	else
+		nbits = 63;
+	mask = (1UL << nbits) - 1;
 	/*
 	 * First, figure out which bit number slot 0 in user-land maps to in the kernel
 	 * rnat.  Do this by figuring out how many register slots we're beyond the user's
@@ -221,20 +227,26 @@
 
 	if (ubspstore + 63 > urnat_addr) {
 		/* some bits need to be merged in from pt->ar_rnat */
-		umask = ((1UL << ia64_rse_slot_num(ubspstore)) - 1);
+		umask = ((1UL << ia64_rse_slot_num(ubspstore)) - 1) & mask;
 		urnat = (pt->ar_rnat & umask);
+		mask &= ~umask;
+		if (!mask)
+			return urnat;
 	}
-	if (rnat0_kaddr >= kbsp) {
+
+	m = mask << shift;
+	if (rnat0_kaddr >= kbsp)
 		rnat0 = sw->ar_rnat;
-	} else if (rnat0_kaddr > krbs) {
+	else if (rnat0_kaddr > krbs)
 		rnat0 = *rnat0_kaddr;
-	}
-	if (rnat1_kaddr >= kbsp) {
+	urnat |= (rnat0 & m) >> shift;
+
+	m = mask >> (63 - shift);
+	if (rnat1_kaddr >= kbsp)
 		rnat1 = sw->ar_rnat;
-	} else if (rnat1_kaddr > krbs) {
+	else if (rnat1_kaddr > krbs)
 		rnat1 = *rnat1_kaddr;
-	}
-	urnat |= ((rnat1 << (63 - shift)) | (rnat0 >> shift)) & ~umask;
+	urnat |= (rnat1 & m) << (63 - shift);
 	return urnat;
 }
 
@@ -243,60 +255,58 @@
  */
 static void
 put_rnat (struct pt_regs *pt, struct switch_stack *sw,
-	  unsigned long *krbs, unsigned long *urnat_addr, unsigned long urnat)
+	  unsigned long *krbs, unsigned long *urnat_addr, unsigned long urnat,
+	  unsigned long *urbs_end)
 {
 	unsigned long rnat0 = 0, rnat1 = 0, *slot0_kaddr, umask = 0, mask, m;
-	unsigned long *kbsp, *ubspstore, *rnat0_kaddr, *rnat1_kaddr, shift, slot, ndirty;
+	unsigned long *kbsp, *ubspstore, *rnat0_kaddr, *rnat1_kaddr, shift;
 	long num_regs, nbits;
 
-	ndirty = ia64_rse_num_regs(krbs, krbs + (pt->loadrs >> 19));
-	nbits = ndirty % 63;
-
 	kbsp = (unsigned long *) sw->ar_bspstore;
 	ubspstore = (unsigned long *) pt->ar_bspstore;
+
+	if (urbs_end < urnat_addr)
+		nbits = ia64_rse_num_regs(urnat_addr - 63, urbs_end);
+	else
+		nbits = 63;
+	mask = (1UL << nbits) - 1;
+
 	/*
 	 * First, figure out which bit number slot 0 in user-land maps to in the kernel
 	 * rnat.  Do this by figuring out how many register slots we're beyond the user's
 	 * backingstore and then computing the equivalent address in kernel space.
 	 */
-	num_regs = (long) ia64_rse_num_regs(ubspstore, urnat_addr + 1);
+	num_regs = ia64_rse_num_regs(ubspstore, urnat_addr + 1);
 	slot0_kaddr = ia64_rse_skip_regs(krbs, num_regs);
 	shift = ia64_rse_slot_num(slot0_kaddr);
 	rnat1_kaddr = ia64_rse_rnat_addr(slot0_kaddr);
 	rnat0_kaddr = rnat1_kaddr - 64;
 
-printk("%s: ubspstore=%p urnat_addr=%p\n", __FUNCTION__, ubspstore, urnat_addr);
 	if (ubspstore + 63 > urnat_addr) {
 		/* some bits need to be place in pt->ar_rnat: */
-		slot = ia64_rse_slot_num(ubspstore);
-		umask = ((1UL << slot) - 1);
+		umask = ((1UL << ia64_rse_slot_num(ubspstore)) - 1) & mask;
 		pt->ar_rnat = (pt->ar_rnat & ~umask) | (urnat & umask);
-		nbits -= slot;
-		if (nbits <= 0)
+		mask &= ~umask;
+		if (!mask)
 			return;
 	}
-	mask = (1UL << nbits) - 1;
 	/*
 	 * Note: Section 11.1 of the EAS guarantees that bit 63 of an
 	 * rnat slot is ignored. so we don't have to clear it here.
 	 */
 	rnat0 = (urnat << shift);
 	m = mask << shift;
-printk("%s: rnat0=%016lx, m=%016lx, rnat0_kaddr=%p kbsp=%p\n", __FUNCTION__, rnat0, m, rnat0_kaddr, kbsp);
-	if (rnat0_kaddr >= kbsp) {
+	if (rnat0_kaddr >= kbsp)
 		sw->ar_rnat = (sw->ar_rnat & ~m) | (rnat0 & m);
-	} else if (rnat0_kaddr > krbs) {
+	else if (rnat0_kaddr > krbs)
 		*rnat0_kaddr = ((*rnat0_kaddr & ~m) | (rnat0 & m));
-	}
 
 	rnat1 = (urnat >> (63 - shift));
 	m = mask >> (63 - shift);
-printk("%s: rnat1=%016lx, m=%016lx, rnat1_kaddr=%p kbsp=%p\n", __FUNCTION__, rnat1, m, rnat1_kaddr, kbsp);
-	if (rnat1_kaddr >= kbsp) {
+	if (rnat1_kaddr >= kbsp)
 		sw->ar_rnat = (sw->ar_rnat & ~m) | (rnat1 & m);
-	} else if (rnat1_kaddr > krbs) {
+	else if (rnat1_kaddr > krbs)
 		*rnat1_kaddr = ((*rnat1_kaddr & ~m) | (rnat1 & m));
-	}
 }
 
 /*
@@ -329,7 +339,7 @@
 		 * read the corresponding bits in the kernel RBS.
 		 */
 		rnat_addr = ia64_rse_rnat_addr(laddr);
-		ret = get_rnat(child_regs, child_stack, krbs, rnat_addr);
+		ret = get_rnat(child_regs, child_stack, krbs, rnat_addr, urbs_end);
 
 		if (laddr == rnat_addr) {
 			/* return NaT collection word itself */
@@ -380,7 +390,7 @@
 		 * => write the corresponding bits in the kernel RBS.
 		 */
 		if (ia64_rse_is_rnat_slot(laddr))
-			put_rnat(child_regs, child_stack, krbs, laddr, val);
+			put_rnat(child_regs, child_stack, krbs, laddr, val, urbs_end);
 		else {
 			if (laddr < urbs_end) {
 				regnum = ia64_rse_num_regs(bspstore, laddr);
@@ -588,17 +598,11 @@
 ia64_flush_fph (struct task_struct *task)
 {
 	struct ia64_psr *psr = ia64_psr(ia64_task_regs(task));
-#ifdef CONFIG_SMP
-	struct task_struct *fpu_owner = current;
-#else
-	struct task_struct *fpu_owner = ia64_get_fpu_owner();
-#endif
 
-	if (task == fpu_owner && psr->mfh) {
+	if (ia64_is_local_fpu_owner(task) && psr->mfh) {
 		psr->mfh = 0;
-		ia64_save_fpu(&task->thread.fph[0]);
 		task->thread.flags |= IA64_THREAD_FPH_VALID;
-		task->thread.last_fph_cpu = smp_processor_id();
+		ia64_save_fpu(&task->thread.fph[0]);
 	}
 }
 
@@ -618,11 +622,9 @@
 	ia64_flush_fph(task);
 	if (!(task->thread.flags & IA64_THREAD_FPH_VALID)) {
 		task->thread.flags |= IA64_THREAD_FPH_VALID;
-		task->thread.last_fph_cpu = -1;		/* force reload */
 		memset(&task->thread.fph, 0, sizeof(task->thread.fph));
 	}
-	if (ia64_get_fpu_owner() == task)
-		ia64_set_fpu_owner(0);
+	ia64_drop_fpu(task);
 	psr->dfh = 1;
 }
 
@@ -667,9 +669,13 @@
 		else
 			ia64_flush_fph(child);
 		ptr = (unsigned long *) ((unsigned long) &child->thread.fph + addr);
-	} else if (addr >= PT_F10 && addr < PT_F15 + 16) {
+	} else if ((addr >= PT_F10) && (addr < PT_F11 + 16)) {
+		/* scratch registers untouched by kernel (saved in pt_regs) */
+		ptr = (unsigned long *)
+			((long) pt + offsetof(struct pt_regs, f10) + addr - PT_F10);
+	} else if (addr >= PT_F12 && addr < PT_F15 + 16) {
 		/* scratch registers untouched by kernel (saved in switch_stack) */
-		ptr = (unsigned long *) ((long) sw + addr - PT_NAT_BITS);
+		ptr = (unsigned long *) ((long) sw + (addr - PT_NAT_BITS - 32));
 	} else if (addr < PT_AR_LC + 8) {
 		/* preserved state: */
 		unsigned long nat_bits, scratch_unat, dummy = 0;
@@ -805,22 +811,75 @@
 			else
 				return ia64_peek(child, sw, urbs_end, rnat_addr, data);
 
-				   case PT_R1:  case PT_R2:  case PT_R3:
+		      case PT_R1:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r1));
+			break;
+
+		      case PT_R2:  case PT_R3:
+			ptr = (unsigned long *)
+				((long) pt + offsetof(struct pt_regs, r2) + addr - PT_R2);
+			break;
 		      case PT_R8:  case PT_R9:  case PT_R10: case PT_R11:
-		      case PT_R12: case PT_R13: case PT_R14: case PT_R15:
+			ptr = (unsigned long *)
+				((long) pt + offsetof(struct pt_regs, r8)+  addr - PT_R8);
+			break;
+		      case PT_R12: case PT_R13:
+			ptr = (unsigned long *)
+				((long) pt + offsetof(struct pt_regs, r12)+  addr - PT_R12);
+			break;
+		      case PT_R14:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r14));
+			break;
+		      case PT_R15:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, r15));
+			break;
 		      case PT_R16: case PT_R17: case PT_R18: case PT_R19:
 		      case PT_R20: case PT_R21: case PT_R22: case PT_R23:
 		      case PT_R24: case PT_R25: case PT_R26: case PT_R27:
 		      case PT_R28: case PT_R29: case PT_R30: case PT_R31:
-		      case PT_B0:  case PT_B6:  case PT_B7:
+			ptr = (unsigned long *)
+				((long) pt + offsetof(struct pt_regs, r16) + addr - PT_R16);
+			break;
+		      case PT_B0:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, b0));
+			break;
+		      case PT_B6:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, b6));
+			break;
+		      case PT_B7:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, b7));
+			break;
 		      case PT_F6:  case PT_F6+8: case PT_F7: case PT_F7+8:
 		      case PT_F8:  case PT_F8+8: case PT_F9: case PT_F9+8:
+			ptr = (unsigned long *)
+				((long) pt + offsetof(struct pt_regs, f6) + addr - PT_F6);
+			break;
 		      case PT_AR_BSPSTORE:
-		      case PT_AR_RSC: case PT_AR_UNAT: case PT_AR_PFS:
-		      case PT_AR_CCV: case PT_AR_FPSR: case PT_CR_IIP: case PT_PR:
-			/* scratch register */
-			ptr = (unsigned long *) ((long) pt + addr - PT_CR_IPSR);
+			ptr = (unsigned long *)
+				((long) pt + offsetof(struct pt_regs, ar_bspstore));
+			break;
+		      case PT_AR_RSC:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_rsc));
+			break;
+		      case PT_AR_UNAT:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_unat));
+			break;
+		      case PT_AR_PFS:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_pfs));
 			break;
+		      case PT_AR_CCV:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_ccv));
+			break;
+		      case PT_AR_FPSR:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, ar_fpsr));
+			break;
+		      case PT_CR_IIP:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, cr_iip));
+			break;
+		      case PT_PR:
+			ptr = (unsigned long *) ((long) pt + offsetof(struct pt_regs, pr));
+			break;
+			/* scratch register */
 
 		      default:
 			/* disallow accessing anything else... */
@@ -828,6 +887,9 @@
 				addr);
 			return -1;
 		}
+	} else if (addr <= PT_AR_SSD) {
+		ptr = (unsigned long *)
+			((long) pt + offsetof(struct pt_regs, ar_csd) + addr - PT_AR_CSD);
 	} else {
 		/* access debug registers */
 
@@ -934,7 +996,8 @@
 
 	/* gr1-gr3 */
 
-	retval |= __copy_to_user(&ppr->gr[1], &pt->r1, sizeof(long) * 3);
+	retval |= __copy_to_user(&ppr->gr[1], &pt->r1, sizeof(long));
+	retval |= __copy_to_user(&ppr->gr[2], &pt->r2, sizeof(long) *2);
 
 	/* gr4-gr7 */
 
@@ -948,7 +1011,9 @@
 
 	/* gr12-gr15 */
 
-	retval |= __copy_to_user(&ppr->gr[12], &pt->r12, sizeof(long) * 4);
+	retval |= __copy_to_user(&ppr->gr[12], &pt->r12, sizeof(long) * 2);
+	retval |= __copy_to_user(&ppr->gr[14], &pt->r14, sizeof(long));
+	retval |= __copy_to_user(&ppr->gr[15], &pt->r15, sizeof(long));
 
 	/* gr16-gr31 */
 
@@ -976,13 +1041,13 @@
 		retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 0);
 	}
 
-	/* fr6-fr9 */
+	/* fr6-fr11 */
 
-	retval |= __copy_to_user(&ppr->fr[6], &pt->f6, sizeof(struct ia64_fpreg) * 4);
+	retval |= __copy_to_user(&ppr->fr[6], &pt->f6, sizeof(struct ia64_fpreg) * 6);
 
-	/* fp scratch regs(10-15) */
+	/* fp scratch regs(12-15) */
 
-	retval |= __copy_to_user(&ppr->fr[10], &sw->f10, sizeof(struct ia64_fpreg) * 6);
+	retval |= __copy_to_user(&ppr->fr[12], &sw->f12, sizeof(struct ia64_fpreg) * 4);
 
 	/* fr16-fr31 */
 
@@ -1059,7 +1124,8 @@
 
 	/* gr1-gr3 */
 
-	retval |= __copy_from_user(&pt->r1, &ppr->gr[1], sizeof(long) * 3);
+	retval |= __copy_from_user(&pt->r1, &ppr->gr[1], sizeof(long));
+	retval |= __copy_from_user(&pt->r2, &ppr->gr[2], sizeof(long) * 2);
 
 	/* gr4-gr7 */
 
@@ -1077,7 +1143,9 @@
 
 	/* gr12-gr15 */
 
-	retval |= __copy_from_user(&pt->r12, &ppr->gr[12], sizeof(long) * 4);
+	retval |= __copy_from_user(&pt->r12, &ppr->gr[12], sizeof(long) * 2);
+	retval |= __copy_from_user(&pt->r14, &ppr->gr[14], sizeof(long));
+	retval |= __copy_from_user(&pt->r15, &ppr->gr[15], sizeof(long));
 
 	/* gr16-gr31 */
 
@@ -1105,13 +1173,13 @@
 		retval |= access_fr(&info, i, 1, (unsigned long *) &ppr->fr[i] + 1, 1);
 	}
 
-	/* fr6-fr9 */
+	/* fr6-fr11 */
 
-	retval |= __copy_from_user(&pt->f6, &ppr->fr[6], sizeof(ppr->fr[6]) * 4);
+	retval |= __copy_from_user(&pt->f6, &ppr->fr[6], sizeof(ppr->fr[6]) * 6);
 
-	/* fp scratch regs(10-15) */
+	/* fp scratch regs(12-15) */
 
-	retval |= __copy_from_user(&sw->f10, &ppr->fr[10], sizeof(ppr->fr[10]) * 6);
+	retval |= __copy_from_user(&sw->f12, &ppr->fr[12], sizeof(ppr->fr[12]) * 4);
 
 	/* fr16-fr31 */
 
diff -Nru a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
--- a/arch/ia64/kernel/setup.c	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/kernel/setup.c	Wed Jun 18 23:42:06 2003
@@ -34,14 +34,16 @@
 #include <linux/initrd.h>
 
 #include <asm/ia32.h>
+#include <asm/machvec.h>
+#include <asm/mca.h>
 #include <asm/page.h>
+#include <asm/patch.h>
 #include <asm/pgtable.h>
-#include <asm/machvec.h>
 #include <asm/processor.h>
 #include <asm/sal.h>
-#include <asm/system.h>
-#include <asm/mca.h>
 #include <asm/smp.h>
+#include <asm/system.h>
+#include <asm/unistd.h>
 
 #if defined(CONFIG_SMP) && (IA64_CPU_SIZE > PAGE_SIZE)
 # error "struct cpuinfo_ia64 too big!"
@@ -66,6 +68,17 @@
 
 unsigned char aux_device_present = 0xaa;        /* XXX remove this when legacy I/O is gone */
 
+/*
+ * The merge_mask variable needs to be set to (max(iommu_page_size(iommu)) - 1).  This
+ * mask specifies a mask of address bits that must be 0 in order for two buffers to be
+ * mergeable by the I/O MMU (i.e., the end address of the first buffer and the start
+ * address of the second buffer must be aligned to (merge_mask+1) in order to be
+ * mergeable).  By default, we assume there is no I/O MMU which can merge physically
+ * discontiguous buffers, so we set the merge_mask to ~0UL, which corresponds to a iommu
+ * page-size of 2^64.
+ */
+unsigned long ia64_max_iommu_merge_mask = ~0UL;
+
 #define COMMAND_LINE_SIZE	512
 
 char saved_command_line[COMMAND_LINE_SIZE]; /* used in proc filesystem */
@@ -102,11 +115,11 @@
 static int
 find_max_pfn (unsigned long start, unsigned long end, void *arg)
 {
-	unsigned long *max_pfn = arg, pfn;
+	unsigned long *max_pfnp = arg, pfn;
 
 	pfn = (PAGE_ALIGN(end - 1) - PAGE_OFFSET) >> PAGE_SHIFT;
-	if (pfn > *max_pfn)
-		*max_pfn = pfn;
+	if (pfn > *max_pfnp)
+		*max_pfnp = pfn;
 	return 0;
 }
 
@@ -265,9 +278,8 @@
 static void
 find_memory (void)
 {
-#	define KERNEL_END	((unsigned long) &_end)
+#	define KERNEL_END	(&_end)
 	unsigned long bootmap_size;
-	unsigned long max_pfn;
 	int n = 0;
 
 	/*
@@ -286,8 +298,8 @@
 				+ strlen(__va(ia64_boot_param->command_line)) + 1);
 	n++;
 
-	rsvd_region[n].start = KERNEL_START;
-	rsvd_region[n].end   = KERNEL_END;
+	rsvd_region[n].start = (unsigned long) ia64_imva((void *)KERNEL_START);
+	rsvd_region[n].end   = (unsigned long) ia64_imva(KERNEL_END);
 	n++;
 
 #ifdef CONFIG_BLK_DEV_INITRD
@@ -350,11 +362,14 @@
 void __init
 setup_arch (char **cmdline_p)
 {
+	extern unsigned long *__start___vtop_patchlist[], *__end____vtop_patchlist[];
 	extern unsigned long ia64_iobase;
 	unsigned long phys_iobase;
 
 	unw_init();
 
+	ia64_patch_vtop((u64) __start___vtop_patchlist, (u64) __end____vtop_patchlist);
+
 	*cmdline_p = __va(ia64_boot_param->command_line);
 	strlcpy(saved_command_line, *cmdline_p, sizeof(saved_command_line));
 
@@ -459,8 +474,6 @@
 
 	platform_setup(cmdline_p);
 	paging_init();
-
-	unw_create_gate_table();
 }
 
 /*
@@ -735,6 +748,8 @@
 	/* Clear the stack memory reserved for pt_regs: */
 	memset(ia64_task_regs(current), 0, sizeof(struct pt_regs));
 
+	ia64_set_kr(IA64_KR_FPU_OWNER, 0);
+
 	/*
 	 * Initialize default control register to defer all speculative faults.  The
 	 * kernel MUST NOT depend on a particular setting of these bits (in other words,
@@ -745,20 +760,15 @@
 	 */
 	ia64_set_dcr(  IA64_DCR_DP | IA64_DCR_DK | IA64_DCR_DX | IA64_DCR_DR
 		     | IA64_DCR_DA | IA64_DCR_DD | IA64_DCR_LC);
-#ifndef CONFIG_SMP
-	ia64_set_fpu_owner(0);
-#endif
-
 	atomic_inc(&init_mm.mm_count);
 	current->active_mm = &init_mm;
 	if (current->mm)
 		BUG();
 
-	ia64_mmu_init(cpu_data);
+	ia64_mmu_init(ia64_imva(cpu_data));
 
 #ifdef CONFIG_IA32_SUPPORT
-	/* initialize global ia32 state - CR0 and CR4 */
-	asm volatile ("mov ar.cflg = %0" :: "r" (((ulong) IA32_CR4 << 32) | IA32_CR0));
+	ia32_cpu_init();
 #endif
 
 	/* disable all local interrupt sources: */
@@ -800,27 +810,9 @@
 void
 check_bugs (void)
 {
-	extern int __start___mckinley_e9_bundles[];
-	extern int __end___mckinley_e9_bundles[];
-	u64 *bundle;
-	int *wp;
+	extern char __start___mckinley_e9_bundles[];
+	extern char __end___mckinley_e9_bundles[];
 
-	if (local_cpu_data->family == 0x1f && local_cpu_data->model == 0)
-		printk(KERN_INFO "check_bugs: leaving McKinley Errata 9 workaround enabled\n");
-	else {
-		printk(KERN_INFO "check_bugs: McKinley Errata 9 workaround not needed; "
-		       "disabling it\n");
-		for (wp = __start___mckinley_e9_bundles; wp < __end___mckinley_e9_bundles; ++wp) {
-			bundle = (u64 *) ((char *) wp + *wp);
-			/* install a bundle of NOPs: */
-			bundle[0] = 0x0000000100000000;
-			bundle[1] = 0x0004000000000200;
-			ia64_fc(bundle);
-		}
-		ia64_insn_group_barrier();
-		ia64_sync_i();
-		ia64_insn_group_barrier();
-		ia64_srlz_i();
-		ia64_insn_group_barrier();
-	}
+	ia64_patch_mckinley_e9((unsigned long) __start___mckinley_e9_bundles,
+			       (unsigned long) __end___mckinley_e9_bundles);
 }
diff -Nru a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c
--- a/arch/ia64/kernel/signal.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/kernel/signal.c	Wed Jun 18 23:42:07 2003
@@ -108,25 +108,22 @@
 	long err;
 
 	/* restore scratch that always needs gets updated during signal delivery: */
-	err = __get_user(flags, &sc->sc_flags);
-
+	err  = __get_user(flags, &sc->sc_flags);
 	err |= __get_user(nat, &sc->sc_nat);
 	err |= __get_user(ip, &sc->sc_ip);			/* instruction pointer */
 	err |= __get_user(cfm, &sc->sc_cfm);
 	err |= __get_user(um, &sc->sc_um);			/* user mask */
 	err |= __get_user(scr->pt.ar_rsc, &sc->sc_ar_rsc);
-	err |= __get_user(scr->pt.ar_ccv, &sc->sc_ar_ccv);
 	err |= __get_user(scr->pt.ar_unat, &sc->sc_ar_unat);
 	err |= __get_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr);
 	err |= __get_user(scr->pt.ar_pfs, &sc->sc_ar_pfs);
 	err |= __get_user(scr->pt.pr, &sc->sc_pr);		/* predicates */
 	err |= __get_user(scr->pt.b0, &sc->sc_br[0]);		/* b0 (rp) */
 	err |= __get_user(scr->pt.b6, &sc->sc_br[6]);		/* b6 */
-	err |= __get_user(scr->pt.b7, &sc->sc_br[7]);		/* b7 */
-	err |= __copy_from_user(&scr->pt.r1, &sc->sc_gr[1], 3*8);	/* r1-r3 */
+	err |= __copy_from_user(&scr->pt.r1, &sc->sc_gr[1], 8);	/* r1 */
 	err |= __copy_from_user(&scr->pt.r8, &sc->sc_gr[8], 4*8);	/* r8-r11 */
-	err |= __copy_from_user(&scr->pt.r12, &sc->sc_gr[12], 4*8);	/* r12-r15 */
-	err |= __copy_from_user(&scr->pt.r16, &sc->sc_gr[16], 16*8);	/* r16-r31 */
+	err |= __copy_from_user(&scr->pt.r12, &sc->sc_gr[12], 2*8);	/* r12-r13 */
+	err |= __copy_from_user(&scr->pt.r15, &sc->sc_gr[15], 8);	/* r15 */
 
 	scr->pt.cr_ifs = cfm | (1UL << 63);
 
@@ -137,17 +134,27 @@
 
 	scr->scratch_unat = ia64_put_scratch_nat_bits(&scr->pt, nat);
 
+	if (!(flags & IA64_SC_FLAG_IN_SYSCALL)) {
+		/* Restore most scratch-state only when not in syscall. */
+		err |= __get_user(scr->pt.ar_ccv, &sc->sc_ar_ccv);		/* ar.ccv */
+		err |= __get_user(scr->pt.b7, &sc->sc_br[7]);			/* b7 */
+		err |= __get_user(scr->pt.r14, &sc->sc_gr[14]);			/* r14 */
+		err |= __copy_from_user(&scr->pt.ar_csd, &sc->sc_ar25, 2*8); /* ar.csd & ar.ssd */
+		err |= __copy_from_user(&scr->pt.r2, &sc->sc_gr[2], 2*8);	/* r2-r3 */
+		err |= __copy_from_user(&scr->pt.r16, &sc->sc_gr[16], 16*8);	/* r16-r31 */
+	}
+
 	if ((flags & IA64_SC_FLAG_FPH_VALID) != 0) {
 		struct ia64_psr *psr = ia64_psr(&scr->pt);
 
 		__copy_from_user(current->thread.fph, &sc->sc_fr[32], 96*16);
 		psr->mfh = 0;	/* drop signal handler's fph contents... */
 		if (psr->dfh)
-			current->thread.last_fph_cpu = -1;
+			ia64_drop_fpu(current);
 		else {
+			/* We already own the local fph, otherwise psr->dfh wouldn't be 0.  */
 			__ia64_load_fpu(current->thread.fph);
-			ia64_set_fpu_owner(current);
-			current->thread.last_fph_cpu = smp_processor_id();
+			ia64_set_local_fpu_owner(current);
 		}
 	}
 	return err;
@@ -166,11 +173,10 @@
 		int err;
 
 		/*
-		 * If you change siginfo_t structure, please be sure
-		 * this code is fixed accordingly.  It should never
-		 * copy any pad contained in the structure to avoid
-		 * security leaks, but must copy the generic 3 ints
-		 * plus the relevant union member.
+		 * If you change siginfo_t structure, please be sure this code is fixed
+		 * accordingly.  It should never copy any pad contained in the structure
+		 * to avoid security leaks, but must copy the generic 3 ints plus the
+		 * relevant union member.
 		 */
 		err = __put_user(from->si_signo, &to->si_signo);
 		err |= __put_user(from->si_errno, &to->si_errno);
@@ -183,24 +189,15 @@
 			err |= __put_user(from->si_addr, &to->si_addr);
 			err |= __put_user(from->si_imm, &to->si_imm);
 			break;
-		      case __SI_CHLD >> 16:
-			err |= __put_user(from->si_utime, &to->si_utime);
-			err |= __put_user(from->si_stime, &to->si_stime);
-			err |= __put_user(from->si_status, &to->si_status);
-		      case __SI_PROF >> 16:
-			err |= __put_user(from->si_uid, &to->si_uid);
-			err |= __put_user(from->si_pid, &to->si_pid);
-			if (from->si_code == PROF_OVFL) {
-				err |= __put_user(from->si_pfm_ovfl[0], &to->si_pfm_ovfl[0]);
-				err |= __put_user(from->si_pfm_ovfl[1], &to->si_pfm_ovfl[1]);
-				err |= __put_user(from->si_pfm_ovfl[2], &to->si_pfm_ovfl[2]);
-				err |= __put_user(from->si_pfm_ovfl[3], &to->si_pfm_ovfl[3]);
-			}
 		      case __SI_TIMER >> 16:
 			err |= __put_user(from->si_tid, &to->si_tid);
 			err |= __put_user(from->si_overrun, &to->si_overrun);
 			err |= __put_user(from->si_value, &to->si_value);
 			break;
+		      case __SI_CHLD >> 16:
+			err |= __put_user(from->si_utime, &to->si_utime);
+			err |= __put_user(from->si_stime, &to->si_stime);
+			err |= __put_user(from->si_status, &to->si_status);
 		      default:
 			err |= __put_user(from->si_uid, &to->si_uid);
 			err |= __put_user(from->si_pid, &to->si_pid);
@@ -237,10 +234,6 @@
 			to->si_code |= __SI_POLL;
 			break;
 
-		      case SIGPROF:
-			to->si_code |= __SI_PROF;
-			break;
-
 		      default:
 			break;
 		}
@@ -352,27 +345,40 @@
 	nat = ia64_get_scratch_nat_bits(&scr->pt, scr->scratch_unat);
 
 	err  = __put_user(flags, &sc->sc_flags);
-
 	err |= __put_user(nat, &sc->sc_nat);
 	err |= PUT_SIGSET(mask, &sc->sc_mask);
 	err |= __put_user(cfm, &sc->sc_cfm);
 	err |= __put_user(scr->pt.cr_ipsr & IA64_PSR_UM, &sc->sc_um);
 	err |= __put_user(scr->pt.ar_rsc, &sc->sc_ar_rsc);
-	err |= __put_user(scr->pt.ar_ccv, &sc->sc_ar_ccv);
 	err |= __put_user(scr->pt.ar_unat, &sc->sc_ar_unat);		/* ar.unat */
 	err |= __put_user(scr->pt.ar_fpsr, &sc->sc_ar_fpsr);		/* ar.fpsr */
 	err |= __put_user(scr->pt.ar_pfs, &sc->sc_ar_pfs);
 	err |= __put_user(scr->pt.pr, &sc->sc_pr);			/* predicates */
 	err |= __put_user(scr->pt.b0, &sc->sc_br[0]);			/* b0 (rp) */
 	err |= __put_user(scr->pt.b6, &sc->sc_br[6]);			/* b6 */
-	err |= __put_user(scr->pt.b7, &sc->sc_br[7]);			/* b7 */
-
-	err |= __copy_to_user(&sc->sc_gr[1], &scr->pt.r1, 3*8);		/* r1-r3 */
+	err |= __copy_to_user(&sc->sc_gr[1], &scr->pt.r1, 8);		/* r1 */
 	err |= __copy_to_user(&sc->sc_gr[8], &scr->pt.r8, 4*8);		/* r8-r11 */
-	err |= __copy_to_user(&sc->sc_gr[12], &scr->pt.r12, 4*8);	/* r12-r15 */
-	err |= __copy_to_user(&sc->sc_gr[16], &scr->pt.r16, 16*8);	/* r16-r31 */
-
+	err |= __copy_to_user(&sc->sc_gr[12], &scr->pt.r12, 2*8);	/* r12-r13 */
+	err |= __copy_to_user(&sc->sc_gr[15], &scr->pt.r15, 8);		/* r15 */
 	err |= __put_user(scr->pt.cr_iip + ia64_psr(&scr->pt)->ri, &sc->sc_ip);
+
+	if (flags & IA64_SC_FLAG_IN_SYSCALL) {
+		/* Clear scratch registers if the signal interrupted a system call. */
+		err |= __put_user(0, &sc->sc_ar_ccv);				/* ar.ccv */
+		err |= __put_user(0, &sc->sc_br[7]);				/* b7 */
+		err |= __put_user(0, &sc->sc_gr[14]);				/* r14 */
+		err |= __clear_user(&sc->sc_ar25, 2*8);			/* ar.csd & ar.ssd */
+		err |= __clear_user(&sc->sc_gr[2], 2*8);			/* r2-r3 */
+		err |= __clear_user(&sc->sc_gr[16], 16*8);			/* r16-r31 */
+	} else {
+		/* Copy scratch regs to sigcontext if the signal didn't interrupt a syscall. */
+		err |= __put_user(scr->pt.ar_ccv, &sc->sc_ar_ccv);		/* ar.ccv */
+		err |= __put_user(scr->pt.b7, &sc->sc_br[7]);			/* b7 */
+		err |= __put_user(scr->pt.r14, &sc->sc_gr[14]);			/* r14 */
+		err |= __copy_to_user(&scr->pt.ar_csd, &sc->sc_ar25, 2*8); /* ar.csd & ar.ssd */
+		err |= __copy_to_user(&sc->sc_gr[2], &scr->pt.r2, 2*8);		/* r2-r3 */
+		err |= __copy_to_user(&sc->sc_gr[16], &scr->pt.r16, 16*8);	/* r16-r31 */
+	}
 	return err;
 }
 
@@ -389,14 +395,14 @@
 setup_frame (int sig, struct k_sigaction *ka, siginfo_t *info, sigset_t *set,
 	     struct sigscratch *scr)
 {
-	extern char ia64_sigtramp[], __start_gate_section[];
+	extern char __kernel_sigtramp[];
 	unsigned long tramp_addr, new_rbs = 0;
 	struct sigframe *frame;
 	struct siginfo si;
 	long err;
 
 	frame = (void *) scr->pt.r12;
-	tramp_addr = GATE_ADDR + (ia64_sigtramp - __start_gate_section);
+	tramp_addr = (unsigned long) __kernel_sigtramp;
 	if ((ka->sa.sa_flags & SA_ONSTACK) && sas_ss_flags((unsigned long) frame) == 0) {
 		frame = (void *) ((current->sas_ss_sp + current->sas_ss_size)
 				  & ~(STACK_ALIGN - 1));
@@ -406,7 +412,7 @@
 		 * in the kernel, register stack is switched in the signal trampoline).
 		 */
 		if (!rbs_on_sig_stack(scr->pt.ar_bspstore))
-			new_rbs  = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1);
+			new_rbs = (current->sas_ss_sp + sizeof(long) - 1) & ~(sizeof(long) - 1);
 	}
 	frame = (void *) frame - ((sizeof(*frame) + STACK_ALIGN - 1) & ~(STACK_ALIGN - 1));
 
@@ -451,8 +457,8 @@
 	scr->scratch_unat = 0; /* ensure NaT bits of r12 is clear */
 
 #if DEBUG_SIG
-	printk("SIG deliver (%s:%d): sig=%d sp=%lx ip=%lx handler=%lx\n",
-	       current->comm, current->pid, sig, scr->pt.r12, scr->pt.cr_iip, scr->pt.r3);
+	printk("SIG deliver (%s:%d): sig=%d sp=%lx ip=%lx handler=%p\n",
+	       current->comm, current->pid, sig, scr->pt.r12, frame->sc.sc_ip, frame->handler);
 #endif
 	return 1;
 
diff -Nru a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
--- a/arch/ia64/kernel/smpboot.c	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/kernel/smpboot.c	Wed Jun 18 23:42:06 2003
@@ -352,10 +352,10 @@
 fork_by_hand (void)
 {
 	/*
-	 * don't care about the eip and regs settings since we'll never reschedule the
+	 * Don't care about the IP and regs settings since we'll never reschedule the
 	 * forked task.
 	 */
-	return do_fork(CLONE_VM|CLONE_IDLETASK, 0, 0, 0, NULL, NULL);
+	return copy_process(CLONE_VM|CLONE_IDLETASK, 0, 0, 0, NULL, NULL);
 }
 
 static int __init
@@ -370,6 +370,7 @@
 	idle = fork_by_hand();
 	if (IS_ERR(idle))
 		panic("failed fork for CPU %d", cpu);
+	wake_up_forked_process(idle);
 
 	/*
 	 * We remove it from the pidhash and the runqueue
@@ -449,7 +450,7 @@
 
 	for (cpu = 1, i = 0; i < smp_boot_data.cpu_count; i++) {
 		sapicid = smp_boot_data.cpu_phys_id[i];
-		if (sapicid == -1 || sapicid == boot_cpu_id)
+		if (sapicid == boot_cpu_id)
 			continue;
 		phys_cpu_present_map |= (1 << cpu);
 		ia64_cpu_to_sapicid[cpu] = sapicid;
@@ -598,7 +599,7 @@
 	/* Tell SAL where to drop the AP's.  */
 	ap_startup = (struct fptr *) start_ap;
 	sal_ret = ia64_sal_set_vectors(SAL_VECTOR_OS_BOOT_RENDEZ,
-				       __pa(ap_startup->fp), __pa(ap_startup->gp), 0, 0, 0, 0);
+				       ia64_tpa(ap_startup->fp), ia64_tpa(ap_startup->gp), 0, 0, 0, 0);
 	if (sal_ret < 0)
 		printk(KERN_ERR "SMP: Can't set SAL AP Boot Rendezvous: %s\n",
 		       ia64_sal_strerror(sal_ret));
diff -Nru a/arch/ia64/kernel/sys_ia64.c b/arch/ia64/kernel/sys_ia64.c
--- a/arch/ia64/kernel/sys_ia64.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/kernel/sys_ia64.c	Wed Jun 18 23:42:07 2003
@@ -2,7 +2,7 @@
  * This file contains various system calls that have different calling
  * conventions on different platforms.
  *
- * Copyright (C) 1999-2000, 2002 Hewlett-Packard Co
+ * Copyright (C) 1999-2000, 2002-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #include <linux/config.h>
diff -Nru a/arch/ia64/kernel/time.c b/arch/ia64/kernel/time.c
--- a/arch/ia64/kernel/time.c	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/kernel/time.c	Wed Jun 18 23:42:06 2003
@@ -17,6 +17,7 @@
 #include <linux/time.h>
 #include <linux/interrupt.h>
 #include <linux/efi.h>
+#include <linux/timex.h>
 
 #include <asm/delay.h>
 #include <asm/hw_irq.h>
@@ -25,10 +26,11 @@
 #include <asm/system.h>
 
 extern unsigned long wall_jiffies;
-extern unsigned long last_nsec_offset;
 
 u64 jiffies_64 = INITIAL_JIFFIES;
 
+#define TIME_KEEPER_ID	0	/* smp_processor_id() of time-keeper */
+
 #ifdef CONFIG_IA64_DEBUG_IRQ
 
 unsigned long last_cli_ip;
@@ -59,19 +61,32 @@
 	atomic_inc((atomic_t *) &prof_buffer[ip]);
 }
 
+static void
+itc_reset (void)
+{
+}
+
+/*
+ * Adjust for the fact that xtime has been advanced by delta_nsec (may be negative and/or
+ * larger than NSEC_PER_SEC.
+ */
+static void
+itc_update (long delta_nsec)
+{
+}
+
 /*
  * Return the number of nano-seconds that elapsed since the last update to jiffy.  The
  * xtime_lock must be at least read-locked when calling this routine.
  */
-static inline unsigned long
-gettimeoffset (void)
+unsigned long
+itc_get_offset (void)
 {
 	unsigned long elapsed_cycles, lost = jiffies - wall_jiffies;
 	unsigned long now, last_tick;
-#	define time_keeper_id	0	/* smp_processor_id() of time-keeper */
 
-	last_tick = (cpu_data(time_keeper_id)->itm_next
-		     - (lost + 1)*cpu_data(time_keeper_id)->itm_delta);
+	last_tick = (cpu_data(TIME_KEEPER_ID)->itm_next
+		     - (lost + 1)*cpu_data(TIME_KEEPER_ID)->itm_delta);
 
 	now = ia64_get_itc();
 	if (unlikely((long) (now - last_tick) < 0)) {
@@ -83,6 +98,12 @@
 	return (elapsed_cycles*local_cpu_data->nsec_per_cyc) >> IA64_NSEC_PER_CYC_SHIFT;
 }
 
+static struct time_interpolator itc_interpolator = {
+	.get_offset =	itc_get_offset,
+	.update =	itc_update,
+	.reset =	itc_reset
+};
+
 static inline void
 set_normalized_timespec (struct timespec *ts, time_t sec, long nsec)
 {
@@ -115,7 +136,7 @@
 		 * Discover what correction gettimeofday would have done, and then undo
 		 * it!
 		 */
-		nsec -= gettimeoffset();
+		nsec -= time_interpolator_get_offset();
 
 		wtm_sec  = wall_to_monotonic.tv_sec + (xtime.tv_sec - sec);
 		wtm_nsec = wall_to_monotonic.tv_nsec + (xtime.tv_nsec - nsec);
@@ -127,6 +148,7 @@
 		time_status |= STA_UNSYNC;
 		time_maxerror = NTP_PHASE_LIMIT;
 		time_esterror = NTP_PHASE_LIMIT;
+		time_interpolator_reset();
 	}
 	write_sequnlock_irq(&xtime_lock);
 	clock_was_set();
@@ -138,14 +160,11 @@
 {
 	unsigned long seq, nsec, usec, sec, old, offset;
 
-	if ((unsigned long)tv->tv_nsec >= NSEC_PER_SEC)
-		return -EINVAL;
-
 	while (1) {
 		seq = read_seqbegin(&xtime_lock);
 		{
 			old = last_nsec_offset;
-			offset = gettimeoffset();
+			offset = time_interpolator_get_offset();
 			sec = xtime.tv_sec;
 			nsec = xtime.tv_nsec;
 		}
@@ -221,7 +240,7 @@
 #endif
 		new_itm += local_cpu_data->itm_delta;
 
-		if (smp_processor_id() == 0) {
+		if (smp_processor_id() == TIME_KEEPER_ID) {
 			/*
 			 * Here we are in the timer irq handler. We have irqs locally
 			 * disabled, but we don't know if the timer_bh is running on
@@ -283,16 +302,17 @@
 void __init
 ia64_init_itm (void)
 {
-	unsigned long platform_base_freq, itc_freq, drift;
+	unsigned long platform_base_freq, itc_freq;
 	struct pal_freq_ratio itc_ratio, proc_ratio;
-	long status;
+	long status, platform_base_drift, itc_drift;
 
 	/*
 	 * According to SAL v2.6, we need to use a SAL call to determine the platform base
 	 * frequency and then a PAL call to determine the frequency ratio between the ITC
 	 * and the base frequency.
 	 */
-	status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM, &platform_base_freq, &drift);
+	status = ia64_sal_freq_base(SAL_FREQ_BASE_PLATFORM,
+				    &platform_base_freq, &platform_base_drift);
 	if (status != 0) {
 		printk(KERN_ERR "SAL_FREQ_BASE_PLATFORM failed: %s\n", ia64_sal_strerror(status));
 	} else {
@@ -305,6 +325,7 @@
 		printk(KERN_ERR
 		       "SAL/PAL failed to obtain frequency info---inventing reasonable values\n");
 		platform_base_freq = 100000000;
+		platform_base_drift = -1;	/* no drift info */
 		itc_ratio.num = 3;
 		itc_ratio.den = 1;
 	}
@@ -312,6 +333,7 @@
 		printk(KERN_ERR "Platform base frequency %lu bogus---resetting to 75MHz!\n",
 		       platform_base_freq);
 		platform_base_freq = 75000000;
+		platform_base_drift = -1;
 	}
 	if (!proc_ratio.den)
 		proc_ratio.den = 1;	/* avoid division by zero */
@@ -319,17 +341,29 @@
 		itc_ratio.den = 1;	/* avoid division by zero */
 
 	itc_freq = (platform_base_freq*itc_ratio.num)/itc_ratio.den;
+	if (platform_base_drift != -1)
+		itc_drift = platform_base_drift*itc_ratio.num/itc_ratio.den;
+	else
+		itc_drift = -1;
+
 	local_cpu_data->itm_delta = (itc_freq + HZ/2) / HZ;
 	printk(KERN_INFO "CPU %d: base freq=%lu.%03luMHz, ITC ratio=%lu/%lu, "
-	       "ITC freq=%lu.%03luMHz\n", smp_processor_id(),
+	       "ITC freq=%lu.%03luMHz+/-%ldppm\n", smp_processor_id(),
 	       platform_base_freq / 1000000, (platform_base_freq / 1000) % 1000,
-	       itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000);
+	       itc_ratio.num, itc_ratio.den, itc_freq / 1000000, (itc_freq / 1000) % 1000,
+	       itc_drift);
 
 	local_cpu_data->proc_freq = (platform_base_freq*proc_ratio.num)/proc_ratio.den;
 	local_cpu_data->itc_freq = itc_freq;
 	local_cpu_data->cyc_per_usec = (itc_freq + USEC_PER_SEC/2) / USEC_PER_SEC;
 	local_cpu_data->nsec_per_cyc = ((NSEC_PER_SEC<<IA64_NSEC_PER_CYC_SHIFT)
 					+ itc_freq/2)/itc_freq;
+
+	if (!(sal_platform_features & IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT)) {
+		itc_interpolator.frequency = local_cpu_data->itc_freq;
+		itc_interpolator.drift = itc_drift;
+		register_time_interpolator(&itc_interpolator);
+	}
 
 	/* Setup the CPU local timer tick */
 	ia64_cpu_local_tick();
diff -Nru a/arch/ia64/kernel/traps.c b/arch/ia64/kernel/traps.c
--- a/arch/ia64/kernel/traps.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/kernel/traps.c	Wed Jun 18 23:42:09 2003
@@ -247,16 +247,17 @@
 	psr->dfh = 0;
 #ifndef CONFIG_SMP
 	{
-		struct task_struct *fpu_owner = ia64_get_fpu_owner();
+		struct task_struct *fpu_owner
+			= (struct task_struct *)ia64_get_kr(IA64_KR_FPU_OWNER);
 
-		if (fpu_owner == current)
+		if (ia64_is_local_fpu_owner(current))
 			return;
 
 		if (fpu_owner)
 			ia64_flush_fph(fpu_owner);
 	}
 #endif /* !CONFIG_SMP */
-	ia64_set_fpu_owner(current);
+	ia64_set_local_fpu_owner(current);
 	if ((current->thread.flags & IA64_THREAD_FPH_VALID) != 0) {
 		__ia64_load_fpu(current->thread.fph);
 		psr->mfh = 0;
@@ -274,7 +275,6 @@
 fp_emulate (int fp_fault, void *bundle, long *ipsr, long *fpsr, long *isr, long *pr, long *ifs,
 	    struct pt_regs *regs)
 {
-	struct ia64_fpreg f6_11[6];
 	fp_state_t fp_state;
 	fpswa_ret_t ret;
 
@@ -289,11 +289,8 @@
 	 * pointer to point to these registers.
 	 */
 	fp_state.bitmask_low64 = 0xfc0;  /* bit6..bit11 */
-	f6_11[0] = regs->f6; f6_11[1] = regs->f7;
-	f6_11[2] = regs->f8; f6_11[3] = regs->f9;
-	__asm__ ("stf.spill %0=f10%P0" : "=m"(f6_11[4]));
-	__asm__ ("stf.spill %0=f11%P0" : "=m"(f6_11[5]));
-	fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) f6_11;
+
+	fp_state.fp_state_low_volatile = (fp_state_low_volatile_t *) &regs->f6;
 	/*
 	 * unsigned long (*EFI_FPSWA) (
 	 *      unsigned long    trap_type,
@@ -309,10 +306,7 @@
 					(unsigned long *) ipsr, (unsigned long *) fpsr,
 					(unsigned long *) isr, (unsigned long *) pr,
 					(unsigned long *) ifs, &fp_state);
-	regs->f6 = f6_11[0]; regs->f7 = f6_11[1];
-	regs->f8 = f6_11[2]; regs->f9 = f6_11[3];
-	__asm__ ("ldf.fill f10=%0%P0" :: "m"(f6_11[4]));
-	__asm__ ("ldf.fill f11=%0%P0" :: "m"(f6_11[5]));
+
 	return ret.status;
 }
 
@@ -336,8 +330,9 @@
 
 	if (jiffies - last_time > 5*HZ)
 		fpu_swa_count = 0;
-	if ((++fpu_swa_count < 5) && !(current->thread.flags & IA64_THREAD_FPEMU_NOPRINT)) {
+	if ((fpu_swa_count < 4) && !(current->thread.flags & IA64_THREAD_FPEMU_NOPRINT)) {
 		last_time = jiffies;
+		++fpu_swa_count;
 		printk(KERN_WARNING "%s(%d): floating-point assist fault at ip %016lx, isr %016lx\n",
 		       current->comm, current->pid, regs->cr_iip + ia64_psr(regs)->ri, isr);
 	}
@@ -533,9 +528,8 @@
 	      case 29: /* Debug */
 	      case 35: /* Taken Branch Trap */
 	      case 36: /* Single Step Trap */
-#ifdef CONFIG_FSYS
 		if (fsys_mode(current, regs)) {
-			extern char syscall_via_break[], __start_gate_section[];
+			extern char __kernel_syscall_via_break[];
 			/*
 			 * Got a trap in fsys-mode: Taken Branch Trap and Single Step trap
 			 * need special handling; Debug trap is not supposed to happen.
@@ -546,12 +540,11 @@
 				return;
 			}
 			/* re-do the system call via break 0x100000: */
-			regs->cr_iip = GATE_ADDR + (syscall_via_break - __start_gate_section);
+			regs->cr_iip = (unsigned long) __kernel_syscall_via_break;
 			ia64_psr(regs)->ri = 0;
 			ia64_psr(regs)->cpl = 3;
 			return;
 		}
-#endif
 		switch (vector) {
 		      case 29:
 			siginfo.si_code = TRAP_HWBKPT;
diff -Nru a/arch/ia64/kernel/unaligned.c b/arch/ia64/kernel/unaligned.c
--- a/arch/ia64/kernel/unaligned.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/kernel/unaligned.c	Wed Jun 18 23:42:09 2003
@@ -218,8 +218,9 @@
 	RSW(f2), RSW(f3), RSW(f4), RSW(f5),
 
 	RPT(f6), RPT(f7), RPT(f8), RPT(f9),
+	RPT(f10), RPT(f11),
 
-	RSW(f10), RSW(f11), RSW(f12), RSW(f13), RSW(f14),
+	RSW(f12), RSW(f13), RSW(f14),
 	RSW(f15), RSW(f16), RSW(f17), RSW(f18), RSW(f19),
 	RSW(f20), RSW(f21), RSW(f22), RSW(f23), RSW(f24),
 	RSW(f25), RSW(f26), RSW(f27), RSW(f28), RSW(f29),
diff -Nru a/arch/ia64/kernel/unwind.c b/arch/ia64/kernel/unwind.c
--- a/arch/ia64/kernel/unwind.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/kernel/unwind.c	Wed Jun 18 23:42:09 2003
@@ -1,6 +1,8 @@
 /*
  * Copyright (C) 1999-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 2003 Fenghua Yu <fenghua.yu@intel.com>
+ * 	- Change pt_regs_off() to make it less dependant on pt_regs structure.
  */
 /*
  * This file implements call frame unwind support for the Linux
@@ -25,6 +27,7 @@
  *	  acquired, then the read-write lock must be acquired first.
  */
 #include <linux/bootmem.h>
+#include <linux/elf.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/slab.h>
@@ -76,7 +79,7 @@
 # define STAT(x...)
 #endif
 
-#define alloc_reg_state()	kmalloc(sizeof(struct unw_state_record), GFP_ATOMIC)
+#define alloc_reg_state()	kmalloc(sizeof(struct unw_reg_state), GFP_ATOMIC)
 #define free_reg_state(usr)	kfree(usr)
 #define alloc_labeled_state()	kmalloc(sizeof(struct unw_labeled_state), GFP_ATOMIC)
 #define free_labeled_state(usr)	kfree(usr)
@@ -84,8 +87,6 @@
 typedef unsigned long unw_word;
 typedef unsigned char unw_hash_index_t;
 
-#define struct_offset(str,fld)	((char *)&((str *)NULL)->fld - (char *) 0)
-
 static struct {
 	spinlock_t lock;			/* spinlock for unwind data */
 
@@ -104,6 +105,8 @@
 	/* index into unw_frame_info for preserved register i */
 	unsigned short preg_index[UNW_NUM_REGS];
 
+	short pt_regs_offsets[32];
+
 	/* unwind table for the kernel: */
 	struct unw_table kernel_table;
 
@@ -153,47 +156,78 @@
 		UNW_REG_UNAT, UNW_REG_LC, UNW_REG_FPSR, UNW_REG_PRI_UNAT_GR
 	},
 	.preg_index = {
-		struct_offset(struct unw_frame_info, pri_unat_loc)/8,	/* PRI_UNAT_GR */
-		struct_offset(struct unw_frame_info, pri_unat_loc)/8,	/* PRI_UNAT_MEM */
-		struct_offset(struct unw_frame_info, bsp_loc)/8,
-		struct_offset(struct unw_frame_info, bspstore_loc)/8,
-		struct_offset(struct unw_frame_info, pfs_loc)/8,
-		struct_offset(struct unw_frame_info, rnat_loc)/8,
-		struct_offset(struct unw_frame_info, psp)/8,
-		struct_offset(struct unw_frame_info, rp_loc)/8,
-		struct_offset(struct unw_frame_info, r4)/8,
-		struct_offset(struct unw_frame_info, r5)/8,
-		struct_offset(struct unw_frame_info, r6)/8,
-		struct_offset(struct unw_frame_info, r7)/8,
-		struct_offset(struct unw_frame_info, unat_loc)/8,
-		struct_offset(struct unw_frame_info, pr_loc)/8,
-		struct_offset(struct unw_frame_info, lc_loc)/8,
-		struct_offset(struct unw_frame_info, fpsr_loc)/8,
-		struct_offset(struct unw_frame_info, b1_loc)/8,
-		struct_offset(struct unw_frame_info, b2_loc)/8,
-		struct_offset(struct unw_frame_info, b3_loc)/8,
-		struct_offset(struct unw_frame_info, b4_loc)/8,
-		struct_offset(struct unw_frame_info, b5_loc)/8,
-		struct_offset(struct unw_frame_info, f2_loc)/8,
-		struct_offset(struct unw_frame_info, f3_loc)/8,
-		struct_offset(struct unw_frame_info, f4_loc)/8,
-		struct_offset(struct unw_frame_info, f5_loc)/8,
-		struct_offset(struct unw_frame_info, fr_loc[16 - 16])/8,
-		struct_offset(struct unw_frame_info, fr_loc[17 - 16])/8,
-		struct_offset(struct unw_frame_info, fr_loc[18 - 16])/8,
-		struct_offset(struct unw_frame_info, fr_loc[19 - 16])/8,
-		struct_offset(struct unw_frame_info, fr_loc[20 - 16])/8,
-		struct_offset(struct unw_frame_info, fr_loc[21 - 16])/8,
-		struct_offset(struct unw_frame_info, fr_loc[22 - 16])/8,
-		struct_offset(struct unw_frame_info, fr_loc[23 - 16])/8,
-		struct_offset(struct unw_frame_info, fr_loc[24 - 16])/8,
-		struct_offset(struct unw_frame_info, fr_loc[25 - 16])/8,
-		struct_offset(struct unw_frame_info, fr_loc[26 - 16])/8,
-		struct_offset(struct unw_frame_info, fr_loc[27 - 16])/8,
-		struct_offset(struct unw_frame_info, fr_loc[28 - 16])/8,
-		struct_offset(struct unw_frame_info, fr_loc[29 - 16])/8,
-		struct_offset(struct unw_frame_info, fr_loc[30 - 16])/8,
-		struct_offset(struct unw_frame_info, fr_loc[31 - 16])/8,
+		offsetof(struct unw_frame_info, pri_unat_loc)/8,	/* PRI_UNAT_GR */
+		offsetof(struct unw_frame_info, pri_unat_loc)/8,	/* PRI_UNAT_MEM */
+		offsetof(struct unw_frame_info, bsp_loc)/8,
+		offsetof(struct unw_frame_info, bspstore_loc)/8,
+		offsetof(struct unw_frame_info, pfs_loc)/8,
+		offsetof(struct unw_frame_info, rnat_loc)/8,
+		offsetof(struct unw_frame_info, psp)/8,
+		offsetof(struct unw_frame_info, rp_loc)/8,
+		offsetof(struct unw_frame_info, r4)/8,
+		offsetof(struct unw_frame_info, r5)/8,
+		offsetof(struct unw_frame_info, r6)/8,
+		offsetof(struct unw_frame_info, r7)/8,
+		offsetof(struct unw_frame_info, unat_loc)/8,
+		offsetof(struct unw_frame_info, pr_loc)/8,
+		offsetof(struct unw_frame_info, lc_loc)/8,
+		offsetof(struct unw_frame_info, fpsr_loc)/8,
+		offsetof(struct unw_frame_info, b1_loc)/8,
+		offsetof(struct unw_frame_info, b2_loc)/8,
+		offsetof(struct unw_frame_info, b3_loc)/8,
+		offsetof(struct unw_frame_info, b4_loc)/8,
+		offsetof(struct unw_frame_info, b5_loc)/8,
+		offsetof(struct unw_frame_info, f2_loc)/8,
+		offsetof(struct unw_frame_info, f3_loc)/8,
+		offsetof(struct unw_frame_info, f4_loc)/8,
+		offsetof(struct unw_frame_info, f5_loc)/8,
+		offsetof(struct unw_frame_info, fr_loc[16 - 16])/8,
+		offsetof(struct unw_frame_info, fr_loc[17 - 16])/8,
+		offsetof(struct unw_frame_info, fr_loc[18 - 16])/8,
+		offsetof(struct unw_frame_info, fr_loc[19 - 16])/8,
+		offsetof(struct unw_frame_info, fr_loc[20 - 16])/8,
+		offsetof(struct unw_frame_info, fr_loc[21 - 16])/8,
+		offsetof(struct unw_frame_info, fr_loc[22 - 16])/8,
+		offsetof(struct unw_frame_info, fr_loc[23 - 16])/8,
+		offsetof(struct unw_frame_info, fr_loc[24 - 16])/8,
+		offsetof(struct unw_frame_info, fr_loc[25 - 16])/8,
+		offsetof(struct unw_frame_info, fr_loc[26 - 16])/8,
+		offsetof(struct unw_frame_info, fr_loc[27 - 16])/8,
+		offsetof(struct unw_frame_info, fr_loc[28 - 16])/8,
+		offsetof(struct unw_frame_info, fr_loc[29 - 16])/8,
+		offsetof(struct unw_frame_info, fr_loc[30 - 16])/8,
+		offsetof(struct unw_frame_info, fr_loc[31 - 16])/8,
+	},
+	.pt_regs_offsets = {
+		[0] = -1,
+		offsetof(struct pt_regs,  r1),
+		offsetof(struct pt_regs,  r2),
+		offsetof(struct pt_regs,  r3),
+		[4] = -1, [5] = -1, [6] = -1, [7] = -1,
+		offsetof(struct pt_regs,  r8),
+		offsetof(struct pt_regs,  r9),
+		offsetof(struct pt_regs, r10),
+		offsetof(struct pt_regs, r11),
+		offsetof(struct pt_regs, r12),
+		offsetof(struct pt_regs, r13),
+		offsetof(struct pt_regs, r14),
+		offsetof(struct pt_regs, r15),
+		offsetof(struct pt_regs, r16),
+		offsetof(struct pt_regs, r17),
+		offsetof(struct pt_regs, r18),
+		offsetof(struct pt_regs, r19),
+		offsetof(struct pt_regs, r20),
+		offsetof(struct pt_regs, r21),
+		offsetof(struct pt_regs, r22),
+		offsetof(struct pt_regs, r23),
+		offsetof(struct pt_regs, r24),
+		offsetof(struct pt_regs, r25),
+		offsetof(struct pt_regs, r26),
+		offsetof(struct pt_regs, r27),
+		offsetof(struct pt_regs, r28),
+		offsetof(struct pt_regs, r29),
+		offsetof(struct pt_regs, r30),
+		offsetof(struct pt_regs, r31),
 	},
 	.hash = { [0 ... UNW_HASH_SIZE - 1] = -1 },
 #ifdef UNW_DEBUG
@@ -209,7 +243,6 @@
 #endif
 };
 
-
 /* Unwind accessors.  */
 
 /*
@@ -218,19 +251,16 @@
 static inline unsigned long
 pt_regs_off (unsigned long reg)
 {
-	unsigned long off =0;
+	short off = -1;
 
-	if (reg >= 1 && reg <= 3)
-		off = struct_offset(struct pt_regs, r1) + 8*(reg - 1);
-	else if (reg <= 11)
-		off = struct_offset(struct pt_regs, r8) + 8*(reg - 8);
-	else if (reg <= 15)
-		off = struct_offset(struct pt_regs, r12) + 8*(reg - 12);
-	else if (reg <= 31)
-		off = struct_offset(struct pt_regs, r16) + 8*(reg - 16);
-	else
+	if (reg < ARRAY_SIZE(unw.pt_regs_offsets))
+		off = unw.pt_regs_offsets[reg];
+
+	if (off < 0) {
 		UNW_DPRINT(0, "unwind.%s: bad scratch reg r%lu\n", __FUNCTION__, reg);
-	return off;
+		off = 0;
+	}
+	return (unsigned long) off;
 }
 
 static inline struct pt_regs *
@@ -239,7 +269,10 @@
 	if (!info->pt) {
 		/* This should not happen with valid unwind info.  */
 		UNW_DPRINT(0, "unwind.%s: bad unwind info: resetting info->pt\n", __FUNCTION__);
-		info->pt = info->sp - 16;
+		if (info->flags & UNW_FLAG_INTERRUPT_FRAME)
+			info->pt = (unsigned long) ((struct pt_regs *) info->psp - 1);
+		else
+			info->pt = info->sp - 16;
 	}
 	UNW_DPRINT(3, "unwind.%s: sp 0x%lx pt 0x%lx\n", __FUNCTION__, info->sp, info->pt);
 	return (struct pt_regs *) info->pt;
@@ -371,12 +404,11 @@
 	unsigned long *addr;
 	struct pt_regs *pt;
 
-	pt = get_scratch_regs(info);
 	switch (regnum) {
 		/* scratch: */
-	      case 0: addr = &pt->b0; break;
-	      case 6: addr = &pt->b6; break;
-	      case 7: addr = &pt->b7; break;
+	      case 0: pt = get_scratch_regs(info); addr = &pt->b0; break;
+	      case 6: pt = get_scratch_regs(info); addr = &pt->b6; break;
+	      case 7: pt = get_scratch_regs(info); addr = &pt->b7; break;
 
 		/* preserved: */
 	      case 1: case 2: case 3: case 4: case 5:
@@ -409,17 +441,17 @@
 		return -1;
 	}
 
-	pt = get_scratch_regs(info);
-
 	if (regnum <= 5) {
 		addr = *(&info->f2_loc + (regnum - 2));
 		if (!addr)
 			addr = &info->sw->f2 + (regnum - 2);
 	} else if (regnum <= 15) {
-		if (regnum <= 9)
+		if (regnum <= 11) {
+			pt = get_scratch_regs(info);
 			addr = &pt->f6  + (regnum - 6);
+		}
 		else
-			addr = &info->sw->f10 + (regnum - 10);
+			addr = &info->sw->f12 + (regnum - 12);
 	} else if (regnum <= 31) {
 		addr = info->fr_loc[regnum - 16];
 		if (!addr)
@@ -447,7 +479,6 @@
 	unsigned long *addr;
 	struct pt_regs *pt;
 
-	pt = get_scratch_regs(info);
 	switch (regnum) {
 	      case UNW_AR_BSP:
 		addr = info->bsp_loc;
@@ -502,13 +533,25 @@
 		break;
 
 	      case UNW_AR_RSC:
+		pt = get_scratch_regs(info);
 		addr = &pt->ar_rsc;
 		break;
 
 	      case UNW_AR_CCV:
+		pt = get_scratch_regs(info);
 		addr = &pt->ar_ccv;
 		break;
 
+	      case UNW_AR_CSD:
+		pt = get_scratch_regs(info);
+		addr = &pt->ar_csd;
+		break;
+
+	      case UNW_AR_SSD:
+		pt = get_scratch_regs(info);
+		addr = &pt->ar_ssd;
+		break;
+
 	      default:
 		UNW_DPRINT(0, "unwind.%s: trying to access non-existent ar%u\n",
 			   __FUNCTION__, regnum);
@@ -782,7 +825,7 @@
 static inline void
 desc_abi (unsigned char abi, unsigned char context, struct unw_state_record *sr)
 {
-	if (abi == 0 && context == 'i') {
+	if (abi == 3 && context == 'i') {
 		sr->flags |= UNW_FLAG_INTERRUPT_FRAME;
 		UNW_DPRINT(3, "unwind.%s: interrupt frame\n",  __FUNCTION__);
 	}
@@ -1376,8 +1419,8 @@
 			val = unw.preg_index[UNW_REG_F16 + (rval - 16)];
 		else {
 			opc = UNW_INSN_MOVE_SCRATCH;
-			if (rval <= 9)
-				val = struct_offset(struct pt_regs, f6) + 16*(rval - 6);
+			if (rval <= 11)
+				val = offsetof(struct pt_regs, f6) + 16*(rval - 6);
 			else
 				UNW_DPRINT(0, "unwind.%s: kernel may not touch f%lu\n",
 					   __FUNCTION__, rval);
@@ -1390,11 +1433,11 @@
 		else {
 			opc = UNW_INSN_MOVE_SCRATCH;
 			if (rval == 0)
-				val = struct_offset(struct pt_regs, b0);
+				val = offsetof(struct pt_regs, b0);
 			else if (rval == 6)
-				val = struct_offset(struct pt_regs, b6);
+				val = offsetof(struct pt_regs, b6);
 			else
-				val = struct_offset(struct pt_regs, b7);
+				val = offsetof(struct pt_regs, b7);
 		}
 		break;
 
@@ -1594,7 +1637,7 @@
 	    && sr.curr.reg[UNW_REG_PSP].val != 0) {
 		/* new psp is sp plus frame size */
 		insn.opc = UNW_INSN_ADD;
-		insn.dst = struct_offset(struct unw_frame_info, psp)/8;
+		insn.dst = offsetof(struct unw_frame_info, psp)/8;
 		insn.val = sr.curr.reg[UNW_REG_PSP].val;	/* frame size */
 		script_emit(script, insn);
 	}
@@ -1728,14 +1771,13 @@
   lazy_init:
 	off = unw.sw_off[val];
 	s[val] = (unsigned long) state->sw + off;
-	if (off >= struct_offset(struct switch_stack, r4)
-	    && off <= struct_offset(struct switch_stack, r7))
+	if (off >= offsetof(struct switch_stack, r4) && off <= offsetof(struct switch_stack, r7))
 		/*
 		 * We're initializing a general register: init NaT info, too.  Note that
 		 * the offset is a multiple of 8 which gives us the 3 bits needed for
 		 * the type field.
 		 */
-		s[val+1] = (struct_offset(struct switch_stack, ar_unat) - off) | UNW_NAT_MEMSTK;
+		s[val+1] = (offsetof(struct switch_stack, ar_unat) - off) | UNW_NAT_MEMSTK;
 	goto redo;
 }
 
@@ -1799,11 +1841,7 @@
 		return -1;
 	}
 	ip = info->ip = *info->rp_loc;
-	if (ip < GATE_ADDR + PAGE_SIZE) {
-		/*
-		 * We don't have unwind info for the gate page, so we consider that part
-		 * of user-space for the purpose of unwinding.
-		 */
+	if (ip < GATE_ADDR) {
 		UNW_DPRINT(2, "unwind.%s: reached user-space (ip=0x%lx)\n", __FUNCTION__, ip);
 		STAT(unw.stat.api.unwind_time += ia64_get_itc() - start; local_irq_restore(flags));
 		return -1;
@@ -1825,7 +1863,7 @@
 		if ((pr & (1UL << pNonSys)) != 0)
 			num_regs = *info->cfm_loc & 0x7f;		/* size of frame */
 		info->pfs_loc =
-			(unsigned long *) (info->pt + struct_offset(struct pt_regs, ar_pfs));
+			(unsigned long *) (info->pt + offsetof(struct pt_regs, ar_pfs));
 		UNW_DPRINT(3, "unwind.%s: interrupt_frame pt 0x%lx\n", __FUNCTION__, info->pt);
 	} else
 		num_regs = (*info->cfm_loc >> 7) & 0x7f;	/* size of locals */
@@ -1876,11 +1914,7 @@
 				   __FUNCTION__, ip);
 			return -1;
 		}
-		/*
-		 * We don't have unwind info for the gate page, so we consider that part
-		 * of user-space for the purpose of unwinding.
-		 */
-		if (ip < GATE_ADDR + PAGE_SIZE)
+		if (ip < GATE_ADDR)
 			return 0;
 	}
 	unw_get_ip(info, &ip);
@@ -2090,30 +2124,41 @@
 	kfree(table);
 }
 
-void
-unw_create_gate_table (void)
+static void __init
+create_gate_table (void)
 {
-	extern char __start_gate_section[], __stop_gate_section[];
-	unsigned long *lp, start, end, segbase = unw.kernel_table.segment_base;
-	const struct unw_table_entry *entry, *first, *unw_table_end;
-	extern int ia64_unw_end;
+	const struct unw_table_entry *entry, *start, *end;
+	unsigned long *lp, segbase = GATE_ADDR;
 	size_t info_size, size;
 	char *info;
+	Elf64_Phdr *punw = NULL, *phdr = (Elf64_Phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);
+	int i;
+
+	for (i = 0; i < GATE_EHDR->e_phnum; ++i, ++phdr)
+		if (phdr->p_type == PT_IA_64_UNWIND) {
+			punw = phdr;
+			break;
+		}
+
+	if (!punw) {
+		printk("%s: failed to find gate DSO's unwind table!\n", __FUNCTION__);
+		return;
+	}
 
-	start = (unsigned long) __start_gate_section - segbase;
-	end   = (unsigned long) __stop_gate_section - segbase;
-	unw_table_end = (struct unw_table_entry *) &ia64_unw_end;
+	start = (const struct unw_table_entry *) punw->p_vaddr;
+	end = (struct unw_table_entry *) ((char *) start + punw->p_memsz);
 	size  = 0;
-	first = lookup(&unw.kernel_table, start);
 
-	for (entry = first; entry < unw_table_end && entry->start_offset < end; ++entry)
+	unw_add_unwind_table("linux-gate.so", segbase, 0, start, end);
+
+	for (entry = start; entry < end; ++entry)
 		size += 3*8 + 8 + 8*UNW_LENGTH(*(u64 *) (segbase + entry->info_offset));
 	size += 8;	/* reserve space for "end of table" marker */
 
-	unw.gate_table = alloc_bootmem(size);
+	unw.gate_table = kmalloc(size, GFP_KERNEL);
 	if (!unw.gate_table) {
 		unw.gate_table_size = 0;
-		printk(KERN_ERR "unwind: unable to create unwind data for gate page!\n");
+		printk(KERN_ERR "%s: unable to create unwind data for gate page!\n", __FUNCTION__);
 		return;
 	}
 	unw.gate_table_size = size;
@@ -2121,19 +2166,21 @@
 	lp = unw.gate_table;
 	info = (char *) unw.gate_table + size;
 
-	for (entry = first; entry < unw_table_end && entry->start_offset < end; ++entry, lp += 3) {
+	for (entry = start; entry < end; ++entry, lp += 3) {
 		info_size = 8 + 8*UNW_LENGTH(*(u64 *) (segbase + entry->info_offset));
 		info -= info_size;
 		memcpy(info, (char *) segbase + entry->info_offset, info_size);
 
-		lp[0] = entry->start_offset - start + GATE_ADDR;	/* start */
-		lp[1] = entry->end_offset - start + GATE_ADDR;		/* end */
-		lp[2] = info - (char *) unw.gate_table;			/* info */
+		lp[0] = segbase + entry->start_offset;		/* start */
+		lp[1] = segbase + entry->end_offset;		/* end */
+		lp[2] = info - (char *) unw.gate_table;		/* info */
 	}
 	*lp = 0;	/* end-of-table marker */
 }
 
-void
+__initcall(create_gate_table);
+
+void __init
 unw_init (void)
 {
 	extern int ia64_unw_start, ia64_unw_end, __gp;
@@ -2174,6 +2221,14 @@
 }
 
 /*
+ * DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED
+ *
+ *	This system call has been deprecated.  The new and improved way to get
+ *	at the kernel's unwind info is via the gate DSO.  The address of the
+ *	ELF header for this DSO is passed to user-level via AT_SYSINFO_EHDR.
+ *
+ * DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED DEPRECATED
+ *
  * This system call copies the unwind data into the buffer pointed to by BUF and returns
  * the size of the unwind data.  If BUF_SIZE is smaller than the size of the unwind data
  * or if BUF is NULL, nothing is copied, but the system call still returns the size of the
diff -Nru a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile
--- a/arch/ia64/lib/Makefile	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/lib/Makefile	Wed Jun 18 23:42:09 2003
@@ -13,6 +13,12 @@
 lib-$(CONFIG_MCKINLEY)	+= copy_page_mck.o memcpy_mck.o
 lib-$(CONFIG_PERFMON)	+= carta_random.o
 
+ifeq ($(CONFIG_MD_RAID5),m)
+	lib-y += xor.o
+else
+	lib-$(CONFIG_MD_RAID5)	+= xor.o
+endif
+
 IGNORE_FLAGS_OBJS =	__divsi3.o __udivsi3.o __modsi3.o __umodsi3.o \
 			__divdi3.o __udivdi3.o __moddi3.o __umoddi3.o
 
diff -Nru a/arch/ia64/lib/idiv64.S b/arch/ia64/lib/idiv64.S
--- a/arch/ia64/lib/idiv64.S	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/lib/idiv64.S	Wed Jun 18 23:42:06 2003
@@ -37,57 +37,44 @@
 #define NAME		PASTE(PASTE(__,SGN),PASTE(OP,di3))
 
 GLOBAL_ENTRY(NAME)
-	.prologue
 	.regstk 2,0,0,0
 	// Transfer inputs to FP registers.
 	setf.sig f8 = in0
 	setf.sig f9 = in1
 	;;
-	.fframe 16
-	.save.f 0x20
-	stf.spill [sp] = f17,-16
-
 	// Convert the inputs to FP, to avoid FP software-assist faults.
 	INT_TO_FP(f8, f8)
-	;;
-
-	.save.f 0x10
-	stf.spill [sp] = f16
-	.body
 	INT_TO_FP(f9, f9)
 	;;
-	frcpa.s1 f17, p6 = f8, f9	// y0 = frcpa(b)
+	frcpa.s1 f11, p6 = f8, f9	// y0 = frcpa(b)
 	;;
-(p6)	fmpy.s1 f7 = f8, f17		// q0 = a*y0
-(p6)	fnma.s1 f6 = f9, f17, f1	// e0 = -b*y0 + 1
+(p6)	fmpy.s1 f7 = f8, f11		// q0 = a*y0
+(p6)	fnma.s1 f6 = f9, f11, f1	// e0 = -b*y0 + 1
 	;;
-(p6)	fma.s1 f16 = f7, f6, f7		// q1 = q0*e0 + q0
+(p6)	fma.s1 f10 = f7, f6, f7		// q1 = q0*e0 + q0
 (p6)	fmpy.s1 f7 = f6, f6		// e1 = e0*e0
 	;;
 #ifdef MODULO
 	sub in1 = r0, in1		// in1 = -b
 #endif
-(p6)	fma.s1 f16 = f16, f7, f16	// q2 = q1*e1 + q1
-(p6)	fma.s1 f6 = f17, f6, f17	// y1 = y0*e0 + y0
+(p6)	fma.s1 f10 = f10, f7, f10	// q2 = q1*e1 + q1
+(p6)	fma.s1 f6 = f11, f6, f11	// y1 = y0*e0 + y0
 	;;
 (p6)	fma.s1 f6 = f6, f7, f6		// y2 = y1*e1 + y1
-(p6)	fnma.s1 f7 = f9, f16, f8	// r = -b*q2 + a
+(p6)	fnma.s1 f7 = f9, f10, f8	// r = -b*q2 + a
 	;;
 #ifdef MODULO
 	setf.sig f8 = in0		// f8 = a
 	setf.sig f9 = in1		// f9 = -b
 #endif
-(p6)	fma.s1 f17 = f7, f6, f16	// q3 = r*y2 + q2
+(p6)	fma.s1 f11 = f7, f6, f10	// q3 = r*y2 + q2
 	;;
-	.restore sp
-	ldf.fill f16 = [sp], 16
-	FP_TO_INT(f17, f17)		// q = trunc(q3)
+	FP_TO_INT(f11, f11)		// q = trunc(q3)
 	;;
 #ifdef MODULO
-	xma.l f17 = f17, f9, f8		// r = q*(-b) + a
+	xma.l f11 = f11, f9, f8		// r = q*(-b) + a
 	;;
 #endif
-	getf.sig r8 = f17		// transfer result to result register
-	ldf.fill f17 = [sp]
+	getf.sig r8 = f11		// transfer result to result register
 	br.ret.sptk.many rp
 END(NAME)
diff -Nru a/arch/ia64/lib/memcpy_mck.S b/arch/ia64/lib/memcpy_mck.S
--- a/arch/ia64/lib/memcpy_mck.S	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/lib/memcpy_mck.S	Wed Jun 18 23:42:07 2003
@@ -15,11 +15,7 @@
 #include <asm/asmmacro.h>
 #include <asm/page.h>
 
-#if __GNUC__ >= 3
-# define EK(y...) EX(y)
-#else
-# define EK(y,x...)  x
-#endif
+#define EK(y...) EX(y)
 
 GLOBAL_ENTRY(bcopy)
 	.regstk 3,0,0,0
diff -Nru a/arch/ia64/lib/xor.S b/arch/ia64/lib/xor.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/lib/xor.S	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,184 @@
+/*
+ * arch/ia64/lib/xor.S
+ *
+ * Optimized RAID-5 checksumming functions for IA-64.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2, or (at your option)
+ * any later version.
+ *
+ * You should have received a copy of the GNU General Public License
+ * (for example /usr/src/linux/COPYING); if not, write to the Free
+ * Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ */
+
+#include <asm/asmmacro.h>
+
+GLOBAL_ENTRY(xor_ia64_2)
+	.prologue
+	.fframe 0
+	.save ar.pfs, r31
+	alloc r31 = ar.pfs, 3, 0, 13, 16
+	.save ar.lc, r30
+	mov r30 = ar.lc
+	.save pr, r29
+	mov r29 = pr
+	;;
+	.body
+	mov r8 = in1
+	mov ar.ec = 6 + 2
+	shr in0 = in0, 3
+	;;
+	adds in0 = -1, in0
+	mov r16 = in1
+	mov r17 = in2
+	;;
+	mov ar.lc = in0
+	mov pr.rot = 1 << 16
+	;;
+	.rotr s1[6+1], s2[6+1], d[2]
+	.rotp p[6+2]
+0:
+(p[0])	ld8.nta s1[0] = [r16], 8
+(p[0])	ld8.nta s2[0] = [r17], 8
+(p[6])	xor d[0] = s1[6], s2[6]
+(p[6+1])st8.nta [r8] = d[1], 8
+	nop.f 0
+	br.ctop.dptk.few 0b
+	;;
+	mov ar.lc = r30
+	mov pr = r29, -1
+	br.ret.sptk.few rp
+END(xor_ia64_2)
+
+GLOBAL_ENTRY(xor_ia64_3)
+	.prologue
+	.fframe 0
+	.save ar.pfs, r31
+	alloc r31 = ar.pfs, 4, 0, 20, 24
+	.save ar.lc, r30
+	mov r30 = ar.lc
+	.save pr, r29
+	mov r29 = pr
+	;;
+	.body
+	mov r8 = in1
+	mov ar.ec = 6 + 2
+	shr in0 = in0, 3
+	;;
+	adds in0 = -1, in0
+	mov r16 = in1
+	mov r17 = in2
+	;;	
+	mov r18 = in3
+	mov ar.lc = in0
+	mov pr.rot = 1 << 16
+	;;
+	.rotr s1[6+1], s2[6+1], s3[6+1], d[2]
+	.rotp p[6+2]
+0:	
+(p[0])	ld8.nta s1[0] = [r16], 8
+(p[0])	ld8.nta s2[0] = [r17], 8
+(p[6])	xor d[0] = s1[6], s2[6]
+	;;
+(p[0])	ld8.nta s3[0] = [r18], 8
+(p[6+1])st8.nta [r8] = d[1], 8
+(p[6])	xor d[0] = d[0], s3[6]
+	br.ctop.dptk.few 0b
+	;;
+	mov ar.lc = r30
+	mov pr = r29, -1
+	br.ret.sptk.few rp
+END(xor_ia64_3)
+
+GLOBAL_ENTRY(xor_ia64_4)
+	.prologue
+	.fframe 0
+	.save ar.pfs, r31
+	alloc r31 = ar.pfs, 5, 0, 27, 32
+	.save ar.lc, r30
+	mov r30 = ar.lc
+	.save pr, r29
+	mov r29 = pr
+	;;
+	.body
+	mov r8 = in1
+	mov ar.ec = 6 + 2
+	shr in0 = in0, 3
+	;;
+	adds in0 = -1, in0
+	mov r16 = in1
+	mov r17 = in2
+	;;
+	mov r18 = in3
+	mov ar.lc = in0
+	mov pr.rot = 1 << 16
+	mov r19 = in4
+	;;
+	.rotr s1[6+1], s2[6+1], s3[6+1], s4[6+1], d[2]
+	.rotp p[6+2]
+0:
+(p[0])	ld8.nta s1[0] = [r16], 8
+(p[0])	ld8.nta s2[0] = [r17], 8
+(p[6])	xor d[0] = s1[6], s2[6]
+(p[0])	ld8.nta s3[0] = [r18], 8
+(p[0])	ld8.nta s4[0] = [r19], 8
+(p[6])	xor r20 = s3[6], s4[6]
+	;;
+(p[6+1])st8.nta [r8] = d[1], 8
+(p[6])	xor d[0] = d[0], r20
+	br.ctop.dptk.few 0b
+	;;
+	mov ar.lc = r30
+	mov pr = r29, -1
+	br.ret.sptk.few rp
+END(xor_ia64_4)
+
+GLOBAL_ENTRY(xor_ia64_5)
+	.prologue
+	.fframe 0
+	.save ar.pfs, r31
+	alloc r31 = ar.pfs, 6, 0, 34, 40
+	.save ar.lc, r30
+	mov r30 = ar.lc
+	.save pr, r29
+	mov r29 = pr
+	;;
+	.body
+	mov r8 = in1
+	mov ar.ec = 6 + 2
+	shr in0 = in0, 3
+	;;
+	adds in0 = -1, in0
+	mov r16 = in1
+	mov r17 = in2
+	;;
+	mov r18 = in3
+	mov ar.lc = in0
+	mov pr.rot = 1 << 16
+	mov r19 = in4
+	mov r20 = in5
+	;;
+	.rotr s1[6+1], s2[6+1], s3[6+1], s4[6+1], s5[6+1], d[2]
+	.rotp p[6+2]
+0:	
+(p[0])	ld8.nta s1[0] = [r16], 8
+(p[0])	ld8.nta s2[0] = [r17], 8
+(p[6])	xor d[0] = s1[6], s2[6]
+(p[0])	ld8.nta s3[0] = [r18], 8
+(p[0])	ld8.nta s4[0] = [r19], 8
+(p[6])	xor r21 = s3[6], s4[6]
+	;;
+(p[0])	ld8.nta s5[0] = [r20], 8
+(p[6+1])st8.nta [r8] = d[1], 8
+(p[6])	xor d[0] = d[0], r21
+	;;
+(p[6])	  xor d[0] = d[0], s5[6]
+	nop.f 0
+	br.ctop.dptk.few 0b
+	;;
+	mov ar.lc = r30
+	mov pr = r29, -1
+	br.ret.sptk.few rp
+END(xor_ia64_5)
diff -Nru a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
--- a/arch/ia64/mm/discontig.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/mm/discontig.c	Wed Jun 18 23:42:09 2003
@@ -285,9 +285,11 @@
 		kaddr = (unsigned long)__va(bdp->node_boot_start);
 		ekaddr = (unsigned long)__va(bdp->node_low_pfn << PAGE_SHIFT);
 		while (kaddr < ekaddr) {
-			bid = BANK_MEM_MAP_INDEX(kaddr);
-			node_data[mynode]->node_id_map[bid] = node;
-			node_data[mynode]->bank_mem_map_base[bid] = page;
+			if (paddr_to_nid(__pa(kaddr)) == node) {
+				bid = BANK_MEM_MAP_INDEX(kaddr);
+				node_data[mynode]->node_id_map[bid] = node;
+				node_data[mynode]->bank_mem_map_base[bid] = page;
+			}
 			kaddr += BANKSIZE;
 			page += BANKSIZE/PAGE_SIZE;
 		}
diff -Nru a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
--- a/arch/ia64/mm/fault.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/mm/fault.c	Wed Jun 18 23:42:09 2003
@@ -43,6 +43,33 @@
 	return 0;
 }
 
+/*
+ * Return TRUE if ADDRESS points at a page in the kernel's mapped segment
+ * (inside region 5, on ia64) and that page is present.
+ */
+static int
+mapped_kernel_page_is_present (unsigned long address)
+{
+	pgd_t *pgd;
+	pmd_t *pmd;
+	pte_t *ptep, pte;
+
+	pgd = pgd_offset_k(address);
+	if (pgd_none(*pgd) || pgd_bad(*pgd))
+		return 0;
+
+	pmd = pmd_offset(pgd,address);
+	if (pmd_none(*pmd) || pmd_bad(*pmd))
+		return 0;
+
+	ptep = pte_offset_kernel(pmd, address);
+	if (!ptep)
+		return 0;
+
+	pte = *ptep;
+	return pte_present(pte);
+}
+
 void
 ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *regs)
 {
@@ -187,6 +214,16 @@
 	}
 
 	if (done_with_exception(regs))
+		return;
+
+	/*
+	 * Since we have no vma's for region 5, we might get here even if the address is
+	 * valid, due to the VHPT walker inserting a non present translation that becomes
+	 * stale. If that happens, the non present fault handler already purged the stale
+	 * translation, which fixed the problem. So, we check to see if the translation is
+	 * valid, and return if it is.
+	 */
+	if (REGION_NUMBER(address) == 5 && mapped_kernel_page_is_present(address))
 		return;
 
 	/*
diff -Nru a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
--- a/arch/ia64/mm/hugetlbpage.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/mm/hugetlbpage.c	Wed Jun 18 23:42:07 2003
@@ -116,7 +116,7 @@
 /* This function checks if the address and address+len falls out of HugeTLB region.  It
  * return -EINVAL if any part of address range falls in HugeTLB region.
  */
-int  is_invalid_hugepage_range(unsigned long addr, unsigned long len)
+int  check_valid_hugepage_range(unsigned long addr, unsigned long len)
 {
 	if (REGION_NUMBER(addr) == REGION_HPAGE)
 		return -EINVAL;
diff -Nru a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
--- a/arch/ia64/mm/init.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/mm/init.c	Wed Jun 18 23:42:07 2003
@@ -1,7 +1,7 @@
 /*
  * Initialize MMU support.
  *
- * Copyright (C) 1998-2002 Hewlett-Packard Co
+ * Copyright (C) 1998-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 #include <linux/config.h>
@@ -9,13 +9,14 @@
 #include <linux/init.h>
 
 #include <linux/bootmem.h>
+#include <linux/efi.h>
+#include <linux/elf.h>
 #include <linux/mm.h>
+#include <linux/mmzone.h>
 #include <linux/personality.h>
 #include <linux/reboot.h>
 #include <linux/slab.h>
 #include <linux/swap.h>
-#include <linux/efi.h>
-#include <linux/mmzone.h>
 
 #include <asm/a.out.h>
 #include <asm/bitops.h>
@@ -23,13 +24,15 @@
 #include <asm/ia32.h>
 #include <asm/io.h>
 #include <asm/machvec.h>
+#include <asm/patch.h>
 #include <asm/pgalloc.h>
 #include <asm/sal.h>
 #include <asm/system.h>
-#include <asm/uaccess.h>
 #include <asm/tlb.h>
+#include <asm/uaccess.h>
+#include <asm/unistd.h>
 
-struct mmu_gather mmu_gathers[NR_CPUS];
+DEFINE_PER_CPU(struct mmu_gather, mmu_gathers);
 
 /* References to section boundaries: */
 extern char _stext, _etext, _edata, __init_begin, __init_end, _end;
@@ -47,6 +50,8 @@
 
 static int pgt_cache_water[2] = { 25, 50 };
 
+struct page *zero_page_memmap_ptr;		/* map entry for zero page */
+
 void
 check_pgt_cache (void)
 {
@@ -65,6 +70,36 @@
 	}
 }
 
+void
+update_mmu_cache (struct vm_area_struct *vma, unsigned long vaddr, pte_t pte)
+{
+	unsigned long addr;
+	struct page *page;
+
+	if (!pte_exec(pte))
+		return;				/* not an executable page... */
+
+	page = pte_page(pte);
+	/* don't use VADDR: it may not be mapped on this CPU (or may have just been flushed): */
+	addr = (unsigned long) page_address(page);
+
+	if (test_bit(PG_arch_1, &page->flags))
+		return;				/* i-cache is already coherent with d-cache */
+
+	flush_icache_range(addr, addr + PAGE_SIZE);
+	set_bit(PG_arch_1, &page->flags);	/* mark page as clean */
+}
+
+inline void
+ia64_set_rbs_bot (void)
+{
+	unsigned long stack_size = current->rlim[RLIMIT_STACK].rlim_max & -16;
+
+	if (stack_size > MAX_USER_STACK_SIZE)
+		stack_size = MAX_USER_STACK_SIZE;
+	current->thread.rbs_bot = STACK_TOP - stack_size;
+}
+
 /*
  * This performs some platform-dependent address space initialization.
  * On IA-64, we want to setup the VM area for the register backing
@@ -76,6 +111,8 @@
 {
 	struct vm_area_struct *vma;
 
+	ia64_set_rbs_bot();
+
 	/*
 	 * If we're out of memory and kmem_cache_alloc() returns NULL, we simply ignore
 	 * the problem.  When the process attempts to write to the register backing store
@@ -84,7 +121,7 @@
 	vma = kmem_cache_alloc(vm_area_cachep, SLAB_KERNEL);
 	if (vma) {
 		vma->vm_mm = current->mm;
-		vma->vm_start = IA64_RBS_BOT;
+		vma->vm_start = current->thread.rbs_bot;
 		vma->vm_end = vma->vm_start + PAGE_SIZE;
 		vma->vm_page_prot = protection_map[VM_DATA_DEFAULT_FLAGS & 0x7];
 		vma->vm_flags = VM_READ|VM_WRITE|VM_MAYREAD|VM_MAYWRITE|VM_GROWSUP;
@@ -112,14 +149,16 @@
 void
 free_initmem (void)
 {
-	unsigned long addr;
+	unsigned long addr, eaddr;
 
-	addr = (unsigned long) &__init_begin;
-	for (; addr < (unsigned long) &__init_end; addr += PAGE_SIZE) {
+	addr = (unsigned long) ia64_imva(&__init_begin);
+	eaddr = (unsigned long) ia64_imva(&__init_end);
+	while (addr < eaddr) {
 		ClearPageReserved(virt_to_page(addr));
 		set_page_count(virt_to_page(addr), 1);
 		free_page(addr);
 		++totalram_pages;
+		addr += PAGE_SIZE;
 	}
 	printk(KERN_INFO "Freeing unused kernel memory: %ldkB freed\n",
 	       (&__init_end - &__init_begin) >> 10);
@@ -230,18 +269,17 @@
 }
 
 /*
- * This is like put_dirty_page() but installs a clean page with PAGE_GATE protection
- * (execute-only, typically).
+ * This is like put_dirty_page() but installs a clean page in the kernel's page table.
  */
 struct page *
-put_gate_page (struct page *page, unsigned long address)
+put_kernel_page (struct page *page, unsigned long address, pgprot_t pgprot)
 {
 	pgd_t *pgd;
 	pmd_t *pmd;
 	pte_t *pte;
 
 	if (!PageReserved(page))
-		printk(KERN_ERR "put_gate_page: gate page at 0x%p not in reserved memory\n",
+		printk(KERN_ERR "put_kernel_page: page at 0x%p not in reserved memory\n",
 		       page_address(page));
 
 	pgd = pgd_offset_k(address);		/* note: this is NOT pgd_offset()! */
@@ -258,7 +296,7 @@
 			pte_unmap(pte);
 			goto out;
 		}
-		set_pte(pte, mk_pte(page, PAGE_GATE));
+		set_pte(pte, mk_pte(page, pgprot));
 		pte_unmap(pte);
 	}
   out:	spin_unlock(&init_mm.page_table_lock);
@@ -266,10 +304,31 @@
 	return page;
 }
 
+static void
+setup_gate (void)
+{
+	struct page *page;
+	extern char __start_gate_section[];
+
+	/*
+	 * Map the gate page twice: once read-only to export the ELF headers etc. and once
+	 * execute-only page to enable privilege-promotion via "epc":
+	 */
+	page = virt_to_page(ia64_imva(__start_gate_section));
+	put_kernel_page(page, GATE_ADDR, PAGE_READONLY);
+#ifdef HAVE_BUGGY_SEGREL
+	page = virt_to_page(ia64_imva(__start_gate_section + PAGE_SIZE));
+	put_kernel_page(page, GATE_ADDR + PAGE_SIZE, PAGE_GATE);
+#else
+	put_kernel_page(page, GATE_ADDR + PERCPU_PAGE_SIZE, PAGE_GATE);
+#endif
+	ia64_patch_gate();
+}
+
 void __init
 ia64_mmu_init (void *my_cpu_data)
 {
-	unsigned long psr, rid, pta, impl_va_bits;
+	unsigned long psr, pta, impl_va_bits;
 	extern void __init tlb_init (void);
 #ifdef CONFIG_DISABLE_VHPT
 #	define VHPT_ENABLE_BIT	0
@@ -277,21 +336,8 @@
 #	define VHPT_ENABLE_BIT	1
 #endif
 
-	/*
-	 * Set up the kernel identity mapping for regions 6 and 5.  The mapping for region
-	 * 7 is setup up in _start().
-	 */
+	/* Pin mapping for percpu area into TLB */
 	psr = ia64_clear_ic();
-
-	rid = ia64_rid(IA64_REGION_ID_KERNEL, __IA64_UNCACHED_OFFSET);
-	ia64_set_rr(__IA64_UNCACHED_OFFSET, (rid << 8) | (IA64_GRANULE_SHIFT << 2));
-
-	rid = ia64_rid(IA64_REGION_ID_KERNEL, VMALLOC_START);
-	ia64_set_rr(VMALLOC_START, (rid << 8) | (PAGE_SHIFT << 2) | 1);
-
-	/* ensure rr6 is up-to-date before inserting the PERCPU_ADDR translation: */
-	ia64_srlz_d();
-
 	ia64_itr(0x2, IA64_TR_PERCPU_DATA, PERCPU_ADDR,
 		 pte_val(pfn_pte(__pa(my_cpu_data) >> PAGE_SHIFT, PAGE_KERNEL)),
 		 PERCPU_PAGE_SHIFT);
@@ -489,6 +535,7 @@
 
 	discontig_paging_init();
 	efi_memmap_walk(count_pages, &num_physpages);
+	zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
 }
 #else /* !CONFIG_DISCONTIGMEM */
 void
@@ -560,6 +607,7 @@
 	}
 	free_area_init(zones_size);
 #  endif /* !CONFIG_VIRTUAL_MEM_MAP */
+	zero_page_memmap_ptr = virt_to_page(ia64_imva(empty_zero_page));
 }
 #endif /* !CONFIG_DISCONTIGMEM */
 
@@ -576,13 +624,32 @@
 	return 0;
 }
 
+/*
+ * Boot command-line option "nolwsys" can be used to disable the use of any light-weight
+ * system call handler.  When this option is in effect, all fsyscalls will end up bubbling
+ * down into the kernel and calling the normal (heavy-weight) syscall handler.  This is
+ * useful for performance testing, but conceivably could also come in handy for debugging
+ * purposes.
+ */
+
+static int nolwsys;
+
+static int __init
+nolwsys_setup (char *s)
+{
+	nolwsys = 1;
+	return 1;
+}
+
+__setup("nolwsys", nolwsys_setup);
+
 void
 mem_init (void)
 {
-	extern char __start_gate_section[];
 	long reserved_pages, codesize, datasize, initsize;
 	unsigned long num_pgt_pages;
 	pg_data_t *pgdat;
+	int i;
 	static struct kcore_list kcore_mem, kcore_vmem, kcore_kernel;
 
 #ifdef CONFIG_PCI
@@ -634,8 +701,19 @@
 	if (num_pgt_pages > (u64) pgt_cache_water[1])
 		pgt_cache_water[1] = num_pgt_pages;
 
-	/* install the gate page in the global page table: */
-	put_gate_page(virt_to_page(__start_gate_section), GATE_ADDR);
+	/*
+	 * For fsyscall entrpoints with no light-weight handler, use the ordinary
+	 * (heavy-weight) handler, but mark it by setting bit 0, so the fsyscall entry
+	 * code can tell them apart.
+	 */
+	for (i = 0; i < NR_syscalls; ++i) {
+		extern unsigned long fsyscall_table[NR_syscalls];
+		extern unsigned long sys_call_table[NR_syscalls];
+
+		if (!fsyscall_table[i] || nolwsys)
+			fsyscall_table[i] = sys_call_table[i] | 1;
+	}
+	setup_gate();	/* setup gate pages before we free up boot memory... */
 
 #ifdef CONFIG_IA32_SUPPORT
 	ia32_gdt_init();
diff -Nru a/arch/ia64/mm/tlb.c b/arch/ia64/mm/tlb.c
--- a/arch/ia64/mm/tlb.c	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/mm/tlb.c	Wed Jun 18 23:42:08 2003
@@ -1,7 +1,7 @@
 /*
  * TLB support routines.
  *
- * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *
  * 08/02/00 A. Mallick <asit.k.mallick@intel.com>
@@ -22,17 +22,10 @@
 #include <asm/pal.h>
 #include <asm/tlbflush.h>
 
-#define SUPPORTED_PGBITS (			\
-		1 << _PAGE_SIZE_256M |		\
-		1 << _PAGE_SIZE_64M  |		\
-		1 << _PAGE_SIZE_16M  |		\
-		1 << _PAGE_SIZE_4M   |		\
-		1 << _PAGE_SIZE_1M   |		\
-		1 << _PAGE_SIZE_256K |		\
-		1 << _PAGE_SIZE_64K  |		\
-		1 << _PAGE_SIZE_16K  |		\
-		1 << _PAGE_SIZE_8K   |		\
-		1 << _PAGE_SIZE_4K )
+static struct {
+	unsigned long mask;	/* mask of supported purge page-sizes */
+	unsigned long max_bits;	/* log2() of largest supported purge page-size */
+} purge;
 
 struct ia64_ctx ia64_ctx = {
 	.lock =		SPIN_LOCK_UNLOCKED,
@@ -154,22 +147,10 @@
 	}
 
 	nbits = ia64_fls(size + 0xfff);
-	if (((1UL << nbits) & SUPPORTED_PGBITS) == 0) {
-		if (nbits > _PAGE_SIZE_256M)
-			nbits = _PAGE_SIZE_256M;
-		else
-			/*
-			 * Some page sizes are not implemented in the
-			 * IA-64 arch, so if we get asked to clear an
-			 * unsupported page size, round up to the
-			 * nearest page size.  Note that we depend on
-			 * the fact that if page size N is not
-			 * implemented, 2*N _is_ implemented.
-			 */
-			++nbits;
-		if (((1UL << nbits) & SUPPORTED_PGBITS) == 0)
-			panic("flush_tlb_range: BUG: nbits=%lu\n", nbits);
-	}
+	while (unlikely (((1UL << nbits) & purge.mask) == 0) && (nbits < purge.max_bits))
+		++nbits;
+	if (nbits > purge.max_bits)
+		nbits = purge.max_bits;
 	start &= ~((1UL << nbits) - 1);
 
 # ifdef CONFIG_SMP
@@ -190,6 +171,15 @@
 ia64_tlb_init (void)
 {
 	ia64_ptce_info_t ptce_info;
+	unsigned long tr_pgbits;
+	long status;
+
+	if ((status = ia64_pal_vm_page_size(&tr_pgbits, &purge.mask)) != 0) {
+		printk(KERN_ERR "PAL_VM_PAGE_SIZE failed with status=%ld;"
+		       "defaulting to architected purge page-sizes.\n", status);
+		purge.mask = 0x115557000;
+	}
+	purge.max_bits = ia64_fls(purge.mask);
 
 	ia64_get_ptce(&ptce_info);
 	local_cpu_data->ptce_base = ptce_info.base;
diff -Nru a/arch/ia64/scripts/check-gas b/arch/ia64/scripts/check-gas
--- a/arch/ia64/scripts/check-gas	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/scripts/check-gas	Wed Jun 18 23:42:08 2003
@@ -2,8 +2,11 @@
 dir=$(dirname $0)
 CC=$1
 OBJDUMP=$2
-$CC -c $dir/check-gas-asm.S
-res=$($OBJDUMP -r --section .data check-gas-asm.o | fgrep 00004 | tr -s ' ' |cut -f3 -d' ')
+tmp=${TMPDIR:-/tmp}
+out=$tmp/out$$.o
+$CC -c $dir/check-gas-asm.S -o $out
+res=$($OBJDUMP -r --section .data $out | fgrep 00004 | tr -s ' ' |cut -f3 -d' ')
+rm -f $out
 if [ $res != ".text" ]; then
 	echo buggy
 else
diff -Nru a/arch/ia64/scripts/check-segrel.S b/arch/ia64/scripts/check-segrel.S
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/scripts/check-segrel.S	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,4 @@
+	.rodata
+	data4 @segrel(start)
+	.data
+start:
diff -Nru a/arch/ia64/scripts/check-segrel.lds b/arch/ia64/scripts/check-segrel.lds
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/scripts/check-segrel.lds	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,11 @@
+SECTIONS {
+	. = SIZEOF_HEADERS;
+	.rodata : { *(.rodata) } :ro
+	. = 0xa0000;
+	.data : { *(.data) } :dat
+	/DISCARD/ : { *(*) }
+}
+PHDRS {
+  ro PT_LOAD FILEHDR PHDRS;
+  dat PT_LOAD;
+}
diff -Nru a/arch/ia64/scripts/toolchain-flags b/arch/ia64/scripts/toolchain-flags
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/scripts/toolchain-flags	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,22 @@
+#!/bin/sh
+#
+# Check whether linker can handle cross-segment @segrel():
+#
+CC=$1
+LD=$2
+OBJDUMP=$3
+dir=$(dirname $0)
+tmp=${TMPDIR:-/tmp}
+out=$tmp/out$$
+$CC -c $dir/check-segrel.S -o $out.o
+$LD -static -T$dir/check-segrel.lds $out.o -o $out
+res=$($OBJDUMP --full --section .rodata $out | fgrep 000 | cut -f3 -d' ')
+rm -f $out $out.o
+if [ $res != 00000a00 ]; then
+    echo " -DHAVE_BUGGY_SEGREL"
+    cat >&2 <<EOF
+warning: your linker cannot handle cross-segment segment-relative relocations.
+         please upgrade to a newer version (it is safe to use this linker, but
+         the kernel will be bigger than strictly necessary).
+EOF
+fi
diff -Nru a/arch/ia64/sn/Makefile b/arch/ia64/sn/Makefile
--- a/arch/ia64/sn/Makefile	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/sn/Makefile	Wed Jun 18 23:42:08 2003
@@ -11,4 +11,4 @@
 
 EXTRA_CFLAGS := -DLITTLE_ENDIAN
 
-obj-y += kernel/ # io/
+obj-y += kernel/ io/
diff -Nru a/arch/ia64/sn/fakeprom/README b/arch/ia64/sn/fakeprom/README
--- a/arch/ia64/sn/fakeprom/README	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/sn/fakeprom/README	Wed Jun 18 23:42:09 2003
@@ -103,7 +103,7 @@
     1GB*<dn>, where dn is the digit number. The amount of memory
     is 8MB*2**<d>. (If <d> = 0, the memory size is 0).
 
-    SN1 doesnt support dimms this small but small memory systems 
+    SN1 doesn't support dimms this small but small memory systems 
     boot faster on Medusa.
 
 
diff -Nru a/arch/ia64/sn/fakeprom/fpmem.c b/arch/ia64/sn/fakeprom/fpmem.c
--- a/arch/ia64/sn/fakeprom/fpmem.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/sn/fakeprom/fpmem.c	Wed Jun 18 23:42:07 2003
@@ -13,7 +13,7 @@
  * FPROM EFI memory descriptor build routines
  *
  * 	- Routines to build the EFI memory descriptor map
- * 	- Should also be usable by the SGI SN1 prom to convert
+ * 	- Should also be usable by the SGI prom to convert
  * 	  klconfig to efi_memmap
  */
 
@@ -53,10 +53,7 @@
 #define KERNEL_SIZE		(4*MB)
 #define PROMRESERVED_SIZE	(1*MB)
 
-#ifdef CONFIG_IA64_SGI_SN1
-#define PHYS_ADDRESS(_n, _x)		(((long)_n<<33) | (long)_x)
-#define MD_BANK_SHFT 30
-#else
+#ifdef SGI_SN2
 #define PHYS_ADDRESS(_n, _x)		(((long)_n<<38) | (long)_x | 0x3000000000UL)
 #define MD_BANK_SHFT 34
 #endif
@@ -77,7 +74,7 @@
 	return sn_config->cpus;
 }
 
-/* For SN1, get the index th nasid */
+/* For SN, get the index th nasid */
 
 int
 GetNasid(int index)
@@ -104,40 +101,7 @@
  * actually disabled etc.
  */
 
-#ifdef CONFIG_IA64_SGI_SN1
-int
-IsBankPresent(int index, node_memmap_t nmemmap)
-{
-	switch (index) {
-		case 0:return nmemmap.b0;
-		case 1:return nmemmap.b1;
-		case 2:return nmemmap.b2;
-		case 3:return nmemmap.b3;
-		case 4:return nmemmap.b4;
-		case 5:return nmemmap.b5;
-		case 6:return nmemmap.b6;
-		case 7:return nmemmap.b7;
-		default:return -1 ;
-	}
-}
-
-int
-GetBankSize(int index, node_memmap_t nmemmap)
-{
-        switch (index) {
-                case 0:
-                case 1:return nmemmap.b01size;
-                case 2:
-                case 3:return nmemmap.b23size;
-                case 4:
-                case 5:return nmemmap.b45size;
-                case 6:
-                case 7:return nmemmap.b67size;
-                default:return -1 ;
-        }
-}
-
-#else
+#ifdef SGI_SN2
 int
 IsBankPresent(int index, node_memmap_t nmemmap)
 {
@@ -192,12 +156,12 @@
 	for (cnode=0;cnode<numnodes;cnode++) {
 		nasid = GetNasid(cnode) ;
 		membank_info = GetMemBankInfo(cnode) ;
-		for (bank=0;bank<NR_BANKS_PER_NODE;bank++) {
+		for (bank=0;bank<MD_BANKS_PER_NODE;bank++) {
 			if (IsBankPresent(bank, membank_info)) {
 				bsize = GetBankSize(bank, membank_info) ;
                                 paddr = PHYS_ADDRESS(nasid, (long)bank<<MD_BANK_SHFT);
                                 numbytes = BankSizeBytes(bsize);
-#ifdef CONFIG_IA64_SGI_SN2
+#ifdef SGI_SN2
 				/* 
 				 * Ignore directory.
 				 * Shorten memory chunk by 1 page - makes a better
@@ -218,7 +182,7 @@
 				}
 
                                 /*
-                                 * Check for the node 0 hole. Since banks can't
+                                 * Check for the node 0 hole. Since banks cant
                                  * span the hole, we only need to check if the end of
                                  * the range is the end of the hole.
                                  */
@@ -226,7 +190,7 @@
                                         numbytes -= NODE0_HOLE_SIZE;
                                 /*
                                  * UGLY hack - we must skip overr the kernel and
-                                 * PROM runtime services but we don't exactly where it is.
+                                 * PROM runtime services but we dont exactly where it is.
                                  * So lets just reserve:
 				 *	node 0
 				 *		0-1MB for PAL
diff -Nru a/arch/ia64/sn/fakeprom/fpmem.h b/arch/ia64/sn/fakeprom/fpmem.h
--- a/arch/ia64/sn/fakeprom/fpmem.h	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/sn/fakeprom/fpmem.h	Wed Jun 18 23:42:07 2003
@@ -4,13 +4,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 #include <linux/config.h>
 
 /*
- * Structure of the mem config of the node as a SN1 MI reg
+ * Structure of the mem config of the node as a SN MI reg
  * Medusa supports this reg config.
  *
  * BankSize nibble to bank size mapping
@@ -24,32 +24,7 @@
 
 #define MBSHIFT				20
 
-#ifdef CONFIG_IA64_SGI_SN1
-typedef struct node_memmap_s
-{
-        unsigned int    b0      :1,     /* 0 bank 0 present */
-                        b1      :1,     /* 1 bank 1 present */
-                        r01     :2,     /* 2-3 reserved */
-                        b01size :4,     /* 4-7 Size of bank 0 and 1 */
-                        b2      :1,     /* 8 bank 2 present */
-                        b3      :1,     /* 9 bank 3 present */
-                        r23     :2,     /* 10-11 reserved */
-                        b23size :4,     /* 12-15 Size of bank 2 and 3 */
-                        b4      :1,     /* 16 bank 4 present */
-                        b5      :1,     /* 17 bank 5 present */
-                        r45     :2,     /* 18-19 reserved */
-                        b45size :4,     /* 20-23 Size of bank 4 and 5 */
-                        b6      :1,     /* 24 bank 6 present */
-                        b7      :1,     /* 25 bank 7 present */
-                        r67     :2,     /* 26-27 reserved */
-                        b67size :4;     /* 28-31 Size of bank 6 and 7 */
-} node_memmap_t ;
-
-/* Support the medusa hack for 8M/16M/32M nodes */
-#define SN1_BANK_SIZE_SHIFT		(MBSHIFT+6)     /* 64 MB */
-#define BankSizeBytes(bsize)            ((bsize<6) ? (1<<((bsize-1)+SN1_BANK_SIZE_SHIFT)) :\
-                                         (1<<((bsize-9)+MBSHIFT)))
-#else
+#ifdef SGI_SN2
 typedef struct node_memmap_s
 {
         unsigned int    b0size  :3,     /* 0-2   bank 0 size */
@@ -73,6 +48,8 @@
 #define SN2_BANK_SIZE_SHIFT		(MBSHIFT+6)     /* 64 MB */
 #define BankPresent(bsize)		(bsize<6)
 #define BankSizeBytes(bsize)            (BankPresent(bsize) ? 1UL<<((bsize)+SN2_BANK_SIZE_SHIFT) : 0)
+#define MD_BANKS_PER_NODE 4
+#define MD_BANKSIZE			(1UL << 34)
 #endif
 
 typedef struct sn_memmap_s
diff -Nru a/arch/ia64/sn/fakeprom/fpromasm.S b/arch/ia64/sn/fakeprom/fpromasm.S
--- a/arch/ia64/sn/fakeprom/fpromasm.S	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/sn/fakeprom/fpromasm.S	Wed Jun 18 23:42:06 2003
@@ -8,7 +8,7 @@
  * Copyright (C) 1998-2000 Hewlett-Packard Co
  * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -57,9 +57,7 @@
  * be 0x00000ffffc000000, but on snia we use the (inverse swizzled)
  * IOSPEC_BASE value
  */
-#ifdef CONFIG_IA64_SGI_SN1
-#define IOPB_PA		0xc0000FFFFC000000
-#else
+#ifdef SGI_SN2
 #define IOPB_PA		0xc000000fcc000000
 #endif
 
@@ -84,10 +82,7 @@
 
 // Isolate node number we are running on.
 	mov		r6 = ip;;
-#ifdef CONFIG_IA64_SGI_SN1
-	shr		r5 = r6,33;;			// r5 = node number
-	shl		r6 = r5,33			// r6 = base memory address of node
-#else
+#ifdef SGI_SN2
 	shr		r5 = r6,38			// r5 = node number
 	dep		r6 = 0,r6,0,36			// r6 = base memory address of node
 
@@ -99,7 +94,7 @@
 	or 		r1 = r1,r6			// Relocate to boot node
 
 // Lets figure out who we are & put it in the LID register.
-#ifdef CONFIG_IA64_SGI_SN2
+#ifdef SGI_SN2
 // On SN2, we (currently) pass the cpu number in r10 at boot
 	and		r25=3,r10;;
 	movl		r16=0x8000008110000400		// Allow IPIs
@@ -324,10 +319,7 @@
 1:	cmp.eq	p6,p7=8,r28		/* PAL_VM_SUMMARY */
 (p7)	br.cond.sptk.few 1f
 	movl	r8=0
-#ifdef CONFIG_IA64_SGI_SN1
-	movl	r9=0x0203083001151059
-	movl	r10=0x1232
-#else
+#ifdef SGI_SN2
 	movl	r9=0x0203083001151065
 	movl	r10=0x183f
 #endif
diff -Nru a/arch/ia64/sn/fakeprom/fw-emu.c b/arch/ia64/sn/fakeprom/fw-emu.c
--- a/arch/ia64/sn/fakeprom/fw-emu.c	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/sn/fakeprom/fw-emu.c	Wed Jun 18 23:42:08 2003
@@ -5,7 +5,7 @@
  * Copyright (C) 1998-2000 David Mosberger-Tang <davidm@hpl.hp.com>
  *
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -36,14 +36,13 @@
  * http://oss.sgi.com/projects/GenInfo/NoticeExplan
  */
 #include <linux/config.h>
-#include <asm/sn/pda.h>
 #include <linux/efi.h>
 #include <asm/pal.h>
 #include <asm/sal.h>
 #include <asm/sn/sn_sal.h>
 #include <asm/processor.h>
 #include <asm/sn/sn_cpuid.h>
-#ifdef CONFIG_IA64_SGI_SN2
+#ifdef SGI_SN2
 #include <asm/sn/sn2/addrs.h>
 #include <asm/sn/sn2/shub_mmr.h>
 #endif
@@ -69,10 +68,7 @@
 #define ACPI_SLIT_REVISION 1
 
 #define OEMID			"SGI"
-#ifdef CONFIG_IA64_SGI_SN1
-#define PRODUCT			"SN1"
-#define PROXIMITY_DOMAIN(nasid)	(nasid)
-#else
+#ifdef SGI_SN2
 #define PRODUCT			"SN2"
 #define PROXIMITY_DOMAIN(nasid)	(((nasid)>>1) & 255)
 #endif
@@ -100,12 +96,7 @@
 
 typedef union ia64_nasid_va {
         struct {
-#if defined(CONFIG_IA64_SGI_SN1)
-                unsigned long off   : 33;       /* intra-region offset */
-		unsigned long nasid :  7;	/* NASID */
-		unsigned long off2  : 21;	/* fill */
-                unsigned long reg   :  3;       /* region number */
-#elif defined(CONFIG_IA64_SGI_SN2)
+#if defined(SGI_SN2)
                 unsigned long off   : 36;       /* intra-region offset */
 		unsigned long attr  :  2;
 		unsigned long nasid : 11;	/* NASID */
@@ -125,9 +116,7 @@
 #define IS_VIRTUAL_MODE() 	 ({struct ia64_psr psr; asm("mov %0=psr" : "=r"(psr)); psr.dt;})
 #define ADDR_OF(p)		(IS_VIRTUAL_MODE() ? ((void*)((long)(p)+PAGE_OFFSET)) : ((void*) (p)))
 
-#if defined(CONFIG_IA64_SGI_SN1)
-#define __fwtab_pa(n,x)		({ia64_nasid_va _v; _v.l = (long) (x); _v.f.nasid = (x) ? (n) : 0; _v.f.reg = 0; _v.l;})
-#elif defined(CONFIG_IA64_SGI_SN2)
+#if defined(SGI_SN2)
 #define __fwtab_pa(n,x)		({ia64_nasid_va _v; _v.l = (long) (x); _v.f.nasid = (x) ? (n) : 0; _v.f.reg = 0; _v.f.attr = 3; _v.l;})
 #endif
 
@@ -208,7 +197,7 @@
 	return EFI_UNSUPPORTED;
 }
 
-#ifdef CONFIG_IA64_SGI_SN2
+#ifdef SGI_SN2
 
 #undef cpu_physical_id
 #define cpu_physical_id(cpuid)                  ((ia64_get_lid() >> 16) & 0xffff)
@@ -301,7 +290,7 @@
 		;
 	} else if (index == SAL_UPDATE_PAL) {
 		;
-#ifdef CONFIG_IA64_SGI_SN2
+#ifdef SGI_SN2
 	} else if (index == SN_SAL_LOG_CE) {
 #ifdef ajmtestcpei
 		fprom_send_cpei();
@@ -501,9 +490,7 @@
 	/*
 	 * Pass the parameter base address to the build_efi_xxx routines.
 	 */
-#if defined(CONFIG_IA64_SGI_SN1)
-	build_init(8LL*GB*base_nasid);
-#else
+#if defined(SGI_SN2)
 	build_init(0x3000000000UL | ((long)base_nasid<<38));
 #endif
 
@@ -559,7 +546,7 @@
 	 * You can also edit this line to pass other arguments to the kernel.
 	 *    Note: disable kernel text replication.
 	 */
-	strcpy(cmd_line, "init=/bin/bash ktreplicate=0");
+	strcpy(cmd_line, "init=/bin/bash console=ttyS0");
 
 	memset(efi_systab, 0, sizeof(efi_systab));
 	efi_systab->hdr.signature = EFI_SYSTEM_TABLE_SIGNATURE;
@@ -625,10 +612,7 @@
 			lsapic20->header.length = sizeof(struct acpi_table_lsapic);
 			lsapic20->acpi_id = cnode*4+cpu;
 			lsapic20->flags.enabled = 1;
-#if defined(CONFIG_IA64_SGI_SN1)
-			lsapic20->eid = cpu;
-			lsapic20->id = nasid;
-#else
+#if defined(SGI_SN2)
 			lsapic20->eid = nasid&0xffff;
 			lsapic20->id = (cpu<<4) | (nasid>>16);
 #endif
@@ -649,12 +633,9 @@
 		srat_memory_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid);
 		srat_memory_affinity->base_addr_lo = 0;
 		srat_memory_affinity->length_lo = 0;
-#if defined(CONFIG_IA64_SGI_SN1)
-		srat_memory_affinity->base_addr_hi = nasid<<1;
-		srat_memory_affinity->length_hi = SN1_NODE_SIZE>>32;
-#else
+#if defined(SGI_SN2)
 		srat_memory_affinity->base_addr_hi = (nasid<<6) | (3<<4);
-		srat_memory_affinity->length_hi = SN2_NODE_SIZE>>32;
+		srat_memory_affinity->length_hi = (MD_BANKSIZE*MD_BANKS_PER_NODE)>>32;
 #endif
 		srat_memory_affinity->memory_type = ACPI_ADDRESS_RANGE_MEMORY;
 		srat_memory_affinity->flags.enabled = 1;
@@ -671,10 +652,7 @@
 			srat_cpu_affinity->header.length = sizeof(struct acpi_table_processor_affinity);
 			srat_cpu_affinity->proximity_domain = PROXIMITY_DOMAIN(nasid);
 			srat_cpu_affinity->flags.enabled = 1;
-#if defined(CONFIG_IA64_SGI_SN1)
-			srat_cpu_affinity->apic_id = nasid;
-			srat_cpu_affinity->lsapic_eid = cpu;
-#else
+#if defined(SGI_SN2)
 			srat_cpu_affinity->lsapic_eid = nasid&0xffff;
 			srat_cpu_affinity->apic_id = (cpu<<4) | (nasid>>16);
 #endif
@@ -708,7 +686,7 @@
 	sal_systab->sal_b_rev_minor = 0x0; /* 1.00 */
 
 	strcpy(sal_systab->oem_id, "SGI");
-	strcpy(sal_systab->product_id, "SN1");
+	strcpy(sal_systab->product_id, "SN2");
 
 	/* fill in an entry point: */	
 	sal_ed->type = SAL_DESC_ENTRY_POINT;
@@ -757,7 +735,7 @@
 	sal_systab->checksum = -checksum;
 
 	/* If the checksum is correct, the kernel tries to use the
-	 * table. We don't build enough table & the kernel aborts.
+	 * table. We dont build enough table & the kernel aborts.
 	 * Note that the PROM hasd thhhe same problem!!
 	 */
 
@@ -786,9 +764,7 @@
 		for(cpu=0; cpu<CPUS_PER_NODE; cpu++) {
 			if (!IsCpuPresent(cnode, cpu))
 				continue;
-#ifdef CONFIG_IA64_SGI_SN1
-			bsp_lid = (GetNasid(cnode)<<24) | (cpu<<16);
-#else
+#ifdef SGI_SN2
 			bsp_lid = (GetNasid(cnode)<<16) | (cpu<<28);
 #endif
 			if (bsp-- > 0)
diff -Nru a/arch/ia64/sn/fakeprom/klgraph_init.c b/arch/ia64/sn/fakeprom/klgraph_init.c
--- a/arch/ia64/sn/fakeprom/klgraph_init.c	Wed Jun 18 23:42:05 2003
+++ b/arch/ia64/sn/fakeprom/klgraph_init.c	Wed Jun 18 23:42:05 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 
@@ -49,41 +49,13 @@
 klgraph_init(void)
 {
 
-#ifdef CONFIG_IA64_SGI_SN1
 	u64 *temp;
-#endif
 	/*
 	 * Initialize some hub/xbow registers that allows access to 
 	 * Xbridge etc.  These are normally done in PROM.
 	 */
 
         /* Write IOERR clear to clear the CRAZY bit in the status */
-#ifdef CONFIG_IA64_SGI_SN1
-        *(volatile uint64_t *)0xc0000a0001c001f8 = (uint64_t)0xffffffff;
-
-        /* set widget control register...setting bedrock widget id to b */
-        *(volatile uint64_t *)0xc0000a0001c00020 = (uint64_t)0x801b;
-
-        /* set io outbound widget access...allow all */
-        *(volatile uint64_t *)0xc0000a0001c00110 = (uint64_t)0xff01;
-
-        /* set io inbound widget access...allow all */
-        *(volatile uint64_t *)0xc0000a0001c00118 = (uint64_t)0xff01;
-
-        /* set io crb timeout to max */
-        *(volatile uint64_t *)0xc0000a0001c003c0 = (uint64_t)0xffffff;
-        *(volatile uint64_t *)0xc0000a0001c003c0 = (uint64_t)0xffffff;
-
-        /* set local block io permission...allow all */
-        *(volatile uint64_t *)0xc0000a0001e04010 = (uint64_t)0xfffffffffffffff;
-
-        /* clear any errors */
-        /* clear_ii_error(); medusa should have cleared these */
-
-        /* set default read response buffers in bridge */
-        *(volatile u32 *)0xc0000a000f000280L = 0xba98;
-        *(volatile u32 *)0xc0000a000f000288L = 0xba98;
-#elif CONFIG_IA64_SGI_SN2
         *(volatile uint64_t *)0xc000000801c001f8 = (uint64_t)0xffffffff;
 
         /* set widget control register...setting bedrock widget id to a */
@@ -108,184 +80,126 @@
         /* set default read response buffers in bridge */
 // [PI]       *(volatile u32 *)0xc00000080f000280L = 0xba98;
 // [PI]       *(volatile u32 *)0xc00000080f000288L = 0xba98;
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-#ifdef CONFIG_IA64_SGI_SN1
-
-	/*
-	 * kldir entries initialization - mankato
-	 */
-	convert(0x8000000000002000, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002010, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002020, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002030, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002040, 0x434d5f53505f5357, 0x0000000000030000);
-	convert(0x8000000000002050, 0x0000000000000000, 0x0000000000010000);
-	convert(0x8000000000002060, 0x0000000000000001, 0x0000000000000000);
-	convert(0x8000000000002070, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002080, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002090, 0x0000000000000000, 0x0000000000000000);
-	convert(0x80000000000020a0, 0x0000000000000000, 0x0000000000000000);
-	convert(0x80000000000020b0, 0x0000000000000000, 0x0000000000000000);
-	convert(0x80000000000020c0, 0x434d5f53505f5357, 0x0000000000000000);
-	convert(0x80000000000020d0, 0x0000000000002400, 0x0000000000000400);
-	convert(0x80000000000020e0, 0x0000000000000001, 0x0000000000000000);
-	convert(0x80000000000020f0, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002100, 0x434d5f53505f5357, 0x0000000000040000);
-	convert(0x8000000000002110, 0x0000000000000000, 0xffffffffffffffff);
-	convert(0x8000000000002120, 0x0000000000000001, 0x0000000000000000);
-	convert(0x8000000000002130, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002140, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002150, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002160, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002170, 0x0000000000000000, 0x0000000000000000);
-	convert(0x8000000000002180, 0x434d5f53505f5357, 0x0000000000020000);
-	convert(0x8000000000002190, 0x0000000000000000, 0x0000000000010000);
-	convert(0x80000000000021a0, 0x0000000000000001, 0x0000000000000000); 
 
-	/*
-	 * klconfig entries initialization - mankato
-	 */
-	convert(0x0000000000030000, 0x00000000beedbabe, 0x0000004800000000);
-	convert(0x0000000000030010, 0x0003007000000018, 0x800002000f820178);
-	convert(0x0000000000030020, 0x80000a000f024000, 0x800002000f800000);
-	convert(0x0000000000030030, 0x0300fafa00012580, 0x00000000040f0000);
-	convert(0x0000000000030040, 0x0000000000000000, 0x0003097000030070);
-	convert(0x0000000000030050, 0x00030970000303b0, 0x0003181000033f70);
-	convert(0x0000000000030060, 0x0003d51000037570, 0x0000000000038330);
-	convert(0x0000000000030070, 0x0203110100030140, 0x0001000000000101);
-	convert(0x0000000000030080, 0x0900000000000000, 0x000000004e465e67);
-	convert(0x0000000000030090, 0x0003097000000000, 0x00030b1000030a40);
-	convert(0x00000000000300a0, 0x00030cb000030be0, 0x000315a0000314d0);
-	convert(0x00000000000300b0, 0x0003174000031670, 0x0000000000000000);
-	convert(0x0000000000030100, 0x000000000000001a, 0x3350490000000000);
-	convert(0x0000000000030110, 0x0000000000000037, 0x0000000000000000);
-	convert(0x0000000000030140, 0x0002420100030210, 0x0001000000000101);
-	convert(0x0000000000030150, 0x0100000000000000, 0xffffffffffffffff);
-	convert(0x0000000000030160, 0x00030d8000000000, 0x0000000000030e50);
-	convert(0x00000000000301c0, 0x0000000000000000, 0x0000000000030070);
-	convert(0x00000000000301d0, 0x0000000000000025, 0x424f490000000000);
-	convert(0x00000000000301e0, 0x000000004b434952, 0x0000000000000000);
-	convert(0x0000000000030210, 0x00027101000302e0, 0x00010000000e4101);
-	convert(0x0000000000030220, 0x0200000000000000, 0xffffffffffffffff);
-	convert(0x0000000000030230, 0x00030f2000000000, 0x0000000000030ff0);
-	convert(0x0000000000030290, 0x0000000000000000, 0x0000000000030140);
-	convert(0x00000000000302a0, 0x0000000000000026, 0x7262490000000000);
-	convert(0x00000000000302b0, 0x00000000006b6369, 0x0000000000000000);
-	convert(0x00000000000302e0, 0x0002710100000000, 0x00010000000f3101);
-	convert(0x00000000000302f0, 0x0500000000000000, 0xffffffffffffffff);
-	convert(0x0000000000030300, 0x000310c000000000, 0x0003126000031190);
-	convert(0x0000000000030310, 0x0003140000031330, 0x0000000000000000);
-	convert(0x0000000000030360, 0x0000000000000000, 0x0000000000030140);
-	convert(0x0000000000030370, 0x0000000000000029, 0x7262490000000000);
-	convert(0x0000000000030380, 0x00000000006b6369, 0x0000000000000000);
-	convert(0x0000000000030970, 0x0000000002010102, 0x0000000000000000);
-	convert(0x0000000000030980, 0x000000004e465e67, 0xffffffff00000000);
-	/* convert(0x00000000000309a0, 0x0000000000037570, 0x0000000100000000); */
-	convert(0x00000000000309a0, 0x0000000000037570, 0xffffffff00000000);
-	convert(0x00000000000309b0, 0x0000000000030070, 0x0000000000000000);
-	convert(0x00000000000309c0, 0x000000000003f420, 0x0000000000000000);
-	convert(0x0000000000030a40, 0x0000000002010125, 0x0000000000000000);
-	convert(0x0000000000030a50, 0xffffffffffffffff, 0xffffffff00000000);
-	convert(0x0000000000030a70, 0x0000000000037b78, 0x0000000000000000);
-	convert(0x0000000000030b10, 0x0000000002010125, 0x0000000000000000);
-	convert(0x0000000000030b20, 0xffffffffffffffff, 0xffffffff00000000);
-	convert(0x0000000000030b40, 0x0000000000037d30, 0x0000000000000001);
-	convert(0x0000000000030be0, 0x00000000ff010203, 0x0000000000000000);
-	convert(0x0000000000030bf0, 0xffffffffffffffff, 0xffffffff000000ff);
-	convert(0x0000000000030c10, 0x0000000000037ee8, 0x0100010000000200);
-	convert(0x0000000000030cb0, 0x00000000ff310111, 0x0000000000000000);
-	convert(0x0000000000030cc0, 0xffffffffffffffff, 0x0000000000000000);
-	convert(0x0000000000030d80, 0x0000000002010104, 0x0000000000000000);
-	convert(0x0000000000030d90, 0xffffffffffffffff, 0x00000000000000ff);
-	convert(0x0000000000030db0, 0x0000000000037f18, 0x0000000000000000);
-	convert(0x0000000000030dc0, 0x0000000000000000, 0x0003007000060000);
-	convert(0x0000000000030de0, 0x0000000000000000, 0x0003021000050000);
-	convert(0x0000000000030df0, 0x000302e000050000, 0x0000000000000000);
-	convert(0x0000000000030e30, 0x0000000000000000, 0x000000000000000a);
-	convert(0x0000000000030e50, 0x00000000ff00011a, 0x0000000000000000);
-	convert(0x0000000000030e60, 0xffffffffffffffff, 0x0000000000000000);
-	convert(0x0000000000030e80, 0x0000000000037fe0, 0x9e6e9e9e9e9e9e9e);
-	convert(0x0000000000030e90, 0x000000000000bc6e, 0x0000000000000000);
-	convert(0x0000000000030f20, 0x0000000002010205, 0x00000000d0020000);
-	convert(0x0000000000030f30, 0xffffffffffffffff, 0x0000000e0000000e);
-	convert(0x0000000000030f40, 0x000000000000000e, 0x0000000000000000);
-	convert(0x0000000000030f50, 0x0000000000038010, 0x00000000000007ff);
-	convert(0x0000000000030f70, 0x0000000000000000, 0x0000000022001077);
-	convert(0x0000000000030fa0, 0x0000000000000000, 0x000000000003f4a8);
-	convert(0x0000000000030ff0, 0x0000000000310120, 0x0000000000000000);
-	convert(0x0000000000031000, 0xffffffffffffffff, 0xffffffff00000002);
-	convert(0x0000000000031010, 0x000000000000000e, 0x0000000000000000);
-	convert(0x0000000000031020, 0x0000000000038088, 0x0000000000000000);
-	convert(0x00000000000310c0, 0x0000000002010205, 0x00000000d0020000);
-	convert(0x00000000000310d0, 0xffffffffffffffff, 0x0000000f0000000f);
-	convert(0x00000000000310e0, 0x000000000000000f, 0x0000000000000000);
-	convert(0x00000000000310f0, 0x00000000000380b8, 0x00000000000007ff);
-	convert(0x0000000000031120, 0x0000000022001077, 0x00000000000310a9);
-	convert(0x0000000000031130, 0x00000000580211c1, 0x000000008009104c);
-	convert(0x0000000000031140, 0x0000000000000000, 0x000000000003f4c0);
-	convert(0x0000000000031190, 0x0000000000310120, 0x0000000000000000);
-	convert(0x00000000000311a0, 0xffffffffffffffff, 0xffffffff00000003);
-	convert(0x00000000000311b0, 0x000000000000000f, 0x0000000000000000);
-	convert(0x00000000000311c0, 0x0000000000038130, 0x0000000000000000);
-	convert(0x0000000000031260, 0x0000000000110106, 0x0000000000000000);
-	convert(0x0000000000031270, 0xffffffffffffffff, 0xffffffff00000004);
-	convert(0x0000000000031280, 0x000000000000000f, 0x0000000000000000);
-	convert(0x00000000000312a0, 0x00000000ff110013, 0x0000000000000000);
-	convert(0x00000000000312b0, 0xffffffffffffffff, 0xffffffff00000000);
-	convert(0x00000000000312c0, 0x000000000000000f, 0x0000000000000000);
-	convert(0x00000000000312e0, 0x0000000000110012, 0x0000000000000000);
-	convert(0x00000000000312f0, 0xffffffffffffffff, 0xffffffff00000000);
-	convert(0x0000000000031300, 0x000000000000000f, 0x0000000000000000);
-	convert(0x0000000000031310, 0x0000000000038160, 0x0000000000000000);
-	convert(0x0000000000031330, 0x00000000ff310122, 0x0000000000000000);
-	convert(0x0000000000031340, 0xffffffffffffffff, 0xffffffff00000005);
-	convert(0x0000000000031350, 0x000000000000000f, 0x0000000000000000);
-	convert(0x0000000000031360, 0x0000000000038190, 0x0000000000000000);
-	convert(0x0000000000031400, 0x0000000000310121, 0x0000000000000000);
-	convert(0x0000000000031400, 0x0000000000310121, 0x0000000000000000);
-	convert(0x0000000000031410, 0xffffffffffffffff, 0xffffffff00000006);
-	convert(0x0000000000031420, 0x000000000000000f, 0x0000000000000000);
-	convert(0x0000000000031430, 0x00000000000381c0, 0x0000000000000000);
-	convert(0x00000000000314d0, 0x00000000ff010201, 0x0000000000000000);
-	convert(0x00000000000314e0, 0xffffffffffffffff, 0xffffffff00000000);
-	convert(0x0000000000031500, 0x00000000000381f0, 0x000030430000ffff);
-	convert(0x0000000000031510, 0x000000000000ffff, 0x0000000000000000);
-	convert(0x00000000000315a0, 0x00000020ff000201, 0x0000000000000000);
-	convert(0x00000000000315b0, 0xffffffffffffffff, 0xffffffff00000001);
-	convert(0x00000000000315d0, 0x0000000000038240, 0x00003f3f0000ffff);
-	convert(0x00000000000315e0, 0x000000000000ffff, 0x0000000000000000);
-	convert(0x0000000000031670, 0x00000000ff010201, 0x0000000000000000);
-	convert(0x0000000000031680, 0xffffffffffffffff, 0x0000000100000002);
-	convert(0x00000000000316a0, 0x0000000000038290, 0x000030430000ffff);
-	convert(0x00000000000316b0, 0x000000000000ffff, 0x0000000000000000);
-	convert(0x0000000000031740, 0x00000020ff000201, 0x0000000000000000);
-	convert(0x0000000000031750, 0xffffffffffffffff, 0x0000000500000003);
-	convert(0x0000000000031770, 0x00000000000382e0, 0x00003f3f0000ffff);
-	convert(0x0000000000031780, 0x000000000000ffff, 0x0000000000000000);
-
-	/*
-	 * GDA initialization - mankato
-	 */
-	convert(0x8000000000002400, 0x0000000258464552, 0x000000000ead0000);
-	convert(0x8000000000002480, 0xffffffff00010000, 0xffffffffffffffff);
-	convert(0x8000000000002490, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024a0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024b0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024c0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024d0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024e0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x80000000000024f0, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002500, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002510, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002520, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002530, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002540, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002550, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002560, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002570, 0xffffffffffffffff, 0xffffffffffffffff);
-	convert(0x8000000000002580, 0x000000000000ffff, 0x0000000000000000);
-#endif
-	
+        /*
+         * klconfig entries initialization - mankato
+         */
+        convert(0xe000003000030000, 0x00000000beedbabe, 0x0000004800000000);
+        convert(0xe000003000030010, 0x0003007000000018, 0x800002000f820178);
+        convert(0xe000003000030020, 0x80000a000f024000, 0x800002000f800000);
+        convert(0xe000003000030030, 0x0300fafa00012580, 0x00000000040f0000);
+        convert(0xe000003000030040, 0x0000000000000000, 0x0003097000030070);
+        convert(0xe000003000030050, 0x00030970000303b0, 0x0003181000033f70);
+        convert(0xe000003000030060, 0x0003d51000037570, 0x0000000000038330);
+        convert(0xe000003000030070, 0x0203110100030140, 0x0001000000000101);
+        convert(0xe000003000030080, 0x0900000000000000, 0x000000004e465e67);
+        convert(0xe000003000030090, 0x0003097000000000, 0x00030b1000030a40);
+        convert(0xe0000030000300a0, 0x00030cb000030be0, 0x000315a0000314d0);
+        convert(0xe0000030000300b0, 0x0003174000031670, 0x0000000000000000);
+        convert(0xe000003000030100, 0x000000000000001a, 0x3350490000000000);
+        convert(0xe000003000030110, 0x0000000000000037, 0x0000000000000000);
+        convert(0xe000003000030140, 0x0002420100030210, 0x0001000000000101);
+        convert(0xe000003000030150, 0x0100000000000000, 0xffffffffffffffff);
+        convert(0xe000003000030160, 0x00030d8000000000, 0x0000000000030e50);
+        convert(0xe0000030000301c0, 0x0000000000000000, 0x0000000000030070);
+        convert(0xe0000030000301d0, 0x0000000000000025, 0x424f490000000000);
+        convert(0xe0000030000301e0, 0x000000004b434952, 0x0000000000000000);
+        convert(0xe000003000030210, 0x00027101000302e0, 0x00010000000e4101);
+        convert(0xe000003000030220, 0x0200000000000000, 0xffffffffffffffff);
+        convert(0xe000003000030230, 0x00030f2000000000, 0x0000000000030ff0);
+        convert(0xe000003000030290, 0x0000000000000000, 0x0000000000030140);
+        convert(0xe0000030000302a0, 0x0000000000000026, 0x7262490000000000);
+        convert(0xe0000030000302b0, 0x00000000006b6369, 0x0000000000000000);
+        convert(0xe0000030000302e0, 0x0002710100000000, 0x00010000000f3101);
+        convert(0xe0000030000302f0, 0x0500000000000000, 0xffffffffffffffff);
+        convert(0xe000003000030300, 0x000310c000000000, 0x0003126000031190);
+        convert(0xe000003000030310, 0x0003140000031330, 0x0000000000000000);
+        convert(0xe000003000030360, 0x0000000000000000, 0x0000000000030140);
+        convert(0xe000003000030370, 0x0000000000000029, 0x7262490000000000);
+        convert(0xe000003000030380, 0x00000000006b6369, 0x0000000000000000);
+        convert(0xe000003000030970, 0x0000000002010102, 0x0000000000000000);
+        convert(0xe000003000030980, 0x000000004e465e67, 0xffffffff00000000);
+        /* convert(0x00000000000309a0, 0x0000000000037570, 0x0000000100000000); */
+        convert(0xe0000030000309a0, 0x0000000000037570, 0xffffffff00000000);
+        convert(0xe0000030000309b0, 0x0000000000030070, 0x0000000000000000);
+        convert(0xe0000030000309c0, 0x000000000003f420, 0x0000000000000000);
+        convert(0xe000003000030a40, 0x0000000002010125, 0x0000000000000000);
+        convert(0xe000003000030a50, 0xffffffffffffffff, 0xffffffff00000000);
+        convert(0xe000003000030a70, 0x0000000000037b78, 0x0000000000000000);
+        convert(0xe000003000030b10, 0x0000000002010125, 0x0000000000000000);
+        convert(0xe000003000030b20, 0xffffffffffffffff, 0xffffffff00000000);
+        convert(0xe000003000030b40, 0x0000000000037d30, 0x0000000000000001);
+        convert(0xe000003000030be0, 0x00000000ff010203, 0x0000000000000000);
+        convert(0xe000003000030bf0, 0xffffffffffffffff, 0xffffffff000000ff);
+        convert(0xe000003000030c10, 0x0000000000037ee8, 0x0100010000000200);
+        convert(0xe000003000030cb0, 0x00000000ff310111, 0x0000000000000000);
+        convert(0xe000003000030cc0, 0xffffffffffffffff, 0x0000000000000000);
+        convert(0xe000003000030d80, 0x0000000002010104, 0x0000000000000000);
+        convert(0xe000003000030d90, 0xffffffffffffffff, 0x00000000000000ff);
+        convert(0xe000003000030db0, 0x0000000000037f18, 0x0000000000000000);
+        convert(0xe000003000030dc0, 0x0000000000000000, 0x0003007000060000);
+        convert(0xe000003000030de0, 0x0000000000000000, 0x0003021000050000);
+        convert(0xe000003000030df0, 0x000302e000050000, 0x0000000000000000);
+        convert(0xe000003000030e30, 0x0000000000000000, 0x000000000000000a);
+        convert(0xe000003000030e50, 0x00000000ff00011a, 0x0000000000000000);
+        convert(0xe000003000030e60, 0xffffffffffffffff, 0x0000000000000000);
+        convert(0xe000003000030e80, 0x0000000000037fe0, 0x9e6e9e9e9e9e9e9e);
+        convert(0xe000003000030e90, 0x000000000000bc6e, 0x0000000000000000);
+        convert(0xe000003000030f20, 0x0000000002010205, 0x00000000d0020000);
+        convert(0xe000003000030f30, 0xffffffffffffffff, 0x0000000e0000000e);
+        convert(0xe000003000030f40, 0x000000000000000e, 0x0000000000000000);
+        convert(0xe000003000030f50, 0x0000000000038010, 0x00000000000007ff);
+        convert(0xe000003000030f70, 0x0000000000000000, 0x0000000022001077);
+        convert(0xe000003000030fa0, 0x0000000000000000, 0x000000000003f4a8);
+        convert(0xe000003000030ff0, 0x0000000000310120, 0x0000000000000000);
+        convert(0xe000003000031000, 0xffffffffffffffff, 0xffffffff00000002);
+        convert(0xe000003000031010, 0x000000000000000e, 0x0000000000000000);
+        convert(0xe000003000031020, 0x0000000000038088, 0x0000000000000000);
+        convert(0xe0000030000310c0, 0x0000000002010205, 0x00000000d0020000);
+        convert(0xe0000030000310d0, 0xffffffffffffffff, 0x0000000f0000000f);
+        convert(0xe0000030000310e0, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe0000030000310f0, 0x00000000000380b8, 0x00000000000007ff);
+        convert(0xe000003000031120, 0x0000000022001077, 0x00000000000310a9);
+        convert(0xe000003000031130, 0x00000000580211c1, 0x000000008009104c);
+        convert(0xe000003000031140, 0x0000000000000000, 0x000000000003f4c0);
+        convert(0xe000003000031190, 0x0000000000310120, 0x0000000000000000);
+        convert(0xe0000030000311a0, 0xffffffffffffffff, 0xffffffff00000003);
+        convert(0xe0000030000311b0, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe0000030000311c0, 0x0000000000038130, 0x0000000000000000);
+        convert(0xe000003000031260, 0x0000000000110106, 0x0000000000000000);
+        convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004);
+        convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004);
+        convert(0xe000003000031280, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe0000030000312a0, 0x00000000ff110013, 0x0000000000000000);
+        convert(0xe0000030000312b0, 0xffffffffffffffff, 0xffffffff00000000);
+        convert(0xe0000030000312c0, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe0000030000312e0, 0x0000000000110012, 0x0000000000000000);
+        convert(0xe0000030000312f0, 0xffffffffffffffff, 0xffffffff00000000);
+        convert(0xe000003000031300, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe000003000031310, 0x0000000000038160, 0x0000000000000000);
+        convert(0xe000003000031330, 0x00000000ff310122, 0x0000000000000000);
+        convert(0xe000003000031340, 0xffffffffffffffff, 0xffffffff00000005);
+        convert(0xe000003000031350, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe000003000031360, 0x0000000000038190, 0x0000000000000000);
+        convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000);
+        convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000);
+        convert(0xe000003000031410, 0xffffffffffffffff, 0xffffffff00000006);
+        convert(0xe000003000031420, 0x000000000000000f, 0x0000000000000000);
+        convert(0xe000003000031430, 0x00000000000381c0, 0x0000000000000000);
+        convert(0xe0000030000314d0, 0x00000000ff010201, 0x0000000000000000);
+        convert(0xe0000030000314e0, 0xffffffffffffffff, 0xffffffff00000000);
+        convert(0xe000003000031500, 0x00000000000381f0, 0x000030430000ffff);
+        convert(0xe000003000031510, 0x000000000000ffff, 0x0000000000000000);
+        convert(0xe0000030000315a0, 0x00000020ff000201, 0x0000000000000000);
+        convert(0xe0000030000315b0, 0xffffffffffffffff, 0xffffffff00000001);
+        convert(0xe0000030000315d0, 0x0000000000038240, 0x00003f3f0000ffff);
+        convert(0xe0000030000315e0, 0x000000000000ffff, 0x0000000000000000);
+        convert(0xe000003000031670, 0x00000000ff010201, 0x0000000000000000);
+        convert(0xe000003000031680, 0xffffffffffffffff, 0x0000000100000002);
+        convert(0xe0000030000316a0, 0x0000000000038290, 0x000030430000ffff);
+        convert(0xe0000030000316b0, 0x000000000000ffff, 0x0000000000000000);
+        convert(0xe000003000031740, 0x00000020ff000201, 0x0000000000000000);
+        convert(0xe000003000031750, 0xffffffffffffffff, 0x0000000500000003);
+        convert(0xe000003000031770, 0x00000000000382e0, 0x00003f3f0000ffff);
+        convert(0xe000003000031780, 0x000000000000ffff, 0x0000000000000000);
 }
-
diff -Nru a/arch/ia64/sn/fakeprom/main.c b/arch/ia64/sn/fakeprom/main.c
--- a/arch/ia64/sn/fakeprom/main.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/sn/fakeprom/main.c	Wed Jun 18 23:42:07 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2001 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
@@ -33,25 +33,9 @@
 	 * First lets figure out who we are. This is done from the
 	 * LID passed to us.
 	 */
-
-#ifdef CONFIG_IA64_SGI_SN1
-	nasid = (lid>>24);
-	syn = (lid>>17)&1;
-	cpu = (lid>>16)&1;
-
-	/*
-	 * Now pick a synergy master to initialize synergy registers.
-	 */
-	if (test_and_set_bit(syn, &nasidmaster[nasid]) == 0) {
-		synergy_init(nasid, syn);
-		test_and_set_bit(syn+2, &nasidmaster[nasid]);
-	} else
-		while (get_bit(syn+2, &nasidmaster[nasid]) == 0);
-#else
 	nasid = (lid>>16)&0xfff;
 	cpu = (lid>>28)&3;
 	syn = 0;
-#endif
 	
 	/*
 	 * Now pick a nasid master to initialize Bedrock registers.
diff -Nru a/arch/ia64/sn/fakeprom/make_textsym b/arch/ia64/sn/fakeprom/make_textsym
--- a/arch/ia64/sn/fakeprom/make_textsym	Wed Jun 18 23:42:05 2003
+++ b/arch/ia64/sn/fakeprom/make_textsym	Wed Jun 18 23:42:05 2003
@@ -7,7 +7,7 @@
 # License.  See the file "COPYING" in the main directory of this archive
 # for more details.
 #
-# Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+# Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
 #
 
 help() {
@@ -37,6 +37,7 @@
 done
 shift `expr $OPTIND - 1`
 
+#OBJDUMP=/usr/bin/ia64-linux-objdump
 LINUX=${1:-vmlinux}
 TEXTSYM=${2:-${LINUX}.sym}
 TMPSYM=${2:-${LINUX}.sym.tmp}
@@ -130,6 +131,8 @@
 
 
 awk '
+/ _start$/ {start=1}
+/ start_ap$/ {start=1}
 /__start_gate_section/ {start=1}
 /^'${dataprefix}\|${textprefix}'/ {
 	if ($4 == ".kdb")
@@ -142,7 +145,7 @@
 			n = 0
 			s = $(NF-1)
 			while (length(s) > 0) {
-				n = n*16 + substr(s,1,1)
+				n = n*16 + (index("0123456789abcdef", substr(s,1,1)) - 1)
 				s = substr(s,2)
 			}
 			printf "GLOBAL | %s | DATA | %s | %d\n", $1, $NF, n
diff -Nru a/arch/ia64/sn/io/Makefile b/arch/ia64/sn/io/Makefile
--- a/arch/ia64/sn/io/Makefile	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/sn/io/Makefile	Wed Jun 18 23:42:06 2003
@@ -11,16 +11,5 @@
 
 EXTRA_CFLAGS    := -DLITTLE_ENDIAN
 
-ifdef CONFIG_IA64_SGI_SN2
-EXTRA_CFLAGS    += -DSHUB_SWAP_WAR
-endif
-
-obj-$(CONFIG_IA64_SGI_SN) += stubs.o sgi_if.o xswitch.o klgraph_hack.o \
-		hcl.o labelcl.o invent.o sgi_io_sim.o \
-		klgraph_hack.o hcl_util.o cdl.o hubdev.o hubspc.o \
-		alenlist.o pci.o pci_dma.o ate_utils.o \
-		ifconfig_net.o io.o ioconfig_bus.o
-
-obj-$(CONFIG_IA64_SGI_SN2) += sn2/
-
-obj-$(CONFIG_PCIBA) += pciba.o
+obj-y += sgi_if.o xswitch.o sgi_io_sim.o cdl.o ate_utils.o \
+	 io.o machvec/ drivers/ platform_init/ sn2/ hwgfs/
diff -Nru a/arch/ia64/sn/io/alenlist.c b/arch/ia64/sn/io/alenlist.c
--- a/arch/ia64/sn/io/alenlist.c	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,899 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-/* Implementation of Address/Length Lists. */
-
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/mmzone.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/alenlist.h>
-
-/*
- * Logically, an Address/Length List is a list of Pairs, where each pair
- * holds an Address and a Length, all in some Address Space.  In this
- * context, "Address Space" is a particular Crosstalk Widget address
- * space, a PCI device address space, a VME bus address space, a
- * physical memory address space, etc.
- *
- * The main use for these Lists is to provide a single mechanism that
- * describes where in an address space a DMA occurs.  This allows the
- * various I/O Bus support layers to provide a single interface for
- * DMA mapping and DMA translation without regard to how the DMA target
- * was specified by upper layers.  The upper layers commonly specify a 
- * DMA target via a buf structure page list, a kernel virtual address,
- * a user virtual address, a vector of addresses (a la uio and iov), 
- * or possibly a pfn list.
- *
- * Address/Length Lists also enable drivers to take advantage of their
- * inate scatter/gather capabilities in systems where some address
- * translation may be required between bus adapters.  The driver forms
- * a List that represents physical memory targets.  This list is passed
- * to the various adapters, which apply various translations.  The final
- * list that's returned to the driver is in terms of its local address
- * address space -- addresses which can be passed off to a scatter/gather
- * capable DMA controller.
- *
- * The current implementation is intended to be useful both in kernels
- * that support interrupt threads (INTR_KTHREAD) and in systems that do
- * not support interrupt threads.  Of course, in the latter case, some
- * interfaces can be called only within a suspendable context.
- *
- * Basic operations on Address/Length Lists include:
- *	alenlist_create		Create a list
- *	alenlist_clear		Clear a list
- *	alenlist_destroy	Destroy a list
- *	alenlist_append		Append a Pair to the end of a list
- *	alenlist_replace	Replace a Pair in the middle of a list
- *	alenlist_get		Get an Address/Length Pair from a list
- *	alenlist_size		Return the number of Pairs in a list
- *	alenlist_concat		Append one list to the end of another
- *	alenlist_clone		Create a new copy of a list
- *
- * Operations that convert from upper-level specifications to Address/
- * Length Lists currently include:
- *	kvaddr_to_alenlist	Convert from a kernel virtual address
- *	uvaddr_to_alenlist	Convert from a user virtual address
- *	buf_to_alenlist		Convert from a buf structure
- *	alenlist_done		Tell system that we're done with an alenlist
- *				obtained from a conversion.
- * Additional convenience operations:
- *	alenpair_init		Create a list and initialize it with a Pair
- *	alenpair_get		Peek at the first pair on a List
- *
- * A supporting type for Address/Length Lists is an alenlist_cursor_t.  A
- * cursor marks a position in a List, and determines which Pair is fetched
- * by alenlist_get.
- *	alenlist_cursor_create	Allocate and initialize a cursor
- *	alenlist_cursor_destroy	Free space consumed by a cursor
- *	alenlist_cursor_init	(Re-)Initialize a cursor to point 
- *				to the start of a list
- *	alenlist_cursor_clone	Clone a cursor (at the current offset)
- *	alenlist_cursor_offset	Return the number of bytes into
- *				a list that this cursor marks
- * Multiple cursors can point at various points into a List.  Also, each
- * list maintains one "internal cursor" which may be updated by alenlist_clear
- * and alenlist_get.  If calling code simply wishes to scan sequentially
- * through a list starting at the beginning, and if it is the only user of
- * a list, it can rely on this internal cursor rather than managing a 
- * separate explicit cursor.
- *
- * The current implementation allows callers to allocate both cursors and
- * the lists as local stack (structure) variables.  This allows for some
- * extra efficiency at the expense of forward binary compatibility.  It 
- * is recommended that customer drivers refrain from local allocation.
- * In fact, we likely will choose to move the structures out of the public 
- * header file into a private place in order to discourage this usage.
- *
- * Currently, no locking is provided by the alenlist implementation.
- *
- * Implementation notes:
- * For efficiency, Pairs are grouped into "chunks" of, say, 32 Pairs
- * and a List consists of some number of these chunks.  Chunks are completely
- * invisible to calling code.  Chunks should be large enough to hold most
- * standard-sized DMA's, but not so large that they consume excessive space.
- *
- * It is generally expected that Lists will be constructed at one time and
- * scanned at a later time.  It is NOT expected that drivers will scan
- * a List while the List is simultaneously extended, although this is
- * theoretically possible with sufficient upper-level locking.
- *
- * In order to support demands of Real-Time drivers and in order to support
- * swapping under low-memory conditions, we support the concept of a
- * "pre-allocated fixed-sized List".  After creating a List with 
- * alenlist_create, a driver may explicitly grow the list (via "alenlist_grow")
- * to a specific number of Address/Length pairs.  It is guaranteed that future 
- * operations involving this list will never automatically grow the list 
- * (i.e. if growth is ever required, the operation will fail).  Additionally, 
- * operations that use alenlist's (e.g. DMA operations) accept a flag which 
- * causes processing to take place "in-situ"; that is, the input alenlist 
- * entries are replaced with output alenlist entries.  The combination of 
- * pre-allocated Lists and in-situ processing allows us to avoid the 
- * potential deadlock scenario where we sleep (waiting for memory) in the 
- * swap out path.
- *
- * For debugging, we track the number of allocated Lists in alenlist_count
- * the number of allocated chunks in alenlist_chunk_count, and the number
- * of allocate cursors in alenlist_cursor_count.  We also provide a debug 
- * routine, alenlist_show, which dumps the contents of an Address/Length List.
- *
- * Currently, Lists are formed by drivers on-demand.  Eventually, we may
- * associate an alenlist with a buf structure and keep it up to date as
- * we go along.  In that case, buf_to_alenlist simply returns a pointer
- * to the existing List, and increments the Lists's reference count.
- * alenlist_done would decrement the reference count and destroys the List
- * if it was the last reference.
- *
- * Eventually alenlist's may allow better support for user-level scatter/
- * gather operations (e.g. via readv/writev):  With proper support, we
- * could potentially handle a vector of reads with a single scatter/gather
- * DMA operation.  This could be especially useful on NUMA systems where
- * there's more of a reason for users to use vector I/O operations.
- *
- * Eventually, alenlist's may replace kaio lists, vhand page lists,
- * buffer cache pfdat lists, DMA page lists, etc.
- */
-
-/* Opaque data types */
-
-/* An Address/Length pair.  */
-typedef struct alen_s {
-	alenaddr_t	al_addr;
-	size_t		al_length;
-} alen_t;
-
-/* 
- * Number of elements in one chunk of an Address/Length List.
- *
- * This size should be sufficient to hold at least an "average" size
- * DMA request.  Must be at least 1, and should be a power of 2,
- * for efficiency.
- */
-#define ALEN_CHUNK_SZ ((512*1024)/NBPP)
-
-/*
- * A fixed-size set of Address/Length Pairs.  Chunks of Pairs are strung together 
- * to form a complete Address/Length List.  Chunking is entirely hidden within the 
- * alenlist implementation, and it simply makes allocation and growth of lists more 
- * efficient.
- */
-typedef struct alenlist_chunk_s {
-	alen_t			alc_pair[ALEN_CHUNK_SZ];/* list of addr/len pairs */
-	struct alenlist_chunk_s *alc_next;		/* point to next chunk of pairs */
-} *alenlist_chunk_t;
-
-/* 
- * An Address/Length List.  An Address/Length List is allocated with alenlist_create.  
- * Alternatively, a list can be allocated on the stack (local variable of type 
- * alenlist_t) and initialized with alenpair_init or with a combination of 
- * alenlist_clear and alenlist_append, etc.  Code which statically allocates these
- * structures loses forward binary compatibility!
- *
- * A statically allocated List is sufficiently large to hold ALEN_CHUNK_SZ pairs.
- */
-struct alenlist_s {
-	unsigned short		al_flags;
-	unsigned short		al_logical_size;	/* logical size of list, in pairs */
-	unsigned short		al_actual_size;		/* actual size of list, in pairs */
-	struct alenlist_chunk_s	*al_last_chunk;		/* pointer to last logical chunk */
-	struct alenlist_cursor_s al_cursor;		/* internal cursor */
-	struct alenlist_chunk_s	al_chunk;		/* initial set of pairs */
-	alenaddr_t		al_compaction_address;	/* used to compact pairs */
-};
-
-/* al_flags field */
-#define AL_FIXED_SIZE	0x1	/* List is pre-allocated, and of fixed size */
-
-
-struct zone *alenlist_zone = NULL;
-struct zone *alenlist_chunk_zone = NULL;
-struct zone *alenlist_cursor_zone = NULL;
-
-#if DEBUG
-int alenlist_count=0;		/* Currently allocated Lists */
-int alenlist_chunk_count = 0;	/* Currently allocated chunks */
-int alenlist_cursor_count = 0;	/* Currently allocate cursors */
-#define INCR_COUNT(ptr) atomic_inc((ptr));
-#define DECR_COUNT(ptr) atomic_dec((ptr));
-#else
-#define INCR_COUNT(ptr)
-#define DECR_COUNT(ptr)
-#endif /* DEBUG */
-
-#if DEBUG
-static void alenlist_show(alenlist_t);
-#endif /* DEBUG */
-
-/*
- * Initialize Address/Length List management.  One time initialization.
- */
-void
-alenlist_init(void)
-{
-	alenlist_zone = snia_kmem_zone_init(sizeof(struct alenlist_s), "alenlist");
-	alenlist_chunk_zone = snia_kmem_zone_init(sizeof(struct alenlist_chunk_s), "alchunk");
-	alenlist_cursor_zone = snia_kmem_zone_init(sizeof(struct alenlist_cursor_s), "alcursor");
-#if DEBUG
-	idbg_addfunc("alenshow", alenlist_show);
-#endif /* DEBUG */
-}
-
-
-/*
- * Initialize an Address/Length List cursor.
- */
-static void
-do_cursor_init(alenlist_t alenlist, alenlist_cursor_t cursorp)
-{
-	cursorp->al_alenlist = alenlist;
-	cursorp->al_offset = 0;
-	cursorp->al_chunk = &alenlist->al_chunk;
-	cursorp->al_index = 0;
-	cursorp->al_bcount = 0;
-}
-
-
-/*
- * Create an Address/Length List, and clear it.
- * Set the cursor to the beginning.
- */
-alenlist_t 
-alenlist_create(unsigned flags)
-{
-	alenlist_t alenlist;
-
-	alenlist = snia_kmem_zone_alloc(alenlist_zone, flags & AL_NOSLEEP ? VM_NOSLEEP : 0);
-	if (alenlist) {
-		INCR_COUNT(&alenlist_count);
-
-		alenlist->al_flags = 0;
-		alenlist->al_logical_size = 0;
-		alenlist->al_actual_size = ALEN_CHUNK_SZ;
-		alenlist->al_last_chunk = &alenlist->al_chunk;
-		alenlist->al_chunk.alc_next = NULL;
-		do_cursor_init(alenlist, &alenlist->al_cursor);
-	}
-
-	return(alenlist);
-}
-
-
-/*
- * Grow an Address/Length List so that all resources needed to contain
- * the specified number of Pairs are pre-allocated.  An Address/Length
- * List that has been explicitly "grown" will never *automatically*
- * grow, shrink, or be destroyed.
- *
- * Pre-allocation is useful for Real-Time drivers and for drivers that
- * may be used along the swap-out path and therefore cannot afford to 
- * sleep until memory is freed.
- * 
- * The cursor is set to the beginning of the list.
- */
-int
-alenlist_grow(alenlist_t alenlist, size_t npairs)
-{
-	/* 
-	 * This interface should be used relatively rarely, so
-	 * the implementation is kept simple: We clear the List,
-	 * then append npairs bogus entries.  Finally, we mark
-	 * the list as FIXED_SIZE and re-initialize the internal
-	 * cursor.
-	 */
-
-	/* 
-	 * Temporarily mark as non-fixed size, since we're about
-	 * to shrink and expand it.
-	 */
-	alenlist->al_flags &= ~AL_FIXED_SIZE;
-
-	/* Free whatever was in the alenlist. */
-	alenlist_clear(alenlist);
-
-	/* Allocate everything that we need via automatic expansion. */
-	while (npairs--)
-		if (alenlist_append(alenlist, 0, 0, AL_NOCOMPACT) == ALENLIST_FAILURE)
-			return(ALENLIST_FAILURE);
-
-	/* Now, mark as FIXED_SIZE */
-	alenlist->al_flags |= AL_FIXED_SIZE;
-
-	/* Clear out bogus entries */
-	alenlist_clear(alenlist);
-
-	/* Initialize internal cursor to the beginning */
-	do_cursor_init(alenlist, &alenlist->al_cursor);
-
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Clear an Address/Length List so that it holds no pairs.
- */
-void
-alenlist_clear(alenlist_t alenlist)
-{
-	alenlist_chunk_t chunk, freechunk;
-
-	/*
-	 * If this List is not FIXED_SIZE, free all the
-	 * extra chunks.
-	 */
-	if (!(alenlist->al_flags & AL_FIXED_SIZE)) {
-		/* First, free any extension alenlist chunks */
-		chunk = alenlist->al_chunk.alc_next;
-		while (chunk) {
-			freechunk = chunk;
-			chunk = chunk->alc_next;
-			snia_kmem_zone_free(alenlist_chunk_zone, freechunk);
-			DECR_COUNT(&alenlist_chunk_count);
-		}
-		alenlist->al_actual_size = ALEN_CHUNK_SZ;
-		alenlist->al_chunk.alc_next = NULL;
-	}
-
-	alenlist->al_logical_size = 0;
-	alenlist->al_last_chunk = &alenlist->al_chunk;
-	do_cursor_init(alenlist, &alenlist->al_cursor);
-}
-
-
-/*
- * Create and initialize an Address/Length Pair.
- * This is intended for degenerate lists, consisting of a single 
- * address/length pair.
- */
-alenlist_t
-alenpair_init(	alenaddr_t address, 
-		size_t length)
-{
-	alenlist_t alenlist;
-
-	alenlist = alenlist_create(0);
-
-	alenlist->al_logical_size = 1;
-	ASSERT(alenlist->al_last_chunk == &alenlist->al_chunk);
-	alenlist->al_chunk.alc_pair[0].al_length = length;
-	alenlist->al_chunk.alc_pair[0].al_addr = address;
-
-	return(alenlist);
-}
-
-/*
- * Return address/length from a degenerate (1-pair) List, or
- * first pair from a larger list.  Does NOT update the internal cursor,
- * so this is an easy way to peek at a start address.
- */
-int
-alenpair_get(	alenlist_t alenlist,
-		alenaddr_t *address,
-		size_t *length)
-{
-	if (alenlist->al_logical_size == 0)
-		return(ALENLIST_FAILURE);
-
-	*length = alenlist->al_chunk.alc_pair[0].al_length;
-	*address = alenlist->al_chunk.alc_pair[0].al_addr;
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Destroy an Address/Length List.
- */
-void 
-alenlist_destroy(alenlist_t alenlist)
-{
-	if (alenlist == NULL)
-		return;
-
-	/* 
-	 * Turn off FIXED_SIZE so this List can be 
-	 * automatically shrunk.
-	 */
-	alenlist->al_flags &= ~AL_FIXED_SIZE;
-
-	/* Free extension chunks first */
-	if (alenlist->al_chunk.alc_next)
-		alenlist_clear(alenlist);
-
-	/* Now, free the alenlist itself */
-	snia_kmem_zone_free(alenlist_zone, alenlist);
-	DECR_COUNT(&alenlist_count);
-}
-
-/*
- * Release an Address/Length List.
- * This is in preparation for a day when alenlist's may be longer-lived, and
- * perhaps associated with a buf structure.  We'd add a reference count, and
- * this routine would decrement the count.  For now, we create alenlist's on
- * on demand and free them when done.  If the driver is not explicitly managing
- * a List for its own use, it should call alenlist_done rather than alenlist_destroy.
- */
-void
-alenlist_done(alenlist_t alenlist)
-{
-	alenlist_destroy(alenlist);
-}
-
-
-/*
- * Append another address/length to the end of an Address/Length List,
- * growing the list if permitted and necessary.
- *
- * Returns: SUCCESS/FAILURE
- */
-int 
-alenlist_append(	alenlist_t alenlist, 		/* append to this list */
-			alenaddr_t address, 		/* address to append */
-			size_t length,			/* length to append */
-			unsigned flags)
-{
-	alen_t *alenp;
-	int index, last_index;
-
-	index = alenlist->al_logical_size % ALEN_CHUNK_SZ;
-
-	if ((alenlist->al_logical_size > 0)) {
-		/*
-		 * See if we can compact this new pair in with the previous entry.
-		 * al_compaction_address holds that value that we'd need to see
-		 * in order to compact.
-		 */
-		if (!(flags & AL_NOCOMPACT) &&
-		    (alenlist->al_compaction_address == address)) {
-			last_index = (alenlist->al_logical_size-1) % ALEN_CHUNK_SZ;
-			alenp = &(alenlist->al_last_chunk->alc_pair[last_index]);
-			alenp->al_length += length;
-			alenlist->al_compaction_address += length;
-			return(ALENLIST_SUCCESS);
-		}
-
-		/*
-		 * If we're out of room in this chunk, move to a new chunk.
-	 	 */
-		if (index == 0) {
-			if (alenlist->al_flags & AL_FIXED_SIZE) {
-				alenlist->al_last_chunk = alenlist->al_last_chunk->alc_next;
-
-				/* If we're out of space in a FIXED_SIZE List, quit. */
-				if (alenlist->al_last_chunk == NULL) {
-					ASSERT(alenlist->al_logical_size == alenlist->al_actual_size);
-					return(ALENLIST_FAILURE);
-				}
-			} else {
-				alenlist_chunk_t new_chunk;
-
-				new_chunk = snia_kmem_zone_alloc(alenlist_chunk_zone, 
-							flags & AL_NOSLEEP ? VM_NOSLEEP : 0);
-
-				if (new_chunk == NULL)
-					return(ALENLIST_FAILURE);
-
-				alenlist->al_last_chunk->alc_next = new_chunk;
-				new_chunk->alc_next = NULL;
-				alenlist->al_last_chunk = new_chunk;
-				alenlist->al_actual_size += ALEN_CHUNK_SZ;
-				INCR_COUNT(&alenlist_chunk_count);
-			}
-		}
-	}
-
-	alenp = &(alenlist->al_last_chunk->alc_pair[index]);
-	alenp->al_addr = address;
-	alenp->al_length = length;
-	
-	alenlist->al_logical_size++;
-	alenlist->al_compaction_address = address + length;
-
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Replace an item in an Address/Length List.  Cursor is updated so
- * that alenlist_get will get the next item in the list.  This interface 
- * is not very useful for drivers; but it is useful to bus providers 
- * that need to translate between address spaced in situ.  The old Address
- * and Length are returned.
- */
-/* ARGSUSED */
-int
-alenlist_replace(	alenlist_t alenlist, 		/* in: replace in this list */
-			alenlist_cursor_t cursorp, 	/* inout: which item to replace */
-			alenaddr_t *addrp, 		/* inout: address */
-			size_t *lengthp,		/* inout: length */
-			unsigned flags)
-{
-	alen_t *alenp;
-	alenlist_chunk_t chunk;
-	unsigned int index;
-	size_t length;
-	alenaddr_t addr;
-
-	if ((addrp == NULL) || (lengthp == NULL))
-		return(ALENLIST_FAILURE);
-
-	if (alenlist->al_logical_size == 0)
-		return(ALENLIST_FAILURE);
-
-	addr = *addrp;
-	length = *lengthp;
-
-	/* 
-	 * If no cursor explicitly specified, use the Address/Length List's 
-	 * internal cursor.
-	 */
-	if (cursorp == NULL)
-		cursorp = &alenlist->al_cursor;
-
-	chunk = cursorp->al_chunk;
-	index = cursorp->al_index;
-
-	ASSERT(cursorp->al_alenlist == alenlist);
-	if (cursorp->al_alenlist != alenlist)
-		return(ALENLIST_FAILURE);
-
-	alenp = &chunk->alc_pair[index];
-
-	/* Return old values */
-	*addrp = alenp->al_length;
-	*lengthp = alenp->al_addr;
-
-	/* Set up new values */
-	alenp->al_length = length;
-	alenp->al_addr = addr;
-
-	/* Update cursor to point to next item */
-	cursorp->al_bcount = length;
-
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Initialize a cursor in order to walk an alenlist.
- * An alenlist_cursor always points to the last thing that was obtained
- * from the list.  If al_chunk is NULL, then nothing has yet been obtained.
- *
- * Note: There is an "internal cursor" associated with every Address/Length List.
- * For users that scan sequentially through a List, it is more efficient to
- * simply use the internal cursor.  The caller must insure that no other users
- * will simultaneously scan the List.  The caller can reposition the internal
- * cursor by calling alenlist_cursor_init with a NULL cursorp.
- */
-int
-alenlist_cursor_init(alenlist_t alenlist, size_t offset, alenlist_cursor_t cursorp)
-{
-	size_t byte_count;
-
-	if (cursorp == NULL)
-		cursorp = &alenlist->al_cursor;
-
-	/* Get internal cursor's byte count for use as a hint.
-	 *
-	 * If the internal cursor points passed the point that we're interested in,
-	 * we need to seek forward from the beginning.  Otherwise, we can seek forward
-	 * from the internal cursor.
-	 */
-	if ((offset > 0) &&
-	   ((byte_count = alenlist_cursor_offset(alenlist, (alenlist_cursor_t)NULL)) <= offset)) {
-		offset -= byte_count;
-		alenlist_cursor_clone(alenlist, NULL, cursorp);
-	} else
-		do_cursor_init(alenlist, cursorp);
-
-	/* We could easily speed this up, but it shouldn't be used very often. */
-	while (offset != 0) {
-		alenaddr_t addr;
-		size_t length;
-
-		if (alenlist_get(alenlist, cursorp, offset, &addr, &length, 0) != ALENLIST_SUCCESS)
-			return(ALENLIST_FAILURE);
-		offset -= length;
-	}
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Copy a cursor.  The source cursor is either an internal alenlist cursor
- * or an explicit cursor.
- */
-int
-alenlist_cursor_clone(	alenlist_t alenlist, 
-			alenlist_cursor_t cursorp_in, 
-			alenlist_cursor_t cursorp_out)
-{
-	ASSERT(cursorp_out);
-
-	if (alenlist && cursorp_in)
-		if (alenlist != cursorp_in->al_alenlist)
-			return(ALENLIST_FAILURE);
-
-	if (alenlist)
-		*cursorp_out = alenlist->al_cursor; /* small structure copy */
-	else if (cursorp_in)
-		*cursorp_out = *cursorp_in; /* small structure copy */
-	else
-		return(ALENLIST_FAILURE); /* no source */
-
-	return(ALENLIST_SUCCESS);
-}
-
-/*
- * Return the number of bytes passed so far according to the specified cursor.
- * If cursorp is NULL, use the alenlist's internal cursor.
- */
-size_t
-alenlist_cursor_offset(alenlist_t alenlist, alenlist_cursor_t cursorp)
-{
-	ASSERT(!alenlist || !cursorp || (alenlist == cursorp->al_alenlist));
-
-	if (cursorp == NULL) {
-		ASSERT(alenlist);
-		cursorp = &alenlist->al_cursor;
-	}
-
-	return(cursorp->al_offset);
-}
-
-/*
- * Allocate and initialize an Address/Length List cursor.
- */
-alenlist_cursor_t
-alenlist_cursor_create(alenlist_t alenlist, unsigned flags)
-{
-	alenlist_cursor_t cursorp;
-
-	ASSERT(alenlist != NULL);
-	cursorp = snia_kmem_zone_alloc(alenlist_cursor_zone, flags & AL_NOSLEEP ? VM_NOSLEEP : 0);
-	if (cursorp) {
-		INCR_COUNT(&alenlist_cursor_count);
-		alenlist_cursor_init(alenlist, 0, cursorp);
-	}
-	return(cursorp);
-}
-
-/*
- * Free an Address/Length List cursor.
- */
-void
-alenlist_cursor_destroy(alenlist_cursor_t cursorp)
-{
-	DECR_COUNT(&alenlist_cursor_count);
-	snia_kmem_zone_free(alenlist_cursor_zone, cursorp);
-}
-
-
-/*
- * Fetch an address/length pair from an Address/Length List.  Update
- * the "cursor" so that next time this routine is called, we'll get
- * the next address range.  Never return a length that exceeds maxlength
- * (if non-zero).  If maxlength is a power of 2, never return a length 
- * that crosses a maxlength boundary.  [This may seem strange at first,
- * but it's what many drivers want.]
- *
- * Returns: SUCCESS/FAILURE
- */
-int
-alenlist_get(	alenlist_t alenlist, 		/* in: get from this list */
-		alenlist_cursor_t cursorp, 	/* inout: which item to get */
-		size_t	maxlength,		/* in: at most this length */
-		alenaddr_t *addrp, 		/* out: address */
-		size_t *lengthp,		/* out: length */
-		unsigned flags)
-{
-	alen_t *alenp;
-	alenlist_chunk_t chunk;
-	unsigned int index;
-	size_t bcount;
-	size_t length;
-
-	/* 
-	 * If no cursor explicitly specified, use the Address/Length List's 
-	 * internal cursor.
-	 */
-	if (cursorp == NULL) {
-		if (alenlist->al_logical_size == 0)
-			return(ALENLIST_FAILURE);
-		cursorp = &alenlist->al_cursor;
-	}
-
-	chunk = cursorp->al_chunk;
-	index = cursorp->al_index;
-	bcount = cursorp->al_bcount;
-
-	ASSERT(cursorp->al_alenlist == alenlist);
-	if (cursorp->al_alenlist != alenlist)
-		return(ALENLIST_FAILURE);
-
-	alenp = &chunk->alc_pair[index];
-	length = alenp->al_length - bcount;
-
-	/* Bump up to next pair, if we're done with this pair. */
-	if (length == 0) {
-		cursorp->al_bcount = bcount = 0;
-		cursorp->al_index = index = (index + 1) % ALEN_CHUNK_SZ;
-
-		/* Bump up to next chunk, if we're done with this chunk. */
-		if (index == 0) {
-			if (cursorp->al_chunk == alenlist->al_last_chunk)
-				return(ALENLIST_FAILURE);
-			chunk = chunk->alc_next;
-			ASSERT(chunk != NULL);
-		} else {
-			/* If in last chunk, don't go beyond end. */
-			if (cursorp->al_chunk == alenlist->al_last_chunk) {
-				int last_size = alenlist->al_logical_size % ALEN_CHUNK_SZ;
-				if (last_size && (index >= last_size))
-					return(ALENLIST_FAILURE);
-			}
-		}
-
-		alenp = &chunk->alc_pair[index];
-		length = alenp->al_length;
-	}
-
-	/* Constrain what we return according to maxlength */
-	if (maxlength) {
-		size_t maxlen1 = maxlength - 1;
-
-		if ((maxlength & maxlen1) == 0) /* power of 2 */
-			maxlength -= 
-			   ((alenp->al_addr + cursorp->al_bcount) & maxlen1);
-
-		length = min(maxlength, length);
-	}
-
-	/* Update the cursor, if desired. */
-	if (!(flags & AL_LEAVE_CURSOR)) {
-		cursorp->al_bcount += length;
-		cursorp->al_chunk = chunk;
-	}
-
-	*lengthp = length;
-	*addrp = alenp->al_addr + bcount;
-
-	return(ALENLIST_SUCCESS);
-}
-
-
-/*
- * Return the number of pairs in the specified Address/Length List.
- * (For FIXED_SIZE Lists, this returns the logical size of the List, 
- * not the actual capacity of the List.)
- */
-int
-alenlist_size(alenlist_t alenlist)
-{
-	return(alenlist->al_logical_size);
-}
-
-
-/*
- * Concatenate two Address/Length Lists.
- */
-void
-alenlist_concat(alenlist_t from,
-		alenlist_t to)
-{
-	struct alenlist_cursor_s cursor;
-	alenaddr_t addr;
-	size_t length;
-
-	alenlist_cursor_init(from, 0, &cursor);
-
-	while(alenlist_get(from, &cursor, (size_t)0, &addr, &length, 0) == ALENLIST_SUCCESS)
-		alenlist_append(to, addr, length, 0);
-}
-
-/*
- * Create a copy of a list.
- * (Not all attributes of the old list are cloned.  For instance, if
- * a FIXED_SIZE list is cloned, the resulting list is NOT FIXED_SIZE.)
- */
-alenlist_t
-alenlist_clone(alenlist_t old_list, unsigned flags)
-{
-	alenlist_t new_list;
-
-	new_list = alenlist_create(flags);
-	if (new_list != NULL)
-		alenlist_concat(old_list, new_list);
-
-	return(new_list);
-}
-
-
-/* 
- * Convert a kernel virtual address to a Physical Address/Length List.
- */
-alenlist_t
-kvaddr_to_alenlist(alenlist_t alenlist, caddr_t kvaddr, size_t length, unsigned flags)
-{
-	alenaddr_t paddr;
-	long offset;
-	size_t piece_length;
-	int created_alenlist;
-
-	if (length <=0)
-		return(NULL);
-
-	/* If caller supplied a List, use it.  Otherwise, allocate one. */
-	if (alenlist == NULL) {
-		alenlist = alenlist_create(0);
-		created_alenlist = 1;
-	} else {
-		alenlist_clear(alenlist);
-		created_alenlist = 0;
-	}
-
-	paddr = kvtophys(kvaddr);
-	offset = poff(kvaddr);
-
-	/* Handle first page */
-	piece_length = min((size_t)(NBPP - offset), length);
-	if (alenlist_append(alenlist, paddr, piece_length, flags) == ALENLIST_FAILURE)
-		goto failure;
-	length -= piece_length;
-	kvaddr += piece_length;
-
-	/* Handle middle pages */
-	while (length >= NBPP) {
-		paddr = kvtophys(kvaddr);
-		if (alenlist_append(alenlist, paddr, NBPP, flags) == ALENLIST_FAILURE)
-			goto failure;
-		length -= NBPP;
-		kvaddr += NBPP;
-	}
-
-	/* Handle last page */
-	if (length) {
-		ASSERT(length < NBPP);
-		paddr = kvtophys(kvaddr);
-		if (alenlist_append(alenlist, paddr, length, flags) == ALENLIST_FAILURE)
-			goto failure;
-	}
-
-	alenlist_cursor_init(alenlist, 0, NULL);
-	return(alenlist);
-
-failure:
-	if (created_alenlist)
-		alenlist_destroy(alenlist);
-	return(NULL);
-}
-
-
-#if DEBUG
-static void
-alenlist_show(alenlist_t alenlist)
-{
-	struct alenlist_cursor_s cursor;
-	alenaddr_t addr;
-	size_t length;
-	int i = 0;
-
-	alenlist_cursor_init(alenlist, 0, &cursor);
-
-	qprintf("Address/Length List@0x%x:\n", alenlist);
-	qprintf("logical size=0x%x actual size=0x%x last_chunk at 0x%x\n", 
-		alenlist->al_logical_size, alenlist->al_actual_size, 
-		alenlist->al_last_chunk);
-	qprintf("cursor: chunk=0x%x index=%d offset=0x%x\n",
-		alenlist->al_cursor.al_chunk, 
-		alenlist->al_cursor.al_index,
-		alenlist->al_cursor.al_bcount);
-	while(alenlist_get(alenlist, &cursor, (size_t)0, &addr, &length, 0) == ALENLIST_SUCCESS)
-		qprintf("%d:\t0x%lx 0x%lx\n", ++i, addr, length);
-}
-#endif /* DEBUG */
diff -Nru a/arch/ia64/sn/io/ate_utils.c b/arch/ia64/sn/io/ate_utils.c
--- a/arch/ia64/sn/io/ate_utils.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/sn/io/ate_utils.c	Wed Jun 18 23:42:07 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,7 +27,6 @@
 #include <asm/sn/ioerror_handling.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/sn_private.h>
 
 #include <asm/sn/ate_utils.h>
diff -Nru a/arch/ia64/sn/io/cdl.c b/arch/ia64/sn/io/cdl.c
--- a/arch/ia64/sn/io/cdl.c	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/sn/io/cdl.c	Wed Jun 18 23:42:06 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/config.h>
@@ -18,9 +18,9 @@
 #include <asm/sn/xtalk/xbow.h>
 
 /* these get called directly in cdl_add_connpt in fops bypass hack */
-extern int pcibr_attach(devfs_handle_t);
-extern int xbow_attach(devfs_handle_t);
-extern int pic_attach(devfs_handle_t);
+extern int pcibr_attach(vertex_hdl_t);
+extern int xbow_attach(vertex_hdl_t);
+extern int pic_attach(vertex_hdl_t);
 
 
 /*
@@ -32,75 +32,20 @@
  *	IO Infrastructure Drivers e.g. pcibr.
  */
 
-struct cdl {
-    int		part_num;
-    int		mfg_num;
-    int (*attach) (devfs_handle_t);
-} dummy_reg;
-
-#ifdef CONFIG_IA64_SGI_SN1
-#define MAX_SGI_IO_INFRA_DRVR 4
-#else
 #define MAX_SGI_IO_INFRA_DRVR 7
-#endif
+
 static struct cdl sgi_infrastructure_drivers[MAX_SGI_IO_INFRA_DRVR] =
 {
 	{ XBRIDGE_WIDGET_PART_NUM, XBRIDGE_WIDGET_MFGR_NUM, pcibr_attach /* &pcibr_fops  */},
 	{ BRIDGE_WIDGET_PART_NUM,  BRIDGE_WIDGET_MFGR_NUM,  pcibr_attach /* &pcibr_fops */},
-#ifndef CONFIG_IA64_SGI_SN1
 	{ PIC_WIDGET_PART_NUM_BUS0,  PIC_WIDGET_MFGR_NUM,   pic_attach /* &pic_fops */},
 	{ PIC_WIDGET_PART_NUM_BUS1,  PIC_WIDGET_MFGR_NUM,   pic_attach /* &pic_fops */},
-#endif
 	{ XXBOW_WIDGET_PART_NUM,   XXBOW_WIDGET_MFGR_NUM,   xbow_attach /* &xbow_fops */},
 	{ XBOW_WIDGET_PART_NUM,    XBOW_WIDGET_MFGR_NUM,    xbow_attach /* &xbow_fops */},
-#ifndef CONFIG_IA64_SGI_SN1
 	{ PXBOW_WIDGET_PART_NUM,   XXBOW_WIDGET_MFGR_NUM,   xbow_attach /* &xbow_fops */},
-#endif
 };
 
 /*
- * cdl_new:  Called by pciio and xtalk.
- */
-cdl_p
-cdl_new(char *name, char *k1str, char *k2str)
-{
-    /*
-     * Just return a dummy pointer.
-     */
-    return((cdl_p)&dummy_reg);
-}
-
-/*
- * cdl_del: Do nothing.
- */
-void
-cdl_del(cdl_p reg)
-{
-	return;
-}
-
-/*
- * cdl_add_driver: The driver part number and manufacturers number 
- * are statically initialized above.
- * 
-  Do nothing.
- */
-int
-cdl_add_driver(cdl_p reg, int key1, int key2, char *prefix, int flags, cdl_drv_f *func)
-{
-    return 0;
-}
-
-/*
- * cdl_del_driver: Not supported.
- */
-void
-cdl_del_driver(cdl_p reg, char *prefix, cdl_drv_f *func)
-{
-	return;
-}
-
-/*
  * cdl_add_connpt: We found a device and it's connect point.  Call the 
  * attach routine of that driver.
  *
@@ -112,8 +57,8 @@
  * vertices.
  */
 int
-cdl_add_connpt(cdl_p reg, int part_num, int mfg_num, 
-	       devfs_handle_t connpt, int drv_flags)
+cdl_add_connpt(int part_num, int mfg_num, 
+	       vertex_hdl_t connpt, int drv_flags)
 {
 	int i;
 	
@@ -121,7 +66,6 @@
 	 * Find the driver entry point and call the attach routine.
 	 */
 	for (i = 0; i < MAX_SGI_IO_INFRA_DRVR; i++) {
-
 		if ( (part_num == sgi_infrastructure_drivers[i].part_num) &&
 		   ( mfg_num == sgi_infrastructure_drivers[i].mfg_num) ) {
 			/*
@@ -139,73 +83,3 @@
 
 	return (0);
 }
-
-/*
- * cdl_del_connpt: Not implemented.
- */
-int
-cdl_del_connpt(cdl_p reg, int key1, int key2, devfs_handle_t connpt, int drv_flags)
-{
-
-	return(0);
-}
-
-/*
- *    cdl_iterate: Not Implemented.
- */
-void
-cdl_iterate(cdl_p reg,
-	    char *prefix,
-	    cdl_iter_f * func)
-{
-	return;
-}
-
-async_attach_t 
-async_attach_new(void)
-{
-
-	return(0);
-}
-
-void 
-async_attach_free(async_attach_t aa)
-{
-	return;
-}
-
-async_attach_t 
-async_attach_get_info(devfs_handle_t vhdl)
-{
-
-	return(0);
-}
-
-void            
-async_attach_add_info(devfs_handle_t vhdl, async_attach_t aa)
-{
-	return;
-
-}
-
-void            
-async_attach_del_info(devfs_handle_t vhdl)
-{
-	return;
-}
-
-void async_attach_signal_start(async_attach_t aa)
-{
-	return;
-}
-
-void async_attach_signal_done(async_attach_t aa)
-{
-	return;
-}
-
-void async_attach_waitall(async_attach_t aa)
-{
-	return;
-}
-
diff -Nru a/arch/ia64/sn/io/drivers/Makefile b/arch/ia64/sn/io/drivers/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/drivers/Makefile	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,12 @@
+#
+# 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) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# Makefile for the sn2 io routines.
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+obj-y				+= ioconfig_bus.o ifconfig_net.o
diff -Nru a/arch/ia64/sn/io/drivers/ifconfig_net.c b/arch/ia64/sn/io/drivers/ifconfig_net.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/drivers/ifconfig_net.c	Wed Jun 18 23:42:06 2003
@@ -0,0 +1,298 @@
+/* $Id: ifconfig_net.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+ *
+ * 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.
+ *
+ *  ifconfig_net - SGI's Persistent Network Device names.
+ *
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/pci.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/skbuff.h>
+
+#include <asm/sn/sgi.h>
+#include <linux/devfs_fs.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/ifconfig_net.h>
+
+#define SGI_IFCONFIG_NET "SGI-PERSISTENT NETWORK DEVICE NAME DRIVER"
+#define SGI_IFCONFIG_NET_VERSION "1.0"
+
+/*
+ * Some Global definitions.
+ */
+static devfs_handle_t ifconfig_net_handle;
+static unsigned long ifconfig_net_debug;
+
+/*
+ * ifconfig_net_open - Opens the special device node "/devhw/.ifconfig_net".
+ */
+static int ifconfig_net_open(struct inode * inode, struct file * filp)
+{
+	if (ifconfig_net_debug) {
+        	printk("ifconfig_net_open called.\n");
+	}
+
+        return(0);
+
+}
+
+/*
+ * ifconfig_net_close - Closes the special device node "/devhw/.ifconfig_net".
+ */
+static int ifconfig_net_close(struct inode * inode, struct file * filp)
+{
+
+	if (ifconfig_net_debug) {
+        	printk("ifconfig_net_close called.\n");
+	}
+
+        return(0);
+}
+
+/*
+ * assign_ifname - Assign the next available interface name from the persistent list.
+ */
+void
+assign_ifname(struct net_device *dev,
+		  struct ifname_num *ifname_num)
+
+{
+
+	/*
+	 * Handle eth devices.
+	 */
+        if ( (memcmp(dev->name, "eth", 3) == 0) ) {
+		if (ifname_num->next_eth != -1) {
+			/*
+			 * Assign it the next available eth interface number. 
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "eth%d", (int)ifname_num->next_eth);
+			ifname_num->next_eth++;
+		} 
+
+                return;
+        }
+
+	/*
+	 * Handle fddi devices.
+	 */
+	if ( (memcmp(dev->name, "fddi", 4) == 0) ) {
+		if (ifname_num->next_fddi != -1) {
+			/*
+			 * Assign it the next available fddi interface number.
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "fddi%d", (int)ifname_num->next_fddi);
+			ifname_num->next_fddi++;
+		}
+
+		return;
+	}
+
+	/*
+	 * Handle hip devices.
+	 */
+	if ( (memcmp(dev->name, "hip", 3) == 0) ) {
+		if (ifname_num->next_hip != -1) {
+			/*
+			 * Assign it the next available hip interface number.
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "hip%d", (int)ifname_num->next_hip);
+			ifname_num->next_hip++;
+		}
+
+		return;
+	}
+
+	/*
+	 * Handle tr devices.
+	 */
+	if ( (memcmp(dev->name, "tr", 2) == 0) ) {
+		if (ifname_num->next_tr != -1) {
+			/*
+			 * Assign it the next available tr interface number.
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "tr%d", (int)ifname_num->next_tr);
+			ifname_num->next_tr++;
+		}
+
+		return;
+	}
+
+	/*
+	 * Handle fc devices.
+	 */
+	if ( (memcmp(dev->name, "fc", 2) == 0) ) {
+		if (ifname_num->next_fc != -1) {
+			/*
+			 * Assign it the next available fc interface number.
+			 */
+			memset(dev->name, 0, strlen(dev->name));
+			sprintf(dev->name, "fc%d", (int)ifname_num->next_fc);
+			ifname_num->next_fc++;
+		}
+
+		return;
+	}
+}
+
+/*
+ * find_persistent_ifname: Returns the entry that was seen in previous boot.
+ */
+struct ifname_MAC *
+find_persistent_ifname(struct net_device *dev,
+	struct ifname_MAC *ifname_MAC)
+
+{
+
+	while (ifname_MAC->addr_len) {
+		if (memcmp(dev->dev_addr, ifname_MAC->dev_addr, dev->addr_len) == 0)
+			return(ifname_MAC);
+
+		ifname_MAC++;
+	}
+
+	return(NULL);
+}
+
+/*
+ * ifconfig_net_ioctl: ifconfig_net driver ioctl interface.
+ */
+static int ifconfig_net_ioctl(struct inode * inode, struct file * file,
+        unsigned int cmd, unsigned long arg)
+{
+
+	extern struct net_device *__dev_get_by_name(const char *);
+#ifdef CONFIG_NET
+	struct net_device *dev;
+	struct ifname_MAC *found;
+	char temp[64];
+#endif
+	struct ifname_MAC *ifname_MAC;
+	struct ifname_MAC *new_devices, *temp_new_devices;
+	struct ifname_num *ifname_num;
+	unsigned long size;
+
+
+	if (ifconfig_net_debug) {
+		printk("HCL: hcl_ioctl called.\n");
+	}
+
+	/*
+	 * Read in the header and see how big of a buffer we really need to 
+	 * allocate.
+	 */
+	ifname_num = (struct ifname_num *) kmalloc(sizeof(struct ifname_num), 
+			GFP_KERNEL);
+	copy_from_user( ifname_num, (char *) arg, sizeof(struct ifname_num));
+	size = ifname_num->size;
+	kfree(ifname_num);
+	ifname_num = (struct ifname_num *) kmalloc(size, GFP_KERNEL);
+	ifname_MAC = (struct ifname_MAC *) ((char *)ifname_num + (sizeof(struct ifname_num)) );
+
+	copy_from_user( ifname_num, (char *) arg, size);
+	new_devices =  kmalloc(size - sizeof(struct ifname_num), GFP_KERNEL);
+	temp_new_devices = new_devices;
+
+	memset(new_devices, 0, size - sizeof(struct ifname_num));
+
+#ifdef CONFIG_NET
+	/*
+	 * Go through the net device entries and make them persistent!
+	 */
+	for (dev = dev_base; dev != NULL; dev = dev->next) {
+		/*
+		 * Skip NULL entries or "lo"
+		 */
+		if ( (dev->addr_len == 0) || ( !strncmp(dev->name, "lo", strlen(dev->name))) ){
+			continue;
+		}
+
+		/*
+		 * See if we have a persistent interface name for this device.
+		 */
+		found = NULL;
+		found = find_persistent_ifname(dev, ifname_MAC);
+		if (found) {
+			strcpy(dev->name, found->name);
+		} else {
+			/* Never seen this before .. */
+			assign_ifname(dev, ifname_num);
+
+			/* 
+			 * Save the information for the next boot.
+			 */
+ 			sprintf(temp,"%s %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
+				dev->dev_addr[0],  dev->dev_addr[1],  dev->dev_addr[2],
+				dev->dev_addr[3],  dev->dev_addr[4],  dev->dev_addr[5]);
+			strcpy(temp_new_devices->name, dev->name);
+			temp_new_devices->addr_len = dev->addr_len;
+			memcpy(temp_new_devices->dev_addr, dev->dev_addr, dev->addr_len);
+			temp_new_devices++;
+		}
+		
+	}
+#endif
+
+	/*
+	 * Copy back to the User Buffer area any new devices encountered.
+	 */
+	copy_to_user((char *)arg + (sizeof(struct ifname_num)), new_devices, 
+			size - sizeof(struct ifname_num));
+
+	return(0);
+
+}
+
+struct file_operations ifconfig_net_fops = {
+	ioctl:ifconfig_net_ioctl,	/* ioctl */
+	open:ifconfig_net_open,		/* open */
+	release:ifconfig_net_close	/* release */
+};
+
+
+/*
+ * init_ifconfig_net() - Boot time initialization.  Ensure that it is called 
+ *	after devfs has been initialized.
+ *
+ */
+#ifdef MODULE
+int init_module (void)
+#else
+int __init init_ifconfig_net(void)
+#endif
+{
+	ifconfig_net_handle = NULL;
+	ifconfig_net_handle = hwgraph_register(hwgraph_root, ".ifconfig_net",
+ 		        0, 0,
+			0, 0,
+			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+			&ifconfig_net_fops, NULL);
+
+	if (ifconfig_net_handle == NULL) {
+		panic("Unable to create SGI PERSISTENT NETWORK DEVICE Name Driver.\n");
+	}
+
+	return(0);
+
+}
diff -Nru a/arch/ia64/sn/io/drivers/ioconfig_bus.c b/arch/ia64/sn/io/drivers/ioconfig_bus.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/drivers/ioconfig_bus.c	Wed Jun 18 23:42:08 2003
@@ -0,0 +1,401 @@
+/*
+ * 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.
+ *
+ *  ioconfig_bus - SGI's Persistent PCI Bus Numbering.
+ *
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/init.h>
+
+#include <linux/pci.h>
+
+#include <asm/sn/sgi.h>
+#include <linux/devfs_fs.h>
+#include <linux/devfs_fs_kernel.h>
+#include <asm/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm//sn/sn_sal.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/ioconfig_bus.h>
+
+#define SGI_IOCONFIG_BUS "SGI-PERSISTENT PCI BUS NUMBERING"
+#define SGI_IOCONFIG_BUS_VERSION "1.0"
+
+/*
+ * Some Global definitions.
+ */
+static vertex_hdl_t ioconfig_bus_handle;
+static unsigned long ioconfig_bus_debug;
+
+#ifdef IOCONFIG_BUS_DEBUG
+#define DBG(x...)	printk(x)
+#else
+#define DBG(x...)
+#endif
+
+static u64 ioconfig_file;
+static u64 ioconfig_file_size;
+static u64 ioconfig_activated;
+static char ioconfig_kernopts[128];
+
+/*
+ * For debugging purpose .. hardcode a table ..
+ */
+struct  ascii_moduleid *ioconfig_bus_table;
+u64 ioconfig_bus_table_size;
+
+
+static int free_entry;
+static int new_entry;
+
+int next_basebus_number;
+
+void
+ioconfig_get_busnum(char *io_moduleid, int *bus_num)
+{
+	struct	ascii_moduleid  *temp;
+	int index;
+
+	DBG("ioconfig_get_busnum io_moduleid %s\n", io_moduleid);
+
+	*bus_num = -1;
+	temp = ioconfig_bus_table;
+	for (index = 0; index < free_entry; temp++, index++) {
+		if ( (io_moduleid[0] == temp->io_moduleid[0]) &&
+		     (io_moduleid[1] == temp->io_moduleid[1]) &&
+		     (io_moduleid[2] == temp->io_moduleid[2]) &&
+		     (io_moduleid[4] == temp->io_moduleid[4]) &&
+		     (io_moduleid[5] == temp->io_moduleid[5]) ) {
+			*bus_num = index * 0x10;
+			return;
+		}
+	}
+
+	/*
+	 * New IO Brick encountered.
+	 */
+	if (((int)io_moduleid[0]) == 0) {
+		DBG("ioconfig_get_busnum: Invalid Module Id given %s\n", io_moduleid);
+		return;
+	}
+
+	io_moduleid[3] = '#';
+	strcpy((char *)&(ioconfig_bus_table[free_entry].io_moduleid), io_moduleid);
+	*bus_num = free_entry * 0x10;
+	free_entry++;
+}
+
+static void
+dump_ioconfig_table(void)
+{
+
+	int index = 0;
+	struct ascii_moduleid *temp;
+
+	temp = ioconfig_bus_table;
+	while (index < free_entry) {
+		DBG("ASSCI Module ID %s\n", temp->io_moduleid);
+		temp++;
+		index++;
+	}
+}
+
+/*
+ * nextline
+ *	This routine returns the nextline in the buffer.
+ */
+int nextline(char *buffer, char **next, char *line)
+{
+
+	char *temp;
+
+	if (buffer[0] == 0x0) {
+		return(0);
+	}
+
+	temp = buffer;
+	while (*temp != 0) {
+		*line = *temp;
+		if (*temp != '\n'){
+			*line = *temp;
+			temp++; line++;
+		} else
+			break;
+	}
+
+	if (*temp == 0)
+		*next = temp;
+	else
+		*next = ++temp;
+
+	return(1);
+}
+
+/*
+ * build_pcibus_name
+ *	This routine parses the ioconfig contents read into
+ *	memory by ioconfig command in EFI and builds the
+ *	persistent pci bus naming table.
+ */
+void
+build_moduleid_table(char *file_contents, struct ascii_moduleid *table)
+{
+	/*
+	 * Read the whole file into memory.
+	 */
+	int rc;
+	char *name;
+	char *temp;
+	char *next;
+	char *current;
+	char *line;
+	struct ascii_moduleid *moduleid;
+
+	line = kmalloc(256, GFP_KERNEL);
+	memset(line, 0,256);
+	name = kmalloc(125, GFP_KERNEL);
+	memset(name, 0, 125);
+	moduleid = table;
+	current = file_contents;
+	while (nextline(current, &next, line)){
+
+		DBG("current 0x%lx next 0x%lx\n", current, next);
+
+		temp = line;
+		/*
+		 * Skip all leading Blank lines ..
+		 */
+		while (isspace(*temp))
+			if (*temp != '\n')
+				temp++;
+			else
+				break;
+
+		if (*temp == '\n') {
+			current = next;
+			memset(line, 0, 256);
+			continue;
+		}
+ 
+		/*
+		 * Skip comment lines
+		 */
+		if (*temp == '#') {
+			current = next;
+			memset(line, 0, 256);
+			continue;
+		}
+
+		/*
+		 * Get the next free entry in the table.
+		 */
+		rc = sscanf(temp, "%s", name);
+		strcpy(&moduleid->io_moduleid[0], name);
+		DBG("Found %s\n", name);
+		moduleid++;
+		free_entry++;
+		current = next;
+		memset(line, 0, 256);
+	}
+
+	new_entry = free_entry;
+	kfree(line);
+	kfree(name);
+
+	return;
+}
+
+void
+ioconfig_bus_init(void)
+{
+
+	struct ia64_sal_retval ret_stuff;
+	u64	*temp;
+	int	cnode;
+
+	DBG("ioconfig_bus_init called.\n");
+
+        for (cnode = 0; cnode < numnodes; cnode++) {
+		nasid_t nasid;
+		/*
+	 	 * Make SAL call to get the address of the bus configuration table.
+	 	 */
+		ret_stuff.status = (uint64_t)0;
+		ret_stuff.v0 = (uint64_t)0;
+		ret_stuff.v1 = (uint64_t)0;
+		ret_stuff.v2 = (uint64_t)0;
+		nasid = COMPACT_TO_NASID_NODEID(cnode);
+		SAL_CALL(ret_stuff, SN_SAL_BUS_CONFIG, 0, nasid, 0, 0, 0, 0, 0);
+		temp = (u64 *)TO_NODE_CAC(nasid, ret_stuff.v0);
+		ioconfig_file = *temp;
+		DBG("ioconfig_bus_init: Nasid %d ret_stuff.v0 0x%lx\n", nasid,
+			ret_stuff.v0);
+		if (ioconfig_file) {
+			ioconfig_file_size = ret_stuff.v1;
+			ioconfig_file = (ioconfig_file | CACHEABLE_MEM_SPACE);
+			ioconfig_activated = 1;
+			break;
+		}
+	}
+
+	DBG("ioconfig_bus_init: ret_stuff.v0 %p ioconfig_file %p %d\n",
+		ret_stuff.v0, (void *)ioconfig_file, (int)ioconfig_file_size);
+
+	ioconfig_bus_table = kmalloc( 512, GFP_KERNEL );
+	memset(ioconfig_bus_table, 0, 512);
+
+	/*
+	 * If ioconfig options are given on the bootline .. take it.
+	 */
+	if (*ioconfig_kernopts != '\0') {
+		/*
+		 * ioconfig="..." kernel options given.
+		 */
+		DBG("ioconfig_bus_init: Kernel Options given.\n");
+		(void) build_moduleid_table((char *)ioconfig_kernopts, ioconfig_bus_table);
+		(void) dump_ioconfig_table();
+		return;
+	}
+
+	if (ioconfig_activated) {
+		DBG("ioconfig_bus_init: ioconfig file given.\n");
+		(void) build_moduleid_table((char *)ioconfig_file, ioconfig_bus_table);
+		(void) dump_ioconfig_table();
+	} else {
+		DBG("ioconfig_bus_init: ioconfig command not executed in prom\n");
+	}
+
+}
+
+void
+ioconfig_bus_new_entries(void)
+{
+
+	
+	int index = 0;
+	struct ascii_moduleid *temp;
+
+	if ((ioconfig_activated) && (free_entry > new_entry)) {
+		printk("### Please add the following new IO Bricks Module ID \n");
+		printk("### to your Persistent Bus Numbering Config File\n");
+	} else
+		return;
+
+	index = new_entry;
+	temp = &ioconfig_bus_table[index];
+        while (index < free_entry) {
+                printk("%s\n", (char *)temp);
+		temp++;
+                index++;
+        }
+	printk("### End\n");
+
+}
+static int ioconfig_bus_ioctl(struct inode * inode, struct file * file,
+        unsigned int cmd, unsigned long arg)
+{
+
+	struct ioconfig_parm parm;
+
+	/*
+	 * Copy in the parameters.
+	 */
+	copy_from_user(&parm, (char *)arg, sizeof(struct ioconfig_parm));
+	parm.number = free_entry - new_entry;
+	parm.ioconfig_activated = ioconfig_activated;
+	copy_to_user((char *)arg, &parm, sizeof(struct ioconfig_parm));
+	copy_to_user((char *)parm.buffer, &ioconfig_bus_table[new_entry], sizeof(struct  ascii_moduleid) * (free_entry - new_entry));
+
+	return 0;
+}
+
+/*
+ * ioconfig_bus_open - Opens the special device node "/dev/hw/.ioconfig_bus".
+ */
+static int ioconfig_bus_open(struct inode * inode, struct file * filp)
+{
+	if (ioconfig_bus_debug) {
+        	DBG("ioconfig_bus_open called.\n");
+	}
+
+        return(0);
+
+}
+
+/*
+ * ioconfig_bus_close - Closes the special device node "/dev/hw/.ioconfig_bus".
+ */
+static int ioconfig_bus_close(struct inode * inode, struct file * filp)
+{
+
+	if (ioconfig_bus_debug) {
+        	DBG("ioconfig_bus_close called.\n");
+	}
+
+        return(0);
+}
+
+struct file_operations ioconfig_bus_fops = {
+	ioctl:ioconfig_bus_ioctl,
+	open:ioconfig_bus_open,		/* open */
+	release:ioconfig_bus_close	/* release */
+};
+
+
+/*
+ * init_ifconfig_bus() - Boot time initialization.  Ensure that it is called 
+ *	after devfs has been initialized.
+ *
+ */
+int init_ioconfig_bus(void)
+{
+	ioconfig_bus_handle = NULL;
+	ioconfig_bus_handle = hwgraph_register(hwgraph_root, ".ioconfig_bus",
+		        0, 0,
+			0, 0,
+			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+			&ioconfig_bus_fops, NULL);
+
+	if (ioconfig_bus_handle == NULL) {
+		panic("Unable to create SGI PERSISTENT BUS NUMBERING Driver.\n");
+	}
+
+	return(0);
+
+}
+
+static int __init ioconfig_bus_setup (char *str)
+{
+
+	char *temp;
+
+	DBG("ioconfig_bus_setup: Kernel Options %s\n", str);
+
+	temp = (char *)ioconfig_kernopts;
+	memset(temp, 0, 128);
+	while ( (*str != '\0') && !isspace (*str) ) {
+		if (*str == ',') {
+			*temp = '\n';
+			temp++;
+			str++;
+			continue;
+		}
+		*temp = *str;
+		temp++;
+		str++;
+	}
+
+	return(0);
+		
+}
+__setup("ioconfig=", ioconfig_bus_setup);
diff -Nru a/arch/ia64/sn/io/eeprom.c b/arch/ia64/sn/io/eeprom.c
--- a/arch/ia64/sn/io/eeprom.c	Wed Jun 18 23:42:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1454 +0,0 @@
-/*
- * 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) 1999-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * WARNING:     There is more than one copy of this file in different isms.
- *              All copies must be kept exactly in sync.
- *              Do not modify this file without also updating the following:
- *
- *              irix/kern/io/eeprom.c
- *              stand/arcs/lib/libsk/ml/eeprom.c
- *		stand/arcs/lib/libkl/io/eeprom.c
- *
- *      (from time to time they might not be in sync but that's due to bringup
- *       activity - this comment is to remind us that they eventually have to
- *       get back together)
- *
- * eeprom.c
- *
- * access to board-mounted EEPROMs via the L1 system controllers
- *
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/simulator.h>
-
-#if defined(EEPROM_DEBUG)
-#define db_printf(x) printk x
-#else
-#define db_printf(x) printk x
-#endif
-
-#define BCOPY(x,y,z)	memcpy(y,x,z)
-
-#define UNDERSCORE	0	/* don't convert underscores to hyphens */
-#define HYPHEN		1	/* convert underscores to hyphens */
-
-void		copy_ascii_field( char *to, char *from, int length,
-			          int change_underscore );
-uint64_t	generate_unique_id( char *sn, int sn_len );
-uchar_t		char_to_base36( char c );
-int		nicify( char *dst, eeprom_brd_record_t *src );
-static void	int64_to_hex_string( char *out, uint64_t val );
-
-// extern int router_lock( net_vec_t, int, int );
-// extern int router_unlock( net_vec_t );
-#define ROUTER_LOCK(p) 	// router_lock(p, 10000, 3000000)
-#define ROUTER_UNLOCK(p) 	// router_unlock(p)
-
-#define IP27LOG_OVNIC           "OverrideNIC"
-
-
-/* the following function converts an EEPROM record to a close facsimile
- * of the string returned by reading a Dallas Semiconductor NIC (see
- * one of the many incarnations of nic.c for details on that driver)
- */
-int nicify( char *dst, eeprom_brd_record_t *src )
-{
-    int field_len;
-    uint64_t unique_id;
-    char *cur_dst = dst;
-    eeprom_board_ia_t   *board;
-
-    board   = src->board_ia;
-    ASSERT( board );  /* there should always be a board info area */
-
-    /* copy part number */
-    strcpy( cur_dst, "Part:" );
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->part_num_tl & FIELD_FORMAT_MASK)
-	    == FIELD_FORMAT_ASCII );
-    field_len = board->part_num_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->part_num, field_len, HYPHEN );
-    cur_dst += field_len;
-
-    /* copy product name */
-    strcpy( cur_dst, ";Name:" );
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->product_tl & FIELD_FORMAT_MASK) == FIELD_FORMAT_ASCII );
-    field_len = board->product_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->product, field_len, UNDERSCORE );
-    cur_dst += field_len;
-
-    /* copy serial number */
-    strcpy( cur_dst, ";Serial:" );
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->serial_num_tl & FIELD_FORMAT_MASK)
-	    == FIELD_FORMAT_ASCII );
-    field_len = board->serial_num_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->serial_num, field_len,
-		      HYPHEN);
-
-    cur_dst += field_len;
-
-    /* copy revision */
-    strcpy( cur_dst, ";Revision:");
-    cur_dst += strlen( cur_dst );
-    ASSERT( (board->board_rev_tl & FIELD_FORMAT_MASK)
-	    == FIELD_FORMAT_ASCII );
-    field_len = board->board_rev_tl & FIELD_LENGTH_MASK;
-    copy_ascii_field( cur_dst, board->board_rev, field_len, HYPHEN );
-    cur_dst += field_len;
-
-    /* EEPROMs don't have equivalents for the Group, Capability and
-     * Variety fields, so we pad these with 0's
-     */
-    strcpy( cur_dst, ";Group:ff;Capability:ffffffff;Variety:ff" );
-    cur_dst += strlen( cur_dst );
-
-    /* use the board serial number to "fake" a laser id */
-    strcpy( cur_dst, ";Laser:" );
-    cur_dst += strlen( cur_dst );
-    unique_id = generate_unique_id( board->serial_num,
-				    board->serial_num_tl & FIELD_LENGTH_MASK );
-    int64_to_hex_string( cur_dst, unique_id );
-    strcat( dst, ";" );
-
-    return 1;
-}
-
-
-/* These functions borrow heavily from chars2* in nic.c
- */
-void copy_ascii_field( char *to, char *from, int length,
-		       int change_underscore )
-{
-    int i;
-    for( i = 0; i < length; i++ ) {
-
-	/* change underscores to hyphens if requested */
-	if( from[i] == '_' && change_underscore == HYPHEN )
-	    to[i] = '-';
-
-	/* ; and ; are separators, so mustn't appear within
-	 * a field */
-	else if( from[i] == ':' || from[i] == ';' )
-	    to[i] = '?';
-
-	/* I'm not sure why or if ASCII character 0xff would
-	 * show up in an EEPROM field, but the NIC parsing
-	 * routines wouldn't like it if it did... so we
-	 * get rid of it, just in case. */
-	else if( (unsigned char)from[i] == (unsigned char)0xff )
-	    to[i] = ' ';
-	
-	/* unprintable characters are replaced with . */
-	else if( from[i] < ' ' || from[i] >= 0x7f )
-	    to[i] = '.';
-
-	/* otherwise, just copy the character */
-	else
-	    to[i] = from[i];
-    }
-
-    if( i == 0 ) {
-	to[i] = ' '; /* return at least a space... */
-	i++;
-    }
-    to[i] = 0;	     /* terminating null */
-}
-
-/* Note that int64_to_hex_string currently only has a big-endian
- * implementation.
- */
-#ifdef _MIPSEB
-static void int64_to_hex_string( char *out, uint64_t val )
-{
-    int i;
-    uchar_t table[] = "0123456789abcdef";
-    uchar_t *byte_ptr = (uchar_t *)&val;
-    for( i = 0; i < sizeof(uint64_t); i++ ) {
-	out[i*2] = table[ ((*byte_ptr) >> 4) & 0x0f ];
-	out[i*2+1] = table[ (*byte_ptr) & 0x0f ];
-	byte_ptr++;
-    }
-    out[i*2] = '\0';
-}
-
-#else /* little endian */
-
-static void int64_to_hex_string( char *out, uint64_t val )
-{
-
-
-	printk("int64_to_hex_string needs a little-endian implementation.\n");
-}
-#endif /* _MIPSEB */
-
-/* Convert a standard ASCII serial number to a unique integer
- * id number by treating the serial number string as though
- * it were a base 36 number
- */
-uint64_t generate_unique_id( char *sn, int sn_len )
-{
-    int uid = 0;
-    int i;
-
-    #define VALID_BASE36(c)	((c >= '0' && c <='9') \
-			    ||   (c >= 'A' && c <='Z') \
-			    ||   (c >= 'a' && c <='z'))
-
-    for( i = 0; i < sn_len; i++ ) {
-	if( !VALID_BASE36(sn[i]) )
-	    continue;
-	uid *= 36;
-	uid += char_to_base36( sn[i] );
-    }
-
-    if( uid == 0 )
-	return rtc_time();
-
-    return uid;
-}
-
-uchar_t char_to_base36( char c )
-{
-    uchar_t val;
-
-    if( c >= '0' && c <= '9' )
-	val = (c - '0');
-
-    else if( c >= 'A' && c <= 'Z' )
-	val = (c - 'A' + 10);
-
-    else if( c >= 'a' && c <= 'z' )
-	val = (c - 'a' + 10);
-
-    else val = 0;
-
-    return val;
-}
-
-
-/* given a pointer to the three-byte little-endian EEPROM representation
- * of date-of-manufacture, this function translates to a big-endian
- * integer format
- */
-int eeprom_xlate_board_mfr_date( uchar_t *src )
-{
-    int rval = 0;
-    rval += *src; src++;
-    rval += ((int)(*src) << 8); src ++;
-    rval += ((int)(*src) << 16);
-    return rval;
-}
-
-
-int eeprom_str( char *nic_str, nasid_t nasid, int component )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-
-    if( (component & C_DIMM) == C_DIMM ) {
-	/* this function isn't applicable to DIMMs */
-	return EEP_PARAM;
-    }
-    else {
-	eep.board_ia = &board;
-	eep.spd = NULL;
-	if( !(component & SUBORD_MASK) )
-	    eep.chassis_ia = &chassis;  /* only main boards have a chassis
-					 * info area */
-	else
-	    eep.chassis_ia = NULL;
-    }
-    
-    switch( component & BRICK_MASK ) {
-      case C_BRICK:
-	r = cbrick_eeprom_read( &eep, nasid, component );
-	break;
-      case IO_BRICK:
-	r = iobrick_eeprom_read( &eep, nasid, component );
-	break;
-      default:
-	return EEP_PARAM;  /* must be an invalid component */
-    }
-    if( r )
-	return r;
-    if( !nicify( nic_str, &eep ) )
-	return EEP_NICIFY;
-
-    return EEP_OK;
-}
-
-int vector_eeprom_str( char *nic_str, nasid_t nasid,
-		       int component, net_vec_t path )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-
-    eep.board_ia = &board;
-    if( !(component & SUBORD_MASK) )
-        eep.chassis_ia = &chassis;  /* only main boards have a chassis
-                                     * info area */
-    else
-        eep.chassis_ia = NULL;
-
-    if( !(component & VECTOR) )
-	return EEP_PARAM;
-
-    if( (r = vector_eeprom_read( &eep, nasid, path, component )) )
-	return r;
-
-    if( !nicify( nic_str, &eep ) )
-        return EEP_NICIFY;
-
-    return EEP_OK;
-}
-
-
-int is_iobrick( int nasid, int widget_num )
-{
-    uint32_t wid_reg;
-    int part_num, mfg_num;
-
-    /* Read the widget's WIDGET_ID register to get
-     * its part number and mfg number
-     */
-    wid_reg = *(volatile int32_t *)
-        (NODE_SWIN_BASE( nasid, widget_num ) + WIDGET_ID);
-
-    part_num = (wid_reg & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT;
-    mfg_num = (wid_reg & WIDGET_MFG_NUM) >> WIDGET_MFG_NUM_SHFT;
-
-    /* Is this the "xbow part" of an XBridge?  If so, this
-     * widget is definitely part of an I/O brick.
-     */
-    if( part_num == XXBOW_WIDGET_PART_NUM &&
-	mfg_num == XXBOW_WIDGET_MFGR_NUM )
-
-	return 1;
-
-    /* Is this a "bridge part" of an XBridge?  If so, once
-     * again, we know this widget is part of an I/O brick.
-     */
-    if( part_num == XBRIDGE_WIDGET_PART_NUM &&
-	mfg_num == XBRIDGE_WIDGET_MFGR_NUM )
-
-	return 1;
-
-    return 0;
-}
-
-
-int cbrick_uid_get( nasid_t nasid, uint64_t *uid )
-{
-#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-    return EEP_L1;
-#else
-    char uid_str[32];
-    char msg[BRL1_QSIZE];
-    int subch, len;
-    l1sc_t sc;
-    l1sc_t *scp;
-    int local = (nasid == get_nasid());
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* If the promlog variable pointed to by IP27LOG_OVNIC is set,
-     * use that value for the cbrick UID rather than the EEPROM
-     * serial number.
-     */
-#ifdef LOG_GETENV
-    if( ip27log_getenv( nasid, IP27LOG_OVNIC, uid_str, NULL, 0 ) >= 0 )
-    {
-	/* We successfully read IP27LOG_OVNIC, so return it as the UID. */
-	db_printf(( "cbrick_uid_get:"
-		    "Overriding UID with environment variable %s\n", 
-		    IP27LOG_OVNIC ));
-	*uid = strtoull( uid_str, NULL, 0 );
-	return EEP_OK;
-    }
-#endif
-
-    /* If this brick is retrieving its own uid, use the local l1sc_t to
-     * arbitrate access to the l1; otherwise, set up a new one.
-     */
-    if( local ) {
-	scp = get_l1sc();
-    }
-    else {
-	scp = &sc;
-	sc_init( &sc, nasid, BRL1_LOCALHUB_UART );
-    }
-
-    /* fill in msg with the opcode & params */
-    BZERO( msg, BRL1_QSIZE );
-    if( (subch = sc_open( scp, L1_ADDR_LOCAL )) < 0 )
-	return EEP_L1;
-
-    if( (len = sc_construct_msg( scp, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_SER_NUM, 0 )) < 0 )
-    {
-	sc_close( scp, subch );
-	return( EEP_L1 );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( scp, subch, msg, msg, &len ) ) {
-	sc_close( scp, subch );
-	return( EEP_L1 );
-    }
-
-    /* free up subchannel */
-    sc_close(scp, subch);
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_ASCII, uid_str ) < 0 )
-    {
-	return( EEP_L1 );
-    }
-
-    *uid = generate_unique_id( uid_str, strlen( uid_str ) );
-
-    return EEP_OK;
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
-}
-
-
-int rbrick_uid_get( nasid_t nasid, net_vec_t path, uint64_t *uid )
-{
-#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-    return EEP_L1;
-#else
-    char uid_str[32];
-    char msg[BRL1_QSIZE];
-    int subch, len;
-    l1sc_t sc;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-#define FAIL								\
-    {									\
-	*uid = rtc_time();						\
-	printk( "rbrick_uid_get failed; using current time as uid\n" );	\
-	return EEP_OK;							\
-    }
-
-    ROUTER_LOCK(path);
-    sc_init( &sc, nasid, path );
-
-    /* fill in msg with the opcode & params */
-    BZERO( msg, BRL1_QSIZE );
-    if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 ) {
-	ROUTER_UNLOCK(path);
-	FAIL;
-    }
-
-    if( (len = sc_construct_msg( &sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_SER_NUM, 0 )) < 0 )
-    {
-	ROUTER_UNLOCK(path);
-	sc_close( &sc, subch );
-	FAIL;
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( &sc, subch, msg, msg, &len ) ) {
-	ROUTER_UNLOCK(path);
-	sc_close( &sc, subch );
-	FAIL;
-    }
-
-    /* free up subchannel */
-    ROUTER_UNLOCK(path);
-    sc_close(&sc, subch);
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_ASCII, uid_str ) < 0 )
-    {
-	FAIL;
-    }
-
-    *uid = generate_unique_id( uid_str, strlen( uid_str ) );
-
-    return EEP_OK;
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
-}
-
-int iobrick_uid_get( nasid_t nasid, uint64_t *uid )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-
-    eep.board_ia = &board;
-    eep.chassis_ia = &chassis;
-    eep.spd = NULL;
-
-    r = iobrick_eeprom_read( &eep, nasid, IO_BRICK );
-    if( r != EEP_OK ) {
-        *uid = rtc_time();
-        return r;
-    }
-
-    *uid = generate_unique_id( board.serial_num,
-                               board.serial_num_tl & FIELD_LENGTH_MASK );
-
-    return EEP_OK;
-}
-
-
-int ibrick_mac_addr_get( nasid_t nasid, char *eaddr )
-{
-    eeprom_brd_record_t eep;
-    eeprom_board_ia_t board;
-    eeprom_chassis_ia_t chassis;
-    int r;
-    char *tmp;
-
-    eep.board_ia = &board;
-    eep.chassis_ia = &chassis;
-    eep.spd = NULL;
-
-    r = iobrick_eeprom_read( &eep, nasid, IO_BRICK );
-    if( (r != EEP_OK) || (board.mac_addr[0] == '\0') ) {
-	db_printf(( "ibrick_mac_addr_get: "
-		    "Couldn't read MAC address from EEPROM\n" ));
-	return EEP_L1;
-    }
-    else {
-	/* successfully read info area */
-	int ix;
-	tmp = board.mac_addr;
-	for( ix = 0; ix < (board.mac_addr_tl & FIELD_LENGTH_MASK); ix++ )
-	{
-	    *eaddr++ = *tmp++;
-	}
-	*eaddr = '\0';
-    }
-
-    return EEP_OK;
-}
-
-
-/* 
- * eeprom_vertex_info_set
- *
- * Given a vertex handle, a component designation, a starting nasid
- * and (in the case of a router) a vector path to the component, this
- * function will read the EEPROM and attach the resulting information
- * to the vertex in the same string format as that provided by the
- * Dallas Semiconductor NIC drivers.  If the vertex already has the
- * string, this function just returns the string.
- */
-
-extern char *nic_vertex_info_get( devfs_handle_t );
-extern void nic_vmc_check( devfs_handle_t, char * );
-/* the following were lifted from nic.c - change later? */
-#define MAX_INFO 2048
-#define NEWSZ(ptr,sz)   ((ptr) = kern_malloc((sz)))
-#define DEL(ptr) (kern_free((ptr)))
-
-char *eeprom_vertex_info_set( int component, int nasid, devfs_handle_t v,
-                              net_vec_t path )
-{
-        char *info_tmp;
-        int info_len;
-        char *info;
-
-        /* see if this vertex is already marked */
-        info_tmp = nic_vertex_info_get(v);
-        if (info_tmp) return info_tmp;
-
-        /* get a temporary place for the data */
-        NEWSZ(info_tmp, MAX_INFO);
-        if (!info_tmp) return NULL;
-
-        /* read the EEPROM */
-	if( component & R_BRICK ) {
-	    if( RBRICK_EEPROM_STR( info_tmp, nasid, path ) != EEP_OK )
-		return NULL;
-	}
-	else {
-            if( eeprom_str( info_tmp, nasid, component ) != EEP_OK )
-	        return NULL;
-	}
-
-        /* allocate a smaller final place */
-        info_len = strlen(info_tmp)+1;
-        NEWSZ(info, info_len);
-        if (info) {
-                strcpy(info, info_tmp);
-                DEL(info_tmp);
-        } else {
-                info = info_tmp;
-        }
-
-        /* add info to the vertex */
-        hwgraph_info_add_LBL(v, INFO_LBL_NIC,
-                             (arbitrary_info_t) info);
-
-        /* see if someone else got there first */
-        info_tmp = nic_vertex_info_get(v);
-        if (info != info_tmp) {
-            DEL(info);
-            return info_tmp;
-        }
-
-        /* export the data */
-        hwgraph_info_export_LBL(v, INFO_LBL_NIC, info_len);
-
-        /* trigger all matching callbacks */
-        nic_vmc_check(v, info);
-
-        return info;
-}
-
-
-/*********************************************************************
- *
- * stubs for use until the Bedrock/L1 link is available
- *
- */
-
-#include <asm/sn/nic.h>
-
-/* #define EEPROM_TEST */
-
-/* fake eeprom reading functions (replace when the BR/L1 communication
- * channel is in working order)
- */
-
-
-/* generate a charater in [0-9A-Z]; if an "extra" character is
- * specified (such as '_'), include it as one of the possibilities.
- */
-char random_eeprom_ch( char extra ) 
-{
-    char ch;
-    int modval = 36;
-    if( extra )
-	modval++;
-    
-    ch = rtc_time() % modval;
-
-    if( ch < 10 )
-        ch += '0';
-    else if( ch >= 10 && ch < 36 )
-	ch += ('A' - 10);
-    else
-	ch = extra;
-
-    return ch;
-}
-
-/* create a part number of the form xxx-xxxx-xxx.
- * It may be important later to generate different
- * part numbers depending on the component we're
- * supposed to be "reading" from, so the component
- * paramter is provided.
- */
-void fake_a_part_number( char *buf, int component )
-{
-    int i;
-    switch( component ) {
-
-    /* insert component-specific routines here */
-
-    case C_BRICK:
-	strcpy( buf, "030-1266-001" );
-	break;
-    default:
-        for( i = 0; i < 12; i++ ) {
-	    if( i == 3 || i == 8 )
-	        buf[i] = '-';
-	    else
-	        buf[i] = random_eeprom_ch(0);
-        }
-    }
-}
-
-
-/* create a six-character serial number */
-void fake_a_serial_number( char *buf, uint64_t ser )
-{
-    int i;
-    static const char hexchars[] = "0123456789ABCDEF";
-
-    if (ser) {
-	for( i = 5; i >=0; i-- ) {
-	    buf[i] = hexchars[ser & 0xf];
-	    ser >>= 4;
-	}
-    }
-    else {
-	for( i = 0; i < 6; i++ )
-	    buf[i] = random_eeprom_ch(0);
-    }
-}
-
-
-void fake_a_product_name( uchar_t *format, char* buf, int component )
-{
-    switch( component & BRICK_MASK ) {
-
-    case C_BRICK:
-	if( component & SUBORD_MASK ) {
-	    strcpy( buf, "C_BRICK_SUB" );
-	    *format = 0xCB;
-	}
-	else {
-	    strcpy( buf, "IP35" );
-	    *format = 0xC4;
-	}
-	break;
-
-    case R_BRICK:
-        if( component & SUBORD_MASK ) {
-            strcpy( buf, "R_BRICK_SUB" );
-            *format = 0xCB;
-        }
-        else {
-            strcpy( buf, "R_BRICK" );
-            *format = 0xC7;
-        }
-        break;
-
-    case IO_BRICK:
-        if( component & SUBORD_MASK ) {
-            strcpy( buf, "IO_BRICK_SUB" );
-            *format = 0xCC;
-        }
-        else {
-            strcpy( buf, "IO_BRICK" );
-            *format = 0xC8;
-        }
-        break;
-
-    default:
-	strcpy( buf, "UNK_DEVICE" );
-	*format = 0xCA;
-    }
-}
-
-
-
-int fake_an_eeprom_record( eeprom_brd_record_t *buf, int component, 
-			   uint64_t ser )
-{
-    eeprom_board_ia_t *board;
-    eeprom_chassis_ia_t *chassis;
-    int i, cs;
-
-    board = buf->board_ia;
-    chassis = buf->chassis_ia;
-
-    if( !(component & SUBORD_MASK) ) {
-	if( !chassis )
-	    return EEP_PARAM;
-	chassis->format = 0;
-	chassis->length = 5;
-	chassis->type = 0x17;
-
-	chassis->part_num_tl = 0xCC;
-	fake_a_part_number( chassis->part_num, component );
-	chassis->serial_num_tl = 0xC6;
-	fake_a_serial_number( chassis->serial_num, ser );
-
-	cs = chassis->format + chassis->length + chassis->type
-	    + chassis->part_num_tl + chassis->serial_num_tl;
-	for( i = 0; i < (chassis->part_num_tl & FIELD_LENGTH_MASK); i++ )
-	    cs += chassis->part_num[i];
-	for( i = 0; i < (chassis->serial_num_tl & FIELD_LENGTH_MASK); i++ )
-	    cs += chassis->serial_num[i];
-	chassis->checksum = 256 - (cs % 256);
-    }
-
-    if( !board )
-	return EEP_PARAM;
-    board->format = 0;
-    board->length = 10;
-    board->language = 0;
-    board->mfg_date = 1789200; /* noon, 5/26/99 */
-    board->manuf_tl = 0xC3;
-    strcpy( board->manuf, "SGI" );
-
-    fake_a_product_name( &(board->product_tl), board->product, component );
-
-    board->serial_num_tl = 0xC6;
-    fake_a_serial_number( board->serial_num, ser );
-
-    board->part_num_tl = 0xCC;
-    fake_a_part_number( board->part_num, component );
-
-    board->board_rev_tl = 0xC2;
-    board->board_rev[0] = '0';
-    board->board_rev[1] = '1';
-
-    board->eeprom_size_tl = 0x01;
-    board->eeprom_size = 1;
-
-    board->temp_waiver_tl = 0xC2;
-    board->temp_waiver[0] = '0';
-    board->temp_waiver[1] = '1';
-
-    cs = board->format + board->length + board->language
-	+ (board->mfg_date & 0xFF)
-	+ (board->mfg_date & 0xFF00)
-	+ (board->mfg_date & 0xFF0000)
-	+ board->manuf_tl + board->product_tl + board->serial_num_tl
-	+ board->part_num_tl + board->board_rev_tl
-	+ board->board_rev[0] + board->board_rev[1]
-	+ board->eeprom_size_tl + board->eeprom_size + board->temp_waiver_tl
-	+ board->temp_waiver[0] + board->temp_waiver[1];
-    for( i = 0; i < (board->manuf_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->manuf[i];
-    for( i = 0; i < (board->product_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->product[i];
-    for( i = 0; i < (board->serial_num_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->serial_num[i];
-    for( i = 0; i < (board->part_num_tl & FIELD_LENGTH_MASK); i++ )
-	cs += board->part_num[i];
-    
-    board->checksum = 256 - (cs % 256);
-
-    return EEP_OK;
-}
-
-#define EEPROM_CHUNKSIZE	64
-
-#if defined(EEPROM_DEBUG)
-#define RETURN_ERROR							\
-{									\
-    printk( "read_ia error return, component 0x%x, line %d"		\
-	    ", address 0x%x, ia code 0x%x\n",				\
-	    l1_compt, __LINE__, sc->subch[subch].target, ia_code );	\
-    return EEP_L1;							\
-}
-
-#else
-#define RETURN_ERROR	return(EEP_L1)
-#endif
-
-int read_ia( l1sc_t *sc, int subch, int l1_compt, 
-	     int ia_code, char *eep_record )
-{
-#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-    return EEP_L1;
-#else
-    char msg[BRL1_QSIZE]; 	   /* message buffer */
-    int len;              	   /* number of bytes used in message buffer */
-    int ia_len = EEPROM_CHUNKSIZE; /* remaining bytes in info area */
-    int offset = 0;                /* current offset into info area */
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    BZERO( msg, BRL1_QSIZE );
-
-    /* retrieve EEPROM data in 64-byte chunks
-     */
-
-    while( ia_len )
-    {
-	/* fill in msg with opcode & params */
-	if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				     L1_ADDR_TASK_GENERAL,
-				     L1_REQ_EEPROM, 8,
-				     L1_ARG_INT, l1_compt,
-				     L1_ARG_INT, ia_code,
-				     L1_ARG_INT, offset,
-				     L1_ARG_INT, ia_len )) < 0 )
-	{
-	    RETURN_ERROR;
-	}
-
-	/* send the request to the L1 */
-
-	if( sc_command( sc, subch, msg, msg, &len ) ) {
-	    RETURN_ERROR;
-	}
-
-	/* check response */
-	if( sc_interpret_resp( msg, 5, 
-			       L1_ARG_INT, &ia_len,
-			       L1_ARG_UNKNOWN, &len, eep_record ) < 0 )
-	{
-	    RETURN_ERROR;
-	}
-
-	if( ia_len > EEPROM_CHUNKSIZE )
-	    ia_len = EEPROM_CHUNKSIZE;
-
-	eep_record += EEPROM_CHUNKSIZE;
-	offset += EEPROM_CHUNKSIZE;
-    }
-
-    return EEP_OK;
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
-}
-
-
-int read_spd( l1sc_t *sc, int subch, int l1_compt,
-	      eeprom_spd_u *spd )
-{
-#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-    return EEP_L1;
-#else
-    char msg[BRL1_QSIZE]; 	    /* message buffer */
-    int len;              	    /* number of bytes used in message buffer */
-    int resp;                       /* l1 response code */
-    int spd_len = EEPROM_CHUNKSIZE; /* remaining bytes in spd record */
-    int offset = 0;		    /* current offset into spd record */
-    char *spd_p = spd->bytes;	    /* "thumb" for writing to spd */
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    BZERO( msg, BRL1_QSIZE );
-
-    /* retrieve EEPROM data in 64-byte chunks
-     */
-
-    while( spd_len )
-    {
-	/* fill in msg with opcode & params */
-	if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				     L1_ADDR_TASK_GENERAL,
-				     L1_REQ_EEPROM, 8,
-				     L1_ARG_INT, l1_compt,
-				     L1_ARG_INT, L1_EEP_SPD,
-				     L1_ARG_INT, offset,
-				     L1_ARG_INT, spd_len )) < 0 )
-	{
-	    return( EEP_L1 );
-	}
-
-	/* send the request to the L1 */
-	if( sc_command( sc, subch, msg, msg, &len ) ) {
-	    return( EEP_L1 );
-	}
-
-	/* check response */
-	if( (resp = sc_interpret_resp( msg, 5, 
-			       L1_ARG_INT, &spd_len,
-			       L1_ARG_UNKNOWN, &len, spd_p )) < 0 )
-	{
-            /*
-             * translate l1 response code to eeprom.c error codes:
-             * The L1 response will be L1_RESP_NAVAIL if the spd
-             * can't be read (i.e. the spd isn't physically there). It will
-             * return L1_RESP_INVAL if the spd exists, but fails the checksum
-             * test because the eeprom wasn't programmed, programmed incorrectly,
-             * or corrupted. L1_RESP_NAVAIL indicates the eeprom is likely not present,
-             * whereas L1_RESP_INVAL indicates the eeprom is present, but the data is
-             * invalid.
-             */
-            if(resp == L1_RESP_INVAL) {
-                resp = EEP_BAD_CHECKSUM;
-            } else {
-                resp = EEP_L1;
-            }
-            return( resp );
-	}
-
-	if( spd_len > EEPROM_CHUNKSIZE )
-	    spd_len = EEPROM_CHUNKSIZE;
-
-	spd_p += EEPROM_CHUNKSIZE;
-	offset += EEPROM_CHUNKSIZE;
-    }
-    return EEP_OK;
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
-}
-
-
-int read_chassis_ia( l1sc_t *sc, int subch, int l1_compt,
-		     eeprom_chassis_ia_t *ia )
-{
-    char eep_record[512];          /* scratch area for building up info area */
-    char *eep_rec_p = eep_record;  /* thumb for moving through eep_record */
-    int checksum = 0;              /* use to verify eeprom record checksum */
-    int i;
-
-    /* Read in info area record from the L1.
-     */
-    if( read_ia( sc, subch, l1_compt, L1_EEP_CHASSIS, eep_record )
-	!= EEP_OK )
-    {
-	return EEP_L1;
-    }
-
-    /* Now we've got the whole info area.  Transfer it to the data structure.
-     */
-
-    eep_rec_p = eep_record;
-    ia->format = *eep_rec_p++;
-    ia->length = *eep_rec_p++;
-    if( ia->length == 0 ) {
-	/* since we're using 8*ia->length-1 as an array index later, make
-	 * sure it's sane.
-	 */
-	db_printf(( "read_chassis_ia: eeprom length byte of ZERO\n" ));
-	return EEP_L1;
-    }
-    ia->type = *eep_rec_p++;
-   
-    ia->part_num_tl = *eep_rec_p++;
-
-    (void)BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK);
-
-    ia->serial_num_tl = *eep_rec_p++;
-
-    BCOPY( eep_rec_p, ia->serial_num, 
-	   (ia->serial_num_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK);
-
-    ia->checksum = eep_record[(8 * ia->length) - 1];
-
-    /* verify checksum */
-    eep_rec_p = eep_record;
-    checksum = 0;
-    for( i = 0; i < (8 * ia->length); i++ ) {
-	checksum += *eep_rec_p++;
-    }
-
-    if( (checksum & 0xff) != 0 )
-    {
-	db_printf(( "read_chassis_ia: bad checksum\n" ));
-	db_printf(( "read_chassis_ia: target 0x%x  uart 0x%lx\n",
-			   sc->subch[subch].target, sc->uart ));
-	return EEP_BAD_CHECKSUM;
-    }
-
-    return EEP_OK;
-}
-
-
-int read_board_ia( l1sc_t *sc, int subch, int l1_compt,
-		   eeprom_board_ia_t *ia )
-{
-    char eep_record[512];          /* scratch area for building up info area */
-    char *eep_rec_p = eep_record;  /* thumb for moving through eep_record */
-    int checksum = 0;              /* running checksum total */
-    int i;
-
-    BZERO( ia, sizeof( eeprom_board_ia_t ) );
-
-    /* Read in info area record from the L1.
-     */
-    if( read_ia( sc, subch, l1_compt, L1_EEP_BOARD, eep_record )
-	!= EEP_OK )
-    {
-	db_printf(( "read_board_ia: error reading info area from L1\n" ));
-	return EEP_L1;
-    }
-
-     /* Now we've got the whole info area.  Transfer it to the data structure.
-      */
-
-    eep_rec_p = eep_record;
-    ia->format = *eep_rec_p++;
-    ia->length = *eep_rec_p++;
-    if( ia->length == 0 ) {
-	/* since we're using 8*ia->length-1 as an array index later, make
-	 * sure it's sane.
-	 */
-	db_printf(( "read_board_ia: eeprom length byte of ZERO\n" ));
-	return EEP_L1;
-    }
-    ia->language = *eep_rec_p++;
-    
-    ia->mfg_date = eeprom_xlate_board_mfr_date( (uchar_t *)eep_rec_p );
-    eep_rec_p += 3;
-
-    ia->manuf_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->manuf, (ia->manuf_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->manuf_tl & FIELD_LENGTH_MASK);
-
-    ia->product_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->product, (ia->product_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->product_tl & FIELD_LENGTH_MASK);
-
-    ia->serial_num_tl = *eep_rec_p++;
-    
-    BCOPY(eep_rec_p, ia->serial_num, (ia->serial_num_tl & FIELD_LENGTH_MASK));
-    eep_rec_p += (ia->serial_num_tl & FIELD_LENGTH_MASK);
-
-    ia->part_num_tl = *eep_rec_p++;
-
-    BCOPY( eep_rec_p, ia->part_num, (ia->part_num_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->part_num_tl & FIELD_LENGTH_MASK);
-
-    eep_rec_p++; /* we do not use the FRU file id */
-    
-    ia->board_rev_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->board_rev, (ia->board_rev_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->board_rev_tl & FIELD_LENGTH_MASK);
-
-    ia->eeprom_size_tl = *eep_rec_p++;
-    ia->eeprom_size = *eep_rec_p++;
-
-    ia->temp_waiver_tl = *eep_rec_p++;
-    
-    BCOPY( eep_rec_p, ia->temp_waiver, 
-	   (ia->temp_waiver_tl & FIELD_LENGTH_MASK) );
-    eep_rec_p += (ia->temp_waiver_tl & FIELD_LENGTH_MASK);
-
-    /* if there's more, we must be reading a main board; get
-     * additional fields
-     */
-    if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) {
-
-	ia->ekey_G_tl = *eep_rec_p++;
-	BCOPY( eep_rec_p, (char *)&ia->ekey_G, 
-	       ia->ekey_G_tl & FIELD_LENGTH_MASK );
-	eep_rec_p += (ia->ekey_G_tl & FIELD_LENGTH_MASK);
-	
-	ia->ekey_P_tl = *eep_rec_p++;
-	BCOPY( eep_rec_p, (char *)&ia->ekey_P, 
-	       ia->ekey_P_tl & FIELD_LENGTH_MASK );
-	eep_rec_p += (ia->ekey_P_tl & FIELD_LENGTH_MASK);
-	
-	ia->ekey_Y_tl = *eep_rec_p++;
-	BCOPY( eep_rec_p, (char *)&ia->ekey_Y, 
-	       ia->ekey_Y_tl & FIELD_LENGTH_MASK );
-	eep_rec_p += (ia->ekey_Y_tl & FIELD_LENGTH_MASK);
-	
-	/* 
-	 * need to get a couple more fields if this is an I brick 
-	 */
-	if( ((unsigned char)*eep_rec_p != (unsigned char)EEPROM_EOF) ) {
-
-	    ia->mac_addr_tl = *eep_rec_p++;
-	    BCOPY( eep_rec_p, ia->mac_addr, 
-		   ia->mac_addr_tl & FIELD_LENGTH_MASK );
-	    eep_rec_p += (ia->mac_addr_tl & FIELD_LENGTH_MASK);
-	    
-	    ia->ieee1394_cfg_tl = *eep_rec_p++;
-	    BCOPY( eep_rec_p, ia->ieee1394_cfg,
-		   ia->ieee1394_cfg_tl & FIELD_LENGTH_MASK );
-	    
-	}
-    }
-
-    ia->checksum = eep_record[(ia->length * 8) - 1];
-
-    /* verify checksum */
-    eep_rec_p = eep_record;
-    checksum = 0;
-    for( i = 0; i < (8 * ia->length); i++ ) {
-	checksum += *eep_rec_p++;
-    }
-
-    if( (checksum & 0xff) != 0 )
-    {
-	db_printf(( "read_board_ia: bad checksum\n" ));
-	db_printf(( "read_board_ia: target 0x%x  uart 0x%lx\n",
-		    sc->subch[subch].target, sc->uart ));
-	return EEP_BAD_CHECKSUM;
-    }
-
-    return EEP_OK;
-}
-
-
-int _cbrick_eeprom_read( eeprom_brd_record_t *buf, l1sc_t *scp,
-			 int component )
-{
-#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-    return EEP_L1;
-#else
-    int r;
-    uint64_t uid = 0;
-#ifdef LOG_GETENV
-    char uid_str[32];
-#endif
-    int l1_compt, subch;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* make sure we're targeting a cbrick */
-    if( !(component & C_BRICK) )
-	return EEP_PARAM;
-
-    /* If the promlog variable pointed to by IP27LOG_OVNIC is set,
-     * use that value for the cbrick UID rather than the EEPROM
-     * serial number.
-     */
-#ifdef LOG_GETENV
-    if( ip27log_getenv( scp->nasid, IP27LOG_OVNIC, uid_str, "0", 0 ) >= 0 )
-    {
-	db_printf(( "_cbrick_eeprom_read: "
-		    "Overriding UID with environment variable %s\n", 
-		    IP27LOG_OVNIC ));
-	uid = strtoull( uid_str, NULL, 0 );
-    }
-#endif
-
-    if( (subch = sc_open( scp, L1_ADDR_LOCAL )) < 0 )
-	return EEP_L1;
-
-    if((component & C_DIMM) == C_DIMM) {
-        l1_compt = L1_EEP_DIMM(component & COMPT_MASK);
-        r = read_spd(scp,subch,l1_compt, buf->spd);
-        sc_close(scp,subch);
-        return(r);
-    }
-
-    switch( component )
-    {
-      case C_BRICK:
-	/* c-brick motherboard */
-	l1_compt = L1_EEP_NODE;
-	r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia );
-	if( r != EEP_OK ) {
-	    sc_close( scp, subch );
-	    db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" ));
-	    return fake_an_eeprom_record( buf, component, uid );
-	}
-	if( uid ) {
-	    /* If IP27LOG_OVNIC is set, we want to put that value
-	     * in as our UID. */
-	    fake_a_serial_number( buf->chassis_ia->serial_num, uid );
-	    buf->chassis_ia->serial_num_tl = 6;
-	}
-	break;
-
-      case C_PIMM:
-	/* one of the PIMM boards */
-	l1_compt = L1_EEP_PIMM( component & COMPT_MASK );
-	break;
-
-      default:
-	/* unsupported board type */
-	sc_close( scp, subch );
-	return EEP_PARAM;
-    }
-	      
-    r = read_board_ia( scp, subch, l1_compt, buf->board_ia );
-    sc_close( scp, subch );
-    if( r != EEP_OK ) 
-    {
-	db_printf(( "_cbrick_eeprom_read: using a fake eeprom record\n" ));
-	return fake_an_eeprom_record( buf, component, uid );
-    }
-    return EEP_OK;
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
-}
-
-
-int cbrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-    		        int component )
-{
-#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-    return EEP_L1;
-#else
-    l1sc_t *scp;
-    int local = (nasid == get_nasid());
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* If this brick is retrieving its own uid, use the local l1sc_t to
-     * arbitrate access to the l1; otherwise, set up a new one (prom) or
-     * use an existing remote l1sc_t (kernel)
-     */
-    if( local ) {
-	scp = get_l1sc();
-    }
-    else {
-	scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
-    }
-
-    return _cbrick_eeprom_read( buf, scp, component );
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
-}
-
-
-int iobrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-			 int component )
-{
-#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-    return EEP_L1;
-#else
-    int r;
-    int l1_compt, subch;
-    l1sc_t *scp;
-    int local = (nasid == get_nasid());
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* make sure we're talking to an applicable brick */
-    if( !(component & IO_BRICK) ) {
-	return EEP_PARAM;
-    }
-
-    /* If we're talking to this c-brick's attached io brick, use
-     * the local l1sc_t; otherwise, set up a new one (prom) or
-     * use an existing remote l1sc_t (kernel)
-     */
-    if( local ) {
-	scp = get_l1sc();
-    }
-    else {
-	scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
-    }
-
-    if( (subch = sc_open( scp, L1_ADDR_LOCALIO )) < 0 )
-	return EEP_L1;
-
-
-    switch( component )
-    {
-      case IO_BRICK:
-	/* IO brick motherboard */
-	l1_compt = L1_EEP_LOGIC;
-	r = read_chassis_ia( scp, subch, l1_compt, buf->chassis_ia );
-
-	if( r != EEP_OK ) {
-	    sc_close( scp, subch );
-	/*
-	 * Whenever we no longer need to test on hardware
-	 * that does not have EEPROMS, then this can be removed.
-	 */
-	    r = fake_an_eeprom_record( buf, component, rtc_time() );
-	    return r;
-	}
-	break;
-
-      case IO_POWER:
-	/* IO brick power board */
-	l1_compt = L1_EEP_POWER;
-	break;
-
-      default:
-	/* unsupported board type */
-	sc_close( scp, subch );
-	return EEP_PARAM;
-    }
-
-    r = read_board_ia( scp, subch, l1_compt, buf->board_ia );
-    sc_close( scp, subch );
-    if( r != EEP_OK ) {
-	return r;
-    }
-    return EEP_OK;
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */    
-}
-
-
-int vector_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-			net_vec_t path, int component )
-{
-#if !defined(CONFIG_SERIAL_SGI_L1_PROTOCOL)
-    return EEP_L1;
-#else
-    int r;
-    uint64_t uid = 0;
-    int l1_compt, subch;
-    l1sc_t sc;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-	return EEP_L1;
-
-    /* make sure we're targeting an applicable brick */
-    if( !(component & VECTOR) )
-	return EEP_PARAM;
-
-    switch( component & BRICK_MASK )
-    {
-      case R_BRICK:
-	ROUTER_LOCK( path );
-	sc_init( &sc, nasid, path );
-
-	if( (subch = sc_open( &sc, L1_ADDR_LOCAL )) < 0 )
-	{
-	    db_printf(( "vector_eeprom_read: couldn't open subch\n" ));
-	    ROUTER_UNLOCK(path);
-	    return EEP_L1;
-	}
-	switch( component )
-	{
-	  case R_BRICK:
-	    /* r-brick motherboard */
-	    l1_compt = L1_EEP_LOGIC;
-    	    r = read_chassis_ia( &sc, subch, l1_compt, buf->chassis_ia );
-	    if( r != EEP_OK ) {
-		sc_close( &sc, subch );
-		ROUTER_UNLOCK( path );
-		printk( "vector_eeprom_read: couldn't get rbrick eeprom info;"
-			" using current time as uid\n" );
-		uid = rtc_time();
-		db_printf(("vector_eeprom_read: using a fake eeprom record\n"));
-		return fake_an_eeprom_record( buf, component, uid );
-	    }
-	    break;
-
-	  case R_POWER:
-	    /* r-brick power board */
-	    l1_compt = L1_EEP_POWER;
-	    break;
-
-	  default:
-	    /* unsupported board type */
-	    sc_close( &sc, subch );
-	    ROUTER_UNLOCK( path );
-	    return EEP_PARAM;
-	}
-	r = read_board_ia( &sc, subch, l1_compt, buf->board_ia );
-	sc_close( &sc, subch );
-	ROUTER_UNLOCK( path );
-	if( r != EEP_OK ) {
-	    db_printf(( "vector_eeprom_read: using a fake eeprom record\n" ));
-	    return fake_an_eeprom_record( buf, component, uid );
-	}
-	return EEP_OK;
-
-      case C_BRICK:
-	sc_init( &sc, nasid, path );
-	return _cbrick_eeprom_read( buf, &sc, component );
-
-      default:
-	/* unsupported brick type */
-	return EEP_PARAM;
-    }
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
-}
diff -Nru a/arch/ia64/sn/io/efi-rtc.c b/arch/ia64/sn/io/efi-rtc.c
--- a/arch/ia64/sn/io/efi-rtc.c	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,185 +0,0 @@
-/*
- * 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) 2001 Silicon Graphics, Inc.
- * Copyright (C) 2001 by Ralf Baechle
- */
-#include <linux/kernel.h>
-#include <linux/types.h>
-#include <linux/spinlock.h>
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/errno.h>
-#include <linux/efi.h>
-#include <asm/sn/klclock.h>
-
-/*
- * No locking necessary when this is called from efirtc which protects us
- * from racing by efi_rtc_lock.
- */
-#define __swizzle(addr) ((u8 *)((unsigned long)(addr) ^ 3))
-#define read_io_port(addr) (*(volatile u8 *) __swizzle(addr))
-#define write_io_port(addr, data) (*(volatile u8 *) __swizzle(addr) = (data))
-
-#define TOD_SGS_M48T35		1
-#define TOD_DALLAS_DS1386	2
-
-static unsigned long nvram_base = 0;
-static int tod_chip_type;
-
-static int
-get_tod_chip_type(void)
-{
-	unsigned char testval;
-
-	write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-	write_io_port(RTC_DAL_DAY_ADDR, 0xff);
-	write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-
-	testval = read_io_port(RTC_DAL_DAY_ADDR);
-	if (testval == 0xff)
-		return TOD_SGS_M48T35;
-
-	return TOD_DALLAS_DS1386;
-}
-
-efi_status_t
-ioc3_get_time(efi_time_t *time, efi_time_cap_t *caps)
-{
-	if (!nvram_base) {
-		printk(KERN_CRIT "nvram_base is zero\n");
-		return EFI_UNSUPPORTED;
-	}
-
-	memset(time, 0, sizeof(*time));
-
-	switch (tod_chip_type) {
-	case TOD_SGS_M48T35:
-		write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_READ_PROTECT);
-
-		time->year = BCD_TO_INT(read_io_port(RTC_SGS_YEAR_ADDR)) + YRREF;
-		time->month = BCD_TO_INT(read_io_port(RTC_SGS_MONTH_ADDR));
-		time->day = BCD_TO_INT(read_io_port(RTC_SGS_DATE_ADDR));
-		time->hour = BCD_TO_INT(read_io_port(RTC_SGS_HOUR_ADDR));
-		time->minute = BCD_TO_INT(read_io_port(RTC_SGS_MIN_ADDR));
-		time->second = BCD_TO_INT(read_io_port(RTC_SGS_SEC_ADDR));
-		time->nanosecond = 0;
-
-		write_io_port(RTC_SGS_CONTROL_ADDR, 0);
-		break;
-
-	case TOD_DALLAS_DS1386:
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-
-		time->nanosecond = 0;
-		time->second = BCD_TO_INT(read_io_port(RTC_DAL_SEC_ADDR));
-		time->minute = BCD_TO_INT(read_io_port(RTC_DAL_MIN_ADDR));
-		time->hour = BCD_TO_INT(read_io_port(RTC_DAL_HOUR_ADDR));
-		time->day = BCD_TO_INT(read_io_port(RTC_DAL_DATE_ADDR));
-		time->month = BCD_TO_INT(read_io_port(RTC_DAL_MONTH_ADDR));
-		time->year = BCD_TO_INT(read_io_port(RTC_DAL_YEAR_ADDR)) + YRREF;
-
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-		break;
-
-	default:
-		break;
-	}
-
-	if (caps) {
-		caps->resolution = 50000000;	/*  50PPM */
-		caps->accuracy = 1000;		/*  1ms */
-		caps->sets_to_zero = 0;
-	}
-
-	return EFI_SUCCESS;
-}
-
-static efi_status_t ioc3_set_time (efi_time_t *t)
-{
-	if (!nvram_base) {
-		printk(KERN_CRIT "nvram_base is zero\n");
-		return EFI_UNSUPPORTED;
-	}
-
-	switch (tod_chip_type) {
-	case TOD_SGS_M48T35:
-		write_io_port(RTC_SGS_CONTROL_ADDR, RTC_SGS_WRITE_ENABLE);
-        	write_io_port(RTC_SGS_YEAR_ADDR, INT_TO_BCD((t->year - YRREF)));
-		write_io_port(RTC_SGS_MONTH_ADDR,INT_TO_BCD(t->month));
-		write_io_port(RTC_SGS_DATE_ADDR, INT_TO_BCD(t->day));
-		write_io_port(RTC_SGS_HOUR_ADDR, INT_TO_BCD(t->hour));
-		write_io_port(RTC_SGS_MIN_ADDR,  INT_TO_BCD(t->minute));
-		write_io_port(RTC_SGS_SEC_ADDR,  INT_TO_BCD(t->second));
-		write_io_port(RTC_SGS_CONTROL_ADDR, 0);
-		break;
-
-	case TOD_DALLAS_DS1386:
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_DISABLE);
-		write_io_port(RTC_DAL_SEC_ADDR,  INT_TO_BCD(t->second));
-		write_io_port(RTC_DAL_MIN_ADDR,  INT_TO_BCD(t->minute));
-		write_io_port(RTC_DAL_HOUR_ADDR, INT_TO_BCD(t->hour));
-		write_io_port(RTC_DAL_DATE_ADDR, INT_TO_BCD(t->day));
-		write_io_port(RTC_DAL_MONTH_ADDR,INT_TO_BCD(t->month));
-		write_io_port(RTC_DAL_YEAR_ADDR, INT_TO_BCD((t->year - YRREF)));
-		write_io_port(RTC_DAL_CONTROL_ADDR, RTC_DAL_UPDATE_ENABLE);
-		break;
-
-	default:
-		break;
-	}
-
-	return EFI_SUCCESS;
-}
-
-/* The following two are not supported atm.  */
-static efi_status_t
-ioc3_get_wakeup_time (efi_bool_t *enabled, efi_bool_t *pending, efi_time_t *tm)
-{
-	return EFI_UNSUPPORTED;
-}
-
-static efi_status_t
-ioc3_set_wakeup_time (efi_bool_t enabled, efi_time_t *tm)
-{
-	return EFI_UNSUPPORTED;
-}
-
-/*
- * It looks like the master IOC3 is usually on bus 0, device 4.  Hope
- * that's right
- */
-static __init int efi_ioc3_time_init(void)
-{
-	struct pci_dev *dev;
-	static struct ioc3 *ioc3;
-
-	dev = pci_find_slot(0, PCI_DEVFN(4, 0));
-	if (!dev) {
-		printk(KERN_CRIT "Couldn't find master IOC3\n");
-
-		return -ENODEV;
-	}
-
-	ioc3 = ioremap(pci_resource_start(dev, 0), pci_resource_len(dev, 0));
-	nvram_base = (unsigned long) ioc3 + IOC3_BYTEBUS_DEV0;
-
-	tod_chip_type = get_tod_chip_type();
-	if (tod_chip_type == 1)
-		printk(KERN_NOTICE "TOD type is SGS M48T35\n");
-	else if (tod_chip_type == 2)
-		printk(KERN_NOTICE "TOD type is Dallas DS1386\n");
-	else
-		printk(KERN_CRIT "No or unknown TOD\n");
-
-	efi.get_time = ioc3_get_time;
-	efi.set_time = ioc3_set_time;
-	efi.get_wakeup_time = ioc3_get_wakeup_time;
-	efi.set_wakeup_time = ioc3_set_wakeup_time;
-
-	return 0;
-}
-
-module_init(efi_ioc3_time_init);
diff -Nru a/arch/ia64/sn/io/hcl.c b/arch/ia64/sn/io/hcl.c
--- a/arch/ia64/sn/io/hcl.c	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1515 +0,0 @@
-/* $Id$
- *
- * 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.
- *
- *  hcl - SGI's Hardware Graph compatibility layer.
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/module.h>
-#include <linux/init.h>
-#include <asm/sn/sgi.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-
-#define HCL_NAME "SGI-HWGRAPH COMPATIBILITY DRIVER"
-#define HCL_TEMP_NAME "HCL_TEMP_NAME_USED_FOR_HWGRAPH_VERTEX_CREATE"
-#define HCL_TEMP_NAME_LEN 44 
-#define HCL_VERSION "1.0"
-devfs_handle_t hwgraph_root = NULL;
-devfs_handle_t linux_busnum = NULL;
-
-/*
- * Debug flag definition.
- */
-#define OPTION_NONE             0x00
-#define HCL_DEBUG_NONE 0x00000
-#define HCL_DEBUG_ALL  0x0ffff
-#if defined(CONFIG_HCL_DEBUG)
-static unsigned int hcl_debug_init __initdata = HCL_DEBUG_NONE;
-#endif
-static unsigned int hcl_debug = HCL_DEBUG_NONE;
-#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE)
-static unsigned int boot_options = OPTION_NONE;
-#endif
-
-/*
- * Some Global definitions.
- */
-devfs_handle_t hcl_handle = NULL;
-
-invplace_t invplace_none = {
-	GRAPH_VERTEX_NONE,
-	GRAPH_VERTEX_PLACE_NONE,
-	NULL
-};
-
-/*
- * HCL device driver.
- * The purpose of this device driver is to provide a facility 
- * for User Level Apps e.g. hinv, ioconfig etc. an ioctl path 
- * to manipulate label entries without having to implement
- * system call interfaces.  This methodology will enable us to 
- * make this feature module loadable.
- */
-static int hcl_open(struct inode * inode, struct file * filp)
-{
-	if (hcl_debug) {
-        	printk("HCL: hcl_open called.\n");
-	}
-
-        return(0);
-
-}
-
-static int hcl_close(struct inode * inode, struct file * filp)
-{
-
-	if (hcl_debug) {
-        	printk("HCL: hcl_close called.\n");
-	}
-
-        return(0);
-
-}
-
-static int hcl_ioctl(struct inode * inode, struct file * file,
-        unsigned int cmd, unsigned long arg)
-{
-
-	if (hcl_debug) {
-		printk("HCL: hcl_ioctl called.\n");
-	}
-
-	switch (cmd) {
-		default:
-			if (hcl_debug) {
-				printk("HCL: hcl_ioctl cmd = 0x%x\n", cmd);
-			}
-	}
-
-	return(0);
-
-}
-
-struct file_operations hcl_fops = {
-	(struct module *)0,
-	NULL,		/* lseek - default */
-	NULL,		/* read - general block-dev read */
-	NULL,		/* write - general block-dev write */
-	NULL,		/* readdir - bad */
-	NULL,		/* poll */
-	hcl_ioctl,      /* ioctl */
-	NULL,		/* mmap */
-	hcl_open,	/* open */
-	NULL,		/* flush */
-	hcl_close,	/* release */
-	NULL,		/* fsync */
-	NULL,		/* fasync */
-	NULL,		/* lock */
-	NULL,		/* readv */
-	NULL,		/* writev */
-};
-
-
-/*
- * init_hcl() - Boot time initialization.  Ensure that it is called 
- *	after devfs has been initialized.
- *
- * For now this routine is being called out of devfs/base.c.  Actually 
- * Not a bad place to be ..
- *
- */
-#ifdef MODULE
-int init_module (void)
-#else
-int __init init_hcl(void)
-#endif
-{
-	extern void string_table_init(struct string_table *);
-	extern struct string_table label_string_table;
-	extern int init_ifconfig_net(void);
-	int rv = 0;
-
-#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE)
-	printk ("\n%s: v%s Colin Ngam (cngam@sgi.com)\n",
-		HCL_NAME, HCL_VERSION);
-
-	hcl_debug = hcl_debug_init;
-	printk ("%s: hcl_debug: 0x%0x\n", HCL_NAME, hcl_debug);
-	printk ("\n%s: boot_options: 0x%0x\n", HCL_NAME, boot_options);
-#endif
-
-	/*
-	 * Create the hwgraph_root on devfs.
-	 */
-	rv = hwgraph_path_add(NULL, EDGE_LBL_HW, &hwgraph_root);
-	if (rv)
-		printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv);
-
-	/*
-	 * Create the hcl driver to support inventory entry manipulations.
-	 * By default, it is expected that devfs is mounted on /dev.
-	 *
-	 */
-	hcl_handle = hwgraph_register(hwgraph_root, ".hcl",
-			0, DEVFS_FL_AUTO_DEVNUM,
-			0, 0,
-			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-			&hcl_fops, NULL);
-
-	if (hcl_handle == NULL) {
-		panic("HCL: Unable to create HCL Driver in init_hcl().\n");
-		return(0);
-	}
-
-	/*
-	 * Initialize the HCL string table.
-	 */
-	string_table_init(&label_string_table);
-
-	/*
-	 * Create the directory that links Linux bus numbers to our Xwidget.
-	 */
-	rv = hwgraph_path_add(hwgraph_root, EDGE_LBL_LINUX_BUS, &linux_busnum);
-	if (linux_busnum == NULL) {
-		panic("HCL: Unable to create %s\n", EDGE_LBL_LINUX_BUS);
-		return(0);
-	}
-
-	/*
-	 * Initialize the ifconfgi_net driver that does network devices 
-	 * Persistent Naming.
-	 */
-	init_ifconfig_net();
-
-	return(0);
-
-}
-
-
-/*
- * hcl_setup() - Process boot time parameters if given.
- *	"hcl="
- *	This routine gets called only if "hcl=" is given in the 
- *	boot line and before init_hcl().
- *
- *	We currently do not have any boot options .. when we do, 
- *	functionalities can be added here.
- *
- */
-static int __init hcl_setup(char *str)
-{
-    while ( (*str != '\0') && !isspace (*str) )
-    {
-#ifdef CONFIG_HCL_DEBUG
-        if (strncmp (str, "all", 3) == 0) {
-            hcl_debug_init |= HCL_DEBUG_ALL;
-            str += 3;
-        } else 
-        	return 0;
-#endif
-        if (*str != ',') return 0;
-        ++str;
-    }
-
-    return 1;
-
-}
-
-__setup("hcl=", hcl_setup);
-
-
-/*
- * Set device specific "fast information".
- *
- */
-void
-hwgraph_fastinfo_set(devfs_handle_t de, arbitrary_info_t fastinfo)
-{
-
-	if (hcl_debug) {
-		printk("HCL: hwgraph_fastinfo_set handle 0x%p fastinfo %ld\n", (void *)de, fastinfo);
-	}
-		
-	labelcl_info_replace_IDX(de, HWGRAPH_FASTINFO, fastinfo, NULL);
-
-}
-
-
-/*
- * Get device specific "fast information".
- *
- */
-arbitrary_info_t
-hwgraph_fastinfo_get(devfs_handle_t de)
-{
-	arbitrary_info_t fastinfo;
-	int rv;
-
-	if (!de) {
-		printk(KERN_WARNING "HCL: hwgraph_fastinfo_get handle given is NULL.\n");
-		return(-1);
-	}
-
-	rv = labelcl_info_get_IDX(de, HWGRAPH_FASTINFO, &fastinfo);
-	if (rv == 0)
-		return(fastinfo);
-
-	return(0);
-}
-
-
-/*
- * hwgraph_connectpt_set - Sets the connect point handle in de to the 
- *	given connect_de handle.  By default, the connect point of the 
- *	devfs node is the parent.  This effectively changes this assumption.
- */
-int
-hwgraph_connectpt_set(devfs_handle_t de, devfs_handle_t connect_de)
-{
-	int rv;
-
-	if (!de)
-		return(-1);
-
-	rv = labelcl_info_connectpt_set(de, connect_de);
-
-	return(rv);
-}
-
-
-/*
- * hwgraph_connectpt_get: Returns the entry's connect point  in the devfs 
- *	tree.
- */
-devfs_handle_t
-hwgraph_connectpt_get(devfs_handle_t de)
-{
-	int rv;
-	arbitrary_info_t info;
-	devfs_handle_t connect;
-
-	rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
-	if (rv != 0) {
-		return(NULL);
-	}
-
-	connect = (devfs_handle_t)info;
-	return(connect);
-
-}
-
-
-/*
- * hwgraph_mk_dir - Creates a directory entry with devfs.
- *	Note that a directory entry in devfs can have children 
- *	but it cannot be a char|block special file.
- */
-devfs_handle_t
-hwgraph_mk_dir(devfs_handle_t de, const char *name,
-                unsigned int namelen, void *info)
-{
-
-	int rv;
-	labelcl_info_t *labelcl_info = NULL;
-	devfs_handle_t new_devfs_handle = NULL;
-	devfs_handle_t parent = NULL;
-
-	/*
-	 * Create the device info structure for hwgraph compatiblity support.
-	 */
-	labelcl_info = labelcl_info_create();
-	if (!labelcl_info)
-		return(NULL);
-
-	/*
-	 * Create a devfs entry.
-	 */
-	new_devfs_handle = devfs_mk_dir(de, name, (void *)labelcl_info);
-	if (!new_devfs_handle) {
-		labelcl_info_destroy(labelcl_info);
-		return(NULL);
-	}
-
-	/*
-	 * Get the parent handle.
-	 */
-	parent = devfs_get_parent (new_devfs_handle);
-
-	/*
-	 * To provide the same semantics as the hwgraph, set the connect point.
-	 */
-	rv = hwgraph_connectpt_set(new_devfs_handle, parent);
-	if (!rv) {
-		/*
-		 * We need to clean up!
-		 */
-	}
-
-	/*
-	 * If the caller provides a private data pointer, save it in the 
-	 * labelcl info structure(fastinfo).  This can be retrieved via
-	 * hwgraph_fastinfo_get()
-	 */
-	if (info)
-		hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
-		
-	return(new_devfs_handle);
-
-}
-
-/*
- * hwgraph_vertex_create - Create a vertex by giving it a temp name.
- */
-
-/*
- * hwgraph_path_add - Create a directory node with the given path starting 
- * from the given devfs_handle_t.
- */
-extern char * dev_to_name(devfs_handle_t, char *, uint);
-int
-hwgraph_path_add(devfs_handle_t  fromv,
-		 char *path,
-		 devfs_handle_t *new_de)
-{
-
-	unsigned int	namelen = strlen(path);
-	int		rv;
-
-	/*
-	 * We need to handle the case when fromv is NULL ..
-	 * in this case we need to create the path from the 
-	 * hwgraph root!
-	 */
-	if (fromv == NULL)
-		fromv = hwgraph_root;
-
-	/*
-	 * check the entry doesn't already exist, if it does
-	 * then we simply want new_de to point to it (otherwise
-	 * we'll overwrite the existing labelcl_info struct)
-	 */
-	rv = hwgraph_edge_get(fromv, path, new_de);
-	if (rv)	{	/* couldn't find entry so we create it */
-		*new_de = hwgraph_mk_dir(fromv, path, namelen, NULL);
-		if (new_de == NULL)
-			return(-1);
-		else
-			return(0);
-	}
-	else 
- 		return(0);
-
-}
-
-/*
- * hwgraph_register  - Creates a file entry with devfs.
- *	Note that a file entry cannot have children .. it is like a 
- *	char|block special vertex in hwgraph.
- */
-devfs_handle_t
-hwgraph_register(devfs_handle_t de, const char *name,
-                unsigned int namelen, unsigned int flags, 
-		unsigned int major, unsigned int minor,
-                umode_t mode, uid_t uid, gid_t gid, 
-		struct file_operations *fops,
-                void *info)
-{
-
-	int rv;
-        void *labelcl_info = NULL;
-        devfs_handle_t new_devfs_handle = NULL;
-	devfs_handle_t parent = NULL;
-
-        /*
-         * Create the labelcl info structure for hwgraph compatiblity support.
-         */
-        labelcl_info = labelcl_info_create();
-        if (!labelcl_info)
-                return(NULL);
-
-        /*
-         * Create a devfs entry.
-         */
-        new_devfs_handle = devfs_register(de, name, flags, major,
-				minor, mode, fops, labelcl_info);
-        if (!new_devfs_handle) {
-                labelcl_info_destroy((labelcl_info_t *)labelcl_info);
-                return(NULL);
-        }
-
-	/*
-	 * Get the parent handle.
-	 */
-	if (de == NULL)
-		parent = devfs_get_parent (new_devfs_handle);
-	else
-		parent = de;
-		
-	/*
-	 * To provide the same semantics as the hwgraph, set the connect point.
-	 */
-	rv = hwgraph_connectpt_set(new_devfs_handle, parent);
-	if (rv) {
-		/*
-		 * We need to clean up!
-		 */
-		printk(KERN_WARNING "HCL: Unable to set the connect point to its parent 0x%p\n",
-			(void *)new_devfs_handle);
-	}
-
-        /*
-         * If the caller provides a private data pointer, save it in the 
-         * labelcl info structure(fastinfo).  This can be retrieved via
-         * hwgraph_fastinfo_get()
-         */
-        if (info)
-                hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
-
-        return(new_devfs_handle);
-
-}
-
-
-/*
- * hwgraph_mk_symlink - Create a symbolic link.
- */
-int
-hwgraph_mk_symlink(devfs_handle_t de, const char *name, unsigned int namelen,
-                unsigned int flags, const char *link, unsigned int linklen, 
-		devfs_handle_t *handle, void *info)
-{
-
-	void *labelcl_info = NULL;
-	int status = 0;
-	devfs_handle_t new_devfs_handle = NULL;
-
-	/*
-	 * Create the labelcl info structure for hwgraph compatiblity support.
-	 */
-	labelcl_info = labelcl_info_create();
-	if (!labelcl_info)
-		return(-1);
-
-	/*
-	 * Create a symbolic link devfs entry.
-	 */
-	status = devfs_mk_symlink(de, name, flags, link,
-				&new_devfs_handle, labelcl_info);
-	if ( (!new_devfs_handle) || (!status) ){
-		labelcl_info_destroy((labelcl_info_t *)labelcl_info);
-		return(-1);
-	}
-
-	/*
-	 * If the caller provides a private data pointer, save it in the 
-	 * labelcl info structure(fastinfo).  This can be retrieved via
-	 * hwgraph_fastinfo_get()
-	 */
-	if (info)
-		hwgraph_fastinfo_set(new_devfs_handle, (arbitrary_info_t)info);
-
-	*handle = new_devfs_handle;
-	return(0);
-
-}
-
-/*
- * hwgraph_vertex_get_next - this routine returns the next sibbling for the 
- *	device entry given in de.  If there are no more sibbling, NULL 
- * 	is returned in next_sibbling.
- *
- *	Currently we do not have any protection against de being deleted 
- *	while it's handle is being held.
- */
-int
-hwgraph_vertex_get_next(devfs_handle_t *next_sibbling, devfs_handle_t *de)
-{
-	*next_sibbling = devfs_get_next_sibling (*de);
-
-	if (*next_sibbling != NULL)
-		*de = *next_sibbling;
-	return (0);
-}
-
-
-/*
- * hwgraph_vertex_destroy - Destroy the devfs entry
- */
-int
-hwgraph_vertex_destroy(devfs_handle_t de)
-{
-
-	void *labelcl_info = NULL;
-
-	labelcl_info = devfs_get_info(de);
-	devfs_unregister(de);
-
-	if (labelcl_info)
-		labelcl_info_destroy((labelcl_info_t *)labelcl_info);
-
-	return(0);
-}
-
-/*
-** See if a vertex has an outgoing edge with a specified name.
-** Vertices in the hwgraph *implicitly* contain these edges:
-**	"." 	refers to "current vertex"
-**	".." 	refers to "connect point vertex"
-**	"char"	refers to current vertex (character device access)
-**	"block"	refers to current vertex (block device access)
-*/
-
-/*
- * hwgraph_edge_add - This routines has changed from the original conext.
- * All it does now is to create a symbolic link from "from" to "to".
- */
-/* ARGSUSED */
-int
-hwgraph_edge_add(devfs_handle_t from, devfs_handle_t to, char *name)
-{
-
-	char *path;
-	char *s1;
-	char *index;
-	int name_start;
-	devfs_handle_t handle = NULL;
-	int rv;
-	int i, count;
-
-	path = kmalloc(1024, GFP_KERNEL);
-	memset(path, 0x0, 1024);
-	name_start = devfs_generate_path (from, path, 1024);
-	s1 = &path[name_start];
-	count = 0;
-	while (1) {
-		index = strstr (s1, "/");
-		if (index) {
-			count++;
-			s1 = ++index;
-		} else {
-			count++;
-			break;
-		}
-	}
-
-	memset(path, 0x0, 1024);
-	name_start = devfs_generate_path (to, path, 1024);
-
-	for (i = 0; i < count; i++) {
-		strcat(path,"../");
-	}
-
-	strcat(path, &path[name_start]);
-
-	/*
-	 * Otherwise, just create a symlink to the vertex.
-	 * In this case the vertex was previous created with a REAL pathname.
-	 */
-	rv = devfs_mk_symlink (from, (const char *)name, 
-			       DEVFS_FL_DEFAULT, path,
-			       &handle, NULL);
-
-	name_start = devfs_generate_path (handle, path, 1024);
-	return(rv);
-
-	
-}
-/* ARGSUSED */
-int
-hwgraph_edge_get(devfs_handle_t from, char *name, devfs_handle_t *toptr)
-{
-
-	int namelen = 0;
-	devfs_handle_t target_handle = NULL;
-
-	if (name == NULL)
-		return(-1);
-
-	if (toptr == NULL)
-		return(-1);
-
-	/*
-	 * If the name is "." just return the current devfs entry handle.
-	 */
-	if (!strcmp(name, HWGRAPH_EDGELBL_DOT)) {
-		if (toptr) {
-			*toptr = from;
-		}
-	} else if (!strcmp(name, HWGRAPH_EDGELBL_DOTDOT)) {
-		/*
-		 * Hmmm .. should we return the connect point or parent ..
-		 * see in hwgraph, the concept of parent is the connectpt!
-		 *
-		 * Maybe we should see whether the connectpt is set .. if 
-		 * not just return the parent!
-		 */
-		target_handle = hwgraph_connectpt_get(from);
-		if (target_handle) {
-			/*
-			 * Just return the connect point.
-			 */
-			*toptr = target_handle;
-			return(0);
-		}
-		target_handle = devfs_get_parent(from);
-		*toptr = target_handle;
-
-	} else {
-		/*
-		 * Call devfs to get the devfs entry.
-		 */
-		namelen = (int) strlen(name);
-		target_handle = devfs_get_handle(from, name, 1); /* Yes traverse symbolic links */
-		if (target_handle == NULL)
-			return(-1);
-		else
-		*toptr = target_handle;
-	}
-
-	return(0);
-}
-
-
-/*
- * hwgraph_edge_get_next - Retrieves the next sibbling given the current
- *	entry number "placeptr".
- *
- * 	Allow the caller to retrieve walk through the sibblings of "source" 
- * 	devfs_handle_t.  The implicit edges "." and ".." is returned first 
- * 	followed by each of the real children.
- *
- *	We may end up returning garbage if another thread perform any deletion 
- *	in this directory before "placeptr".
- *
- */
-/* ARGSUSED */
-int
-hwgraph_edge_get_next(devfs_handle_t source, char *name, devfs_handle_t *target,
-                              uint *placeptr)
-
-{
-
-        uint which_place;
-	unsigned int namelen = 0;
-	const char *tempname = NULL;
-
-        if (placeptr == NULL)
-                return(-1);
-
-        which_place = *placeptr;
-
-again:
-        if (which_place <= HWGRAPH_RESERVED_PLACES) {
-                if (which_place == EDGE_PLACE_WANT_CURRENT) {
-			/*
-			 * Looking for "."
-			 * Return the current devfs handle.
-			 */
-                        if (name != NULL)
-                                strcpy(name, HWGRAPH_EDGELBL_DOT);
-
-                        if (target != NULL) {
-                                *target = source; 
-				/* XXX should incr "source" ref count here if we
-				 * ever implement ref counts */
-                        }
-
-                } else if (which_place == EDGE_PLACE_WANT_CONNECTPT) {
-			/*
-			 * Looking for the connect point or parent.
-			 * If the connect point is set .. it returns the connect point.
-			 * Otherwise, it returns the parent .. will we support 
-			 * connect point?
-			 */
-                        devfs_handle_t connect_point = hwgraph_connectpt_get(source);
-
-                        if (connect_point == NULL) {
-				/*
-				 * No connectpoint set .. either the User
-				 * explicitly NULL it or this node was not 
-				 * created via hcl.
-				 */
-                                which_place++;
-                                goto again;
-                        }
-
-                        if (name != NULL)
-                                strcpy(name, HWGRAPH_EDGELBL_DOTDOT);
-
-                        if (target != NULL)
-                                *target = connect_point;
-
-                } else if (which_place == EDGE_PLACE_WANT_REAL_EDGES) {
-			/* 
-			 * return first "real" entry in directory, and increment
-			 * placeptr.  Next time around we should have 
-			 * which_place > HWGRAPH_RESERVED_EDGES so we'll fall through
-			 * this nested if block.
-			 */
-			*target = devfs_get_first_child(source);
-			if (*target && name) {
-				tempname = devfs_get_name(*target, &namelen);
-				if (tempname && namelen)
-					strcpy(name, tempname);
-			}
-					
-			*placeptr = which_place + 1;
-			return (0);
-                }
-
-                *placeptr = which_place+1;
-                return(0);
-        }
-
-	/*
-	 * walk linked list, (which_place - HWGRAPH_RESERVED_PLACES) times
-	 */
-	{
-		devfs_handle_t	curr;
-		int		i = 0;
-
-		for (curr=devfs_get_first_child(source), i= i+HWGRAPH_RESERVED_PLACES; 
-			curr!=NULL && i<which_place; 
-			curr=devfs_get_next_sibling(curr), i++)
-			;
-		*target = curr;
-		*placeptr = which_place + 1;
-		if (curr && name) {
-			tempname = devfs_get_name(*target, &namelen);
-			if (tempname && namelen)
-				strcpy(name, tempname);
-		}
-	}
-	if (target == NULL)
-		return(-1);
-	else
-        	return(0);
-}
-
-/*
- * hwgraph_info_add_LBL - Adds a new label for the device.  Mark the info_desc
- *	of the label as INFO_DESC_PRIVATE and store the info in the label.
- */
-/* ARGSUSED */
-int
-hwgraph_info_add_LBL(	devfs_handle_t de,
-			char *name,
-			arbitrary_info_t info)
-{
-	return(labelcl_info_add_LBL(de, name, INFO_DESC_PRIVATE, info));
-}
-
-/*
- * hwgraph_info_remove_LBL - Remove the label entry for the device.
- */
-/* ARGSUSED */
-int
-hwgraph_info_remove_LBL(	devfs_handle_t de,
-				char *name,
-				arbitrary_info_t *old_info)
-{
-	return(labelcl_info_remove_LBL(de, name, NULL, old_info));
-}
-
-/*
- * hwgraph_info_replace_LBL - replaces an existing label with 
- *	a new label info value.
- */
-/* ARGSUSED */
-int
-hwgraph_info_replace_LBL(	devfs_handle_t de,
-				char *name,
-				arbitrary_info_t info,
-				arbitrary_info_t *old_info)
-{
-	return(labelcl_info_replace_LBL(de, name,
-			INFO_DESC_PRIVATE, info,
-			NULL, old_info));
-}
-/*
- * hwgraph_info_get_LBL - Get and return the info value in the label of the 
- * 	device.
- */
-/* ARGSUSED */
-int
-hwgraph_info_get_LBL(	devfs_handle_t de,
-			char *name,
-			arbitrary_info_t *infop)
-{
-	return(labelcl_info_get_LBL(de, name, NULL, infop));
-}
-
-/*
- * hwgraph_info_get_exported_LBL - Retrieve the info_desc and info pointer 
- *	of the given label for the device.  The weird thing is that the label 
- *	that matches the name is return irrespective of the info_desc value!
- *	Do not understand why the word "exported" is used!
- */
-/* ARGSUSED */
-int
-hwgraph_info_get_exported_LBL(	devfs_handle_t de,
-				char *name,
-				int *export_info,
-				arbitrary_info_t *infop)
-{
-	int rc;
-	arb_info_desc_t info_desc;
-
-	rc = labelcl_info_get_LBL(de, name, &info_desc, infop);
-	if (rc == 0)
-		*export_info = (int)info_desc;
-
-	return(rc);
-}
-
-/*
- * hwgraph_info_get_next_LBL - Returns the next label info given the 
- *	current label entry in place.
- *
- *	Once again this has no locking or reference count for protection.
- *
- */
-/* ARGSUSED */
-int
-hwgraph_info_get_next_LBL(	devfs_handle_t de,
-				char *buf,
-				arbitrary_info_t *infop,
-				labelcl_info_place_t *place)
-{
-	return(labelcl_info_get_next_LBL(de, buf, NULL, infop, place));
-}
-
-/*
- * hwgraph_info_export_LBL - Retrieve the specified label entry and modify 
- *	the info_desc field with the given value in nbytes.
- */
-/* ARGSUSED */
-int
-hwgraph_info_export_LBL(devfs_handle_t de, char *name, int nbytes)
-{
-	arbitrary_info_t info;
-	int rc;
-
-	if (nbytes == 0)
-		nbytes = INFO_DESC_EXPORT;
-
-	if (nbytes < 0)
-		return(-1);
-
-	rc = labelcl_info_get_LBL(de, name, NULL, &info);
-	if (rc != 0)
-		return(rc);
-
-	rc = labelcl_info_replace_LBL(de, name,
-				nbytes, info, NULL, NULL);
-
-	return(rc);
-}
-
-/*
- * hwgraph_info_unexport_LBL - Retrieve the given label entry and change the 
- * label info_descr filed to INFO_DESC_PRIVATE.
- */
-/* ARGSUSED */
-int
-hwgraph_info_unexport_LBL(devfs_handle_t de, char *name)
-{
-	arbitrary_info_t info;
-	int rc;
-
-	rc = labelcl_info_get_LBL(de, name, NULL, &info);
-	if (rc != 0)
-		return(rc);
-
-	rc = labelcl_info_replace_LBL(de, name,
-				INFO_DESC_PRIVATE, info, NULL, NULL);
-
-	return(rc);
-}
-
-/*
- * hwgraph_path_lookup - return the handle for the given path.
- *
- */
-int
-hwgraph_path_lookup(	devfs_handle_t start_vertex_handle,
-			char *lookup_path,
-			devfs_handle_t *vertex_handle_ptr,
-			char **remainder)
-{
-	*vertex_handle_ptr = devfs_get_handle(start_vertex_handle,	/* start dir */
-					lookup_path,		/* path */
-					1);			/* traverse symlinks */
-	if (*vertex_handle_ptr == NULL)
-		return(-1);
-	else
-		return(0);
-}
-
-/*
- * hwgraph_traverse - Find and return the devfs handle starting from de.
- *
- */
-graph_error_t
-hwgraph_traverse(devfs_handle_t de, char *path, devfs_handle_t *found)
-{
-	/* 
-	 * get the directory entry (path should end in a directory)
-	 */
-
-	*found = devfs_get_handle(de,	/* start dir */
-			    path,	/* path */
-			    1);		/* traverse symlinks */
-	if (*found == NULL)
-		return(GRAPH_NOT_FOUND);
-	else
-		return(GRAPH_SUCCESS);
-}
-
-/*
- * hwgraph_path_to_vertex - Return the devfs entry handle for the given 
- *	pathname .. assume traverse symlinks too!.
- */
-devfs_handle_t
-hwgraph_path_to_vertex(char *path)
-{
-	return(devfs_get_handle(NULL,	/* start dir */
-			path,		/* path */
-		    	1));		/* traverse symlinks */
-}
-
-/*
- * hwgraph_path_to_dev - Returns the devfs_handle_t of the given path ..
- *	We only deal with devfs handle and not devfs_handle_t.
-*/
-devfs_handle_t
-hwgraph_path_to_dev(char *path)
-{
-	devfs_handle_t  de;
-
-	de = hwgraph_path_to_vertex(path);
-	return(de);
-}
-
-/*
- * hwgraph_block_device_get - return the handle of the block device file.
- *	The assumption here is that de is a directory.
-*/
-devfs_handle_t
-hwgraph_block_device_get(devfs_handle_t de)
-{
-	return(devfs_get_handle(de,		/* start dir */
-			"block",		/* path */
-		    	1));			/* traverse symlinks */
-}
-
-/*
- * hwgraph_char_device_get - return the handle of the char device file.
- *      The assumption here is that de is a directory.
-*/
-devfs_handle_t
-hwgraph_char_device_get(devfs_handle_t de)
-{
-	return(devfs_get_handle(de,		/* start dir */
-			"char",			/* path */
-		    	1));			/* traverse symlinks */
-}
-
-/*
-** Inventory is now associated with a vertex in the graph.  For items that
-** belong in the inventory but have no vertex 
-** (e.g. old non-graph-aware drivers), we create a bogus vertex under the 
-** INFO_LBL_INVENT name.
-**
-** For historical reasons, we prevent exact duplicate entries from being added
-** to a single vertex.
-*/
-
-/*
- * hwgraph_inventory_add - Adds an inventory entry into de.
- */
-int
-hwgraph_inventory_add(	devfs_handle_t de,
-			int class,
-			int type,
-			major_t controller,
-			minor_t unit,
-			int state)
-{
-	inventory_t *pinv = NULL, *old_pinv = NULL, *last_pinv = NULL;
-	int rv;
-
-	/*
-	 * Add our inventory data to the list of inventory data
-	 * associated with this vertex.
-	 */
-again:
-	/* GRAPH_LOCK_UPDATE(&invent_lock); */
-	rv = labelcl_info_get_LBL(de,
-			INFO_LBL_INVENT,
-			NULL, (arbitrary_info_t *)&old_pinv);
-	if ((rv != LABELCL_SUCCESS) && (rv != LABELCL_NOT_FOUND))
-		goto failure;
-
-	/*
-	 * Seek to end of inventory items associated with this
-	 * vertex.  Along the way, make sure we're not duplicating
-	 * an inventory item (for compatibility with old add_to_inventory)
-	 */
-	for (;old_pinv; last_pinv = old_pinv, old_pinv = old_pinv->inv_next) {
-		if ((int)class != -1 && old_pinv->inv_class != class)
-			continue;
-		if ((int)type != -1 && old_pinv->inv_type != type)
-			continue;
-		if ((int)state != -1 && old_pinv->inv_state != state)
-			continue;
-		if ((int)controller != -1
-		    && old_pinv->inv_controller != controller)
-			continue;
-		if ((int)unit != -1 && old_pinv->inv_unit != unit)
-			continue;
-
-		/* exact duplicate of previously-added inventory item */
-		rv = LABELCL_DUP;
-		goto failure;
-	}
-
-	/* Not a duplicate, so we know that we need to add something. */
-	if (pinv == NULL) {
-		/* Release lock while we wait for memory. */
-		/* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */
-		pinv = (inventory_t *)kmalloc(sizeof(inventory_t), GFP_KERNEL);
-		replace_in_inventory(pinv, class, type, controller, unit, state);
-		goto again;
-	}
-
-	pinv->inv_next = NULL;
-	if (last_pinv) {
-		last_pinv->inv_next = pinv;
-	} else {
-		rv = labelcl_info_add_LBL(de, INFO_LBL_INVENT, 
-			sizeof(inventory_t), (arbitrary_info_t)pinv);
-
-		if (!rv)
-			goto failure;
-	}
-
-	/* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */
-	return(0);
-
-failure:
-	/* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */
-	if (pinv)
-		kfree(pinv);
-	return(rv);
-}
-
-
-/*
- * hwgraph_inventory_remove - Removes an inventory entry.
- *
- *	Remove an inventory item associated with a vertex.   It is the caller's
- *	responsibility to make sure that there are no races between removing
- *	inventory from a vertex and simultaneously removing that vertex.
-*/
-int
-hwgraph_inventory_remove(	devfs_handle_t de,
-				int class,
-				int type,
-				major_t controller,
-				minor_t unit,
-				int state)
-{
-	inventory_t *pinv = NULL, *last_pinv = NULL, *next_pinv = NULL;
-	labelcl_error_t rv;
-
-	/*
-	 * We never remove stuff from ".invent" ..
-	 */
-	if (!de)
-		return (-1);
-
-	/*
-	 * Remove our inventory data to the list of inventory data
-	 * associated with this vertex.
-	 */
-	/* GRAPH_LOCK_UPDATE(&invent_lock); */
-	rv = labelcl_info_get_LBL(de,
-			INFO_LBL_INVENT,
-			NULL, (arbitrary_info_t *)&pinv);
-	if (rv != LABELCL_SUCCESS)
-		goto failure;
-
-	/*
-	 * Search through inventory items associated with this
-	 * vertex, looking for a match.
-	 */
-	for (;pinv; pinv = next_pinv) {
-		next_pinv = pinv->inv_next;
-
-		if(((int)class == -1 || pinv->inv_class == class) &&
-		   ((int)type == -1 || pinv->inv_type == type) &&
-		   ((int)state == -1 || pinv->inv_state == state) &&
-		   ((int)controller == -1 || pinv->inv_controller == controller) &&
-		   ((int)unit == -1 || pinv->inv_unit == unit)) {
-
-			/* Found a matching inventory item. Remove it. */
-			if (last_pinv) {
-				last_pinv->inv_next = pinv->inv_next;
-			} else {
-				rv = hwgraph_info_replace_LBL(de, INFO_LBL_INVENT, (arbitrary_info_t)pinv->inv_next, NULL);
-				if (rv != LABELCL_SUCCESS)
-					goto failure;
-			}
-
-			pinv->inv_next = NULL; /* sanity */
-			kfree(pinv);
-		} else
-			last_pinv = pinv;
-	}
-
-	if (last_pinv == NULL) {
-		rv = hwgraph_info_remove_LBL(de, INFO_LBL_INVENT, NULL);
-		if (rv != LABELCL_SUCCESS)
-			goto failure;
-	}
-
-	rv = LABELCL_SUCCESS;
-
-failure:
-	/* GRAPH_LOCK_DONE_UPDATE(&invent_lock); */
-	return(rv);
-}
-
-/*
- * hwgraph_inventory_get_next - Get next inventory item associated with the 
- *	specified vertex.
- *
- *	No locking is really needed.  We don't yet have the ability
- *	to remove inventory items, and new items are always added to
- *	the end of a vertex' inventory list.
- *
- * 	However, a devfs entry can be removed!
-*/
-int
-hwgraph_inventory_get_next(devfs_handle_t de, invplace_t *place, inventory_t **ppinv)
-{
-	inventory_t *pinv;
-	labelcl_error_t rv;
-
-	if (de == NULL)
-		return(LABELCL_BAD_PARAM);
-
-	if (place->invplace_vhdl == NULL) {
-		place->invplace_vhdl = de;
-		place->invplace_inv = NULL;
-	}
-
-	if (de != place->invplace_vhdl)
-		return(LABELCL_BAD_PARAM);
-
-	if (place->invplace_inv == NULL) {
-		/* Just starting on this vertex */
-		rv = labelcl_info_get_LBL(de, INFO_LBL_INVENT,
-						NULL, (arbitrary_info_t *)&pinv);
-		if (rv != LABELCL_SUCCESS)
-			return(LABELCL_NOT_FOUND);
-
-	} else {
-		/* Advance to next item on this vertex */
-		pinv = place->invplace_inv->inv_next;
-	}
-	place->invplace_inv = pinv;
-	*ppinv = pinv;
-
-	return(LABELCL_SUCCESS);
-}
-
-/*
- * hwgraph_controller_num_get - Returns the controller number in the inventory 
- *	entry.
- */
-int
-hwgraph_controller_num_get(devfs_handle_t device)
-{
-	inventory_t *pinv;
-	invplace_t invplace = { NULL, NULL, NULL };
-	int val = -1;
-	if ((pinv = device_inventory_get_next(device, &invplace)) != NULL) {
-		val = (pinv->inv_class == INV_NETWORK)? pinv->inv_unit: pinv->inv_controller;
-	}
-#ifdef DEBUG
-	/*
-	 * It does not make any sense to call this on vertexes with multiple
-	 * inventory structs chained together
-	 */
-	if ( device_inventory_get_next(device, &invplace) != NULL ) {
-		printk("Should panic here ... !\n");
-#endif
-	return (val);	
-}
-
-/*
- * hwgraph_controller_num_set - Sets the controller number in the inventory 
- *	entry.
- */
-void
-hwgraph_controller_num_set(devfs_handle_t device, int contr_num)
-{
-	inventory_t *pinv;
-	invplace_t invplace = { NULL, NULL, NULL };
-	if ((pinv = device_inventory_get_next(device, &invplace)) != NULL) {
-		if (pinv->inv_class == INV_NETWORK)
-			pinv->inv_unit = contr_num;
-		else {
-			if (pinv->inv_class == INV_FCNODE)
-				pinv = device_inventory_get_next(device, &invplace);
-			if (pinv != NULL)
-				pinv->inv_controller = contr_num;
-		}
-	}
-#ifdef DEBUG
-	/*
-	 * It does not make any sense to call this on vertexes with multiple
-	 * inventory structs chained together
-	 */
-	if(pinv != NULL)
-		ASSERT(device_inventory_get_next(device, &invplace) == NULL);
-#endif
-}
-
-/*
- * Find the canonical name for a given vertex by walking back through
- * connectpt's until we hit the hwgraph root vertex (or until we run
- * out of buffer space or until something goes wrong).
- *
- *	COMPATIBILITY FUNCTIONALITY
- * Walks back through 'parents', not necessarily the same as connectpts.
- *
- * Need to resolve the fact that devfs does not return the path from 
- * "/" but rather it just stops right before /dev ..
- */
-int
-hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen)
-{
-	char *locbuf;
-	int   pos;
-
-	if (buflen < 1)
-		return(-1);	/* XXX should be GRAPH_BAD_PARAM ? */
-
-	locbuf = kmalloc(buflen, GFP_KERNEL);
-
-	pos = devfs_generate_path(vhdl, locbuf, buflen);
-	if (pos < 0) {
-		kfree(locbuf);
-		return pos;
-	}
-
-	strcpy(buf, &locbuf[pos]);
-	kfree(locbuf);
-	return 0;
-}
-
-/*
-** vertex_to_name converts a vertex into a canonical name by walking
-** back through connect points until we hit the hwgraph root (or until
-** we run out of buffer space).
-**
-** Usually returns a pointer to the original buffer, filled in as
-** appropriate.  If the buffer is too small to hold the entire name,
-** or if anything goes wrong while determining the name, vertex_to_name
-** returns "UnknownDevice".
-*/
-
-#define DEVNAME_UNKNOWN "UnknownDevice"
-
-char *
-vertex_to_name(devfs_handle_t vhdl, char *buf, uint buflen)
-{
-	if (hwgraph_vertex_name_get(vhdl, buf, buflen) == GRAPH_SUCCESS)
-		return(buf);
-	else
-		return(DEVNAME_UNKNOWN);
-}
-
-#ifdef LATER
-/*
-** Return the compact node id of the node that ultimately "owns" the specified
-** vertex.  In order to do this, we walk back through masters and connect points
-** until we reach a vertex that represents a node.
-*/
-cnodeid_t
-master_node_get(devfs_handle_t vhdl)
-{
-	cnodeid_t cnodeid;
-	devfs_handle_t master;
-
-	for (;;) {
-		cnodeid = nodevertex_to_cnodeid(vhdl);
-		if (cnodeid != CNODEID_NONE)
-			return(cnodeid);
-
-		master = device_master_get(vhdl);
-
-		/* Check for exceptional cases */
-		if (master == vhdl) {
-			/* Since we got a reference to the "master" thru
-			 * device_master_get() we should decrement
-			 * its reference count by 1
-			 */
-			hwgraph_vertex_unref(master);
-			return(CNODEID_NONE);
-		}
-
-		if (master == GRAPH_VERTEX_NONE) {
-			master = hwgraph_connectpt_get(vhdl);
-			if ((master == GRAPH_VERTEX_NONE) ||
-			    (master == vhdl)) {
-				if (master == vhdl)
-					/* Since we got a reference to the
-					 * "master" thru
-					 * hwgraph_connectpt_get() we should
-					 * decrement its reference count by 1
-					 */
-					hwgraph_vertex_unref(master);
-				return(CNODEID_NONE);
-			}
-		}
-		
-		vhdl = master;
-		/* Decrement the reference to "master" which was got
-		 * either thru device_master_get() or hwgraph_connectpt_get()
-		 * above.
-		 */
-		hwgraph_vertex_unref(master);
-	}
-}
-
-/*
- * Using the canonical path name to get hold of the desired vertex handle will
- * not work on multi-hub sn0 nodes. Hence, we use the following (slightly
- * convoluted) algorithm.
- *
- * - Start at the vertex corresponding to the driver (provided as input parameter)
- * - Loop till you reach a vertex which has EDGE_LBL_MEMORY
- *    - If EDGE_LBL_CONN exists, follow that up.
- *      else if EDGE_LBL_MASTER exists, follow that up.
- *      else follow EDGE_LBL_DOTDOT up.
- *
- * * We should be at desired hub/heart vertex now *
- * - Follow EDGE_LBL_CONN to the widget vertex.
- *
- * - return vertex handle of this widget.
- */
-devfs_handle_t
-mem_vhdl_get(devfs_handle_t drv_vhdl)
-{
-devfs_handle_t cur_vhdl, cur_upper_vhdl;
-devfs_handle_t tmp_mem_vhdl, mem_vhdl;
-graph_error_t loop_rv;
-
-  /* Initializations */
-  cur_vhdl = drv_vhdl;
-  loop_rv = ~GRAPH_SUCCESS;
-
-  /* Loop till current vertex has EDGE_LBL_MEMORY */
-  while (loop_rv != GRAPH_SUCCESS) {
-
-    if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_CONN, &cur_upper_vhdl)) == GRAPH_SUCCESS) {
-
-    } else if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_MASTER, &cur_upper_vhdl)) == GRAPH_SUCCESS) {
-      } else { /* Follow HWGRAPH_EDGELBL_DOTDOT up */
-           (void) hwgraph_edge_get(cur_vhdl, HWGRAPH_EDGELBL_DOTDOT, &cur_upper_vhdl);
-        }
-
-    cur_vhdl = cur_upper_vhdl;
-
-#if DEBUG && HWG_DEBUG
-    printf("Current vhdl %d \n", cur_vhdl);
-#endif /* DEBUG */
-
-    loop_rv = hwgraph_edge_get(cur_vhdl, EDGE_LBL_MEMORY, &tmp_mem_vhdl);
-  }
-
-  /* We should be at desired hub/heart vertex now */
-  if ((hwgraph_edge_get(cur_vhdl, EDGE_LBL_CONN, &mem_vhdl)) != GRAPH_SUCCESS)
-    return (GRAPH_VERTEX_NONE);
-
-  return (mem_vhdl);
-}
-#endif /* LATER */
-
-
-/*
-** Add a char device -- if the driver supports it -- at a specified vertex.
-*/
-graph_error_t
-hwgraph_char_device_add(        devfs_handle_t from,
-                                char *path,
-                                char *prefix,
-                                devfs_handle_t *devhdl)
-{
-	devfs_handle_t xx = NULL;
-
-	printk("WARNING: hwgraph_char_device_add() not supported .. use hwgraph_register.\n");
-	*devhdl = xx;	// Must set devhdl
-	return(GRAPH_SUCCESS);
-}
-
-graph_error_t
-hwgraph_edge_remove(devfs_handle_t from, char *name, devfs_handle_t *toptr)
-{
-	printk("WARNING: hwgraph_edge_remove NOT supported.\n");
-	return(GRAPH_ILLEGAL_REQUEST);
-}
-
-graph_error_t
-hwgraph_vertex_unref(devfs_handle_t vhdl)
-{
-	return(GRAPH_ILLEGAL_REQUEST);
-}
-
-
-EXPORT_SYMBOL(hwgraph_mk_dir);
-EXPORT_SYMBOL(hwgraph_path_add);
-EXPORT_SYMBOL(hwgraph_char_device_add);
-EXPORT_SYMBOL(hwgraph_register);
-EXPORT_SYMBOL(hwgraph_vertex_destroy);
-
-EXPORT_SYMBOL(hwgraph_fastinfo_get);
-EXPORT_SYMBOL(hwgraph_edge_get);
-
-EXPORT_SYMBOL(hwgraph_fastinfo_set);
-EXPORT_SYMBOL(hwgraph_connectpt_set);
-EXPORT_SYMBOL(hwgraph_connectpt_get);
-EXPORT_SYMBOL(hwgraph_edge_get_next);
-EXPORT_SYMBOL(hwgraph_info_add_LBL);
-EXPORT_SYMBOL(hwgraph_info_remove_LBL);
-EXPORT_SYMBOL(hwgraph_info_replace_LBL);
-EXPORT_SYMBOL(hwgraph_info_get_LBL);
-EXPORT_SYMBOL(hwgraph_info_get_exported_LBL);
-EXPORT_SYMBOL(hwgraph_info_get_next_LBL);
-EXPORT_SYMBOL(hwgraph_info_export_LBL);
-EXPORT_SYMBOL(hwgraph_info_unexport_LBL);
-EXPORT_SYMBOL(hwgraph_path_lookup);
-EXPORT_SYMBOL(hwgraph_traverse);
-EXPORT_SYMBOL(hwgraph_path_to_vertex);
-EXPORT_SYMBOL(hwgraph_path_to_dev);
-EXPORT_SYMBOL(hwgraph_block_device_get);
-EXPORT_SYMBOL(hwgraph_char_device_get);
-EXPORT_SYMBOL(hwgraph_vertex_name_get);
diff -Nru a/arch/ia64/sn/io/hcl_util.c b/arch/ia64/sn/io/hcl_util.c
--- a/arch/ia64/sn/io/hcl_util.c	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,200 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/kernel.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/sn/sgi.h>
-#include <asm/io.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/nodepda.h>
-
-static devfs_handle_t hwgraph_all_cnodes = GRAPH_VERTEX_NONE;
-extern devfs_handle_t hwgraph_root;
-
-
-/*
-** Return the "master" for a given vertex.  A master vertex is a
-** controller or adapter or other piece of hardware that the given
-** vertex passes through on the way to the rest of the system.
-*/
-devfs_handle_t
-device_master_get(devfs_handle_t vhdl)
-{
-	graph_error_t rc;
-	devfs_handle_t master;
-
-	rc = hwgraph_edge_get(vhdl, EDGE_LBL_MASTER, &master);
-	if (rc == GRAPH_SUCCESS)
-		return(master);
-	else
-		return(GRAPH_VERTEX_NONE);
-}
-
-/*
-** Set the master for a given vertex.
-** Returns 0 on success, non-0 indicates failure
-*/
-int
-device_master_set(devfs_handle_t vhdl, devfs_handle_t master)
-{
-	graph_error_t rc;
-
-	rc = hwgraph_edge_add(vhdl, master, EDGE_LBL_MASTER);
-	return(rc != GRAPH_SUCCESS);
-}
-
-
-/*
-** Return the compact node id of the node that ultimately "owns" the specified
-** vertex.  In order to do this, we walk back through masters and connect points
-** until we reach a vertex that represents a node.
-*/
-cnodeid_t
-master_node_get(devfs_handle_t vhdl)
-{
-	cnodeid_t cnodeid;
-	devfs_handle_t master;
-
-	for (;;) {
-		cnodeid = nodevertex_to_cnodeid(vhdl);
-		if (cnodeid != CNODEID_NONE)
-			return(cnodeid);
-
-		master = device_master_get(vhdl);
-
-		/* Check for exceptional cases */
-		if (master == vhdl) {
-			/* Since we got a reference to the "master" thru
-			 * device_master_get() we should decrement
-			 * its reference count by 1
-			 */
-			return(CNODEID_NONE);
-		}
-
-		if (master == GRAPH_VERTEX_NONE) {
-			master = hwgraph_connectpt_get(vhdl);
-			if ((master == GRAPH_VERTEX_NONE) ||
-			    (master == vhdl)) {
-				return(CNODEID_NONE);
-			}
-		}
-
-		vhdl = master;
-	}
-}
-
-static devfs_handle_t hwgraph_all_cpuids = GRAPH_VERTEX_NONE;
-extern int maxcpus;
-
-void
-mark_cpuvertex_as_cpu(devfs_handle_t vhdl, cpuid_t cpuid)
-{
-	if (cpuid == CPU_NONE)
-		return;
-
-	(void)labelcl_info_add_LBL(vhdl, INFO_LBL_CPUID, INFO_DESC_EXPORT,
-			(arbitrary_info_t)cpuid);
-	{
-		char cpuid_buffer[10];
-
-		if (hwgraph_all_cpuids == GRAPH_VERTEX_NONE) {
-			(void)hwgraph_path_add( hwgraph_root,
-						EDGE_LBL_CPUNUM,
-						&hwgraph_all_cpuids);
-		}
-
-		sprintf(cpuid_buffer, "%ld", cpuid);
-		(void)hwgraph_edge_add( hwgraph_all_cpuids,
-							vhdl,
-							cpuid_buffer);
-	}
-}
-
-/*
-** If the specified device represents a node, return its
-** compact node ID; otherwise, return CNODEID_NONE.
-*/
-cnodeid_t
-nodevertex_to_cnodeid(devfs_handle_t vhdl)
-{
-	int rv = 0;
-	arbitrary_info_t cnodeid = CNODEID_NONE;
-
-	rv = labelcl_info_get_LBL(vhdl, INFO_LBL_CNODEID, NULL, &cnodeid);
-
-	return((cnodeid_t)cnodeid);
-}
-
-void
-mark_nodevertex_as_node(devfs_handle_t vhdl, cnodeid_t cnodeid)
-{
-	if (cnodeid == CNODEID_NONE)
-		return;
-
-	cnodeid_to_vertex(cnodeid) = vhdl;
-	labelcl_info_add_LBL(vhdl, INFO_LBL_CNODEID, INFO_DESC_EXPORT, 
-		(arbitrary_info_t)cnodeid);
-
-	{
-		char cnodeid_buffer[10];
-
-		if (hwgraph_all_cnodes == GRAPH_VERTEX_NONE) {
-			(void)hwgraph_path_add( hwgraph_root,
-						EDGE_LBL_NODENUM,
-						&hwgraph_all_cnodes);
-		}
-
-		sprintf(cnodeid_buffer, "%d", cnodeid);
-		(void)hwgraph_edge_add( hwgraph_all_cnodes,
-					vhdl,
-					cnodeid_buffer);
-	}
-}
-
-/*
-** If the specified device represents a CPU, return its cpuid;
-** otherwise, return CPU_NONE.
-*/
-cpuid_t
-cpuvertex_to_cpuid(devfs_handle_t vhdl)
-{
-	arbitrary_info_t cpuid = CPU_NONE;
-
-	(void)labelcl_info_get_LBL(vhdl, INFO_LBL_CPUID, NULL, &cpuid);
-
-	return((cpuid_t)cpuid);
-}
-
-
-/*
-** dev_to_name converts a devfs_handle_t into a canonical name.  If the devfs_handle_t
-** represents a vertex in the hardware graph, it is converted in the
-** normal way for vertices.  If the devfs_handle_t is an old devfs_handle_t (one which
-** does not represent a hwgraph vertex), we synthesize a name based
-** on major/minor number.
-**
-** Usually returns a pointer to the original buffer, filled in as
-** appropriate.  If the buffer is too small to hold the entire name,
-** or if anything goes wrong while determining the name, dev_to_name
-** returns "UnknownDevice".
-*/
-char *
-dev_to_name(devfs_handle_t dev, char *buf, uint buflen)
-{
-        return(vertex_to_name(dev, buf, buflen));
-}
-
-
diff -Nru a/arch/ia64/sn/io/hubdev.c b/arch/ia64/sn/io/hubdev.c
--- a/arch/ia64/sn/io/hubdev.c	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,132 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/sn1/hubdev.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-
-struct hubdev_callout {
-        int (*attach_method)(devfs_handle_t);
-        struct hubdev_callout *fp;
-};
-
-typedef struct hubdev_callout hubdev_callout_t;
-
-mutex_t hubdev_callout_mutex;
-hubdev_callout_t *hubdev_callout_list = NULL;
-
-void
-hubdev_init(void)
-{
-	mutex_init(&hubdev_callout_mutex);
-        hubdev_callout_list = NULL;
-}
-        
-void
-hubdev_register(int (*attach_method)(devfs_handle_t))
-{
-        hubdev_callout_t *callout;
-        
-        ASSERT(attach_method);
-
-        callout =  (hubdev_callout_t *)snia_kmem_zalloc(sizeof(hubdev_callout_t), KM_SLEEP);
-        ASSERT(callout);
-        
-	mutex_lock(&hubdev_callout_mutex);
-        /*
-         * Insert at the end of the list
-         */
-        callout->fp = hubdev_callout_list;
-        hubdev_callout_list = callout;
-        callout->attach_method = attach_method;
-	mutex_unlock(&hubdev_callout_mutex);
-}
-
-int
-hubdev_unregister(int (*attach_method)(devfs_handle_t))
-{
-        hubdev_callout_t **p;
-        
-        ASSERT(attach_method);
-   
-	mutex_lock(&hubdev_callout_mutex);
-        /*
-         * Remove registry element containing attach_method
-         */
-        for (p = &hubdev_callout_list; *p != NULL; p = &(*p)->fp) {
-                if ((*p)->attach_method == attach_method) {
-                        hubdev_callout_t* victim = *p;
-                        *p = (*p)->fp;
-                        kfree(victim);
-                        mutex_unlock(&hubdev_callout_mutex);
-                        return (0);
-                }
-        }
-        mutex_unlock(&hubdev_callout_mutex);
-        return (ENOENT);
-}
-
-
-int
-hubdev_docallouts(devfs_handle_t hub)
-{
-        hubdev_callout_t *p;
-        int errcode;
-
-	mutex_lock(&hubdev_callout_mutex);
-        
-        for (p = hubdev_callout_list; p != NULL; p = p->fp) {
-                ASSERT(p->attach_method);
-                errcode = (*p->attach_method)(hub);
-                if (errcode != 0) {
-			mutex_unlock(&hubdev_callout_mutex);
-                        return (errcode);
-                }
-        }
-        mutex_unlock(&hubdev_callout_mutex);
-        return (0);
-}
-
-/*
- * Given a hub vertex, return the base address of the Hspec space
- * for that hub.
- */
-
-#if defined(CONFIG_IA64_SGI_SN1)
-
-caddr_t
-hubdev_prombase_get(devfs_handle_t hub)
-{
-	hubinfo_t	hinfo = NULL;
-
-	hubinfo_get(hub, &hinfo);
-	ASSERT(hinfo);
-
-	return ((caddr_t)NODE_RBOOT_BASE(hinfo->h_nasid));
-}
-
-cnodeid_t
-hubdev_cnodeid_get(devfs_handle_t hub)
-{
-	hubinfo_t	hinfo = NULL;
-	hubinfo_get(hub, &hinfo);
-	ASSERT(hinfo);
-
-	return hinfo->h_cnodeid;
-}
-
-#endif	/* CONFIG_IA64_SGI_SN1 */
diff -Nru a/arch/ia64/sn/io/hubspc.c b/arch/ia64/sn/io/hubspc.c
--- a/arch/ia64/sn/io/hubspc.c	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,251 +0,0 @@
-/* $Id$
- *
- * 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) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-/*
- * hubspc.c - Hub Memory Space Management Driver
- * This driver implements the managers for the following
- * memory resources:
- * 1) reference counters
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/sn1/mem_refcnt.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/snconfig.h>
-#include <asm/sn/sn1/hubspc.h>
-#include <asm/sn/ksys/elsc.h>
-#include <asm/sn/simulator.h>
-
-
-/* Uncomment the following line for tracing */
-/* #define HUBSPC_DEBUG 1 */
-
-int hubspc_devflag = D_MP;
-
-
-/***********************************************************************/
-/* CPU Prom Space 						       */
-/***********************************************************************/
-
-typedef struct cpuprom_info {
-	devfs_handle_t	prom_dev;
-	devfs_handle_t	nodevrtx;
-	struct	cpuprom_info *next;
-}cpuprom_info_t;
-
-static cpuprom_info_t	*cpuprom_head;
-static spinlock_t	cpuprom_spinlock;
-#define	PROM_LOCK()	mutex_spinlock(&cpuprom_spinlock)
-#define	PROM_UNLOCK(s)	mutex_spinunlock(&cpuprom_spinlock, (s))
-
-/*
- * Add prominfo to the linked list maintained.
- */
-void
-prominfo_add(devfs_handle_t hub, devfs_handle_t prom)
-{
-	cpuprom_info_t	*info;
-	unsigned long	s;
-
-	info = kmalloc(sizeof(cpuprom_info_t), GFP_KERNEL);
-	ASSERT(info);
-	info->prom_dev = prom;
-	info->nodevrtx = hub;
-
-
-	s = PROM_LOCK();
-	info->next = cpuprom_head;
-	cpuprom_head = info;
-	PROM_UNLOCK(s);
-}
-
-void
-prominfo_del(devfs_handle_t prom)
-{
-	unsigned long	s;
-	cpuprom_info_t	*info;
-	cpuprom_info_t	**prev;
-
-	s = PROM_LOCK();
-	prev = &cpuprom_head;
-	while ( (info = *prev) ) {
-		if (info->prom_dev == prom) {
-			*prev = info->next;
-			PROM_UNLOCK(s);
-			return;
-		}
-		
-		prev = &info->next;
-	}
-	PROM_UNLOCK(s);
-	ASSERT(0);
-}
-
-devfs_handle_t
-prominfo_nodeget(devfs_handle_t prom)
-{
-	unsigned long	s;
-	cpuprom_info_t	*info;
-
-	s = PROM_LOCK();
-	info = cpuprom_head;
-	while (info) {
-		if(info->prom_dev == prom) {
-			PROM_UNLOCK(s);
-			return info->nodevrtx;
-		}
-		info = info->next;
-	}
-	PROM_UNLOCK(s);
-	return 0;
-}
-
-#if defined(CONFIG_IA64_SGI_SN1)
-#define	SN_PROMVERSION		INV_IP35PROM
-
-/* Add "detailed" labelled inventory information to the
- * prom vertex 
- */
-void
-cpuprom_detailed_inventory_info_add(devfs_handle_t prom_dev,devfs_handle_t node)
-{
-	invent_miscinfo_t 	*cpuprom_inventory_info;
-	extern invent_generic_t *klhwg_invent_alloc(cnodeid_t cnode, 
-						     int class, int size);
-	cnodeid_t		cnode = hubdev_cnodeid_get(node);
-
-	/* Allocate memory for the extra inventory information
-	 * for the  prom
-	 */
-	cpuprom_inventory_info = (invent_miscinfo_t *) 
-		klhwg_invent_alloc(cnode, INV_PROM, sizeof(invent_miscinfo_t));
-
-	ASSERT(cpuprom_inventory_info);
-
-	/* Set the enabled flag so that the hinv interprets this
-	 * information
-	 */
-	cpuprom_inventory_info->im_gen.ig_flag = INVENT_ENABLED;
-	cpuprom_inventory_info->im_type = SN_PROMVERSION;
-	/* Store prom revision into inventory information */
-	cpuprom_inventory_info->im_rev = IP27CONFIG.pvers_rev;
-	cpuprom_inventory_info->im_version = IP27CONFIG.pvers_vers;
-
-	/* Store this info as labelled information hanging off the
-	 * prom device vertex
-	 */
-	hwgraph_info_add_LBL(prom_dev, INFO_LBL_DETAIL_INVENT, 
-			     (arbitrary_info_t) cpuprom_inventory_info);
-	/* Export this information so that user programs can get to
-	 * this by using attr_get()
-	 */
-        hwgraph_info_export_LBL(prom_dev, INFO_LBL_DETAIL_INVENT,
-				sizeof(invent_miscinfo_t));
-}
-
-#endif  /* CONFIG_IA64_SGI_SN1 */
-
-
-/***********************************************************************/
-/* Base Hub Space Driver                                               */
-/***********************************************************************/
-
-/*
- * hubspc_init
- * Registration of the hubspc devices with the hub manager
- */
-void
-hubspc_init(void)
-{
-        /*
-         * Register with the hub manager
-         */
-
-        /* The reference counters */
-#if defined(CONFIG_IA64_SGI_SN1)
-        hubdev_register(mem_refcnt_attach);
-#endif
-
-#ifdef CONFIG_IA64_SGI_SN1
-	/* L1 system controller link */
-	if ( !IS_RUNNING_ON_SIMULATOR() ) {
-		/* initialize the L1 link */
-		extern void l1_init(void);
-		l1_init();
-	}
-#endif	/* CONFIG_IA64_SGI_SN1 */
-#ifdef	HUBSPC_DEBUG
-	printk("hubspc_init: Completed\n");
-#endif	/* HUBSPC_DEBUG */
-	/* Initialize spinlocks */
-	mutex_spinlock_init(&cpuprom_spinlock);
-}
-
-/* ARGSUSED */
-int
-hubspc_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp)
-{
-        return (0);
-}
-
-
-/* ARGSUSED */
-int
-hubspc_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-        return (0);
-}
-
-/* ARGSUSED */
-int
-hubspc_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-	/*REFERENCED*/
-        int errcode = 0;
-
-	/* check validity of request */
-	if( len == 0 ) {
-		return -ENXIO;
-        }
-
-	return errcode;
-}
-
-/* ARGSUSED */
-int
-hubspc_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-	return (0);
-
-}
-
-/* ARGSUSED */
-int
-hubspc_ioctl(devfs_handle_t dev,
-             int cmd,
-             void *arg,
-             int mode,
-             cred_t *cred_p,
-             int *rvalp)
-{
-	return (0);
-
-}
diff -Nru a/arch/ia64/sn/io/hwgfs/Makefile b/arch/ia64/sn/io/hwgfs/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/hwgfs/Makefile	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,13 @@
+#
+# 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) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# Makefile for the sn2 io routines.
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+obj-y				+= hcl.o labelcl.o hcl_util.o invent_stub.o \
+				   ramfs.o interface.o
diff -Nru a/arch/ia64/sn/io/hwgfs/hcl.c b/arch/ia64/sn/io/hwgfs/hcl.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/hwgfs/hcl.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,938 @@
+/*
+ * 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.
+ *
+ *  hcl - SGI's Hardware Graph compatibility layer.
+ *
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <linux/ctype.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/sched.h>                /* needed for smp_lock.h :( */
+#include <linux/smp_lock.h>
+#include <asm/sn/sgi.h>
+#include <asm/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/hwgfs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/simulator.h>
+
+#define HCL_NAME "SGI-HWGRAPH COMPATIBILITY DRIVER"
+#define HCL_TEMP_NAME "HCL_TEMP_NAME_USED_FOR_HWGRAPH_VERTEX_CREATE"
+#define HCL_TEMP_NAME_LEN 44 
+#define HCL_VERSION "1.0"
+
+#define vertex_hdl_t hwgfs_handle_t
+vertex_hdl_t hwgraph_root;
+vertex_hdl_t linux_busnum;
+
+extern void pci_bus_cvlink_init(void);
+
+/*
+ * Debug flag definition.
+ */
+#define OPTION_NONE             0x00
+#define HCL_DEBUG_NONE 0x00000
+#define HCL_DEBUG_ALL  0x0ffff
+#if defined(CONFIG_HCL_DEBUG)
+static unsigned int hcl_debug_init __initdata = HCL_DEBUG_NONE;
+#endif
+static unsigned int hcl_debug = HCL_DEBUG_NONE;
+#if defined(CONFIG_HCL_DEBUG) && !defined(MODULE)
+static unsigned int boot_options = OPTION_NONE;
+#endif
+
+/*
+ * Some Global definitions.
+ */
+vertex_hdl_t hcl_handle;
+
+invplace_t invplace_none = {
+	GRAPH_VERTEX_NONE,
+	GRAPH_VERTEX_PLACE_NONE,
+	NULL
+};
+
+/*
+ * HCL device driver.
+ * The purpose of this device driver is to provide a facility 
+ * for User Level Apps e.g. hinv, ioconfig etc. an ioctl path 
+ * to manipulate label entries without having to implement
+ * system call interfaces.  This methodology will enable us to 
+ * make this feature module loadable.
+ */
+static int hcl_open(struct inode * inode, struct file * filp)
+{
+	if (hcl_debug) {
+        	printk("HCL: hcl_open called.\n");
+	}
+
+        return(0);
+
+}
+
+static int hcl_close(struct inode * inode, struct file * filp)
+{
+
+	if (hcl_debug) {
+        	printk("HCL: hcl_close called.\n");
+	}
+
+        return(0);
+
+}
+
+static int hcl_ioctl(struct inode * inode, struct file * file,
+        unsigned int cmd, unsigned long arg)
+{
+
+	if (hcl_debug) {
+		printk("HCL: hcl_ioctl called.\n");
+	}
+
+	switch (cmd) {
+		default:
+			if (hcl_debug) {
+				printk("HCL: hcl_ioctl cmd = 0x%x\n", cmd);
+			}
+	}
+
+	return(0);
+
+}
+
+struct file_operations hcl_fops = {
+	(struct module *)0,
+	NULL,		/* lseek - default */
+	NULL,		/* read - general block-dev read */
+	NULL,		/* write - general block-dev write */
+	NULL,		/* readdir - bad */
+	NULL,		/* poll */
+	hcl_ioctl,      /* ioctl */
+	NULL,		/* mmap */
+	hcl_open,	/* open */
+	NULL,		/* flush */
+	hcl_close,	/* release */
+	NULL,		/* fsync */
+	NULL,		/* fasync */
+	NULL,		/* lock */
+	NULL,		/* readv */
+	NULL,		/* writev */
+};
+
+
+/*
+ * init_hcl() - Boot time initialization.
+ *
+ */
+int __init init_hcl(void)
+{
+	extern void string_table_init(struct string_table *);
+	extern struct string_table label_string_table;
+	extern int init_ifconfig_net(void);
+	extern int init_ioconfig_bus(void);
+	extern int init_hwgfs_fs(void);
+	int rv = 0;
+
+	if (IS_RUNNING_ON_SIMULATOR()) {
+		extern u64 klgraph_addr[];
+		klgraph_addr[0] = 0xe000003000030000;
+	}
+
+	init_hwgfs_fs();
+
+	/*
+	 * Create the hwgraph_root.
+	 */
+	rv = hwgraph_path_add(NULL, EDGE_LBL_HW, &hwgraph_root);
+	if (rv)
+		printk ("WARNING: init_hcl: Failed to create hwgraph_root. Error = %d.\n", rv);
+
+	/*
+	 * Create the hcl driver to support inventory entry manipulations.
+	 *
+	 */
+	hcl_handle = hwgraph_register(hwgraph_root, ".hcl",
+		        0, 0,
+			0, 0,
+			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+			&hcl_fops, NULL);
+
+	if (hcl_handle == NULL) {
+		panic("HCL: Unable to create HCL Driver in init_hcl().\n");
+		return(0);
+	}
+
+	/*
+	 * Initialize the HCL string table.
+	 */
+
+	string_table_init(&label_string_table);
+
+	/*
+	 * Create the directory that links Linux bus numbers to our Xwidget.
+	 */
+	rv = hwgraph_path_add(hwgraph_root, EDGE_LBL_LINUX_BUS, &linux_busnum);
+	if (linux_busnum == NULL) {
+		panic("HCL: Unable to create %s\n", EDGE_LBL_LINUX_BUS);
+		return(0);
+	}
+
+	pci_bus_cvlink_init();
+
+	/*
+	 * Initialize the ifconfgi_net driver that does network devices 
+	 * Persistent Naming.
+	 */
+	init_ifconfig_net();
+	init_ioconfig_bus();
+
+	return(0);
+
+}
+
+
+/*
+ * hcl_setup() - Process boot time parameters if given.
+ *	"hcl="
+ *	This routine gets called only if "hcl=" is given in the 
+ *	boot line and before init_hcl().
+ *
+ *	We currently do not have any boot options .. when we do, 
+ *	functionalities can be added here.
+ *
+ */
+static int __init hcl_setup(char *str)
+{
+    while ( (*str != '\0') && !isspace (*str) )
+    {
+#ifdef CONFIG_HCL_DEBUG
+        if (strncmp (str, "all", 3) == 0) {
+            hcl_debug_init |= HCL_DEBUG_ALL;
+            str += 3;
+        } else 
+        	return 0;
+#endif
+        if (*str != ',') return 0;
+        ++str;
+    }
+
+    return 1;
+
+}
+
+__setup("hcl=", hcl_setup);
+
+
+/*
+ * Set device specific "fast information".
+ *
+ */
+void
+hwgraph_fastinfo_set(vertex_hdl_t de, arbitrary_info_t fastinfo)
+{
+	labelcl_info_replace_IDX(de, HWGRAPH_FASTINFO, fastinfo, NULL);
+}
+
+
+/*
+ * Get device specific "fast information".
+ *
+ */
+arbitrary_info_t
+hwgraph_fastinfo_get(vertex_hdl_t de)
+{
+	arbitrary_info_t fastinfo;
+	int rv;
+
+	if (!de) {
+		printk(KERN_WARNING "HCL: hwgraph_fastinfo_get handle given is NULL.\n");
+		return(-1);
+	}
+
+	rv = labelcl_info_get_IDX(de, HWGRAPH_FASTINFO, &fastinfo);
+	if (rv == 0)
+		return(fastinfo);
+
+	return(0);
+}
+
+
+/*
+ * hwgraph_connectpt_set - Sets the connect point handle in de to the 
+ *	given connect_de handle.  By default, the connect point of the 
+ *	node is the parent.  This effectively changes this assumption.
+ */
+int
+hwgraph_connectpt_set(vertex_hdl_t de, vertex_hdl_t connect_de)
+{
+	int rv;
+
+	if (!de)
+		return(-1);
+
+	rv = labelcl_info_connectpt_set(de, connect_de);
+
+	return(rv);
+}
+
+
+/*
+ * hwgraph_connectpt_get: Returns the entry's connect point.
+ *
+ */
+vertex_hdl_t
+hwgraph_connectpt_get(vertex_hdl_t de)
+{
+	int rv;
+	arbitrary_info_t info;
+	vertex_hdl_t connect;
+
+	rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
+	if (rv != 0) {
+		return(NULL);
+	}
+
+	connect = (vertex_hdl_t)info;
+	return(connect);
+
+}
+
+
+/*
+ * hwgraph_mk_dir - Creates a directory entry.
+ */
+vertex_hdl_t
+hwgraph_mk_dir(vertex_hdl_t de, const char *name,
+                unsigned int namelen, void *info)
+{
+
+	int rv;
+	labelcl_info_t *labelcl_info = NULL;
+	vertex_hdl_t new_handle = NULL;
+	vertex_hdl_t parent = NULL;
+
+	/*
+	 * Create the device info structure for hwgraph compatiblity support.
+	 */
+	labelcl_info = labelcl_info_create();
+	if (!labelcl_info)
+		return(NULL);
+
+	/*
+	 * Create an entry.
+	 */
+	new_handle = hwgfs_mk_dir(de, name, (void *)labelcl_info);
+	if (!new_handle) {
+		labelcl_info_destroy(labelcl_info);
+		return(NULL);
+	}
+
+	/*
+	 * Get the parent handle.
+	 */
+	parent = hwgfs_get_parent (new_handle);
+
+	/*
+	 * To provide the same semantics as the hwgraph, set the connect point.
+	 */
+	rv = hwgraph_connectpt_set(new_handle, parent);
+	if (!rv) {
+		/*
+		 * We need to clean up!
+		 */
+	}
+
+	/*
+	 * If the caller provides a private data pointer, save it in the 
+	 * labelcl info structure(fastinfo).  This can be retrieved via
+	 * hwgraph_fastinfo_get()
+	 */
+	if (info)
+		hwgraph_fastinfo_set(new_handle, (arbitrary_info_t)info);
+		
+	return(new_handle);
+
+}
+
+/*
+ * hwgraph_path_add - Create a directory node with the given path starting 
+ * from the given fromv.
+ */
+int
+hwgraph_path_add(vertex_hdl_t  fromv,
+		 char *path,
+		 vertex_hdl_t *new_de)
+{
+
+	unsigned int	namelen = strlen(path);
+	int		rv;
+
+	/*
+	 * We need to handle the case when fromv is NULL ..
+	 * in this case we need to create the path from the 
+	 * hwgraph root!
+	 */
+	if (fromv == NULL)
+		fromv = hwgraph_root;
+
+	/*
+	 * check the entry doesn't already exist, if it does
+	 * then we simply want new_de to point to it (otherwise
+	 * we'll overwrite the existing labelcl_info struct)
+	 */
+	rv = hwgraph_edge_get(fromv, path, new_de);
+	if (rv)	{	/* couldn't find entry so we create it */
+		*new_de = hwgraph_mk_dir(fromv, path, namelen, NULL);
+		if (new_de == NULL)
+			return(-1);
+		else
+			return(0);
+	}
+	else 
+ 		return(0);
+
+}
+
+/*
+ * hwgraph_register  - Creates a special device file.
+ *
+ */
+vertex_hdl_t
+hwgraph_register(vertex_hdl_t de, const char *name,
+                unsigned int namelen, unsigned int flags, 
+		unsigned int major, unsigned int minor,
+                umode_t mode, uid_t uid, gid_t gid, 
+		struct file_operations *fops,
+                void *info)
+{
+
+        vertex_hdl_t new_handle = NULL;
+
+        /*
+         * Create an entry.
+         */
+        new_handle = hwgfs_register(de, name, flags, major,
+				minor, mode, fops, info);
+
+        return(new_handle);
+
+}
+
+
+/*
+ * hwgraph_mk_symlink - Create a symbolic link.
+ */
+int
+hwgraph_mk_symlink(vertex_hdl_t de, const char *name, unsigned int namelen,
+                unsigned int flags, const char *link, unsigned int linklen, 
+		vertex_hdl_t *handle, void *info)
+{
+
+	void *labelcl_info = NULL;
+	int status = 0;
+	vertex_hdl_t new_handle = NULL;
+
+	/*
+	 * Create the labelcl info structure for hwgraph compatiblity support.
+	 */
+	labelcl_info = labelcl_info_create();
+	if (!labelcl_info)
+		return(-1);
+
+	/*
+	 * Create a symbolic link.
+	 */
+	status = hwgfs_mk_symlink(de, name, flags, link,
+				&new_handle, labelcl_info);
+	if ( (!new_handle) || (!status) ){
+		labelcl_info_destroy((labelcl_info_t *)labelcl_info);
+		return(-1);
+	}
+
+	/*
+	 * If the caller provides a private data pointer, save it in the 
+	 * labelcl info structure(fastinfo).  This can be retrieved via
+	 * hwgraph_fastinfo_get()
+	 */
+	if (info)
+		hwgraph_fastinfo_set(new_handle, (arbitrary_info_t)info);
+
+	*handle = new_handle;
+	return(0);
+
+}
+
+/*
+ * hwgraph_vertex_destroy - Destroy the entry
+ */
+int
+hwgraph_vertex_destroy(vertex_hdl_t de)
+{
+
+	void *labelcl_info = NULL;
+
+	labelcl_info = hwgfs_get_info(de);
+	hwgfs_unregister(de);
+
+	if (labelcl_info)
+		labelcl_info_destroy((labelcl_info_t *)labelcl_info);
+
+	return(0);
+}
+
+#if 0
+/*
+ * hwgraph_edge_add - This routines has changed from the original conext.
+ * All it does now is to create a symbolic link from "from" to "to".
+ */
+/* ARGSUSED */
+int
+hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name)
+{
+
+	char *path, *link;
+	vertex_hdl_t handle = NULL;
+	int rv, i;
+
+	handle = hwgfs_find_handle(from, name, 0, 0, 0, 1);
+	if (handle) {
+		return(0);
+	}
+
+	path = kmalloc(1024, GFP_KERNEL);
+	memset(path, 0x0, 1024);
+	link = kmalloc(1024, GFP_KERNEL);
+	memset(path, 0x0, 1024);
+	i = hwgfs_generate_path (to, link, 1024);
+	rv = hwgfs_mk_symlink (from, (const char *)name, 
+			       DEVFS_FL_DEFAULT, link,
+			       &handle, NULL);
+	return(0);
+
+
+}
+#endif
+
+int
+hwgraph_edge_add(vertex_hdl_t from, vertex_hdl_t to, char *name)
+{
+
+	char *path, *link;
+	char *s1;
+	char *index;
+	vertex_hdl_t handle = NULL;
+	int rv;
+	int i, count;
+
+	path = kmalloc(1024, GFP_KERNEL);
+	memset((char *)path, 0x0, 1024);
+	link = kmalloc(1024, GFP_KERNEL);
+	memset((char *)link, 0x0, 1024);
+
+	i = hwgfs_generate_path (from, path, 1024);
+	s1 = (char *)path;
+	count = 0;
+	while (1) {
+		index = strstr (s1, "/");
+		if (index) {
+			count++;
+			s1 = ++index;
+		} else {
+			count++;
+			break;
+		}
+	}
+
+	for (i = 0; i < count; i++) {
+		strcat((char *)link,"../");
+	}
+
+	memset(path, 0x0, 1024);
+	i = hwgfs_generate_path (to, path, 1024);
+	strcat((char *)link, (char *)path);
+
+	/*
+	 * Otherwise, just create a symlink to the vertex.
+	 * In this case the vertex was previous created with a REAL pathname.
+	 */
+	rv = hwgfs_mk_symlink (from, (const char *)name,
+			       DEVFS_FL_DEFAULT, link,
+			       &handle, NULL);
+	kfree(path);
+	kfree(link);
+
+	return(rv);
+
+
+}
+
+/* ARGSUSED */
+int
+hwgraph_edge_get(vertex_hdl_t from, char *name, vertex_hdl_t *toptr)
+{
+
+	vertex_hdl_t target_handle = NULL;
+
+	if (name == NULL)
+		return(-1);
+
+	if (toptr == NULL)
+		return(-1);
+
+	/*
+	 * If the name is "." just return the current entry handle.
+	 */
+	if (!strcmp(name, HWGRAPH_EDGELBL_DOT)) {
+		if (toptr) {
+			*toptr = from;
+		}
+	} else if (!strcmp(name, HWGRAPH_EDGELBL_DOTDOT)) {
+		/*
+		 * Hmmm .. should we return the connect point or parent ..
+		 * see in hwgraph, the concept of parent is the connectpt!
+		 *
+		 * Maybe we should see whether the connectpt is set .. if 
+		 * not just return the parent!
+		 */
+		target_handle = hwgraph_connectpt_get(from);
+		if (target_handle) {
+			/*
+			 * Just return the connect point.
+			 */
+			*toptr = target_handle;
+			return(0);
+		}
+		target_handle = hwgfs_get_parent(from);
+		*toptr = target_handle;
+
+	} else {
+		target_handle = hwgfs_find_handle (from, name, 0, 0,
+					0, 1); /* Yes traverse symbolic links */
+	}
+
+	if (target_handle == NULL)
+		return(-1);
+	else
+	 *toptr = target_handle;
+
+	return(0);
+}
+
+/*
+ * hwgraph_info_add_LBL - Adds a new label for the device.  Mark the info_desc
+ *	of the label as INFO_DESC_PRIVATE and store the info in the label.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_add_LBL( vertex_hdl_t de,
+			char *name,
+			arbitrary_info_t info)
+{
+	return(labelcl_info_add_LBL(de, name, INFO_DESC_PRIVATE, info));
+}
+
+/*
+ * hwgraph_info_remove_LBL - Remove the label entry for the device.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_remove_LBL( vertex_hdl_t de,
+				char *name,
+				arbitrary_info_t *old_info)
+{
+	return(labelcl_info_remove_LBL(de, name, NULL, old_info));
+}
+
+/*
+ * hwgraph_info_replace_LBL - replaces an existing label with 
+ *	a new label info value.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_replace_LBL( vertex_hdl_t de,
+				char *name,
+				arbitrary_info_t info,
+				arbitrary_info_t *old_info)
+{
+	return(labelcl_info_replace_LBL(de, name,
+			INFO_DESC_PRIVATE, info,
+			NULL, old_info));
+}
+/*
+ * hwgraph_info_get_LBL - Get and return the info value in the label of the 
+ * 	device.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_get_LBL(vertex_hdl_t de,
+			char *name,
+			arbitrary_info_t *infop)
+{
+	return(labelcl_info_get_LBL(de, name, NULL, infop));
+}
+
+/*
+ * hwgraph_info_get_exported_LBL - Retrieve the info_desc and info pointer 
+ *	of the given label for the device.  The weird thing is that the label 
+ *	that matches the name is return irrespective of the info_desc value!
+ *	Do not understand why the word "exported" is used!
+ */
+/* ARGSUSED */
+int
+hwgraph_info_get_exported_LBL(vertex_hdl_t de,
+				char *name,
+				int *export_info,
+				arbitrary_info_t *infop)
+{
+	int rc;
+	arb_info_desc_t info_desc;
+
+	rc = labelcl_info_get_LBL(de, name, &info_desc, infop);
+	if (rc == 0)
+		*export_info = (int)info_desc;
+
+	return(rc);
+}
+
+/*
+ * hwgraph_info_get_next_LBL - Returns the next label info given the 
+ *	current label entry in place.
+ *
+ *	Once again this has no locking or reference count for protection.
+ *
+ */
+/* ARGSUSED */
+int
+hwgraph_info_get_next_LBL(vertex_hdl_t de,
+				char *buf,
+				arbitrary_info_t *infop,
+				labelcl_info_place_t *place)
+{
+	return(labelcl_info_get_next_LBL(de, buf, NULL, infop, place));
+}
+
+/*
+ * hwgraph_info_export_LBL - Retrieve the specified label entry and modify 
+ *	the info_desc field with the given value in nbytes.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_export_LBL(vertex_hdl_t de, char *name, int nbytes)
+{
+	arbitrary_info_t info;
+	int rc;
+
+	if (nbytes == 0)
+		nbytes = INFO_DESC_EXPORT;
+
+	if (nbytes < 0)
+		return(-1);
+
+	rc = labelcl_info_get_LBL(de, name, NULL, &info);
+	if (rc != 0)
+		return(rc);
+
+	rc = labelcl_info_replace_LBL(de, name,
+				nbytes, info, NULL, NULL);
+
+	return(rc);
+}
+
+/*
+ * hwgraph_info_unexport_LBL - Retrieve the given label entry and change the 
+ * label info_descr filed to INFO_DESC_PRIVATE.
+ */
+/* ARGSUSED */
+int
+hwgraph_info_unexport_LBL(vertex_hdl_t de, char *name)
+{
+	arbitrary_info_t info;
+	int rc;
+
+	rc = labelcl_info_get_LBL(de, name, NULL, &info);
+	if (rc != 0)
+		return(rc);
+
+	rc = labelcl_info_replace_LBL(de, name,
+				INFO_DESC_PRIVATE, info, NULL, NULL);
+
+	return(rc);
+}
+
+/*
+ * hwgraph_path_lookup - return the handle for the given path.
+ *
+ */
+int
+hwgraph_path_lookup(vertex_hdl_t start_vertex_handle,
+			char *lookup_path,
+			vertex_hdl_t *vertex_handle_ptr,
+			char **remainder)
+{
+	*vertex_handle_ptr = hwgfs_find_handle(start_vertex_handle,	/* start dir */
+					lookup_path,		/* path */
+					0,			/* major */
+					0,			/* minor */
+					0,			/* char | block */
+					1);			/* traverse symlinks */
+	if (*vertex_handle_ptr == NULL)
+		return(-1);
+	else
+		return(0);
+}
+
+/*
+ * hwgraph_traverse - Find and return the handle starting from de.
+ *
+ */
+graph_error_t
+hwgraph_traverse(vertex_hdl_t de, char *path, vertex_hdl_t *found)
+{
+	/* 
+	 * get the directory entry (path should end in a directory)
+	 */
+
+	*found = hwgfs_find_handle(de,	/* start dir */
+			    path,	/* path */
+			    0,		/* major */
+			    0,		/* minor */
+			    0,		/* char | block */
+			    1);		/* traverse symlinks */
+	if (*found == NULL)
+		return(GRAPH_NOT_FOUND);
+	else
+		return(GRAPH_SUCCESS);
+}
+
+/*
+ * hwgraph_path_to_vertex - Return the entry handle for the given 
+ *	pathname .. assume traverse symlinks too!.
+ */
+vertex_hdl_t
+hwgraph_path_to_vertex(char *path)
+{
+	return(hwgfs_find_handle(NULL,	/* start dir */
+			path,		/* path */
+		    	0,		/* major */
+		    	0,		/* minor */
+		    	0,		/* char | block */
+		    	1));		/* traverse symlinks */
+}
+
+/*
+ * hwgraph_inventory_remove - Removes an inventory entry.
+ *
+ *	Remove an inventory item associated with a vertex.   It is the caller's
+ *	responsibility to make sure that there are no races between removing
+ *	inventory from a vertex and simultaneously removing that vertex.
+*/
+int
+hwgraph_inventory_remove(	vertex_hdl_t de,
+				int class,
+				int type,
+				major_t controller,
+				minor_t unit,
+				int state)
+{
+	return(0); /* Just a Stub for IRIX code. */
+}
+
+/*
+ * Find the canonical name for a given vertex by walking back through
+ * connectpt's until we hit the hwgraph root vertex (or until we run
+ * out of buffer space or until something goes wrong).
+ *
+ *	COMPATIBILITY FUNCTIONALITY
+ * Walks back through 'parents', not necessarily the same as connectpts.
+ *
+ * Need to resolve the fact that does not return the path from 
+ * "/" but rather it just stops right before /dev ..
+ */
+int
+hwgraph_vertex_name_get(vertex_hdl_t vhdl, char *buf, uint buflen)
+{
+	char *locbuf;
+	int   pos;
+
+	if (buflen < 1)
+		return(-1);	/* XXX should be GRAPH_BAD_PARAM ? */
+
+	locbuf = kmalloc(buflen, GFP_KERNEL);
+
+	pos = hwgfs_generate_path(vhdl, locbuf, buflen);
+	if (pos < 0) {
+		kfree(locbuf);
+		return pos;
+	}
+
+	strcpy(buf, &locbuf[pos]);
+	kfree(locbuf);
+	return 0;
+}
+
+/*
+** vertex_to_name converts a vertex into a canonical name by walking
+** back through connect points until we hit the hwgraph root (or until
+** we run out of buffer space).
+**
+** Usually returns a pointer to the original buffer, filled in as
+** appropriate.  If the buffer is too small to hold the entire name,
+** or if anything goes wrong while determining the name, vertex_to_name
+** returns "UnknownDevice".
+*/
+
+#define DEVNAME_UNKNOWN "UnknownDevice"
+
+char *
+vertex_to_name(vertex_hdl_t vhdl, char *buf, uint buflen)
+{
+	if (hwgraph_vertex_name_get(vhdl, buf, buflen) == GRAPH_SUCCESS)
+		return(buf);
+	else
+		return(DEVNAME_UNKNOWN);
+}
+
+graph_error_t
+hwgraph_edge_remove(vertex_hdl_t from, char *name, vertex_hdl_t *toptr)
+{
+	return(GRAPH_ILLEGAL_REQUEST);
+}
+
+graph_error_t
+hwgraph_vertex_unref(vertex_hdl_t vhdl)
+{
+	return(GRAPH_ILLEGAL_REQUEST);
+}
+
+
+EXPORT_SYMBOL(hwgraph_mk_dir);
+EXPORT_SYMBOL(hwgraph_path_add);
+EXPORT_SYMBOL(hwgraph_register);
+EXPORT_SYMBOL(hwgraph_vertex_destroy);
+EXPORT_SYMBOL(hwgraph_fastinfo_get);
+EXPORT_SYMBOL(hwgraph_fastinfo_set);
+EXPORT_SYMBOL(hwgraph_connectpt_set);
+EXPORT_SYMBOL(hwgraph_connectpt_get);
+EXPORT_SYMBOL(hwgraph_info_add_LBL);
+EXPORT_SYMBOL(hwgraph_info_remove_LBL);
+EXPORT_SYMBOL(hwgraph_info_replace_LBL);
+EXPORT_SYMBOL(hwgraph_info_get_LBL);
+EXPORT_SYMBOL(hwgraph_info_get_exported_LBL);
+EXPORT_SYMBOL(hwgraph_info_get_next_LBL);
+EXPORT_SYMBOL(hwgraph_info_export_LBL);
+EXPORT_SYMBOL(hwgraph_info_unexport_LBL);
+EXPORT_SYMBOL(hwgraph_path_lookup);
+EXPORT_SYMBOL(hwgraph_traverse);
+EXPORT_SYMBOL(hwgraph_vertex_name_get);
diff -Nru a/arch/ia64/sn/io/hwgfs/hcl_util.c b/arch/ia64/sn/io/hwgfs/hcl_util.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/hwgfs/hcl_util.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,200 @@
+/* $Id$
+ *
+ * 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) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <asm/sn/sgi.h>
+#include <asm/io.h>
+#include <asm/sn/io.h>
+#include <asm/sn/iograph.h>
+#include <asm/sn/hwgfs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl_util.h>
+#include <asm/sn/nodepda.h>
+
+static vertex_hdl_t hwgraph_all_cnodes = GRAPH_VERTEX_NONE;
+extern vertex_hdl_t hwgraph_root;
+
+
+/*
+** Return the "master" for a given vertex.  A master vertex is a
+** controller or adapter or other piece of hardware that the given
+** vertex passes through on the way to the rest of the system.
+*/
+vertex_hdl_t
+device_master_get(vertex_hdl_t vhdl)
+{
+	graph_error_t rc;
+	vertex_hdl_t master;
+
+	rc = hwgraph_edge_get(vhdl, EDGE_LBL_MASTER, &master);
+	if (rc == GRAPH_SUCCESS)
+		return(master);
+	else
+		return(GRAPH_VERTEX_NONE);
+}
+
+/*
+** Set the master for a given vertex.
+** Returns 0 on success, non-0 indicates failure
+*/
+int
+device_master_set(vertex_hdl_t vhdl, vertex_hdl_t master)
+{
+	graph_error_t rc;
+
+	rc = hwgraph_edge_add(vhdl, master, EDGE_LBL_MASTER);
+	return(rc != GRAPH_SUCCESS);
+}
+
+
+/*
+** Return the compact node id of the node that ultimately "owns" the specified
+** vertex.  In order to do this, we walk back through masters and connect points
+** until we reach a vertex that represents a node.
+*/
+cnodeid_t
+master_node_get(vertex_hdl_t vhdl)
+{
+	cnodeid_t cnodeid;
+	vertex_hdl_t master;
+
+	for (;;) {
+		cnodeid = nodevertex_to_cnodeid(vhdl);
+		if (cnodeid != CNODEID_NONE)
+			return(cnodeid);
+
+		master = device_master_get(vhdl);
+
+		/* Check for exceptional cases */
+		if (master == vhdl) {
+			/* Since we got a reference to the "master" thru
+			 * device_master_get() we should decrement
+			 * its reference count by 1
+			 */
+			return(CNODEID_NONE);
+		}
+
+		if (master == GRAPH_VERTEX_NONE) {
+			master = hwgraph_connectpt_get(vhdl);
+			if ((master == GRAPH_VERTEX_NONE) ||
+			    (master == vhdl)) {
+				return(CNODEID_NONE);
+			}
+		}
+
+		vhdl = master;
+	}
+}
+
+static vertex_hdl_t hwgraph_all_cpuids = GRAPH_VERTEX_NONE;
+extern int maxcpus;
+
+void
+mark_cpuvertex_as_cpu(vertex_hdl_t vhdl, cpuid_t cpuid)
+{
+	if (cpuid == CPU_NONE)
+		return;
+
+	(void)labelcl_info_add_LBL(vhdl, INFO_LBL_CPUID, INFO_DESC_EXPORT,
+			(arbitrary_info_t)cpuid);
+	{
+		char cpuid_buffer[10];
+
+		if (hwgraph_all_cpuids == GRAPH_VERTEX_NONE) {
+			(void)hwgraph_path_add( hwgraph_root,
+						EDGE_LBL_CPUNUM,
+						&hwgraph_all_cpuids);
+		}
+
+		sprintf(cpuid_buffer, "%ld", cpuid);
+		(void)hwgraph_edge_add( hwgraph_all_cpuids,
+							vhdl,
+							cpuid_buffer);
+	}
+}
+
+/*
+** If the specified device represents a node, return its
+** compact node ID; otherwise, return CNODEID_NONE.
+*/
+cnodeid_t
+nodevertex_to_cnodeid(vertex_hdl_t vhdl)
+{
+	int rv = 0;
+	arbitrary_info_t cnodeid = CNODEID_NONE;
+
+	rv = labelcl_info_get_LBL(vhdl, INFO_LBL_CNODEID, NULL, &cnodeid);
+
+	return((cnodeid_t)cnodeid);
+}
+
+void
+mark_nodevertex_as_node(vertex_hdl_t vhdl, cnodeid_t cnodeid)
+{
+	if (cnodeid == CNODEID_NONE)
+		return;
+
+	cnodeid_to_vertex(cnodeid) = vhdl;
+	labelcl_info_add_LBL(vhdl, INFO_LBL_CNODEID, INFO_DESC_EXPORT, 
+		(arbitrary_info_t)cnodeid);
+
+	{
+		char cnodeid_buffer[10];
+
+		if (hwgraph_all_cnodes == GRAPH_VERTEX_NONE) {
+			(void)hwgraph_path_add( hwgraph_root,
+						EDGE_LBL_NODENUM,
+						&hwgraph_all_cnodes);
+		}
+
+		sprintf(cnodeid_buffer, "%d", cnodeid);
+		(void)hwgraph_edge_add( hwgraph_all_cnodes,
+					vhdl,
+					cnodeid_buffer);
+	}
+}
+
+/*
+** If the specified device represents a CPU, return its cpuid;
+** otherwise, return CPU_NONE.
+*/
+cpuid_t
+cpuvertex_to_cpuid(vertex_hdl_t vhdl)
+{
+	arbitrary_info_t cpuid = CPU_NONE;
+
+	(void)labelcl_info_get_LBL(vhdl, INFO_LBL_CPUID, NULL, &cpuid);
+
+	return((cpuid_t)cpuid);
+}
+
+
+/*
+** dev_to_name converts a vertex_hdl_t into a canonical name.  If the vertex_hdl_t
+** represents a vertex in the hardware graph, it is converted in the
+** normal way for vertices.  If the vertex_hdl_t is an old vertex_hdl_t (one which
+** does not represent a hwgraph vertex), we synthesize a name based
+** on major/minor number.
+**
+** Usually returns a pointer to the original buffer, filled in as
+** appropriate.  If the buffer is too small to hold the entire name,
+** or if anything goes wrong while determining the name, dev_to_name
+** returns "UnknownDevice".
+*/
+char *
+dev_to_name(vertex_hdl_t dev, char *buf, uint buflen)
+{
+        return(vertex_to_name(dev, buf, buflen));
+}
+
+
diff -Nru a/arch/ia64/sn/io/hwgfs/interface.c b/arch/ia64/sn/io/hwgfs/interface.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/hwgfs/interface.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,353 @@
+/*
+ * Copyright (c) 2003 Silicon Graphics, Inc.  All Rights Reserved.
+ *
+ *  Portions based on Adam Richter's smalldevfs and thus
+ *  Copyright 2002-2003  Yggdrasil Computing, Inc.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like.  Any license provided herein, whether implied or
+ * otherwise, applies only to this software file.  Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA  94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/mount.h>
+#include <linux/namei.h>
+#include <linux/string.h>
+#include <linux/slab.h>
+#include <asm/sn/hwgfs.h>
+
+
+extern struct vfsmount *hwgfs_vfsmount;
+
+/* TODO: Move this to some .h file or, more likely, use a slightly
+   different interface from lookup_create. */
+extern struct dentry *lookup_create(struct nameidata *nd, int is_dir);
+
+static int
+walk_parents_mkdir(
+	const char		**path,
+	struct nameidata	*nd,
+	int			is_dir)
+{
+	char			*slash;
+	char			buf[strlen(*path)+1];
+	int			error;
+
+	while ((slash = strchr(*path, '/')) != NULL) {
+		int len = slash - *path;
+		memcpy(buf, *path, len);
+		buf[len] = '\0';
+
+		error = link_path_walk(buf, nd); 
+		if (unlikely(error))
+			return error;
+
+		nd->dentry = lookup_create(nd, is_dir);
+		if (unlikely(IS_ERR(nd->dentry)))
+			return PTR_ERR(nd->dentry);
+
+		if (!nd->dentry->d_inode)
+			error = vfs_mkdir(nd->dentry->d_parent->d_inode,
+					nd->dentry, 0755);
+		
+		up(&nd->dentry->d_parent->d_inode->i_sem);
+		if (unlikely(error))
+			return error;
+
+		*path += len + 1;
+	}
+
+	return 0;
+}
+
+/* On success, returns with parent_inode->i_sem taken. */
+static int
+hwgfs_decode(
+	hwgfs_handle_t		dir,
+	const char		*name,
+	int			is_dir,
+	struct inode		**parent_inode,
+	struct dentry		**dentry)
+{
+	struct nameidata	nd;
+	int			error;
+
+	if (!dir)
+		dir = hwgfs_vfsmount->mnt_sb->s_root;
+
+	memset(&nd, 0, sizeof(nd));
+	nd.flags = LOOKUP_PARENT;
+	nd.mnt = mntget(hwgfs_vfsmount);
+	nd.dentry = dget(dir);
+
+	error = walk_parents_mkdir(&name, &nd, is_dir);
+	if (unlikely(error))
+		return error;
+
+	error = link_path_walk(name, &nd);
+	if (unlikely(error))
+		return error;
+
+	*dentry = lookup_create(&nd, is_dir);
+
+	if (unlikely(IS_ERR(*dentry)))
+		return PTR_ERR(*dentry);
+	*parent_inode = (*dentry)->d_parent->d_inode;
+	return 0;
+}
+
+static int
+path_len(
+	struct dentry		*de,
+	struct dentry		*root)
+{
+	int			len = 0;
+
+	while (de != root) {
+		len += de->d_name.len + 1;	/* count the '/' */
+		de = de->d_parent;
+	}
+	return len;		/* -1 because we omit the leading '/',
+				   +1 because we include trailing '\0' */
+}
+
+int
+hwgfs_generate_path(
+	hwgfs_handle_t		de,
+	char			*path,
+	int			buflen)
+{
+	struct dentry		*hwgfs_root;
+	int			len;
+	char			*path_orig = path;
+
+	if (unlikely(de == NULL))
+		return -EINVAL;
+
+	hwgfs_root = hwgfs_vfsmount->mnt_sb->s_root;
+	if (unlikely(de == hwgfs_root))
+		return -EINVAL;
+
+	spin_lock(&dcache_lock);
+	len = path_len(de, hwgfs_root);
+	if (len > buflen) {
+		spin_unlock(&dcache_lock);
+		return -ENAMETOOLONG;
+	}
+
+	path += len - 1;
+	*path = '\0';
+
+	for (;;) {
+		path -= de->d_name.len;
+		memcpy(path, de->d_name.name, de->d_name.len);
+		de = de->d_parent;
+		if (de == hwgfs_root)
+			break;
+		*(--path) = '/';
+	}
+		
+	spin_unlock(&dcache_lock);
+	BUG_ON(path != path_orig);
+	return 0;
+}
+
+hwgfs_handle_t
+hwgfs_register(
+	hwgfs_handle_t		dir,
+	const char		*name,
+	unsigned int		flags,
+	unsigned int		major,
+	unsigned int		minor,
+	umode_t			mode,
+	void			*ops,
+	void			*info)
+{
+	dev_t			devnum = MKDEV(major, minor);
+	struct inode		*parent_inode;
+	struct dentry		*dentry;
+	int			error;
+
+	error = hwgfs_decode(dir, name, 0, &parent_inode, &dentry);
+	if (likely(!error)) {
+		error = vfs_mknod(parent_inode, dentry, mode, devnum);
+		if (likely(!error)) {
+			/*
+			 * Do this inside parents i_sem to avoid racing
+			 * with lookups.
+			 */
+			if (S_ISCHR(mode))
+				dentry->d_inode->i_fop = ops;
+			dentry->d_fsdata = info;
+			up(&parent_inode->i_sem);
+		} else {
+			up(&parent_inode->i_sem);
+			dput(dentry);
+			dentry = NULL;
+                }
+	}
+
+	return dentry;
+}
+
+int
+hwgfs_mk_symlink(
+	hwgfs_handle_t		dir,
+	const char		*name,
+	unsigned int		flags,
+	const char		*link,
+	hwgfs_handle_t		*handle,
+	void			*info)
+{
+	struct inode		*parent_inode;
+	struct dentry		*dentry;
+	int			error;
+
+	error = hwgfs_decode(dir, name, 0, &parent_inode, &dentry);
+	if (likely(!error)) {
+		error = vfs_symlink(parent_inode, dentry, link);
+		dentry->d_fsdata = info;
+		if (handle)
+			*handle = dentry;
+		up(&parent_inode->i_sem);
+		/* dput(dentry); */
+	}
+	return error;
+}
+
+hwgfs_handle_t
+hwgfs_mk_dir(
+	hwgfs_handle_t		dir,
+	const char		*name,
+	void			*info)
+{
+	struct inode		*parent_inode;
+	struct dentry		*dentry;
+	int			error;
+
+	error = hwgfs_decode(dir, name, 1, &parent_inode, &dentry);
+	if (likely(!error)) {
+		error = vfs_mkdir(parent_inode, dentry, 0755);
+		up(&parent_inode->i_sem);
+
+		if (unlikely(error)) {
+			dput(dentry);
+			dentry = NULL;
+		} else {
+			dentry->d_fsdata = info;
+		}
+	}
+	return dentry;
+}
+
+void
+hwgfs_unregister(
+	hwgfs_handle_t		de)
+{
+	struct inode		*parent_inode = de->d_parent->d_inode;
+
+	if (S_ISDIR(de->d_inode->i_mode))
+		vfs_rmdir(parent_inode, de);
+	else
+		vfs_unlink(parent_inode, de);
+}
+
+/* XXX: this function is utterly bogus.  Every use of it is racy and the
+        prototype is stupid.  You have been warned.  --hch.  */
+hwgfs_handle_t
+hwgfs_find_handle(
+	hwgfs_handle_t		base,
+	const char		*name,
+	unsigned int		major,		/* IGNORED */
+	unsigned int		minor,		/* IGNORED */
+	char			type,		/* IGNORED */
+	int			traverse_symlinks)
+{
+	struct dentry		*dentry = NULL;
+	struct nameidata	nd;
+	int			error;
+
+	BUG_ON(*name=='/');
+
+	memset(&nd, 0, sizeof(nd));
+
+	nd.mnt = mntget(hwgfs_vfsmount);
+	nd.dentry = dget(base ? base : hwgfs_vfsmount->mnt_sb->s_root);
+	if (traverse_symlinks)
+		nd.flags = LOOKUP_FOLLOW;
+
+	error = link_path_walk(name, &nd);
+	if (likely(!error)) {
+		dentry = nd.dentry;
+		path_release(&nd);		/* stale data from here! */
+	}
+
+	return dentry;
+}
+
+hwgfs_handle_t
+hwgfs_get_parent(
+	hwgfs_handle_t		de)
+{
+	struct dentry		*parent;
+
+	spin_lock(&de->d_lock);
+	parent = de->d_parent;
+	spin_unlock(&de->d_lock);
+
+	return parent;
+}
+
+int
+hwgfs_set_info(
+	hwgfs_handle_t		de,
+	void			*info)
+{
+	if (unlikely(de == NULL))
+		return -EINVAL;
+	de->d_fsdata = info;
+	return 0;
+}
+
+void *
+hwgfs_get_info(
+	hwgfs_handle_t		de)
+{
+	return de->d_fsdata;
+}
+
+EXPORT_SYMBOL(hwgfs_generate_path);
+EXPORT_SYMBOL(hwgfs_register);
+EXPORT_SYMBOL(hwgfs_unregister);
+EXPORT_SYMBOL(hwgfs_mk_symlink);
+EXPORT_SYMBOL(hwgfs_mk_dir);
+EXPORT_SYMBOL(hwgfs_find_handle);
+EXPORT_SYMBOL(hwgfs_get_parent);
+EXPORT_SYMBOL(hwgfs_set_info);
+EXPORT_SYMBOL(hwgfs_get_info);
diff -Nru a/arch/ia64/sn/io/hwgfs/invent_stub.c b/arch/ia64/sn/io/hwgfs/invent_stub.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/hwgfs/invent_stub.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,148 @@
+/* $Id$
+ *
+ * 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) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+/*
+ * Hardware Inventory
+ *
+ * See sys/sn/invent.h for an explanation of the hardware inventory contents.
+ *
+ */
+#include <linux/types.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/hwgfs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+#include <asm/sn/invent.h>
+
+void
+inventinit(void)
+{
+}
+
+/*
+ * For initializing/updating an inventory entry.
+ */
+void
+replace_in_inventory(
+	inventory_t *pinv, int class, int type,
+	int controller, int unit, int state)
+{
+}
+
+/*
+ * Inventory addition 
+ *
+ * XXX NOTE: Currently must be called after dynamic memory allocator is
+ * initialized.
+ *
+ */
+void
+add_to_inventory(int class, int type, int controller, int unit, int state)
+{
+}
+
+
+/*
+ * Inventory retrieval 
+ *
+ * These two routines are intended to prevent the caller from having to know
+ * the internal structure of the inventory table.
+ *
+ * The caller of get_next_inventory is supposed to call start_scan_invent
+ * before the irst call to get_next_inventory, and the caller is required
+ * to call end_scan_invent after the last call to get_next_inventory.
+ */
+inventory_t *
+get_next_inventory(invplace_t *place)
+{
+	return((inventory_t *) NULL);
+}
+
+/* ARGSUSED */
+int
+get_sizeof_inventory(int abi)
+{
+	return sizeof(inventory_t);
+}
+
+/* Must be called prior to first call to get_next_inventory */
+void
+start_scan_inventory(invplace_t *iplace)
+{
+}
+
+/* Must be called after last call to get_next_inventory */
+void
+end_scan_inventory(invplace_t *iplace)
+{
+}
+
+/*
+ * Hardware inventory scanner.
+ *
+ * Calls fun() for every entry in inventory list unless fun() returns something
+ * other than 0.
+ */
+int
+scaninvent(int (*fun)(inventory_t *, void *), void *arg)
+{
+	return 0;
+}
+
+/*
+ * Find a particular inventory object
+ *
+ * pinv can be a pointer to an inventory entry and the search will begin from
+ * there, or it can be 0 in which case the search starts at the beginning.
+ * A -1 for any of the other arguments is a wildcard (i.e. it always matches).
+ */
+inventory_t *
+find_inventory(inventory_t *pinv, int class, int type, int controller,
+	       int unit, int state)
+{
+	return((inventory_t *) NULL);
+}
+
+
+/*
+** Retrieve inventory data associated with a device.
+*/
+inventory_t *
+device_inventory_get_next(	vertex_hdl_t device,
+				invplace_t *invplace)
+{
+		return((inventory_t *) NULL);
+}
+
+
+/*
+** Associate canonical inventory information with a device (and
+** add it to the general inventory).
+*/
+void
+device_inventory_add(	vertex_hdl_t device,
+			int class, 
+			int type, 
+			major_t controller, 
+			minor_t unit, 
+			int state)
+{
+}
+
+int
+device_controller_num_get(vertex_hdl_t device)
+{
+	return (0);
+}
+
+void
+device_controller_num_set(vertex_hdl_t device, int contr_num)
+{
+}
diff -Nru a/arch/ia64/sn/io/hwgfs/labelcl.c b/arch/ia64/sn/io/hwgfs/labelcl.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/hwgfs/labelcl.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,657 @@
+/*  labelcl - SGI's Hwgraph Compatibility Layer.
+ *
+ * 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) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
+*/
+
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/string.h>
+#include <linux/sched.h>                /* needed for smp_lock.h :( */
+#include <linux/smp_lock.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/hwgfs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/labelcl.h>
+
+/*
+** Very simple and dumb string table that supports only find/insert.
+** In practice, if this table gets too large, we may need a more
+** efficient data structure.   Also note that currently there is no 
+** way to delete an item once it's added.  Therefore, name collision 
+** will return an error.
+*/
+
+struct string_table label_string_table;
+
+
+
+/*
+ * string_table_init - Initialize the given string table.
+ */
+void
+string_table_init(struct string_table *string_table)
+{
+	string_table->string_table_head = NULL;
+	string_table->string_table_generation = 0;
+
+	/*
+	 * We nedd to initialize locks here!
+	 */
+
+	return;
+}
+
+
+/*
+ * string_table_destroy - Destroy the given string table.
+ */
+void
+string_table_destroy(struct string_table *string_table)
+{
+	struct string_table_item *item, *next_item;
+
+	item = string_table->string_table_head;
+	while (item) {
+		next_item = item->next;
+
+		STRTBL_FREE(item);
+		item = next_item;
+	}
+
+	/*
+	 * We need to destroy whatever lock we have here
+	 */
+
+	return;
+}
+
+
+
+/*
+ * string_table_insert - Insert an entry in the string table .. duplicate 
+ *	names are not allowed.
+ */
+char *
+string_table_insert(struct string_table *string_table, char *name)
+{
+	struct string_table_item *item, *new_item = NULL, *last_item = NULL;
+
+again:
+	/*
+	 * Need to lock the table ..
+	 */
+	item = string_table->string_table_head;
+	last_item = NULL;
+
+	while (item) {
+		if (!strcmp(item->string, name)) {
+			/*
+			 * If we allocated space for the string and the found that
+			 * someone else already entered it into the string table,
+			 * free the space we just allocated.
+			 */
+			if (new_item)
+				STRTBL_FREE(new_item);
+
+
+			/*
+			 * Search optimization: move the found item to the head
+			 * of the list.
+			 */
+			if (last_item != NULL) {
+				last_item->next = item->next;
+				item->next = string_table->string_table_head;
+				string_table->string_table_head = item;
+			}
+			goto out;
+		}
+		last_item = item;
+		item=item->next;
+	}
+
+	/*
+	 * name was not found, so add it to the string table.
+	 */
+	if (new_item == NULL) {
+		long old_generation = string_table->string_table_generation;
+
+		new_item = STRTBL_ALLOC(strlen(name));
+
+		strcpy(new_item->string, name);
+
+		/*
+		 * While we allocated memory for the new string, someone else 
+		 * changed the string table.
+		 */
+		if (old_generation != string_table->string_table_generation) {
+			goto again;
+		}
+	} else {
+		/* At this we only have the string table lock in access mode.
+		 * Promote the access lock to an update lock for the string
+		 * table insertion below.
+		 */
+			long old_generation = 
+				string_table->string_table_generation;
+
+			/*
+			 * After we did the unlock and wer waiting for update
+			 * lock someone could have potentially updated
+			 * the string table. Check the generation number
+			 * for this case. If it is the case we have to
+			 * try all over again.
+			 */
+			if (old_generation != 
+			    string_table->string_table_generation) {
+				goto again;
+			}
+		}
+
+	/*
+	 * At this point, we're committed to adding new_item to the string table.
+	 */
+	new_item->next = string_table->string_table_head;
+	item = string_table->string_table_head = new_item;
+	string_table->string_table_generation++;
+
+out:
+	/*
+	 * Need to unlock here.
+	 */
+	return(item->string);
+}
+
+/*
+ * labelcl_info_create - Creates the data structure that will hold the
+ *	device private information asscoiated with a entry.
+ *	The pointer to this structure is what gets stored in the 
+ *	(void * info).
+ */
+labelcl_info_t *
+labelcl_info_create()
+{
+
+	labelcl_info_t *new = NULL;
+
+	/* Initial allocation does not include any area for labels */
+	if ( ( new = (labelcl_info_t *)kmalloc (sizeof(labelcl_info_t), GFP_KERNEL) ) == NULL )
+		return NULL;
+
+	memset (new, 0, sizeof(labelcl_info_t));
+	new->hwcl_magic = LABELCL_MAGIC;
+	return( new);
+
+}
+
+/*
+ * labelcl_info_destroy - Frees the data structure that holds the
+ *      device private information asscoiated with a entry.  This 
+ *	data structure was created by device_info_create().
+ *
+ *	The caller is responsible for nulling the (void *info) in the 
+ *	corresponding entry.
+ */
+int
+labelcl_info_destroy(labelcl_info_t *labelcl_info)
+{
+
+	if (labelcl_info == NULL)
+		return(0);
+
+	/* Free the label list */
+	if (labelcl_info->label_list)
+		kfree(labelcl_info->label_list);
+
+	/* Now free the label info area */
+	labelcl_info->hwcl_magic = 0;
+	kfree(labelcl_info);
+
+	return(0);
+}
+
+/*
+ * labelcl_info_add_LBL - Adds a new label entry in the labelcl info 
+ *	structure.
+ *
+ *	Error is returned if we find another label with the same name.
+ */
+int
+labelcl_info_add_LBL(vertex_hdl_t de,
+			char *info_name,
+			arb_info_desc_t info_desc,
+			arbitrary_info_t info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	int new_label_list_size;
+	label_info_t *old_label_list, *new_label_list = NULL;
+	char *name;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+        labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	if (info_name == NULL)
+		return(-1);
+
+	if (strlen(info_name) >= LABEL_LENGTH_MAX)
+		return(-1);
+
+	name = string_table_insert(&label_string_table, info_name);
+
+	num_labels = labelcl_info->num_labels;
+	new_label_list_size = sizeof(label_info_t) * (num_labels+1);
+
+	/*
+	 * Create a new label info area.
+	 */
+	if (new_label_list_size != 0) {
+		new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
+
+		if (new_label_list == NULL)
+			return(-1);
+	}
+
+	/*
+	 * At this point, we are committed to adding the labelled info, 
+	 * if there isn't already information there with the same name.
+	 */
+	old_label_list = labelcl_info->label_list;
+
+	/* 
+	 * Look for matching info name.
+	 */
+	for (i=0; i<num_labels; i++) {
+		if (!strcmp(info_name, old_label_list[i].name)) {
+			/* Not allowed to add duplicate labelled info names. */
+			kfree(new_label_list);
+			return(-1);
+		}
+		new_label_list[i] = old_label_list[i]; /* structure copy */
+	}
+
+	new_label_list[num_labels].name = name;
+	new_label_list[num_labels].desc = info_desc;
+	new_label_list[num_labels].info = info;
+
+	labelcl_info->num_labels = num_labels+1;
+	labelcl_info->label_list = new_label_list;
+
+	if (old_label_list != NULL)
+		kfree(old_label_list);
+
+	return(0);
+}
+
+/*
+ * labelcl_info_remove_LBL - Remove a label entry.
+ */
+int
+labelcl_info_remove_LBL(vertex_hdl_t de,
+			 char *info_name,
+			 arb_info_desc_t *info_desc,
+			 arbitrary_info_t *info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	int new_label_list_size;
+	label_info_t *old_label_list, *new_label_list = NULL;
+	arb_info_desc_t label_desc_found;
+	arbitrary_info_t label_info_found;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	num_labels = labelcl_info->num_labels;
+	if (num_labels == 0) {
+		return(-1);
+	}
+
+	/*
+	 * Create a new info area.
+	 */
+	new_label_list_size = sizeof(label_info_t) * (num_labels-1);
+	if (new_label_list_size) {
+		new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
+		if (new_label_list == NULL)
+			return(-1);
+	}
+
+	/*
+	 * At this point, we are committed to removing the labelled info, 
+	 * if it still exists.
+	 */
+	old_label_list = labelcl_info->label_list;
+
+	/* 
+	 * Find matching info name.
+	 */
+	for (i=0; i<num_labels; i++) {
+		if (!strcmp(info_name, old_label_list[i].name)) {
+			label_desc_found = old_label_list[i].desc;
+			label_info_found = old_label_list[i].info;
+			goto found;
+		}
+		if (i < num_labels-1) /* avoid walking off the end of the new vertex */
+			new_label_list[i] = old_label_list[i]; /* structure copy */
+	}
+
+	/* The named info doesn't exist. */
+	if (new_label_list)
+		kfree(new_label_list);
+
+	return(-1);
+
+found:
+	/* Finish up rest of labelled info */
+	for (i=i+1; i<num_labels; i++)
+		new_label_list[i-1] = old_label_list[i]; /* structure copy */
+
+	labelcl_info->num_labels = num_labels+1;
+	labelcl_info->label_list = new_label_list;
+
+	kfree(old_label_list);
+
+	if (info != NULL)
+		*info = label_info_found;
+
+	if (info_desc != NULL)
+		*info_desc = label_desc_found;
+
+	return(0);
+}
+
+
+/*
+ * labelcl_info_replace_LBL - Replace an existing label entry with the 
+ *	given new information.
+ *
+ *	Label entry must exist.
+ */
+int
+labelcl_info_replace_LBL(vertex_hdl_t de,
+			char *info_name,
+			arb_info_desc_t info_desc,
+			arbitrary_info_t info,
+			arb_info_desc_t *old_info_desc,
+			arbitrary_info_t *old_info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	label_info_t *label_list;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	num_labels = labelcl_info->num_labels;
+	if (num_labels == 0) {
+		return(-1);
+	}
+
+	if (info_name == NULL)
+		return(-1);
+
+	label_list = labelcl_info->label_list;
+
+	/* 
+	 * Verify that information under info_name already exists.
+	 */
+	for (i=0; i<num_labels; i++)
+		if (!strcmp(info_name, label_list[i].name)) {
+			if (old_info != NULL)
+				*old_info = label_list[i].info;
+
+			if (old_info_desc != NULL)
+				*old_info_desc = label_list[i].desc;
+
+			label_list[i].info = info;
+			label_list[i].desc = info_desc;
+
+			return(0);
+		}
+
+
+	return(-1);
+}
+
+/*
+ * labelcl_info_get_LBL - Retrieve and return the information for the 
+ *	given label entry.
+ */
+int
+labelcl_info_get_LBL(vertex_hdl_t de,
+		      char *info_name,
+		      arb_info_desc_t *info_desc,
+		      arbitrary_info_t *info)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	int num_labels;
+	label_info_t *label_list;
+	int i;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	num_labels = labelcl_info->num_labels;
+	if (num_labels == 0) {
+		return(-1);
+	}
+
+	label_list = labelcl_info->label_list;
+
+	/* 
+	 * Find information under info_name.
+	 */
+	for (i=0; i<num_labels; i++)
+		if (!strcmp(info_name, label_list[i].name)) {
+			if (info != NULL)
+				*info = label_list[i].info;
+			if (info_desc != NULL)
+				*info_desc = label_list[i].desc;
+
+			return(0);
+		}
+
+	return(-1);
+}
+
+/*
+ * labelcl_info_get_next_LBL - returns the next label entry on the list.
+ */
+int
+labelcl_info_get_next_LBL(vertex_hdl_t de,
+			   char *buffer,
+			   arb_info_desc_t *info_descp,
+			   arbitrary_info_t *infop,
+			   labelcl_info_place_t *placeptr)
+{
+	labelcl_info_t	*labelcl_info = NULL;
+	uint which_info;
+	label_info_t *label_list;
+
+	if ((buffer == NULL) && (infop == NULL))
+		return(-1);
+
+	if (placeptr == NULL)
+		return(-1);
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	which_info = *placeptr;
+
+	if (which_info >= labelcl_info->num_labels) {
+		return(-1);
+	}
+
+	label_list = (label_info_t *) labelcl_info->label_list;
+
+	if (buffer != NULL)
+		strcpy(buffer, label_list[which_info].name);
+
+	if (infop)
+		*infop = label_list[which_info].info;
+
+	if (info_descp)
+		*info_descp = label_list[which_info].desc;
+
+	*placeptr = which_info + 1;
+
+	return(0);
+}
+
+
+int
+labelcl_info_replace_IDX(vertex_hdl_t de,
+			int index,
+			arbitrary_info_t info,
+			arbitrary_info_t *old_info)
+{
+	arbitrary_info_t *info_list_IDX;
+	labelcl_info_t	*labelcl_info = NULL;
+
+	if (de == NULL) {
+		printk(KERN_ALERT "labelcl: NULL handle given.\n");
+		return(-1);
+	}
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL) {
+		printk(KERN_ALERT "labelcl: Entry %p does not have info pointer.\n", (void *)de);
+		return(-1);
+	}
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
+		return(-1);
+
+	/*
+	 * Replace information at the appropriate index in this vertex with 
+	 * the new info.
+	 */
+	info_list_IDX = labelcl_info->IDX_list;
+	if (old_info != NULL)
+		*old_info = info_list_IDX[index];
+	info_list_IDX[index] = info;
+
+	return(0);
+
+}
+
+/*
+ * labelcl_info_connectpt_set - Sets the connectpt.
+ */
+int
+labelcl_info_connectpt_set(hwgfs_handle_t de,
+			  hwgfs_handle_t connect_de)
+{
+	arbitrary_info_t old_info;
+	int	rv;
+
+	rv = labelcl_info_replace_IDX(de, HWGRAPH_CONNECTPT, 
+		(arbitrary_info_t) connect_de, &old_info);
+
+	if (rv) {
+		return(rv);
+	}
+
+	return(0);
+}
+
+
+/*
+ * labelcl_info_get_IDX - Returns the information pointed at by index.
+ *
+ */
+int
+labelcl_info_get_IDX(vertex_hdl_t de,
+			int index,
+			arbitrary_info_t *info)
+{
+	arbitrary_info_t *info_list_IDX;
+	labelcl_info_t	*labelcl_info = NULL;
+
+	if (de == NULL)
+		return(-1);
+
+	labelcl_info = hwgfs_get_info(de);
+	if (labelcl_info == NULL)
+		return(-1);
+
+	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
+		return(-1);
+
+	if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
+		return(-1);
+
+	/*
+	 * Return information at the appropriate index in this vertex.
+	 */
+	info_list_IDX = labelcl_info->IDX_list;
+	if (info != NULL)
+		*info = info_list_IDX[index];
+
+	return(0);
+}
+
+/*
+ * labelcl_info_connectpt_get - Retrieve the connect point for a device entry.
+ */
+hwgfs_handle_t
+labelcl_info_connectpt_get(hwgfs_handle_t de)
+{
+	int rv;
+	arbitrary_info_t info;
+
+	rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
+	if (rv)
+		return(NULL);
+
+	return((hwgfs_handle_t) info);
+}
diff -Nru a/arch/ia64/sn/io/hwgfs/ramfs.c b/arch/ia64/sn/io/hwgfs/ramfs.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/hwgfs/ramfs.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,233 @@
+/*
+ * Copyright (c) 2003 Silicon Graphics, Inc.  All Rights Reserved.
+ *
+ *  Mostly shameless copied from Linus Torvalds' ramfs and thus
+ *  Copyright (C) 2000 Linus Torvalds.
+ *                2000 Transmeta Corp.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like.  Any license provided herein, whether implied or
+ * otherwise, applies only to this software file.  Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write the Free Software Foundation, Inc., 59
+ * Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information: Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA  94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/SGIGPLNoticeExplan/
+ */
+
+#include <linux/module.h>
+#include <linux/backing-dev.h>
+#include <linux/fs.h>
+#include <linux/pagemap.h>
+#include <linux/init.h>
+#include <linux/string.h>
+#include <asm/uaccess.h>
+
+/* some random number */
+#define HWGFS_MAGIC	0x12061983
+
+static struct super_operations hwgfs_ops;
+static struct address_space_operations hwgfs_aops;
+static struct file_operations hwgfs_file_operations;
+static struct inode_operations hwgfs_file_inode_operations;
+static struct inode_operations hwgfs_dir_inode_operations;
+
+static struct backing_dev_info hwgfs_backing_dev_info = {
+	.ra_pages       = 0,	/* No readahead */
+	.memory_backed  = 1,	/* Does not contribute to dirty memory */
+};
+
+struct inode *hwgfs_get_inode(struct super_block *sb, int mode, dev_t dev)
+{
+	struct inode * inode = new_inode(sb);
+
+	if (inode) {
+		inode->i_mode = mode;
+		inode->i_uid = current->fsuid;
+		inode->i_gid = current->fsgid;
+		inode->i_blksize = PAGE_CACHE_SIZE;
+		inode->i_blocks = 0;
+		inode->i_rdev = NODEV;
+		inode->i_mapping->a_ops = &hwgfs_aops;
+		inode->i_mapping->backing_dev_info = &hwgfs_backing_dev_info;
+		inode->i_atime = inode->i_mtime = inode->i_ctime = CURRENT_TIME;
+		switch (mode & S_IFMT) {
+		default:
+			init_special_inode(inode, mode, dev);
+			break;
+		case S_IFREG:
+			inode->i_op = &hwgfs_file_inode_operations;
+			inode->i_fop = &hwgfs_file_operations;
+			break;
+		case S_IFDIR:
+			inode->i_op = &hwgfs_dir_inode_operations;
+			inode->i_fop = &simple_dir_operations;
+			inode->i_nlink++;
+			break;
+		case S_IFLNK:
+			inode->i_op = &page_symlink_inode_operations;
+			break;
+		}
+	}
+	return inode;
+}
+
+static int hwgfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
+{
+	struct inode * inode = hwgfs_get_inode(dir->i_sb, mode, dev);
+	int error = -ENOSPC;
+
+	if (inode) {
+		d_instantiate(dentry, inode);
+		dget(dentry);		/* Extra count - pin the dentry in core */
+		error = 0;
+	}
+	return error;
+}
+
+static int hwgfs_mkdir(struct inode * dir, struct dentry * dentry, int mode)
+{
+	return hwgfs_mknod(dir, dentry, mode | S_IFDIR, 0);
+}
+
+static int hwgfs_create(struct inode *dir, struct dentry *dentry, int mode)
+{
+	return hwgfs_mknod(dir, dentry, mode | S_IFREG, 0);
+}
+
+static int hwgfs_symlink(struct inode * dir, struct dentry *dentry, const char * symname)
+{
+	struct inode *inode;
+	int error = -ENOSPC;
+
+	inode = hwgfs_get_inode(dir->i_sb, S_IFLNK|S_IRWXUGO, 0);
+	if (inode) {
+		int l = strlen(symname)+1;
+		error = page_symlink(inode, symname, l);
+		if (!error) {
+			d_instantiate(dentry, inode);
+			dget(dentry);
+		} else
+			iput(inode);
+	}
+	return error;
+}
+
+static struct address_space_operations hwgfs_aops = {
+	.readpage	= simple_readpage,
+	.prepare_write	= simple_prepare_write,
+	.commit_write	= simple_commit_write
+};
+
+static struct file_operations hwgfs_file_operations = {
+	.read		= generic_file_read,
+	.write		= generic_file_write,
+	.mmap		= generic_file_mmap,
+	.fsync		= simple_sync_file,
+	.sendfile	= generic_file_sendfile,
+};
+
+static struct inode_operations hwgfs_file_inode_operations = {
+	.getattr	= simple_getattr,
+};
+
+static struct inode_operations hwgfs_dir_inode_operations = {
+	.create		= hwgfs_create,
+	.lookup		= simple_lookup,
+	.link		= simple_link,
+	.unlink		= simple_unlink,
+	.symlink	= hwgfs_symlink,
+	.mkdir		= hwgfs_mkdir,
+	.rmdir		= simple_rmdir,
+	.mknod		= hwgfs_mknod,
+	.rename		= simple_rename,
+};
+
+static struct super_operations hwgfs_ops = {
+	.statfs		= simple_statfs,
+	.drop_inode	= generic_delete_inode,
+};
+
+static int hwgfs_fill_super(struct super_block * sb, void * data, int silent)
+{
+	struct inode * inode;
+	struct dentry * root;
+
+	sb->s_blocksize = PAGE_CACHE_SIZE;
+	sb->s_blocksize_bits = PAGE_CACHE_SHIFT;
+	sb->s_magic = HWGFS_MAGIC;
+	sb->s_op = &hwgfs_ops;
+	inode = hwgfs_get_inode(sb, S_IFDIR | 0755, 0);
+	if (!inode)
+		return -ENOMEM;
+
+	root = d_alloc_root(inode);
+	if (!root) {
+		iput(inode);
+		return -ENOMEM;
+	}
+	sb->s_root = root;
+	return 0;
+}
+
+static struct super_block *hwgfs_get_sb(struct file_system_type *fs_type,
+	int flags, char *dev_name, void *data)
+{
+	return get_sb_single(fs_type, flags, data, hwgfs_fill_super);
+}
+
+static struct file_system_type hwgfs_fs_type = {
+	.owner		= THIS_MODULE,
+	.name           = "hwgfs",
+	.get_sb         = hwgfs_get_sb,
+	.kill_sb        = kill_litter_super,
+};
+
+struct vfsmount *hwgfs_vfsmount;
+
+int __init init_hwgfs_fs(void)
+{
+	int error;
+
+	error = register_filesystem(&hwgfs_fs_type);
+	if (error)
+		return error;
+
+	hwgfs_vfsmount = kern_mount(&hwgfs_fs_type);
+	if (IS_ERR(hwgfs_vfsmount))
+		goto fail;
+	return 0;
+
+fail:
+	unregister_filesystem(&hwgfs_fs_type);
+	return PTR_ERR(hwgfs_vfsmount);
+}
+
+static void __exit exit_hwgfs_fs(void)
+{
+	unregister_filesystem(&hwgfs_fs_type);
+}
+
+MODULE_LICENSE("GPL");
+
+module_init(init_hwgfs_fs)
+module_exit(exit_hwgfs_fs)
diff -Nru a/arch/ia64/sn/io/ifconfig_net.c b/arch/ia64/sn/io/ifconfig_net.c
--- a/arch/ia64/sn/io/ifconfig_net.c	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,298 +0,0 @@
-/* $Id: ifconfig_net.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * 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.
- *
- *  ifconfig_net - SGI's Persistent Network Device names.
- *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/pci.h>
-#include <linux/netdevice.h>
-#include <linux/etherdevice.h>
-#include <linux/skbuff.h>
-
-#include <asm/sn/sgi.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/ifconfig_net.h>
-
-#define SGI_IFCONFIG_NET "SGI-PERSISTENT NETWORK DEVICE NAME DRIVER"
-#define SGI_IFCONFIG_NET_VERSION "1.0"
-
-/*
- * Some Global definitions.
- */
-devfs_handle_t ifconfig_net_handle = NULL;
-unsigned long ifconfig_net_debug = 0;
-
-/*
- * ifconfig_net_open - Opens the special device node "/devhw/.ifconfig_net".
- */
-static int ifconfig_net_open(struct inode * inode, struct file * filp)
-{
-	if (ifconfig_net_debug) {
-        	printk("ifconfig_net_open called.\n");
-	}
-
-        return(0);
-
-}
-
-/*
- * ifconfig_net_close - Closes the special device node "/devhw/.ifconfig_net".
- */
-static int ifconfig_net_close(struct inode * inode, struct file * filp)
-{
-
-	if (ifconfig_net_debug) {
-        	printk("ifconfig_net_close called.\n");
-	}
-
-        return(0);
-}
-
-/*
- * assign_ifname - Assign the next available interface name from the persistent list.
- */
-void
-assign_ifname(struct net_device *dev,
-		  struct ifname_num *ifname_num)
-
-{
-
-	/*
-	 * Handle eth devices.
-	 */
-        if ( (memcmp(dev->name, "eth", 3) == 0) ) {
-		if (ifname_num->next_eth != -1) {
-			/*
-			 * Assign it the next available eth interface number. 
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "eth%d", (int)ifname_num->next_eth);
-			ifname_num->next_eth++;
-		} 
-
-                return;
-        }
-
-	/*
-	 * Handle fddi devices.
-	 */
-	if ( (memcmp(dev->name, "fddi", 4) == 0) ) {
-		if (ifname_num->next_fddi != -1) {
-			/*
-			 * Assign it the next available fddi interface number.
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "fddi%d", (int)ifname_num->next_fddi);
-			ifname_num->next_fddi++;
-		}
-
-		return;
-	}
-
-	/*
-	 * Handle hip devices.
-	 */
-	if ( (memcmp(dev->name, "hip", 3) == 0) ) {
-		if (ifname_num->next_hip != -1) {
-			/*
-			 * Assign it the next available hip interface number.
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "hip%d", (int)ifname_num->next_hip);
-			ifname_num->next_hip++;
-		}
-
-		return;
-	}
-
-	/*
-	 * Handle tr devices.
-	 */
-	if ( (memcmp(dev->name, "tr", 2) == 0) ) {
-		if (ifname_num->next_tr != -1) {
-			/*
-			 * Assign it the next available tr interface number.
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "tr%d", (int)ifname_num->next_tr);
-			ifname_num->next_tr++;
-		}
-
-		return;
-	}
-
-	/*
-	 * Handle fc devices.
-	 */
-	if ( (memcmp(dev->name, "fc", 2) == 0) ) {
-		if (ifname_num->next_fc != -1) {
-			/*
-			 * Assign it the next available fc interface number.
-			 */
-			memset(dev->name, 0, strlen(dev->name));
-			sprintf(dev->name, "fc%d", (int)ifname_num->next_fc);
-			ifname_num->next_fc++;
-		}
-
-		return;
-	}
-}
-
-/*
- * find_persistent_ifname: Returns the entry that was seen in previous boot.
- */
-struct ifname_MAC *
-find_persistent_ifname(struct net_device *dev,
-	struct ifname_MAC *ifname_MAC)
-
-{
-
-	while (ifname_MAC->addr_len) {
-		if (memcmp(dev->dev_addr, ifname_MAC->dev_addr, dev->addr_len) == 0)
-			return(ifname_MAC);
-
-		ifname_MAC++;
-	}
-
-	return(NULL);
-}
-
-/*
- * ifconfig_net_ioctl: ifconfig_net driver ioctl interface.
- */
-static int ifconfig_net_ioctl(struct inode * inode, struct file * file,
-        unsigned int cmd, unsigned long arg)
-{
-
-	extern struct net_device *__dev_get_by_name(const char *);
-#ifdef CONFIG_NET
-	struct net_device *dev;
-	struct ifname_MAC *found;
-	char temp[64];
-#endif
-	struct ifname_MAC *ifname_MAC;
-	struct ifname_MAC *new_devices, *temp_new_devices;
-	struct ifname_num *ifname_num;
-	unsigned long size;
-
-
-	if (ifconfig_net_debug) {
-		printk("HCL: hcl_ioctl called.\n");
-	}
-
-	/*
-	 * Read in the header and see how big of a buffer we really need to 
-	 * allocate.
-	 */
-	ifname_num = (struct ifname_num *) kmalloc(sizeof(struct ifname_num), 
-			GFP_KERNEL);
-	copy_from_user( ifname_num, (char *) arg, sizeof(struct ifname_num));
-	size = ifname_num->size;
-	kfree(ifname_num);
-	ifname_num = (struct ifname_num *) kmalloc(size, GFP_KERNEL);
-	ifname_MAC = (struct ifname_MAC *) ((char *)ifname_num + (sizeof(struct ifname_num)) );
-
-	copy_from_user( ifname_num, (char *) arg, size);
-	new_devices =  kmalloc(size - sizeof(struct ifname_num), GFP_KERNEL);
-	temp_new_devices = new_devices;
-
-	memset(new_devices, 0, size - sizeof(struct ifname_num));
-
-#ifdef CONFIG_NET
-	/*
-	 * Go through the net device entries and make them persistent!
-	 */
-	for (dev = dev_base; dev != NULL; dev = dev->next) {
-		/*
-		 * Skip NULL entries or "lo"
-		 */
-		if ( (dev->addr_len == 0) || ( !strncmp(dev->name, "lo", strlen(dev->name))) ){
-			continue;
-		}
-
-		/*
-		 * See if we have a persistent interface name for this device.
-		 */
-		found = NULL;
-		found = find_persistent_ifname(dev, ifname_MAC);
-		if (found) {
-			strcpy(dev->name, found->name);
-		} else {
-			/* Never seen this before .. */
-			assign_ifname(dev, ifname_num);
-
-			/* 
-			 * Save the information for the next boot.
-			 */
- 			sprintf(temp,"%s %02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
-				dev->dev_addr[0],  dev->dev_addr[1],  dev->dev_addr[2],
-				dev->dev_addr[3],  dev->dev_addr[4],  dev->dev_addr[5]);
-			strcpy(temp_new_devices->name, dev->name);
-			temp_new_devices->addr_len = dev->addr_len;
-			memcpy(temp_new_devices->dev_addr, dev->dev_addr, dev->addr_len);
-			temp_new_devices++;
-		}
-		
-	}
-#endif
-
-	/*
-	 * Copy back to the User Buffer area any new devices encountered.
-	 */
-	copy_to_user((char *)arg + (sizeof(struct ifname_num)), new_devices, 
-			size - sizeof(struct ifname_num));
-
-	return(0);
-
-}
-
-struct file_operations ifconfig_net_fops = {
-	ioctl:ifconfig_net_ioctl,	/* ioctl */
-	open:ifconfig_net_open,		/* open */
-	release:ifconfig_net_close	/* release */
-};
-
-
-/*
- * init_ifconfig_net() - Boot time initialization.  Ensure that it is called 
- *	after devfs has been initialized.
- *
- */
-#ifdef MODULE
-int init_module (void)
-#else
-int __init init_ifconfig_net(void)
-#endif
-{
-	ifconfig_net_handle = NULL;
-	ifconfig_net_handle = hwgraph_register(hwgraph_root, ".ifconfig_net",
-			0, DEVFS_FL_AUTO_DEVNUM,
-			0, 0,
-			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-			&ifconfig_net_fops, NULL);
-
-	if (ifconfig_net_handle == NULL) {
-		panic("Unable to create SGI PERSISTENT NETWORK DEVICE Name Driver.\n");
-	}
-
-	return(0);
-
-}
diff -Nru a/arch/ia64/sn/io/invent.c b/arch/ia64/sn/io/invent.c
--- a/arch/ia64/sn/io/invent.c	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,224 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * Hardware Inventory
- *
- * See sys/sn/invent.h for an explanation of the hardware inventory contents.
- *
- */
-#include <linux/types.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-
-void
-inventinit(void)
-{
-}
-
-/*
- * For initializing/updating an inventory entry.
- */
-void
-replace_in_inventory(
-	inventory_t *pinv, int class, int type,
-	int controller, int unit, int state)
-{
-	pinv->inv_class = class;
-	pinv->inv_type = type;
-	pinv->inv_controller = controller;
-	pinv->inv_unit = unit;
-	pinv->inv_state = state;
-}
-
-/*
- * Inventory addition 
- *
- * XXX NOTE: Currently must be called after dynamic memory allocator is
- * initialized.
- *
- */
-void
-add_to_inventory(int class, int type, int controller, int unit, int state)
-{
-	(void)device_inventory_add((devfs_handle_t)GRAPH_VERTEX_NONE, class, type, 
-					controller, unit, state);
-}
-
-
-/*
- * Inventory retrieval 
- *
- * These two routines are intended to prevent the caller from having to know
- * the internal structure of the inventory table.
- *
- * The caller of get_next_inventory is supposed to call start_scan_invent
- * before the irst call to get_next_inventory, and the caller is required
- * to call end_scan_invent after the last call to get_next_inventory.
- */
-inventory_t *
-get_next_inventory(invplace_t *place)
-{
-	inventory_t *pinv;
-	devfs_handle_t device = place->invplace_vhdl;
-	int rv;
-
-	while ((pinv = device_inventory_get_next(device, place)) == NULL) {
-		/*
-		 * We've exhausted inventory items on the last device.
-		 * Advance to next device.
-		 */
-		place->invplace_inv = NULL; /* Start from beginning invent on this device */
-		rv = hwgraph_vertex_get_next(&device, &place->invplace_vplace);
-		if (rv == LABELCL_SUCCESS) {
-			place->invplace_vhdl = device;
-		}
-		else {
-			place->invplace_vhdl = GRAPH_VERTEX_NONE;
-			return(NULL);
-		}
-	}
-
-	return(pinv);
-}
-
-/* ARGSUSED */
-int
-get_sizeof_inventory(int abi)
-{
-	return sizeof(inventory_t);
-}
-
-/* Must be called prior to first call to get_next_inventory */
-void
-start_scan_inventory(invplace_t *iplace)
-{
-	*iplace = INVPLACE_NONE;
-}
-
-/* Must be called after last call to get_next_inventory */
-void
-end_scan_inventory(invplace_t *iplace)
-{
-	devfs_handle_t vhdl = iplace->invplace_vhdl;
-	if (vhdl != GRAPH_VERTEX_NONE)
-		hwgraph_vertex_unref(vhdl);
-	*iplace = INVPLACE_NONE; /* paranoia */
-}
-
-/*
- * Hardware inventory scanner.
- *
- * Calls fun() for every entry in inventory list unless fun() returns something
- * other than 0.
- */
-int
-scaninvent(int (*fun)(inventory_t *, void *), void *arg)
-{
-	inventory_t *ie;
-	invplace_t iplace = { NULL,NULL, NULL };
-	int rc;
-
-	ie = 0;
-	rc = 0;
-	start_scan_inventory(&iplace);
-	while ((ie = (inventory_t *)get_next_inventory(&iplace))) {
-		rc = (*fun)(ie, arg);
-		if (rc)
-			break;
-	}
-	end_scan_inventory(&iplace);
-	return rc;
-}
-
-/*
- * Find a particular inventory object
- *
- * pinv can be a pointer to an inventory entry and the search will begin from
- * there, or it can be 0 in which case the search starts at the beginning.
- * A -1 for any of the other arguments is a wildcard (i.e. it always matches).
- */
-inventory_t *
-find_inventory(inventory_t *pinv, int class, int type, int controller,
-	       int unit, int state)
-{
-	invplace_t iplace =  { NULL,NULL, NULL };
-
-	start_scan_inventory(&iplace);
-	while ((pinv = (inventory_t *)get_next_inventory(&iplace)) != NULL) {
-		if (class != -1 && pinv->inv_class != class)
-			continue;
-		if (type != -1 && pinv->inv_type != type)
-			continue;
-
-		/* XXXX - perhaps the "state" entry should be ignored so an
-		 * an existing entry can be updated.  See vino_init() and
-		 * ml/IP22.c:add_ioboard() for an example.
-		 */
-		if (state != -1 && pinv->inv_state != state)
-			continue;
-		if (controller != -1
-		    && pinv->inv_controller != controller)
-			continue;
-		if (unit != -1 && pinv->inv_unit != unit)
-			continue;
-		break;
-	}
-	end_scan_inventory(&iplace);
-
-	return(pinv);
-}
-
-
-/*
-** Retrieve inventory data associated with a device.
-*/
-inventory_t *
-device_inventory_get_next(	devfs_handle_t device,
-				invplace_t *invplace)
-{
-	inventory_t *pinv;
-	int rv;
-
-	rv = hwgraph_inventory_get_next(device, invplace, &pinv);
-	if (rv == LABELCL_SUCCESS)
-		return(pinv);
-	else
-		return(NULL);
-}
-
-
-/*
-** Associate canonical inventory information with a device (and
-** add it to the general inventory).
-*/
-void
-device_inventory_add(	devfs_handle_t device,
-			int class, 
-			int type, 
-			major_t controller, 
-			minor_t unit, 
-			int state)
-{
-	hwgraph_inventory_add(device, class, type, controller, unit, state);
-}
-
-int
-device_controller_num_get(devfs_handle_t device)
-{
-	return (hwgraph_controller_num_get(device));
-}
-
-void
-device_controller_num_set(devfs_handle_t device, int contr_num)
-{
-	hwgraph_controller_num_set(device, contr_num);
-}
diff -Nru a/arch/ia64/sn/io/io.c b/arch/ia64/sn/io/io.c
--- a/arch/ia64/sn/io/io.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/sn/io/io.c	Wed Jun 18 23:42:07 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #include <linux/config.h>
@@ -29,17 +29,11 @@
 #include <asm/sn/sn_cpuid.h>
 
 extern xtalk_provider_t hub_provider;
-extern void hub_intr_init(devfs_handle_t hubv);
+extern void hub_intr_init(vertex_hdl_t hubv);
 
+static int force_fire_and_forget = 1;
+static int ignore_conveyor_override;
 
-/*
- * Perform any initializations needed to support hub-based I/O.
- * Called once during startup.
- */
-void
-hubio_init(void)
-{
-}
 
 /* 
  * Implementation of hub iobus operations.
@@ -58,8 +52,8 @@
 /*
  * Setup pio structures needed for a particular hub.
  */
-void
-hub_pio_init(devfs_handle_t hubv)
+static void
+hub_pio_init(vertex_hdl_t hubv)
 {
 	xwidgetnum_t widget;
 	hubinfo_t hubinfo;
@@ -114,7 +108,7 @@
  */
 /* ARGSUSED */
 hub_piomap_t
-hub_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
+hub_piomap_alloc(vertex_hdl_t dev,	/* set up mapping for this device */
 		device_desc_t dev_desc,	/* device descriptor */
 		iopaddr_t xtalk_addr,	/* map for this xtalk_addr range */
 		size_t byte_count,
@@ -123,7 +117,7 @@
 {
 	xwidget_info_t widget_info = xwidget_info_get(dev);
 	xwidgetnum_t widget = xwidget_info_id_get(widget_info);
-	devfs_handle_t hubv = xwidget_info_master_get(widget_info);
+	vertex_hdl_t hubv = xwidget_info_master_get(widget_info);
 	hubinfo_t hubinfo;
 	hub_piomap_t bw_piomap;
 	int bigwin, free_bw_index;
@@ -288,7 +282,7 @@
 void
 hub_piomap_free(hub_piomap_t hub_piomap)
 {
-	devfs_handle_t hubv;
+	vertex_hdl_t hubv;
 	hubinfo_t hubinfo;
 	nasid_t nasid;
 	unsigned long s;
@@ -371,7 +365,7 @@
  */
 /* ARGSUSED */
 caddr_t
-hub_piotrans_addr(	devfs_handle_t dev,	/* translate to this device */
+hub_piotrans_addr(	vertex_hdl_t dev,	/* translate to this device */
 			device_desc_t dev_desc,	/* device descriptor */
 			iopaddr_t xtalk_addr,	/* Crosstalk address */
 			size_t byte_count,	/* map this many bytes */
@@ -379,7 +373,7 @@
 {
 	xwidget_info_t widget_info = xwidget_info_get(dev);
 	xwidgetnum_t widget = xwidget_info_id_get(widget_info);
-	devfs_handle_t hubv = xwidget_info_master_get(widget_info);
+	vertex_hdl_t hubv = xwidget_info_master_get(widget_info);
 	hub_piomap_t hub_piomap;
 	hubinfo_t hubinfo;
 	caddr_t addr;
@@ -416,7 +410,7 @@
  */
 /* ARGSUSED */
 hub_dmamap_t
-hub_dmamap_alloc(	devfs_handle_t dev,	/* set up mappings for this device */
+hub_dmamap_alloc(	vertex_hdl_t dev,	/* set up mappings for this device */
 			device_desc_t dev_desc,	/* device descriptor */
 			size_t byte_count_max, 	/* max size of a mapping */
 			unsigned flags)		/* defined in dma.h */
@@ -424,7 +418,7 @@
 	hub_dmamap_t dmamap;
 	xwidget_info_t widget_info = xwidget_info_get(dev);
 	xwidgetnum_t widget = xwidget_info_id_get(widget_info);
-	devfs_handle_t hubv = xwidget_info_master_get(widget_info);
+	vertex_hdl_t hubv = xwidget_info_master_get(widget_info);
 
 	dmamap = kmalloc(sizeof(struct hub_dmamap_s), GFP_ATOMIC);
 	dmamap->hdma_xtalk_info.xd_dev = dev;
@@ -460,7 +454,7 @@
 			paddr_t paddr,		/* map for this address */
 			size_t byte_count)	/* map this many bytes */
 {
-	devfs_handle_t vhdl;
+	vertex_hdl_t vhdl;
 
 	ASSERT(dmamap->hdma_flags & HUB_DMAMAP_IS_VALID);
 
@@ -479,12 +473,7 @@
 	}
 
 	/* There isn't actually any DMA mapping hardware on the hub. */
-#ifdef CONFIG_IA64_SGI_SN2
         return( (PHYS_TO_DMA(paddr)) );
-#else
-        /* no translation needed */
-        return(paddr);
-#endif
 }
 
 /*
@@ -498,7 +487,7 @@
 		alenlist_t palenlist,		/* map this area of memory */
 		unsigned flags)
 {
-	devfs_handle_t vhdl;
+	vertex_hdl_t vhdl;
 
 	ASSERT(hub_dmamap->hdma_flags & HUB_DMAMAP_IS_VALID);
 
@@ -527,7 +516,7 @@
 void
 hub_dmamap_done(hub_dmamap_t hub_dmamap)	/* done with these mapping resources */
 {
-	devfs_handle_t vhdl;
+	vertex_hdl_t vhdl;
 
 	if (hub_dmamap->hdma_flags & HUB_DMAMAP_USED) {
 		hub_dmamap->hdma_flags &= ~HUB_DMAMAP_USED;
@@ -549,18 +538,13 @@
  */
 /* ARGSUSED */
 iopaddr_t
-hub_dmatrans_addr(	devfs_handle_t dev,	/* translate for this device */
+hub_dmatrans_addr(	vertex_hdl_t dev,	/* translate for this device */
 			device_desc_t dev_desc,	/* device descriptor */
 			paddr_t paddr,		/* system physical address */
 			size_t byte_count,	/* length */
 			unsigned flags)		/* defined in dma.h */
 {
-#ifdef CONFIG_IA64_SGI_SN2
 	return( (PHYS_TO_DMA(paddr)) );
-#else
-	/* no translation needed */
-	return(paddr);
-#endif
 }
 
 /*
@@ -570,7 +554,7 @@
  */
 /* ARGSUSED */
 alenlist_t
-hub_dmatrans_list(	devfs_handle_t dev,	/* translate for this device */
+hub_dmatrans_list(	vertex_hdl_t dev,	/* translate for this device */
 			device_desc_t dev_desc,	/* device descriptor */
 			alenlist_t palenlist,	/* system address/length list */
 			unsigned flags)		/* defined in dma.h */
@@ -589,7 +573,7 @@
 
 /*ARGSUSED*/
 void
-hub_dmaaddr_drain(	devfs_handle_t vhdl,
+hub_dmaaddr_drain(	vertex_hdl_t vhdl,
 			paddr_t addr,
 			size_t bytes)
 {
@@ -598,7 +582,7 @@
 
 /*ARGSUSED*/
 void
-hub_dmalist_drain(	devfs_handle_t vhdl,
+hub_dmalist_drain(	vertex_hdl_t vhdl,
 			alenlist_t list)
 {
     /* XXX- flush caches, if cache coherency WAR is needed */
@@ -612,10 +596,8 @@
  * Perform initializations that allow this hub to start crosstalk support.
  */
 void
-hub_provider_startup(devfs_handle_t hubv)
+hub_provider_startup(vertex_hdl_t hubv)
 {
-	extern void hub_pio_init(devfs_handle_t hubv);
-
 	hub_pio_init(hubv);
 	hub_intr_init(hubv);
 }
@@ -624,7 +606,7 @@
  * Shutdown crosstalk support from a hub.
  */
 void
-hub_provider_shutdown(devfs_handle_t hub)
+hub_provider_shutdown(vertex_hdl_t hub)
 {
 	/* TBD */
 	xtalk_provider_unregister(hub);
@@ -666,46 +648,6 @@
 
 
 /*
- * Determine whether two PCI addresses actually refer to the same device.
- * This only works if both addresses are in small windows.  It's used to
- * determine whether prom addresses refer to particular PCI devices.
- */
-/*	
- * XXX - This won't work as written if we ever have more than two nodes
- * on a crossbow.  In that case, we'll need an array or partners.
- */
-int
-hub_check_pci_equiv(void *addra, void *addrb)
-{
-	nasid_t nasida, nasidb;
-
-	/*
-	 * This is for a permanent workaround that causes us to use a
-	 * big window in place of small window 0.
-	 */
-	if (!hub_check_window_equiv(addra, addrb))
-		return 0;
-
-	/* If the offsets aren't the same, forget it. */
-	if (SWIN_WIDGETADDR((__psunsigned_t)addra) !=
-	    (SWIN_WIDGETADDR((__psunsigned_t)addrb)))
-		return 0;
-
-	/* Now, check the nasids */
-	nasida = NASID_GET(addra);
-	nasidb = NASID_GET(addrb);
-
-	ASSERT(NASID_TO_COMPACT_NODEID(nasida) != INVALID_NASID);
-	ASSERT(NASID_TO_COMPACT_NODEID(nasidb) != INVALID_NASID);
-
-	/*
-	 * Either the NASIDs must be the same or they must be crossbow
-	 * partners (on the same crossbow).
-	 */
-	return (check_nasid_equiv(nasida, nasidb));
-}
-
-/*
  * hub_setup_prb(nasid, prbnum, credits, conveyor)
  *
  * 	Put a PRB into fire-and-forget mode if conveyor isn't set.  Otherwise,
@@ -716,8 +658,6 @@
 {
 	iprb_t prb;
 	int prb_offset;
-	extern int force_fire_and_forget;
-	extern volatile int ignore_conveyor_override;
 
 	if (force_fire_and_forget && !ignore_conveyor_override)
 	    if (conveyor == HUB_PIO_CONVEYOR)
@@ -776,13 +716,8 @@
 	int direct_connect;
 	hubii_wcr_t ii_wcr;
 	int prbnum;
-	int cons_lock = 0;
 
 	ASSERT(NASID_TO_COMPACT_NODEID(nasid) != INVALID_CNODEID);
-	if (nasid == get_console_nasid()) {
-		PUTBUF_LOCK(s);	
-		cons_lock = 1;
-	}
 
 	ii_iowa = REMOTE_HUB_L(nasid, IIO_OUTWIDGET_ACCESS);
 	REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, 0);
@@ -812,9 +747,6 @@
 	}
 
 	REMOTE_HUB_S(nasid, IIO_OUTWIDGET_ACCESS, ii_iowa);
-
-	if (cons_lock)
-	    PUTBUF_UNLOCK(s);
 }
 /* Interface to allow special drivers to set hub specific
  * device flags.
@@ -842,90 +774,6 @@
 
 	return 1;
 }
-/* Interface to allow special drivers to set hub specific
- * device flags.
- * Return 0 on failure , 1 on success
- */
-int
-hub_device_flags_set(devfs_handle_t	widget_vhdl,
-		     hub_widget_flags_t	flags)
-{
-	xwidget_info_t		widget_info = xwidget_info_get(widget_vhdl);
-	xwidgetnum_t		widget_num  = xwidget_info_id_get(widget_info);
-	devfs_handle_t		hub_vhdl    = xwidget_info_master_get(widget_info);
-	hubinfo_t		hub_info = 0;
-	nasid_t			nasid;
-	unsigned long		s;
-	int			rv;
-
-	/* Use the nasid from the hub info hanging off the hub vertex
-	 * and widget number from the widget vertex
-	 */
-	hubinfo_get(hub_vhdl, &hub_info);
-	/* Being over cautious by grabbing a lock */
-	s 	= mutex_spinlock(&hub_info->h_bwlock);
-	nasid 	= hub_info->h_nasid;
-	rv 	= hub_widget_flags_set(nasid,widget_num,flags);
-	mutex_spinunlock(&hub_info->h_bwlock, s);
-
-	return rv;
-}
-
-/*
- * hub_device_inquiry
- *	Find out the xtalk widget related information stored in this 
- *	hub's II.
- */
-void
-hub_device_inquiry(devfs_handle_t	xbus_vhdl, xwidgetnum_t widget)
-{
-	devfs_handle_t	xconn, hub_vhdl;
-	char		widget_name[8];
-	hubreg_t	ii_iidem,ii_iiwa, ii_iowa;
-	hubinfo_t	hubinfo;
-	nasid_t		nasid;
-	int		d;
-
-	sprintf(widget_name, "%d", widget);
-	if (hwgraph_traverse(xbus_vhdl, widget_name, &xconn)
-	    != GRAPH_SUCCESS)
-		return;
-
-	hub_vhdl = device_master_get(xconn);
-	if (hub_vhdl == GRAPH_VERTEX_NONE)
-		return;
-
-	hubinfo_get(hub_vhdl, &hubinfo);
-	if (!hubinfo)
-		return;
-	
-	nasid = hubinfo->h_nasid;
-
-	ii_iidem	= REMOTE_HUB_L(nasid, IIO_IIDEM);
-	ii_iiwa 	= REMOTE_HUB_L(nasid, IIO_IIWA);
-	ii_iowa 	= REMOTE_HUB_L(nasid, IIO_IOWA);
-
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-	printk("Inquiry Info for %v\n", xconn);
-#else
-	printk("Inquiry Info for %p\n", (void *)xconn);
-#endif
-
-	printk("\tDevices shutdown [ ");
-
-	for (d = 0 ; d <= 7 ; d++)
-		if (!(ii_iidem & (IIO_IIDEM_WIDGETDEV_MASK(widget,d))))
-			printk(" %d", d);
-
-	printk("]\n");
-
-	printk("\tInbound access ? %s\n",
-		ii_iiwa & IIO_IIWA_WIDGET(widget) ? "yes" : "no");
-
-	printk("\tOutbound access ? %s\n",
-		ii_iowa & IIO_IOWA_WIDGET(widget) ? "yes" : "no");
-
-}
 
 /*
  * A pointer to this structure hangs off of every hub hwgraph vertex.
@@ -955,8 +803,6 @@
 	(xtalk_intr_free_f *)		hub_intr_free,
 	(xtalk_intr_connect_f *)	hub_intr_connect,
 	(xtalk_intr_disconnect_f *)	hub_intr_disconnect,
-	(xtalk_intr_cpu_get_f *)	hub_intr_cpu_get,
-
 	(xtalk_provider_startup_f *)	hub_provider_startup,
 	(xtalk_provider_shutdown_f *)	hub_provider_shutdown,
 };
diff -Nru a/arch/ia64/sn/io/ioconfig_bus.c b/arch/ia64/sn/io/ioconfig_bus.c
--- a/arch/ia64/sn/io/ioconfig_bus.c	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,402 +0,0 @@
-/* $Id$
- *
- * 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.
- *
- *  ioconfig_bus - SGI's Persistent PCI Bus Numbering.
- *
- * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <linux/module.h>
-#include <linux/init.h>
-
-#include <linux/pci.h>
-
-#include <asm/sn/sgi.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm//sn/sn_sal.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/ioconfig_bus.h>
-
-#define SGI_IOCONFIG_BUS "SGI-PERSISTENT PCI BUS NUMBERING"
-#define SGI_IOCONFIG_BUS_VERSION "1.0"
-
-/*
- * Some Global definitions.
- */
-devfs_handle_t ioconfig_bus_handle = NULL;
-unsigned long ioconfig_bus_debug = 0;
-
-#ifdef IOCONFIG_BUS_DEBUG
-#define DBG(x...)	printk(x)
-#else
-#define DBG(x...)
-#endif
-
-u64 ioconfig_file = 0;
-u64 ioconfig_file_size = 0;
-u64 ioconfig_activated = 0;
-char ioconfig_kernopts[128];
-
-/*
- * For debugging purpose .. hardcode a table ..
- */
-struct  ascii_moduleid *ioconfig_bus_table;
-u64 ioconfig_bus_table_size = 0;
-
-
-int free_entry = 0;
-int new_entry = 0;
-
-int next_basebus_number = 0;
-
-void
-ioconfig_get_busnum(char *io_moduleid, int *bus_num)
-{
-	struct	ascii_moduleid  *temp;
-	int index;
-
-	DBG("ioconfig_get_busnum io_moduleid %s\n", io_moduleid);
-
-	*bus_num = -1;
-	temp = ioconfig_bus_table;
-	for (index = 0; index < free_entry; temp++, index++) {
-		if ( (io_moduleid[0] == temp->io_moduleid[0]) &&
-		     (io_moduleid[1] == temp->io_moduleid[1]) &&
-		     (io_moduleid[2] == temp->io_moduleid[2]) &&
-		     (io_moduleid[4] == temp->io_moduleid[4]) &&
-		     (io_moduleid[5] == temp->io_moduleid[5]) ) {
-			*bus_num = index * 0x10;
-			return;
-		}
-	}
-
-	/*
-	 * New IO Brick encountered.
-	 */
-	if (((int)io_moduleid[0]) == 0) {
-		DBG("ioconfig_get_busnum: Invalid Module Id given %s\n", io_moduleid);
-		return;
-	}
-
-	io_moduleid[3] = '#';
-	strcpy((char *)&(ioconfig_bus_table[free_entry].io_moduleid), io_moduleid);
-	*bus_num = free_entry * 0x10;
-	free_entry++;
-}
-
-void
-dump_ioconfig_table()
-{
-
-	int index = 0;
-	struct ascii_moduleid *temp;
-
-	temp = ioconfig_bus_table;
-	while (index < free_entry) {
-		DBG("ASSCI Module ID %s\n", temp->io_moduleid);
-		temp++;
-		index++;
-	}
-}
-
-/*
- * nextline
- *	This routine returns the nextline in the buffer.
- */
-int nextline(char *buffer, char **next, char *line)
-{
-
-	char *temp;
-
-	if (buffer[0] == 0x0) {
-		return(0);
-	}
-
-	temp = buffer;
-	while (*temp != 0) {
-		*line = *temp;
-		if (*temp != '\n'){
-			*line = *temp;
-			temp++; line++;
-		} else
-			break;
-	}
-
-	if (*temp == 0)
-		*next = temp;
-	else
-		*next = ++temp;
-
-	return(1);
-}
-
-/*
- * build_pcibus_name
- *	This routine parses the ioconfig contents read into
- *	memory by ioconfig command in EFI and builds the
- *	persistent pci bus naming table.
- */
-void
-build_moduleid_table(char *file_contents, struct ascii_moduleid *table)
-{
-	/*
-	 * Read the whole file into memory.
-	 */
-	int rc;
-	char *name;
-	char *temp;
-	char *next;
-	char *current;
-	char *line;
-	struct ascii_moduleid *moduleid;
-
-	line = kmalloc(256, GFP_KERNEL);
-	memset(line, 0,256);
-	name = kmalloc(125, GFP_KERNEL);
-	memset(name, 0, 125);
-	moduleid = table;
-	current = file_contents;
-	while (nextline(current, &next, line)){
-
-		DBG("current 0x%lx next 0x%lx\n", current, next);
-
-		temp = line;
-		/*
-		 * Skip all leading Blank lines ..
-		 */
-		while (isspace(*temp))
-			if (*temp != '\n')
-				temp++;
-			else
-				break;
-
-		if (*temp == '\n') {
-			current = next;
-			memset(line, 0, 256);
-			continue;
-		}
- 
-		/*
-		 * Skip comment lines
-		 */
-		if (*temp == '#') {
-			current = next;
-			memset(line, 0, 256);
-			continue;
-		}
-
-		/*
-		 * Get the next free entry in the table.
-		 */
-		rc = sscanf(temp, "%s", name);
-		strcpy(&moduleid->io_moduleid[0], name);
-		DBG("Found %s\n", name);
-		moduleid++;
-		free_entry++;
-		current = next;
-		memset(line, 0, 256);
-	}
-
-	new_entry = free_entry;
-	kfree(line);
-	kfree(name);
-
-	return;
-}
-
-void
-ioconfig_bus_init(void)
-{
-
-	struct ia64_sal_retval ret_stuff;
-	u64	*temp;
-	int	cnode;
-
-	DBG("ioconfig_bus_init called.\n");
-
-        for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid_t nasid;
-		/*
-	 	 * Make SAL call to get the address of the bus configuration table.
-	 	 */
-		ret_stuff.status = (uint64_t)0;
-		ret_stuff.v0 = (uint64_t)0;
-		ret_stuff.v1 = (uint64_t)0;
-		ret_stuff.v2 = (uint64_t)0;
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-		SAL_CALL(ret_stuff, SN_SAL_BUS_CONFIG, 0, nasid, 0, 0, 0, 0, 0);
-		temp = (u64 *)TO_NODE_CAC(nasid, ret_stuff.v0);
-		ioconfig_file = *temp;
-		DBG("ioconfig_bus_init: Nasid %d ret_stuff.v0 0x%lx\n", nasid,
-			ret_stuff.v0);
-		if (ioconfig_file) {
-			ioconfig_file_size = ret_stuff.v1;
-			ioconfig_file = (ioconfig_file | CACHEABLE_MEM_SPACE);
-			ioconfig_activated = 1;
-			break;
-		}
-	}
-
-	DBG("ioconfig_bus_init: ret_stuff.v0 %p ioconfig_file %p %d\n",
-		ret_stuff.v0, (void *)ioconfig_file, (int)ioconfig_file_size);
-
-	ioconfig_bus_table = kmalloc( 512, GFP_KERNEL );
-	memset(ioconfig_bus_table, 0, 512);
-
-	/*
-	 * If ioconfig options are given on the bootline .. take it.
-	 */
-	if (*ioconfig_kernopts != '\0') {
-		/*
-		 * ioconfig="..." kernel options given.
-		 */
-		DBG("ioconfig_bus_init: Kernel Options given.\n");
-		(void) build_moduleid_table((char *)ioconfig_kernopts, ioconfig_bus_table);
-		(void) dump_ioconfig_table(ioconfig_bus_table);
-		return;
-	}
-
-	if (ioconfig_activated) {
-		DBG("ioconfig_bus_init: ioconfig file given.\n");
-		(void) build_moduleid_table((char *)ioconfig_file, ioconfig_bus_table);
-		(void) dump_ioconfig_table(ioconfig_bus_table);
-	} else {
-		DBG("ioconfig_bus_init: ioconfig command not executed in prom\n");
-	}
-
-}
-
-void
-ioconfig_bus_new_entries(void)
-{
-
-	
-	int index = 0;
-	struct ascii_moduleid *temp;
-
-	if ((ioconfig_activated) && (free_entry > new_entry)) {
-		printk("### Please add the following new IO Bricks Module ID \n");
-		printk("### to your Persistent Bus Numbering Config File\n");
-	} else
-		return;
-
-	index = new_entry;
-	temp = &ioconfig_bus_table[index];
-        while (index < free_entry) {
-                printk("%s\n", temp);
-		temp++;
-                index++;
-        }
-	printk("### End\n");
-
-}
-static int ioconfig_bus_ioctl(struct inode * inode, struct file * file,
-        unsigned int cmd, unsigned long arg)
-{
-
-	struct ioconfig_parm parm;
-
-	/*
-	 * Copy in the parameters.
-	 */
-	copy_from_user(&parm, (char *)arg, sizeof(struct ioconfig_parm));
-	parm.number = free_entry - new_entry;
-	parm.ioconfig_activated = ioconfig_activated;
-	copy_to_user((char *)arg, &parm, sizeof(struct ioconfig_parm));
-	copy_to_user((char *)parm.buffer, &ioconfig_bus_table[new_entry], sizeof(struct  ascii_moduleid) * (free_entry - new_entry));
-
-	return 0;
-}
-
-/*
- * ioconfig_bus_open - Opens the special device node "/dev/hw/.ioconfig_bus".
- */
-static int ioconfig_bus_open(struct inode * inode, struct file * filp)
-{
-	if (ioconfig_bus_debug) {
-        	DBG("ioconfig_bus_open called.\n");
-	}
-
-        return(0);
-
-}
-
-/*
- * ioconfig_bus_close - Closes the special device node "/dev/hw/.ioconfig_bus".
- */
-static int ioconfig_bus_close(struct inode * inode, struct file * filp)
-{
-
-	if (ioconfig_bus_debug) {
-        	DBG("ioconfig_bus_close called.\n");
-	}
-
-        return(0);
-}
-
-struct file_operations ioconfig_bus_fops = {
-	ioctl:ioconfig_bus_ioctl,
-	open:ioconfig_bus_open,		/* open */
-	release:ioconfig_bus_close	/* release */
-};
-
-
-/*
- * init_ifconfig_bus() - Boot time initialization.  Ensure that it is called 
- *	after devfs has been initialized.
- *
- */
-int init_ioconfig_bus(void)
-{
-	ioconfig_bus_handle = NULL;
-	ioconfig_bus_handle = hwgraph_register(hwgraph_root, ".ioconfig_bus",
-			0, DEVFS_FL_AUTO_DEVNUM,
-			0, 0,
-			S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-			&ioconfig_bus_fops, NULL);
-
-	if (ioconfig_bus_handle == NULL) {
-		panic("Unable to create SGI PERSISTENT BUS NUMBERING Driver.\n");
-	}
-
-	return(0);
-
-}
-
-static int __init ioconfig_bus_setup (char *str)
-{
-
-	char *temp;
-
-	DBG("ioconfig_bus_setup: Kernel Options %s\n", str);
-
-	temp = (char *)ioconfig_kernopts;
-	memset(temp, 0, 128);
-	while ( (*str != '\0') && !isspace (*str) ) {
-		if (*str == ',') {
-			*temp = '\n';
-			temp++;
-			str++;
-			continue;
-		}
-		*temp = *str;
-		temp++;
-		str++;
-	}
-
-	return(0);
-		
-}
-__setup("ioconfig=", ioconfig_bus_setup);
diff -Nru a/arch/ia64/sn/io/klconflib.c b/arch/ia64/sn/io/klconflib.c
--- a/arch/ia64/sn/io/klconflib.c	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1040 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/ctype.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/module.h>
-#include <asm/sn/router.h>
-#include <asm/sn/xtalk/xbow.h>
-
-#define printf printk
-int hasmetarouter;
-
-#define LDEBUG 0
-#define NIC_UNKNOWN ((nic_t) -1)
-
-#undef DEBUG_KLGRAPH
-#ifdef DEBUG_KLGRAPH
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* DEBUG_KLGRAPH */
-
-static void sort_nic_names(lboard_t *) ;
-
-u64 klgraph_addr[MAX_COMPACT_NODES];
-
-lboard_t *
-find_lboard(lboard_t *start, unsigned char brd_type)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (start->brd_type == brd_type)
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-lboard_t *
-find_lboard_class(lboard_t *start, unsigned char brd_type)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (KLCLASS(start->brd_type) == KLCLASS(brd_type))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-klinfo_t *
-find_component(lboard_t *brd, klinfo_t *kli, unsigned char struct_type)
-{
-	int index, j;
-
-	if (kli == (klinfo_t *)NULL) {
-		index = 0;
-	} else {
-		for (j = 0; j < KLCF_NUM_COMPS(brd); j++) {
-			if (kli == KLCF_COMP(brd, j))
-				break;
-		}
-		index = j;
-		if (index == KLCF_NUM_COMPS(brd)) {
-			DBG("find_component: Bad pointer: 0x%p\n", kli);
-			return (klinfo_t *)NULL;
-		}
-		index++;	/* next component */
-	}
-	
-	for (; index < KLCF_NUM_COMPS(brd); index++) {		
-		kli = KLCF_COMP(brd, index);
-		DBG("find_component: brd %p kli %p  request type = 0x%x kli type 0x%x\n", brd, kli, kli->struct_type, KLCF_COMP_TYPE(kli));
-		if (KLCF_COMP_TYPE(kli) == struct_type)
-			return kli;
-	}
-
-	/* Didn't find it. */
-	return (klinfo_t *)NULL;
-}
-
-klinfo_t *
-find_first_component(lboard_t *brd, unsigned char struct_type)
-{
-	return find_component(brd, (klinfo_t *)NULL, struct_type);
-}
-
-lboard_t *
-find_lboard_modslot(lboard_t *start, moduleid_t mod, slotid_t slot)
-{
-	/* Search all boards stored on this node. */
-	while (start) {
-		if (MODULE_MATCH(start->brd_module, mod) &&
-		    (start->brd_slot == slot))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-lboard_t *
-find_lboard_module(lboard_t *start, moduleid_t mod)
-{
-        /* Search all boards stored on this node. */
-        while (start) {
-                if (MODULE_MATCH(start->brd_module, mod))
-                        return start;
-                start = KLCF_NEXT(start);
-        }
-
-        /* Didn't find it. */
-        return (lboard_t *)NULL;
-}
-
-lboard_t *
-find_lboard_module_class(lboard_t *start, moduleid_t mod,
-                                                unsigned char brd_type)
-{
-	while (start) {
-
-		DBG("find_lboard_module_class: lboard 0x%p, start->brd_module 0x%x, mod 0x%x, start->brd_type 0x%x, brd_type 0x%x\n", start, start->brd_module, mod, start->brd_type, brd_type);
-
-		if (MODULE_MATCH(start->brd_module, mod) &&
-			(KLCLASS(start->brd_type) == KLCLASS(brd_type)))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
-
-/*
- * Convert a NIC name to a name for use in the hardware graph.
- */
-void
-nic_name_convert(char *old_name, char *new_name)
-{
-        int i;
-        char c;
-        char *compare_ptr;
-
-	if ((old_name[0] == '\0') || (old_name[1] == '\0')) {
-                strcpy(new_name, EDGE_LBL_XWIDGET);
-        } else {
-                for (i = 0; i < strlen(old_name); i++) {
-                        c = old_name[i];
-
-                        if (isalpha(c))
-                                new_name[i] = tolower(c);
-                        else if (isdigit(c))
-                                new_name[i] = c;
-                        else
-                                new_name[i] = '_';
-                }
-                new_name[i] = '\0';
-        }
-
-        /* XXX -
-         * Since a bunch of boards made it out with weird names like
-         * IO6-fibbbed and IO6P2, we need to look for IO6 in a name and
-         * replace it with "baseio" to avoid confusion in the field.
-	 * We also have to make sure we don't report media_io instead of
-	 * baseio.
-         */
-
-        /* Skip underscores at the beginning of the name */
-        for (compare_ptr = new_name; (*compare_ptr) == '_'; compare_ptr++)
-                ;
-
-	/*
-	 * Check for some names we need to replace.  Early boards
-	 * had junk following the name so check only the first
-	 * characters.
-	 */
-        if (!strncmp(new_name, "io6", 3) || 
-            !strncmp(new_name, "mio", 3) || 
-	    !strncmp(new_name, "media_io", 8))
-		strcpy(new_name, "baseio");
-	else if (!strncmp(new_name, "divo", 4))
-		strcpy(new_name, "divo") ;
-
-}
-
-/* Check if the given board corresponds to the global 
- * master io6
- */
-int
-is_master_baseio(nasid_t nasid,moduleid_t module,slotid_t slot)
-{
-	lboard_t	*board;
-
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-/* If this works then look for callers of is_master_baseio()
- * (e.g. iograph.c) and let them pass in a slot if they want
- */
-	board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid), module);
-#else
-	board = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid), module, slot);
-#endif
-
-#ifndef _STANDALONE
-	{
-		cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
-
-		if (!board && (NODEPDA(cnode)->xbow_peer != INVALID_NASID))
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-			board = find_lboard_module((lboard_t *)
-				    KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer),
-				    module);
-#else
-			board = find_lboard_modslot((lboard_t *)
-				    KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer),
-				    module, slot);
-#endif
-	}
-#endif
-	if (!board)
-		return(0);
-	return(board->brd_flags & GLOBAL_MASTER_IO6);
-}
-/*
- * Find the lboard structure and get the board name.
- * If we can't find the structure or it's too low a revision,
- * use default name.
- */
-lboard_t *
-get_board_name(nasid_t nasid, moduleid_t mod, slotid_t slot, char *name)
-{
-	lboard_t *brd;
-
-	brd = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid),
-				  mod, slot);
-
-#ifndef _STANDALONE
-	{
-		cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
-
-		if (!brd && (NODEPDA(cnode)->xbow_peer != INVALID_NASID))
-			brd = find_lboard_modslot((lboard_t *)
-				KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer),
-				mod, slot);
-	}
-#endif
-
-	if (!brd || (brd->brd_sversion < 2)) {
-		strcpy(name, EDGE_LBL_XWIDGET);
-	} else {
-		nic_name_convert(brd->brd_name, name);
-	}
-
-	/*
- 	 * PV # 540860
-	 * If the name is not 'baseio' 
-	 * get the lowest of all the names in the nic string.
-	 * This is needed for boards like divo, which can have
-	 * a bunch of daughter cards, but would like to be called
-	 * divo. We could do this for baseio 
- 	 * but it has some special case names that we would not
- 	 * like to disturb at this point.
-	 */
-
-	/* gfx boards don't need any of this name scrambling */
-	if (brd && (KLCLASS(brd->brd_type) == KLCLASS_GFX)) {
-		return(brd);
-	}
-
-	if (!(!strcmp(name, "baseio") )) {
-		if (brd) {
-			sort_nic_names(brd) ;
-			/* Convert to small case, '-' to '_' etc */
-			nic_name_convert(brd->brd_name, name) ;
-		}
-	}
-
-	return(brd);
-}
-
-/*
- * get_actual_nasid
- *
- *	Completely disabled brds have their klconfig on 
- *	some other nasid as they have no memory. But their
- *	actual nasid is hidden in the klconfig. Use this
- *	routine to get it. Works for normal boards too.
- */
-nasid_t
-get_actual_nasid(lboard_t *brd)
-{
-	klhub_t	*hub ;
-
-	if (!brd)
-		return INVALID_NASID ;
-
-	/* find out if we are a completely disabled brd. */
-
-        hub  = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
-	if (!hub)
-                return INVALID_NASID ;
-	if (!(hub->hub_info.flags & KLINFO_ENABLE))	/* disabled node brd */
-		return hub->hub_info.physid ;
-	else
-		return brd->brd_nasid ;
-}
-
-int
-xbow_port_io_enabled(nasid_t nasid, int link)
-{
-	lboard_t *brd;
-	klxbow_t *xbow_p;
-
-	/*
-	 * look for boards that might contain an xbow or xbridge
-	 */
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IOBRICK_XBOW);
-	if (brd == NULL) return 0;
-		
-	if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW))
-	    == NULL)
-	    return 0;
-
-	if (!XBOW_PORT_TYPE_IO(xbow_p, link) || !XBOW_PORT_IS_ENABLED(xbow_p, link))
-	    return 0;
-
-	DBG("xbow_port_io_enabled:  brd 0x%p xbow_p 0x%p \n", brd, xbow_p);
-
-	return 1;
-}
-
-void
-board_to_path(lboard_t *brd, char *path)
-{
-	moduleid_t modnum;
-	char *board_name;
-
-	ASSERT(brd);
-
-	switch (KLCLASS(brd->brd_type)) {
-
-		case KLCLASS_NODE:
-			board_name = EDGE_LBL_NODE;
-			break;
-		case KLCLASS_ROUTER:
-			if (brd->brd_type == KLTYPE_META_ROUTER) {
-				board_name = EDGE_LBL_META_ROUTER;
-				hasmetarouter++;
-			} else if (brd->brd_type == KLTYPE_REPEATER_ROUTER) {
-				board_name = EDGE_LBL_REPEATER_ROUTER;
-				hasmetarouter++;
-			} else
-				board_name = EDGE_LBL_ROUTER;
-			break;
-		case KLCLASS_MIDPLANE:
-			board_name = EDGE_LBL_MIDPLANE;
-			break;
-		case KLCLASS_IO:
-			board_name = EDGE_LBL_IO;
-			break;
-		case KLCLASS_IOBRICK:
-			if (brd->brd_type == KLTYPE_PBRICK)
-				board_name = EDGE_LBL_PBRICK;
-			else if (brd->brd_type == KLTYPE_IBRICK)
-				board_name = EDGE_LBL_IBRICK;
-			else if (brd->brd_type == KLTYPE_XBRICK)
-				board_name = EDGE_LBL_XBRICK;
-			else
-				board_name = EDGE_LBL_IOBRICK;
-			break;
-		default:
-			board_name = EDGE_LBL_UNKNOWN;
-	}
-			
-	modnum = brd->brd_module;
-
-	ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE);
-#ifdef __ia64
-	{
-		char	buffer[16];
-		memset(buffer, 0, 16);
-		format_module_id(buffer, modnum, MODULE_FORMAT_BRIEF);
-		sprintf(path, EDGE_LBL_MODULE "/%s/%s", buffer, board_name);
-	}
-#else
-	sprintf(path, "%H/%s", modnum, board_name);
-#endif
-}
-
-/*
- * Get the module number for a NASID.
- */
-moduleid_t
-get_module_id(nasid_t nasid)
-{
-	lboard_t *brd;
-
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-
-	if (!brd)
-		return INVALID_MODULE;
-	else
-		return brd->brd_module;
-}
-
-
-#define MHZ	1000000
-
-
-/* Get the canonical hardware graph name for the given pci component
- * on the given io board.
- */
-void
-device_component_canonical_name_get(lboard_t 	*brd,
-				    klinfo_t 	*component,
-				    char 	*name)
-{
-	moduleid_t 	modnum;
-	slotid_t 	slot;
-	char 		board_name[20];
-
-	ASSERT(brd);
-
-	/* Get the module number of this board */
-	modnum = brd->brd_module;
-
-	/* Convert the [ CLASS | TYPE ] kind of slotid
-	 * into a string 
-	 */
-	slot = brd->brd_slot;
-	ASSERT(modnum != MODULE_UNKNOWN && modnum != INVALID_MODULE);
-
-	/* Get the io board name  */
-	if (!brd || (brd->brd_sversion < 2)) {
-		strcpy(name, EDGE_LBL_XWIDGET);
-	} else {
-		nic_name_convert(brd->brd_name, board_name);
-	}
-
-	/* Give out the canonical  name of the pci device*/
-	sprintf(name, 
-		"/dev/hw/"EDGE_LBL_MODULE "/%x/"EDGE_LBL_SLOT"/%s/"
-		EDGE_LBL_PCI"/%d", 
-		modnum, board_name,KLCF_BRIDGE_W_ID(component));
-}
-
-/*
- * Get the serial number of the main  component of a board
- * Returns 0 if a valid serial number is found
- * 1 otherwise.
- * Assumptions: Nic manufacturing string  has the following format
- *			*Serial:<serial_number>;*
- */
-static int
-component_serial_number_get(lboard_t 		*board,
-			    klconf_off_t 	mfg_nic_offset,
-			    char		*serial_number,
-			    char		*key_pattern)
-{
-
-	char	*mfg_nic_string;
-	char	*serial_string,*str;
-	int	i;
-	char	*serial_pattern = "Serial:";
-
-	/* We have an error on a null mfg nic offset */
-	if (!mfg_nic_offset)
-		return(1);
-	/* Get the hub's manufacturing nic information
-	 * which is in the form of a pre-formatted string
-	 */
-	mfg_nic_string = 
-		(char *)NODE_OFFSET_TO_K0(NASID_GET(board),
-					  mfg_nic_offset);
-	/* There is no manufacturing nic info */
-	if (!mfg_nic_string)
-		return(1);
-
-	str = mfg_nic_string;
-	/* Look for the key pattern first (if it is  specified)
-	 * and then print the serial number corresponding to that.
-	 */
-	if (strcmp(key_pattern,"") && 
-	    !(str = strstr(mfg_nic_string,key_pattern)))
-		return(1);
-
-	/* There is no serial number info in the manufacturing
-	 * nic info
-	 */
-	if (!(serial_string = strstr(str,serial_pattern)))
-		return(1);
-
-	serial_string = serial_string + strlen(serial_pattern);
-	/*  Copy the serial number information from the klconfig */
-	i = 0;
-	while (serial_string[i] != ';') {
-		serial_number[i] = serial_string[i];
-		i++;
-	}
-	serial_number[i] = 0;
-	
-	return(0);
-}
-/*
- * Get the serial number of a board
- * Returns 0 if a valid serial number is found
- * 1 otherwise.
- */
-
-int
-board_serial_number_get(lboard_t *board,char *serial_number)
-{
-	ASSERT(board && serial_number);
-	if (!board || !serial_number)
-		return(1);
-
-	strcpy(serial_number,"");
-	switch(KLCLASS(board->brd_type)) {
-	case KLCLASS_CPU: {	/* Node board */
-		klhub_t	*hub;
-		
-		/* Get the hub component information */
-		hub = (klhub_t *)find_first_component(board,
-						      KLSTRUCT_HUB);
-		/* If we don't have a hub component on an IP27
-		 * then we have a weird klconfig.
-		 */
-		if (!hub)
-			return(1);
-		/* Get the serial number information from
-		 * the hub's manufacturing nic info
-		 */
-		if (component_serial_number_get(board,
-						hub->hub_mfg_nic,
-						serial_number,
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-						"IP37"))
-#else
-						"IP27"))
-			/* Try with IP31 key if IP27 key fails */
-			if (component_serial_number_get(board,
-							hub->hub_mfg_nic,
-							serial_number,
-							"IP31"))
-#endif /* CONFIG_IA64_SGI_SN1 */
-				return(1);
-		break;
-	}
-	case KLCLASS_IO: {	/* IO board */
-		if (KLTYPE(board->brd_type) == KLTYPE_TPU) {
-		/* Special case for TPU boards */
-			kltpu_t *tpu;	
-		
-			/* Get the tpu component information */
-			tpu = (kltpu_t *)find_first_component(board,
-						      KLSTRUCT_TPU);
-			/* If we don't have a tpu component on a tpu board
-			 * then we have a weird klconfig.
-			 */
-			if (!tpu)
-				return(1);
-			/* Get the serial number information from
-			 * the tpu's manufacturing nic info
-			 */
-			if (component_serial_number_get(board,
-						tpu->tpu_mfg_nic,
-						serial_number,
-						""))
-				return(1);
-			break;
-		} else  if ((KLTYPE(board->brd_type) == KLTYPE_GSN_A) ||
-		            (KLTYPE(board->brd_type) == KLTYPE_GSN_B)) {
-		/* Special case for GSN boards */
-			klgsn_t *gsn;	
-		
-			/* Get the gsn component information */
-			gsn = (klgsn_t *)find_first_component(board,
-			      ((KLTYPE(board->brd_type) == KLTYPE_GSN_A) ?
-					KLSTRUCT_GSN_A : KLSTRUCT_GSN_B));
-			/* If we don't have a gsn component on a gsn board
-			 * then we have a weird klconfig.
-			 */
-			if (!gsn)
-				return(1);
-			/* Get the serial number information from
-			 * the gsn's manufacturing nic info
-			 */
-			if (component_serial_number_get(board,
-						gsn->gsn_mfg_nic,
-						serial_number,
-						""))
-				return(1);
-			break;
-		} else {
-		     	klbri_t	*bridge;
-		
-			/* Get the bridge component information */
-			bridge = (klbri_t *)find_first_component(board,
-							 KLSTRUCT_BRI);
-			/* If we don't have a bridge component on an IO board
-			 * then we have a weird klconfig.
-			 */
-			if (!bridge)
-				return(1);
-			/* Get the serial number information from
-		 	 * the bridge's manufacturing nic info
-			 */
-			if (component_serial_number_get(board,
-						bridge->bri_mfg_nic,
-						serial_number,
-						""))
-				return(1);
-			break;
-		}
-	}
-	case KLCLASS_ROUTER: {	/* Router board */
-		klrou_t *router;	
-		
-		/* Get the router component information */
-		router = (klrou_t *)find_first_component(board,
-							 KLSTRUCT_ROU);
-		/* If we don't have a router component on a router board
-		 * then we have a weird klconfig.
-		 */
-		if (!router)
-			return(1);
-		/* Get the serial number information from
-		 * the router's manufacturing nic info
-		 */
-		if (component_serial_number_get(board,
-						router->rou_mfg_nic,
-						serial_number,
-						""))
-			return(1);
-		break;
-	}
-	case KLCLASS_GFX: {	/* Gfx board */
-		klgfx_t *graphics;
-		
-		/* Get the graphics component information */
-		graphics = (klgfx_t *)find_first_component(board, KLSTRUCT_GFX);
-		/* If we don't have a gfx component on a gfx board
-		 * then we have a weird klconfig.
-		 */
-		if (!graphics)
-			return(1);
-		/* Get the serial number information from
-		 * the graphics's manufacturing nic info
-		 */
-		if (component_serial_number_get(board,
-						graphics->gfx_mfg_nic,
-						serial_number,
-						""))
-			return(1);
-		break;
-	}
-	default:
-		strcpy(serial_number,"");
-		break;
-	}
-	return(0);
-}
-
-#include "asm/sn/sn_private.h"
-
-xwidgetnum_t
-nodevertex_widgetnum_get(devfs_handle_t node_vtx)
-{
-	hubinfo_t hubinfo_p;
-
-	hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, 
-			     (arbitrary_info_t *) &hubinfo_p);
-	return(hubinfo_p->h_widgetid);
-}
-
-devfs_handle_t
-nodevertex_xbow_peer_get(devfs_handle_t node_vtx)
-{
-	hubinfo_t hubinfo_p;
-	nasid_t xbow_peer_nasid;
-	cnodeid_t xbow_peer;
-
-	hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO,
-				     (arbitrary_info_t *) &hubinfo_p);
-	xbow_peer_nasid = hubinfo_p->h_nodepda->xbow_peer;
-	if(xbow_peer_nasid == INVALID_NASID) 
-			return ( (devfs_handle_t)-1);
-	xbow_peer = NASID_TO_COMPACT_NODEID(xbow_peer_nasid);
-	return(NODEPDA(xbow_peer)->node_vertex);
-}
-
-/* NIC Sorting Support */
-
-#define MAX_NICS_PER_STRING 	32
-#define MAX_NIC_NAME_LEN	32
-
-static char *
-get_nic_string(lboard_t *lb)
-{
-        int         	i;
-        klinfo_t    	*k = NULL ;
-    	klconf_off_t    mfg_off = 0 ;
-    	char            *mfg_nic = NULL ;
-
-        for (i = 0; i < KLCF_NUM_COMPS(lb); i++) {
-                k = KLCF_COMP(lb, i) ;
-                switch(k->struct_type) {
-                        case KLSTRUCT_BRI:
-            			mfg_off = ((klbri_t *)k)->bri_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_HUB:
-            			mfg_off = ((klhub_t *)k)->hub_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_ROU:
-            			mfg_off = ((klrou_t *)k)->rou_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_GFX:
-            			mfg_off = ((klgfx_t *)k)->gfx_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_TPU:
-            			mfg_off = ((kltpu_t *)k)->tpu_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_GSN_A:
-                        case KLSTRUCT_GSN_B:
-            			mfg_off = ((klgsn_t *)k)->gsn_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_XTHD:
-                                mfg_off = ((klxthd_t *)k)->xthd_mfg_nic ;
-                                break;
-
-			default:
-				mfg_off = 0 ;
-                                break ;
-                }
-		if (mfg_off)
-			break ;
-        }
-
-	if ((mfg_off) && (k))
-		mfg_nic = (char *)NODE_OFFSET_TO_K0(k->nasid, mfg_off) ;
-
-        return mfg_nic ;
-}
-
-char *
-get_first_string(char **ptrs, int n)
-{
-        int     i ;
-        char    *tmpptr ;
-
-        if ((ptrs == NULL) || (n == 0))
-                return NULL ;
-
-        tmpptr = ptrs[0] ;
-
-        if (n == 1)
-                return tmpptr ;
-
-        for (i = 0 ; i < n ; i++) {
-                if (strcmp(tmpptr, ptrs[i]) > 0)
-                        tmpptr = ptrs[i] ;
-        }
-
-        return tmpptr ;
-}
-
-int
-get_ptrs(char *idata, char **ptrs, int n, char *label)
-{
-        int     i = 0 ;
-        char    *tmp = idata ;
-
-        if ((ptrs == NULL) || (idata == NULL) || (label == NULL) || (n == 0))
-                return 0 ;
-
-        while  ( (tmp = strstr(tmp, label)) ){
-                tmp += strlen(label) ;
-                /* check for empty name field, and last NULL ptr */
-                if ((i < (n-1)) && (*tmp != ';')) {
-                        ptrs[i++] = tmp ;
-                }
-        }
-
-        ptrs[i] = NULL ;
-
-        return i ;
-}
-
-/*
- * sort_nic_names
- *
- * 	Does not really do sorting. Find the alphabetically lowest
- *	name among all the nic names found in a nic string.
- *
- * Return:
- *	Nothing
- *
- * Side Effects:
- *
- *	lb->brd_name gets the new name found
- */
-
-static void
-sort_nic_names(lboard_t *lb)
-{
-	char 	*nic_str ;
-        char    *ptrs[MAX_NICS_PER_STRING] ;
-        char    name[MAX_NIC_NAME_LEN] ;
-        char    *tmp, *tmp1 ;
-
-	*name = 0 ;
-
-	/* Get the nic pointer from the lb */
-
-	if ((nic_str = get_nic_string(lb)) == NULL)
-		return ;
-
-        tmp = get_first_string(ptrs,
-                        get_ptrs(nic_str, ptrs, MAX_NICS_PER_STRING, "Name:")) ;
-
-        if (tmp == NULL)
-		return ;
-
-        if  ( (tmp1 = strchr(tmp, ';')) ){
-                strlcpy(name, tmp, tmp1-tmp) ;
-        } else {
-                strlcpy(name, tmp, (sizeof(name))) ;
-        }
-
-	strlcpy(lb->brd_name, name, sizeof(lb->brd_name)) ;
-}
-
-
-
-char brick_types[MAX_BRICK_TYPES + 1] = "crikxdp789012345";
-
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-
-/*
- * Format a module id for printing.
- */
-void
-format_module_id(char *buffer, moduleid_t m, int fmt)
-{
-	int rack, position;
-	char brickchar;
-
-	rack = MODULE_GET_RACK(m);
-	ASSERT(MODULE_GET_BTYPE(m) < MAX_BRICK_TYPES);
-	brickchar = MODULE_GET_BTCHAR(m);
-	position = MODULE_GET_BPOS(m);
-
-	if (fmt == MODULE_FORMAT_BRIEF) {
-	    /* Brief module number format, eg. 002c15 */
-
-	    /* Decompress the rack number */
-	    *buffer++ = '0' + RACK_GET_CLASS(rack);
-	    *buffer++ = '0' + RACK_GET_GROUP(rack);
-	    *buffer++ = '0' + RACK_GET_NUM(rack);
-
-	    /* Add the brick type */
-	    *buffer++ = brickchar;
-	}
-	else if (fmt == MODULE_FORMAT_LONG) {
-	    /* Fuller hwgraph format, eg. rack/002/bay/15 */
-
-	    strcpy(buffer, EDGE_LBL_RACK "/");  buffer += strlen(buffer);
-
-	    *buffer++ = '0' + RACK_GET_CLASS(rack);
-	    *buffer++ = '0' + RACK_GET_GROUP(rack);
-	    *buffer++ = '0' + RACK_GET_NUM(rack);
-
-	    strcpy(buffer, "/" EDGE_LBL_RPOS "/");  buffer += strlen(buffer);
-	}
-
-	/* Add the bay position, using at least two digits */
-	if (position < 10)
-	    *buffer++ = '0';
-	sprintf(buffer, "%d", position);
-
-}
-
-/*
- * Parse a module id, in either brief or long form.
- * Returns < 0 on error.
- * The long form does not include a brick type, so it defaults to 0 (CBrick)
- */
-int
-parse_module_id(char *buffer)
-{
-	unsigned int	v, rack, bay, type, form;
-	moduleid_t	m;
-	char 		c;
-
-	if (strstr(buffer, EDGE_LBL_RACK "/") == buffer) {
-		form = MODULE_FORMAT_LONG;
-		buffer += strlen(EDGE_LBL_RACK "/");
-
-		/* A long module ID must be exactly 5 non-template chars. */
-		if (strlen(buffer) != strlen("/" EDGE_LBL_RPOS "/") + 5)
-			return -1;
-	}
-	else {
-		form = MODULE_FORMAT_BRIEF;
-
-		/* A brief module id must be exactly 6 characters */
-		if (strlen(buffer) != 6)
-			return -2;
-	}
-
-	/* The rack number must be exactly 3 digits */
-	if (!(isdigit(buffer[0]) && isdigit(buffer[1]) && isdigit(buffer[2])))
-		return -3;
-
-	rack = 0;
-	v = *buffer++ - '0';
-	if (v > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-		return -4;
-	RACK_ADD_CLASS(rack, v);
-
-	v = *buffer++ - '0';
-	if (v > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-		return -5;
-	RACK_ADD_GROUP(rack, v);
-
-	v = *buffer++ - '0';
-	/* rack numbers are 1-based */
-	if (v-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-		return -6;
-	RACK_ADD_NUM(rack, v);
-
-	if (form == MODULE_FORMAT_BRIEF) {
-		/* Next should be a module type character.  Accept ucase or lcase. */
-		c = *buffer++;
-		if (!isalpha(c))
-			return -7;
-
-		/* strchr() returns a pointer into brick_types[], or NULL */
-		type = (unsigned int)(strchr(brick_types, tolower(c)) - brick_types);
-		if (type > MODULE_BTYPE_MASK >> MODULE_BTYPE_SHFT)
-			return -8;
-	}
-	else {
-		/* Hardcode the module type, and skip over the boilerplate */
-		type = MODULE_CBRICK;
-
-		if (strstr(buffer, "/" EDGE_LBL_RPOS "/") != buffer)
-			return -9;
-
-		buffer += strlen("/" EDGE_LBL_RPOS "/");
-	}
-		
-	/* The bay number is last.  Make sure it's exactly two digits */
-
-	if (!(isdigit(buffer[0]) && isdigit(buffer[1]) && !buffer[2]))
-		return -10;
-
-	bay = 10 * (buffer[0] - '0') + (buffer[1] - '0');
-
-	if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-		return -11;
-
-	m = RBT_TO_MODULE(rack, bay, type);
-
-	/* avoid sign extending the moduleid_t */
-	return (int)(unsigned short)m;
-}
-
-#else /* CONFIG_IA64_SGI_SN1 */
-
-/*
- * Format a module id for printing.
- */
-void
-format_module_id(char *buffer, moduleid_t m, int fmt)
-{
-    if (fmt == MODULE_FORMAT_BRIEF) {
-		sprintf(buffer, "%d", m);
-    }
-    else if (fmt == MODULE_FORMAT_LONG) {
-		sprintf(buffer, EDGE_LBL_MODULE "/%d", m);
-    }
-}
-
-/*
- * Parse a module id, in either brief or long form.
- * Returns < 0 on error.
- */
-int
-parse_module_id(char *buffer)
-{
-    moduleid_t m;
-    char c;
-
-    if (strstr(buffer, EDGE_LBL_MODULE "/") == buffer)
-	buffer += strlen(EDGE_LBL_MODULE "/");
-
-    for (m = 0; *buffer; buffer++) {
-	c = *buffer;
-	if (!isdigit(c))
-	    return -1;
-	m = 10 * m + (c - '0');
-    }
-
-    /* avoid sign extending the moduleid_t */
-    return (int)(unsigned short)m;
-}
-
-#endif /* CONFIG_IA64_SGI_SN1 */
-
-
diff -Nru a/arch/ia64/sn/io/klgraph.c b/arch/ia64/sn/io/klgraph.c
--- a/arch/ia64/sn/io/klgraph.c	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,804 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * klgraph.c-
- *      This file specifies the interface between the kernel and the PROM's
- *      configuration data structures.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/kldir.h>
-#include <asm/sn/gda.h> 
-#include <asm/sn/klconfig.h>
-#include <asm/sn/router.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/hcl_util.h>
-
-/* #define KLGRAPH_DEBUG 1 */
-#ifdef KLGRAPH_DEBUG
-#define GRPRINTF(x)	printk x
-#define CE_GRPANIC	CE_PANIC
-#else
-#define GRPRINTF(x)
-#define CE_GRPANIC	CE_PANIC
-#endif
-
-#include <asm/sn/sn_private.h>
-
-extern char arg_maxnodes[];
-extern u64 klgraph_addr[];
-
-/*
- * Support for verbose inventory via hardware graph. 
- * klhwg_invent_alloc allocates the necessary size of inventory information
- * and fills in the generic information.
- */
-invent_generic_t *
-klhwg_invent_alloc(cnodeid_t cnode, int class, int size)
-{
-	invent_generic_t *invent;
-
-	invent = kern_malloc(size);
-	if (!invent) return NULL;
-	
-	invent->ig_module = NODE_MODULEID(cnode);
-	invent->ig_slot = SLOTNUM_GETSLOT(NODE_SLOTID(cnode));
-	invent->ig_invclass = class;
-
-	return invent;
-}
-
-/* 
- * Add information about the baseio prom version number
- * as a part of detailed inventory info in the hwgraph.
- */
-void
-klhwg_baseio_inventory_add(devfs_handle_t baseio_vhdl,cnodeid_t cnode)
-{
-	invent_miscinfo_t	*baseio_inventory;
-	unsigned char		version = 0,revision = 0;
-
-	/* Allocate memory for the "detailed inventory" info
-	 * for the baseio
-	 */
-	baseio_inventory = (invent_miscinfo_t *) 
-		klhwg_invent_alloc(cnode, INV_PROM, sizeof(invent_miscinfo_t));
-	baseio_inventory->im_type = INV_IO6PROM;
-	/* Read the io6prom revision from the nvram */
-#ifdef LATER
-	nvram_prom_version_get(&version,&revision);
-#endif
-	/* Store the revision info  in the inventory */
-	baseio_inventory->im_version = version;
-	baseio_inventory->im_rev = revision;
-	/* Put the inventory info in the hardware graph */
-	hwgraph_info_add_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT, 
-			     (arbitrary_info_t) baseio_inventory);
-	/* Make the information available to the user programs
-	 * thru hwgfs.
-	 */
-        hwgraph_info_export_LBL(baseio_vhdl, INFO_LBL_DETAIL_INVENT,
-				sizeof(invent_miscinfo_t));
-}
-
-char	*hub_rev[] = {
-	"0.0",
-	"1.0",
-	"2.0",
-	"2.1",
-	"2.2",
-	"2.3"
-};
-
-/*
- * Add detailed cpu inventory info to the hardware graph.
- */
-void
-klhwg_hub_invent_info(devfs_handle_t hubv,
-		      cnodeid_t cnode, 
-		      klhub_t *hub)
-{
-	invent_miscinfo_t *hub_invent;
-
-	hub_invent = (invent_miscinfo_t *) 
-	    klhwg_invent_alloc(cnode, INV_MISC, sizeof(invent_miscinfo_t));
-	if (!hub_invent)
-	    return;
-
-	if (KLCONFIG_INFO_ENABLED((klinfo_t *)hub))
-	    hub_invent->im_gen.ig_flag = INVENT_ENABLED;
-
-	hub_invent->im_type = INV_HUB;
-	hub_invent->im_rev = hub->hub_info.revision;
-	hub_invent->im_speed = hub->hub_speed;
-	hwgraph_info_add_LBL(hubv, INFO_LBL_DETAIL_INVENT, 
-			     (arbitrary_info_t) hub_invent);
-        hwgraph_info_export_LBL(hubv, INFO_LBL_DETAIL_INVENT,
-				sizeof(invent_miscinfo_t));
-}
-
-/* ARGSUSED */
-void
-klhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode)
-{
-#if defined(CONFIG_IA64_SGI_SN1)
-	devfs_handle_t myhubv;
-	devfs_handle_t hub_mon;
-	devfs_handle_t synergy;
-	devfs_handle_t fsb0;
-	devfs_handle_t fsb1;
-	int rc;
-	extern struct file_operations hub_mon_fops;
-
-	GRPRINTF(("klhwg_add_hub: adding %s\n", EDGE_LBL_HUB));
-
-	(void) hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv);
-	rc = device_master_set(myhubv, node_vertex);
-
-	/*
-	 * hub perf stats.
-	 */
-	rc = hwgraph_info_add_LBL(myhubv, INFO_LBL_HUB_INFO,
-                        (arbitrary_info_t)(&NODEPDA(cnode)->hubstats));
-
-	if (rc != GRAPH_SUCCESS) {
-		printk(KERN_WARNING  "klhwg_add_hub: Can't add hub info label 0x%p, code %d",
-			(void *)myhubv, rc);
-	}
-
-	klhwg_hub_invent_info(myhubv, cnode, hub);
-
-	hub_mon = hwgraph_register(myhubv, EDGE_LBL_PERFMON,
-	    0, DEVFS_FL_AUTO_DEVNUM,
-	    0, 0,
-	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-	    &hub_mon_fops,
-	    (void *)(long)cnode);
-
-	init_hub_stats(cnode, NODEPDA(cnode));
-
-	/*
-	 * synergy perf
-	 */
-	(void) hwgraph_path_add(myhubv, EDGE_LBL_SYNERGY, &synergy);
-	(void) hwgraph_path_add(synergy, "0", &fsb0);
-	(void) hwgraph_path_add(synergy, "1", &fsb1);
-
-	fsb0 = hwgraph_register(fsb0, EDGE_LBL_PERFMON,
-	    0, DEVFS_FL_AUTO_DEVNUM,
-	    0, 0,
-	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-	    &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 0));
-
-	fsb1 = hwgraph_register(fsb1, EDGE_LBL_PERFMON,
-	    0, DEVFS_FL_AUTO_DEVNUM,
-	    0, 0,
-	    S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-	    &synergy_mon_fops, (void *)SYNERGY_PERF_INFO(cnode, 1));
-#endif /* CONFIG_IA64_SGI_SN1 */
-}
-
-void
-klhwg_add_xbow(cnodeid_t cnode, nasid_t nasid)
-{
-	lboard_t *brd;
-	klxbow_t *xbow_p;
-	nasid_t hub_nasid;
-	cnodeid_t hub_cnode;
-	int widgetnum;
-	devfs_handle_t xbow_v, hubv;
-	/*REFERENCED*/
-	graph_error_t err;
-
-	if ((brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_IOBRICK_XBOW)) == NULL)
-			return;
-
-	if (KL_CONFIG_DUPLICATE_BOARD(brd))
-	    return;
-
-	GRPRINTF(("klhwg_add_xbow: adding cnode %d nasid %d xbow edges\n",
-			cnode, nasid));
-
-	if ((xbow_p = (klxbow_t *)find_component(brd, NULL, KLSTRUCT_XBOW))
-	    == NULL)
-	    return;
-
-#ifdef	LATER
-	/*
-	 * We cannot support this function in devfs .. see below where 
-	 * we use hwgraph_path_add() to create this vertex with a known 
-	 * name.
-	 */
-	err = hwgraph_vertex_create(&xbow_v);
-	ASSERT(err == GRAPH_SUCCESS);
-
-	xswitch_vertex_init(xbow_v);
-#endif /* LATER */
-
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
-		if (!XBOW_PORT_TYPE_HUB(xbow_p, widgetnum)) 
-		    continue;
-
-		hub_nasid = XBOW_PORT_NASID(xbow_p, widgetnum);
-		if (hub_nasid == INVALID_NASID) {
-			printk(KERN_WARNING  "hub widget %d, skipping xbow graph\n", widgetnum);
-			continue;
-		}
-
-		hub_cnode = NASID_TO_COMPACT_NODEID(hub_nasid);
-
-		if (is_specified(arg_maxnodes) && hub_cnode == INVALID_CNODEID) {
-			continue;
-		}
-			
-		hubv = cnodeid_to_vertex(hub_cnode);
-
-		err = hwgraph_path_add(hubv, EDGE_LBL_XTALK, &xbow_v);
-                if (err != GRAPH_SUCCESS) {
-                        if (err == GRAPH_DUP)
-                                printk(KERN_WARNING  "klhwg_add_xbow: Check for "
-                                        "working routers and router links!");
-
-                        PRINT_PANIC("klhwg_add_xbow: Failed to add "
-                                "edge: vertex 0x%p to vertex 0x%p,"
-                                "error %d\n",
-                                (void *)hubv, (void *)xbow_v, err);
-                }
-		xswitch_vertex_init(xbow_v); 
-
-		NODEPDA(hub_cnode)->xbow_vhdl = xbow_v;
-
-		/*
-		 * XXX - This won't work is we ever hook up two hubs
-		 * by crosstown through a crossbow.
-		 */
-		if (hub_nasid != nasid) {
-			NODEPDA(hub_cnode)->xbow_peer = nasid;
-			NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->xbow_peer =
-				hub_nasid;
-		}
-
-		GRPRINTF(("klhwg_add_xbow: adding port nasid %d %s to vertex 0x%p\n",
-			hub_nasid, EDGE_LBL_XTALK, hubv));
-
-#ifdef	LATER
-		err = hwgraph_edge_add(hubv, xbow_v, EDGE_LBL_XTALK);
-		if (err != GRAPH_SUCCESS) {
-			if (err == GRAPH_DUP)
-				printk(KERN_WARNING  "klhwg_add_xbow: Check for "
-					"working routers and router links!");
-
-			PRINT_PANIC("klhwg_add_xbow: Failed to add "
-				"edge: vertex 0x%p (0x%p) to vertex 0x%p (0x%p), "
-				"error %d\n",
-				hubv, hubv, xbow_v, xbow_v, err);
-		}
-#endif
-	}
-}
-
-
-/* ARGSUSED */
-void
-klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap)
-{
-	nasid_t nasid;
-	lboard_t *brd;
-	klhub_t *hub;
-	devfs_handle_t node_vertex = NULL;
-	char path_buffer[100];
-	int rv;
-	char *s;
-	int board_disabled = 0;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-	brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-	GRPRINTF(("klhwg_add_node: Adding cnode %d, nasid %d, brd 0x%p\n",
-                cnode, nasid, brd));
-	ASSERT(brd);
-
-	do {
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(brd, path_buffer);
-
-		GRPRINTF(("klhwg_add_node: adding %s to vertex 0x%p\n",
-			path_buffer, hwgraph_root));
-		rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex);
-
-		if (rv != GRAPH_SUCCESS)
-			PRINT_PANIC("Node vertex creation failed.  "
-					  "Path == %s",
-				path_buffer);
-
-		hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
-		ASSERT(hub);
-		if(hub->hub_info.flags & KLINFO_ENABLE)
-			board_disabled = 0;
-		else
-			board_disabled = 1;
-		
-		if(!board_disabled) {
-			mark_nodevertex_as_node(node_vertex,
-					    cnode + board_disabled * numnodes);
-
-			s = dev_to_name(node_vertex, path_buffer, sizeof(path_buffer));
-			NODEPDA(cnode)->hwg_node_name =
-						kmalloc(strlen(s) + 1,
-						GFP_KERNEL);
-			ASSERT_ALWAYS(NODEPDA(cnode)->hwg_node_name != NULL);
-			strcpy(NODEPDA(cnode)->hwg_node_name, s);
-
-			hubinfo_set(node_vertex, NODEPDA(cnode)->pdinfo);
-
-			/* Set up node board's slot */
-			NODEPDA(cnode)->slotdesc = brd->brd_slot;
-
-			/* Set up the module we're in */
-			NODEPDA(cnode)->module_id = brd->brd_module;
-			NODEPDA(cnode)->module = module_lookup(brd->brd_module);
-		}
-
-		if(!board_disabled)
-		klhwg_add_hub(node_vertex, hub, cnode);
-		
-		brd = KLCF_NEXT(brd);
-		if (brd)
-			brd = find_lboard(brd, KLTYPE_SNIA);
-		else
-			break;
-	} while(brd);
-}
-
-
-/* ARGSUSED */
-void
-klhwg_add_all_routers(devfs_handle_t hwgraph_root)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd;
-	devfs_handle_t node_vertex;
-	char path_buffer[100];
-	int rv;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		GRPRINTF(("klhwg_add_all_routers: adding router on cnode %d\n",
-			cnode));
-
-		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
-				KLTYPE_ROUTER);
-
-		if (!brd)
-			/* No routers stored in this node's memory */
-			continue;
-
-		do {
-			ASSERT(brd);
-			GRPRINTF(("Router board struct is %p\n", brd));
-
-			/* Don't add duplicate boards. */
-			if (brd->brd_flags & DUPLICATE_BOARD)
-				continue;
-
-			GRPRINTF(("Router 0x%p module number is %d\n", brd, brd->brd_module));
-			/* Generate a hardware graph path for this board. */
-			board_to_path(brd, path_buffer);
-
-			GRPRINTF(("Router path is %s\n", path_buffer));
-
-			/* Add the router */
-			GRPRINTF(("klhwg_add_all_routers: adding %s to vertex 0x%p\n",
-				path_buffer, hwgraph_root));
-			rv = hwgraph_path_add(hwgraph_root, path_buffer, &node_vertex);
-
-			if (rv != GRAPH_SUCCESS)
-				PRINT_PANIC("Router vertex creation "
-						  "failed.  Path == %s",
-					path_buffer);
-
-			GRPRINTF(("klhwg_add_all_routers: get next board from 0x%p\n",
-					brd));
-		/* Find the rest of the routers stored on this node. */
-		} while ( (brd = find_lboard_class(KLCF_NEXT(brd),
-			 KLTYPE_ROUTER)) );
-
-		GRPRINTF(("klhwg_add_all_routers: Done.\n"));
-	}
-
-}
-
-/* ARGSUSED */
-void
-klhwg_connect_one_router(devfs_handle_t hwgraph_root, lboard_t *brd,
-			 cnodeid_t cnode, nasid_t nasid)
-{
-	klrou_t *router;
-	char path_buffer[50];
-	char dest_path[50];
-	devfs_handle_t router_hndl;
-	devfs_handle_t dest_hndl;
-	int rc;
-	int port;
-	lboard_t *dest_brd;
-
-	GRPRINTF(("klhwg_connect_one_router: Connecting router on cnode %d\n",
-			cnode));
-
-	/* Don't add duplicate boards. */
-	if (brd->brd_flags & DUPLICATE_BOARD) {
-		GRPRINTF(("klhwg_connect_one_router: Duplicate router 0x%p on cnode %d\n",
-			brd, cnode));
-		return;
-	}
-
-	/* Generate a hardware graph path for this board. */
-	board_to_path(brd, path_buffer);
-
-	rc = hwgraph_traverse(hwgraph_root, path_buffer, &router_hndl);
-
-	if (rc != GRAPH_SUCCESS && is_specified(arg_maxnodes))
-			return;
-
-	if (rc != GRAPH_SUCCESS)
-		printk(KERN_WARNING  "Can't find router: %s", path_buffer);
-
-	/* We don't know what to do with multiple router components */
-	if (brd->brd_numcompts != 1) {
-		PRINT_PANIC("klhwg_connect_one_router: %d cmpts on router\n",
-			brd->brd_numcompts);
-		return;
-	}
-
-
-	/* Convert component 0 to klrou_t ptr */
-	router = (klrou_t *)NODE_OFFSET_TO_K0(NASID_GET(brd),
-					      brd->brd_compts[0]);
-
-	for (port = 1; port <= MAX_ROUTER_PORTS; port++) {
-		/* See if the port's active */
-		if (router->rou_port[port].port_nasid == INVALID_NASID) {
-			GRPRINTF(("klhwg_connect_one_router: port %d inactive.\n",
-				 port));
-			continue;
-		}
-		if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(router->rou_port[port].port_nasid) 
-		    == INVALID_CNODEID) {
-			continue;
-		}
-
-		dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
-				router->rou_port[port].port_nasid,
-				router->rou_port[port].port_offset);
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(dest_brd, dest_path);
-
-		rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl);
-
-		if (rc != GRAPH_SUCCESS) {
-			if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd))
-				continue;
-			PRINT_PANIC("Can't find router: %s", dest_path);
-		}
-		GRPRINTF(("klhwg_connect_one_router: Link from %s/%d to %s\n",
-			  path_buffer, port, dest_path));
-
-		sprintf(dest_path, "%d", port);
-
-		rc = hwgraph_edge_add(router_hndl, dest_hndl, dest_path);
-
-		if (rc == GRAPH_DUP) {
-			GRPRINTF(("Skipping port %d. nasid %d %s/%s\n",
-				  port, router->rou_port[port].port_nasid,
-				  path_buffer, dest_path));
-			continue;
-		}
-
-		if (rc != GRAPH_SUCCESS && !is_specified(arg_maxnodes))
-			PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p error 0x%x\n",
-				path_buffer, dest_path, (void *)dest_hndl, rc);
-		
-	}
-}
-
-
-void
-klhwg_connect_routers(devfs_handle_t hwgraph_root)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		GRPRINTF(("klhwg_connect_routers: Connecting routers on cnode %d\n",
-			cnode));
-
-		brd = find_lboard_class((lboard_t *)KL_CONFIG_INFO(nasid),
-				KLTYPE_ROUTER);
-
-		if (!brd)
-			continue;
-
-		do {
-
-			nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-			klhwg_connect_one_router(hwgraph_root, brd,
-						 cnode, nasid);
-
-		/* Find the rest of the routers stored on this node. */
-		} while ( (brd = find_lboard_class(KLCF_NEXT(brd), KLTYPE_ROUTER)) );
-	}
-}
-
-
-
-void
-klhwg_connect_hubs(devfs_handle_t hwgraph_root)
-{
-	nasid_t nasid;
-	cnodeid_t cnode;
-	lboard_t *brd;
-	klhub_t *hub;
-	lboard_t *dest_brd;
-	devfs_handle_t hub_hndl;
-	devfs_handle_t dest_hndl;
-	char path_buffer[50];
-	char dest_path[50];
-	graph_error_t rc;
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-		GRPRINTF(("klhwg_connect_hubs: Connecting hubs on cnode %d\n",
-			cnode));
-
-		brd = find_lboard((lboard_t *)KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-		ASSERT(brd);
-
-		hub = (klhub_t *)find_first_component(brd, KLSTRUCT_HUB);
-		ASSERT(hub);
-
-		/* See if the port's active */
-		if (hub->hub_port.port_nasid == INVALID_NASID) {
-			GRPRINTF(("klhwg_connect_hubs: port inactive.\n"));
-			continue;
-		}
-
-		if (is_specified(arg_maxnodes) && NASID_TO_COMPACT_NODEID(hub->hub_port.port_nasid) == INVALID_CNODEID)
-			continue;
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(brd, path_buffer);
-
-		GRPRINTF(("klhwg_connect_hubs: Hub path is %s.\n", path_buffer));
-		rc = hwgraph_traverse(hwgraph_root, path_buffer, &hub_hndl);
-
-		if (rc != GRAPH_SUCCESS)
-			printk(KERN_WARNING  "Can't find hub: %s", path_buffer);
-
-		dest_brd = (lboard_t *)NODE_OFFSET_TO_K0(
-				hub->hub_port.port_nasid,
-				hub->hub_port.port_offset);
-
-		/* Generate a hardware graph path for this board. */
-		board_to_path(dest_brd, dest_path);
-
-		rc = hwgraph_traverse(hwgraph_root, dest_path, &dest_hndl);
-
-		if (rc != GRAPH_SUCCESS) {
-			if (is_specified(arg_maxnodes) && KL_CONFIG_DUPLICATE_BOARD(dest_brd))
-				continue;
-			PRINT_PANIC("Can't find board: %s", dest_path);
-		} else {
-		
-
-			GRPRINTF(("klhwg_connect_hubs: Link from %s to %s.\n",
-			  path_buffer, dest_path));
-
-			rc = hwgraph_edge_add(hub_hndl, dest_hndl, EDGE_LBL_INTERCONNECT);
-
-			if (rc != GRAPH_SUCCESS)
-				PRINT_PANIC("Can't create edge: %s/%s to vertex 0x%p, error 0x%x\n",
-				path_buffer, dest_path, (void *)dest_hndl, rc);
-
-		}
-	}
-}
-
-/* Store the pci/vme disabled board information as extended administrative
- * hints which can later be used by the drivers using the device/driver
- * admin interface. 
- */
-void
-klhwg_device_disable_hints_add(void)
-{
-	cnodeid_t	cnode; 		/* node we are looking at */
-	nasid_t		nasid;		/* nasid of the node */
-	lboard_t	*board;		/* board we are looking at */
-	int		comp_index;	/* component index */
-	klinfo_t	*component;	/* component in the board we are
-					 * looking at 
-					 */
-	char		device_name[MAXDEVNAME];
-	
-#ifdef	LATER
-	device_admin_table_init();
-#endif
-	for(cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-		board = (lboard_t *)KL_CONFIG_INFO(nasid);
-		/* Check out all the board info stored  on a node */
-		while(board) {
-			/* No need to look at duplicate boards or non-io 
-			 * boards
-			 */
-			if (KL_CONFIG_DUPLICATE_BOARD(board) ||
-			    KLCLASS(board->brd_type) != KLCLASS_IO) {
-				board = KLCF_NEXT(board);
-				continue;
-			}
-			/* Check out all the components of a board */
-			for (comp_index = 0; 
-			     comp_index < KLCF_NUM_COMPS(board);
-			     comp_index++) {
-				component = KLCF_COMP(board,comp_index);
-				/* If the component is enabled move on to
-				 * the next component
-				 */
-				if (KLCONFIG_INFO_ENABLED(component))
-					continue;
-				/* NOTE : Since the prom only supports
-				 * the disabling of pci devices the following
-				 * piece of code makes sense. 
-				 * Make sure that this assumption is valid
-				 */
-				/* This component is disabled. Store this
-				 * hint in the extended device admin table
-				 */
-				/* Get the canonical name of the pci device */
-				device_component_canonical_name_get(board,
-							    component,
-							    device_name);
-#ifdef	LATER
-				device_admin_table_update(device_name,
-							  ADMIN_LBL_DISABLED,
-							  "yes");
-#endif
-#ifdef DEBUG
-				printf("%s DISABLED\n",device_name);
-#endif				
-			}
-			/* go to the next board info stored on this 
-			 * node 
-			 */
-			board = KLCF_NEXT(board);
-		}
-	}
-}
-
-void
-klhwg_add_all_modules(devfs_handle_t hwgraph_root)
-{
-	cmoduleid_t	cm;
-	char		name[128];
-	devfs_handle_t	vhdl;
-	int		rc;
-	char		buffer[16];
-
-	/* Add devices under each module */
-
-	for (cm = 0; cm < nummodules; cm++) {
-		/* Use module as module vertex fastinfo */
-
-#ifdef __ia64
-		memset(buffer, 0, 16);
-		format_module_id(buffer, modules[cm]->id, MODULE_FORMAT_BRIEF);
-		sprintf(name, EDGE_LBL_MODULE "/%s", buffer);
-#else
-		sprintf(name, EDGE_LBL_MODULE "/%x", modules[cm]->id);
-#endif
-
-		rc = hwgraph_path_add(hwgraph_root, name, &vhdl);
-		ASSERT(rc == GRAPH_SUCCESS);
-		rc = rc;
-
-		hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) modules[cm]);
-
-		/* Add system controller */
-
-#ifdef __ia64
-		sprintf(name,
-			EDGE_LBL_MODULE "/%s/" EDGE_LBL_L1,
-			buffer);
-#else
-		sprintf(name,
-			EDGE_LBL_MODULE "/%x/" EDGE_LBL_L1,
-			modules[cm]->id);
-#endif
-
-		rc = hwgraph_path_add(hwgraph_root, name, &vhdl);
-		ASSERT_ALWAYS(rc == GRAPH_SUCCESS); 
-		rc = rc;
-
-		hwgraph_info_add_LBL(vhdl,
-				     INFO_LBL_ELSC,
-				     (arbitrary_info_t) (__psint_t) 1);
-
-#ifdef	LATER
-		sndrv_attach(vhdl);
-#else
-		/*
-		 * We need to call the drivers attach routine ..
-		 */
-		FIXME("klhwg_add_all_modules: Need code to call driver attach.\n");
-#endif
-	}
-}
-
-void
-klhwg_add_all_nodes(devfs_handle_t hwgraph_root)
-{
-	//gda_t		*gdap = GDA;
-	gda_t		*gdap;
-	cnodeid_t	cnode;
-
-	gdap = (gda_t *)0xe000000000002400;
-
-	FIXME("klhwg_add_all_nodes: FIX GDA\n");
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		ASSERT(gdap->g_nasidtable[cnode] != INVALID_NASID);
-		klhwg_add_node(hwgraph_root, cnode, gdap);
-	}
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		ASSERT(gdap->g_nasidtable[cnode] != INVALID_NASID);
-
-		klhwg_add_xbow(cnode, gdap->g_nasidtable[cnode]);
-	}
-
-	/*
-	 * As for router hardware inventory information, we set this
-	 * up in router.c. 
-	 */
-	
-	klhwg_add_all_routers(hwgraph_root);
-	klhwg_connect_routers(hwgraph_root);
-	klhwg_connect_hubs(hwgraph_root);
-
-	/* Assign guardian nodes to each of the
-	 * routers in the system.
-	 */
-
-#ifdef	LATER
-	router_guardians_set(hwgraph_root);
-#endif
-
-	/* Go through the entire system's klconfig
-	 * to figure out which pci components have been disabled
-	 */
-	klhwg_device_disable_hints_add();
-
-}
diff -Nru a/arch/ia64/sn/io/klgraph_hack.c b/arch/ia64/sn/io/klgraph_hack.c
--- a/arch/ia64/sn/io/klgraph_hack.c	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,341 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-/*
- * This is a temporary file that statically initializes the expected 
- * initial klgraph information that is normally provided by prom.
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/simulator.h>
-
-extern u64 klgraph_addr[];
-void * real_port;
-void * real_io_base;
-void * real_addr;
-
-char *BW0 = NULL;
-
-kl_config_hdr_t *linux_klcfg;
-
-#ifdef DEFINE_DUMP_RTNS
-/* forward declarations */
-static void dump_ii(void), dump_crossbow(void);
-static void clear_ii_error(void);
-#endif /* DEFINE_DUMP_RTNS */
-
-#define SYNERGY_WIDGET          ((char *)0xc0000e0000000000)
-#define SYNERGY_SWIZZLE         ((char *)0xc0000e0000000400)
-#define HUBREG                  ((char *)0xc0000a0001e00000)
-#define WIDGET0                 ((char *)0xc0000a0000000000)
-#define WIDGET4                 ((char *)0xc0000a0000000004)
-
-#define SYNERGY_WIDGET          ((char *)0xc0000e0000000000)
-#define SYNERGY_SWIZZLE         ((char *)0xc0000e0000000400)
-#define HUBREG                  ((char *)0xc0000a0001e00000)
-#define WIDGET0                 ((char *)0xc0000a0000000000)
-
-#define convert(a,b,c) temp = (u64 *)a; *temp = b; temp++; *temp = c
-
-void
-klgraph_hack_init(void)
-{
-
-	u64     *temp;
-
-#ifdef CONFIG_IA64_SGI_SN1
-	/*
-	 * We need to know whether we are booting from PROM or 
-	 * boot from disk.
-	 */
-	linux_klcfg = (kl_config_hdr_t *)0xe000000000030000;
-	if (linux_klcfg->ch_magic == 0xbeedbabe) {
-		return;
-	} else {
-		panic("klgraph_hack_init: Unable to locate KLCONFIG TABLE\n");
-	}
-
-	convert(0x0000000000030000, 0x00000000beedbabe, 0x0000004800000000);
-
-#else
-
-	if (IS_RUNNING_ON_SIMULATOR()) {
-		printk("Creating FAKE Klconfig Structure for Embeded Kernel\n");
-		klgraph_addr[0] = 0xe000003000030000;
-
-        /*
-         * klconfig entries initialization - mankato
-         */
-        convert(0xe000003000030000, 0x00000000beedbabe, 0x0000004800000000);
-        convert(0xe000003000030010, 0x0003007000000018, 0x800002000f820178);
-        convert(0xe000003000030020, 0x80000a000f024000, 0x800002000f800000);
-        convert(0xe000003000030030, 0x0300fafa00012580, 0x00000000040f0000);
-        convert(0xe000003000030040, 0x0000000000000000, 0x0003097000030070);
-        convert(0xe000003000030050, 0x00030970000303b0, 0x0003181000033f70);
-        convert(0xe000003000030060, 0x0003d51000037570, 0x0000000000038330);
-        convert(0xe000003000030070, 0x0203110100030140, 0x0001000000000101);
-        convert(0xe000003000030080, 0x0900000000000000, 0x000000004e465e67);
-        convert(0xe000003000030090, 0x0003097000000000, 0x00030b1000030a40);
-        convert(0xe0000030000300a0, 0x00030cb000030be0, 0x000315a0000314d0);
-        convert(0xe0000030000300b0, 0x0003174000031670, 0x0000000000000000);
-        convert(0xe000003000030100, 0x000000000000001a, 0x3350490000000000);
-        convert(0xe000003000030110, 0x0000000000000037, 0x0000000000000000);
-        convert(0xe000003000030140, 0x0002420100030210, 0x0001000000000101);
-        convert(0xe000003000030150, 0x0100000000000000, 0xffffffffffffffff);
-        convert(0xe000003000030160, 0x00030d8000000000, 0x0000000000030e50);
-        convert(0xe0000030000301c0, 0x0000000000000000, 0x0000000000030070);
-        convert(0xe0000030000301d0, 0x0000000000000025, 0x424f490000000000);
-        convert(0xe0000030000301e0, 0x000000004b434952, 0x0000000000000000);
-        convert(0xe000003000030210, 0x00027101000302e0, 0x00010000000e4101);
-        convert(0xe000003000030220, 0x0200000000000000, 0xffffffffffffffff);
-        convert(0xe000003000030230, 0x00030f2000000000, 0x0000000000030ff0);
-        convert(0xe000003000030290, 0x0000000000000000, 0x0000000000030140);
-        convert(0xe0000030000302a0, 0x0000000000000026, 0x7262490000000000);
-        convert(0xe0000030000302b0, 0x00000000006b6369, 0x0000000000000000);
-        convert(0xe0000030000302e0, 0x0002710100000000, 0x00010000000f3101);
-        convert(0xe0000030000302f0, 0x0500000000000000, 0xffffffffffffffff);
-        convert(0xe000003000030300, 0x000310c000000000, 0x0003126000031190);
-        convert(0xe000003000030310, 0x0003140000031330, 0x0000000000000000);
-        convert(0xe000003000030360, 0x0000000000000000, 0x0000000000030140);
-        convert(0xe000003000030370, 0x0000000000000029, 0x7262490000000000);
-        convert(0xe000003000030380, 0x00000000006b6369, 0x0000000000000000);
-        convert(0xe000003000030970, 0x0000000002010102, 0x0000000000000000);
-        convert(0xe000003000030980, 0x000000004e465e67, 0xffffffff00000000);
-        /* convert(0x00000000000309a0, 0x0000000000037570, 0x0000000100000000); */
-        convert(0xe0000030000309a0, 0x0000000000037570, 0xffffffff00000000);
-        convert(0xe0000030000309b0, 0x0000000000030070, 0x0000000000000000);
-        convert(0xe0000030000309c0, 0x000000000003f420, 0x0000000000000000);
-        convert(0xe000003000030a40, 0x0000000002010125, 0x0000000000000000);
-        convert(0xe000003000030a50, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe000003000030a70, 0x0000000000037b78, 0x0000000000000000);
-        convert(0xe000003000030b10, 0x0000000002010125, 0x0000000000000000);
-        convert(0xe000003000030b20, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe000003000030b40, 0x0000000000037d30, 0x0000000000000001);
-        convert(0xe000003000030be0, 0x00000000ff010203, 0x0000000000000000);
-        convert(0xe000003000030bf0, 0xffffffffffffffff, 0xffffffff000000ff);
-        convert(0xe000003000030c10, 0x0000000000037ee8, 0x0100010000000200);
-        convert(0xe000003000030cb0, 0x00000000ff310111, 0x0000000000000000);
-        convert(0xe000003000030cc0, 0xffffffffffffffff, 0x0000000000000000);
-        convert(0xe000003000030d80, 0x0000000002010104, 0x0000000000000000);
-        convert(0xe000003000030d90, 0xffffffffffffffff, 0x00000000000000ff);
-        convert(0xe000003000030db0, 0x0000000000037f18, 0x0000000000000000);
-        convert(0xe000003000030dc0, 0x0000000000000000, 0x0003007000060000);
-        convert(0xe000003000030de0, 0x0000000000000000, 0x0003021000050000);
-        convert(0xe000003000030df0, 0x000302e000050000, 0x0000000000000000);
-        convert(0xe000003000030e30, 0x0000000000000000, 0x000000000000000a);
-        convert(0xe000003000030e50, 0x00000000ff00011a, 0x0000000000000000);
-        convert(0xe000003000030e60, 0xffffffffffffffff, 0x0000000000000000);
-        convert(0xe000003000030e80, 0x0000000000037fe0, 0x9e6e9e9e9e9e9e9e);
-        convert(0xe000003000030e90, 0x000000000000bc6e, 0x0000000000000000);
-        convert(0xe000003000030f20, 0x0000000002010205, 0x00000000d0020000);
-        convert(0xe000003000030f30, 0xffffffffffffffff, 0x0000000e0000000e);
-        convert(0xe000003000030f40, 0x000000000000000e, 0x0000000000000000);
-        convert(0xe000003000030f50, 0x0000000000038010, 0x00000000000007ff);
-        convert(0xe000003000030f70, 0x0000000000000000, 0x0000000022001077);
-        convert(0xe000003000030fa0, 0x0000000000000000, 0x000000000003f4a8);
-        convert(0xe000003000030ff0, 0x0000000000310120, 0x0000000000000000);
-        convert(0xe000003000031000, 0xffffffffffffffff, 0xffffffff00000002);
-        convert(0xe000003000031010, 0x000000000000000e, 0x0000000000000000);
-        convert(0xe000003000031020, 0x0000000000038088, 0x0000000000000000);
-        convert(0xe0000030000310c0, 0x0000000002010205, 0x00000000d0020000);
-        convert(0xe0000030000310d0, 0xffffffffffffffff, 0x0000000f0000000f);
-        convert(0xe0000030000310e0, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe0000030000310f0, 0x00000000000380b8, 0x00000000000007ff);
-        convert(0xe000003000031120, 0x0000000022001077, 0x00000000000310a9);
-        convert(0xe000003000031130, 0x00000000580211c1, 0x000000008009104c);
-        convert(0xe000003000031140, 0x0000000000000000, 0x000000000003f4c0);
-        convert(0xe000003000031190, 0x0000000000310120, 0x0000000000000000);
-        convert(0xe0000030000311a0, 0xffffffffffffffff, 0xffffffff00000003);
-        convert(0xe0000030000311b0, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe0000030000311c0, 0x0000000000038130, 0x0000000000000000);
-        convert(0xe000003000031260, 0x0000000000110106, 0x0000000000000000);
-        convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004);
-        convert(0xe000003000031270, 0xffffffffffffffff, 0xffffffff00000004);
-        convert(0xe000003000031280, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe0000030000312a0, 0x00000000ff110013, 0x0000000000000000);
-        convert(0xe0000030000312b0, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe0000030000312c0, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe0000030000312e0, 0x0000000000110012, 0x0000000000000000);
-        convert(0xe0000030000312f0, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe000003000031300, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe000003000031310, 0x0000000000038160, 0x0000000000000000);
-        convert(0xe000003000031330, 0x00000000ff310122, 0x0000000000000000);
-        convert(0xe000003000031340, 0xffffffffffffffff, 0xffffffff00000005);
-        convert(0xe000003000031350, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe000003000031360, 0x0000000000038190, 0x0000000000000000);
-        convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000);
-        convert(0xe000003000031400, 0x0000000000310121, 0x0000000000000000);
-        convert(0xe000003000031410, 0xffffffffffffffff, 0xffffffff00000006);
-        convert(0xe000003000031420, 0x000000000000000f, 0x0000000000000000);
-        convert(0xe000003000031430, 0x00000000000381c0, 0x0000000000000000);
-        convert(0xe0000030000314d0, 0x00000000ff010201, 0x0000000000000000);
-        convert(0xe0000030000314e0, 0xffffffffffffffff, 0xffffffff00000000);
-        convert(0xe000003000031500, 0x00000000000381f0, 0x000030430000ffff);
-        convert(0xe000003000031510, 0x000000000000ffff, 0x0000000000000000);
-        convert(0xe0000030000315a0, 0x00000020ff000201, 0x0000000000000000);
-        convert(0xe0000030000315b0, 0xffffffffffffffff, 0xffffffff00000001);
-        convert(0xe0000030000315d0, 0x0000000000038240, 0x00003f3f0000ffff);
-        convert(0xe0000030000315e0, 0x000000000000ffff, 0x0000000000000000);
-        convert(0xe000003000031670, 0x00000000ff010201, 0x0000000000000000);
-        convert(0xe000003000031680, 0xffffffffffffffff, 0x0000000100000002);
-        convert(0xe0000030000316a0, 0x0000000000038290, 0x000030430000ffff);
-        convert(0xe0000030000316b0, 0x000000000000ffff, 0x0000000000000000);
-        convert(0xe000003000031740, 0x00000020ff000201, 0x0000000000000000);
-        convert(0xe000003000031750, 0xffffffffffffffff, 0x0000000500000003);
-        convert(0xe000003000031770, 0x00000000000382e0, 0x00003f3f0000ffff);
-        convert(0xe000003000031780, 0x000000000000ffff, 0x0000000000000000);
-}
-
-#endif
-
-}
-
-
-
-
-	
-#ifdef DEFINE_DUMP_RTNS
-/* 
- * these were useful for printing out registers etc
- * during bringup  
- */
-
-static void
-xdump(long long *addr, int count)
-{
-	int ii;
-	volatile long long *xx = addr;
-
-	for ( ii = 0; ii < count; ii++, xx++ ) {
-		printk("0x%p : 0x%p\n", (void *)xx, (void *)*xx);
-	}
-}
-
-static void
-xdump32(unsigned int *addr, int count)
-{
-	int ii;
-	volatile unsigned int *xx = addr;
-
-	for ( ii = 0; ii < count; ii++, xx++ ) {
-		printk("0x%p : 0x%0x\n", (void *)xx, (int)*xx);
-	}
-}
-
-static void
-clear_ii_error(void)
-{
-	volatile long long *tmp;
-
-	printk("... WSTAT ");
-	xdump((long long *)0xc0000a0001c00008, 1);
-	printk("... WCTRL ");
-	xdump((long long *)0xc0000a0001c00020, 1);
-	printk("... WLCSR ");
-	xdump((long long *)0xc0000a0001c00128, 1);
-	printk("... IIDSR ");
-	xdump((long long *)0xc0000a0001c00138, 1);
-        printk("... IOPRBs ");
-	xdump((long long *)0xc0000a0001c00198, 9);
-	printk("... IXSS ");
-	xdump((long long *)0xc0000a0001c00210, 1);
-	printk("... IBLS0 ");
-	xdump((long long *)0xc0000a0001c10000, 1);
-	printk("... IBLS1 ");
-	xdump((long long *)0xc0000a0001c20000, 1);
-
-        /* Write IOERR clear to clear the CRAZY bit in the status */
-        tmp = (long long *)0xc0000a0001c001f8; *tmp = (long long)0xffffffff;
-
-	/* dump out local block error registers */
-	printk("... ");
-	xdump((long long *)0xc0000a0001e04040, 1);	/* LB_ERROR_BITS */
-	printk("... ");
-	xdump((long long *)0xc0000a0001e04050, 1);	/* LB_ERROR_HDR1 */
-	printk("... ");
-	xdump((long long *)0xc0000a0001e04058, 1);	/* LB_ERROR_HDR2 */
-	/* and clear the LB_ERROR_BITS */
-	tmp = (long long *)0xc0000a0001e04040; *tmp = 0x0;
-	printk("clr: ");
-	xdump((long long *)0xc0000a0001e04040, 1);	/* LB_ERROR_BITS */
-	tmp = (long long *)0xc0000a0001e04050; *tmp = 0x0;
-	tmp = (long long *)0xc0000a0001e04058; *tmp = 0x0;
-}
-
-
-static void
-dump_ii(void)
-{
-	printk("===== Dump the II regs =====\n");
-	xdump((long long *)0xc0000a0001c00000, 2);
-	xdump((long long *)0xc0000a0001c00020, 1);
-	xdump((long long *)0xc0000a0001c00100, 37);
-	xdump((long long *)0xc0000a0001c00300, 98);
-	xdump((long long *)0xc0000a0001c10000, 6);
-	xdump((long long *)0xc0000a0001c20000, 6);
-	xdump((long long *)0xc0000a0001c30000, 2);
-
-	xdump((long long *)0xc0000a0000000000, 1);
-	xdump((long long *)0xc0000a0001000000, 1);
-	xdump((long long *)0xc0000a0002000000, 1);
-	xdump((long long *)0xc0000a0003000000, 1);
-	xdump((long long *)0xc0000a0004000000, 1);
-	xdump((long long *)0xc0000a0005000000, 1);
-	xdump((long long *)0xc0000a0006000000, 1);
-	xdump((long long *)0xc0000a0007000000, 1);
-	xdump((long long *)0xc0000a0008000000, 1);
-	xdump((long long *)0xc0000a0009000000, 1);
-	xdump((long long *)0xc0000a000a000000, 1);
-	xdump((long long *)0xc0000a000b000000, 1);
-	xdump((long long *)0xc0000a000c000000, 1);
-	xdump((long long *)0xc0000a000d000000, 1);
-	xdump((long long *)0xc0000a000e000000, 1);
-	xdump((long long *)0xc0000a000f000000, 1);
-}
-
-static void
-dump_crossbow(void)
-{
-	printk("===== Dump the Crossbow regs =====\n");
-	clear_ii_error();
-	xdump32((unsigned int *)0xc0000a0000000004, 1);
-	clear_ii_error();
-	xdump32((unsigned int *)0xc0000a0000000000, 1);
-	printk("and again..\n");
-	xdump32((unsigned int *)0xc0000a0000000000, 1);
-	xdump32((unsigned int *)0xc0000a0000000000, 1);
-
-
-	clear_ii_error();
-
-	xdump32((unsigned int *)0xc000020000000004, 1);
-	clear_ii_error();
-	xdump32((unsigned int *)0xc000020000000000, 1);
-	clear_ii_error();
-
-	xdump32((unsigned int *)0xc0000a0000800004, 1);
-	clear_ii_error();
-	xdump32((unsigned int *)0xc0000a0000800000, 1);
-	clear_ii_error();
-
-	xdump32((unsigned int *)0xc000020000800004, 1);
-	clear_ii_error();
-	xdump32((unsigned int *)0xc000020000800000, 1);
-	clear_ii_error();
-
-
-}
-#endif /* DEFINE_DUMP_RTNS */
diff -Nru a/arch/ia64/sn/io/l1.c b/arch/ia64/sn/io/l1.c
--- a/arch/ia64/sn/io/l1.c	Wed Jun 18 23:42:09 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,3056 +0,0 @@
-/* $Id$
- *
- * 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) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-/* In general, this file is organized in a hierarchy from lower-level
- * to higher-level layers, as follows:
- *
- *	UART routines
- *	Bedrock/L1 "PPP-like" protocol implementation
- *	System controller "message" interface (allows multiplexing
- *		of various kinds of requests and responses with
- *		console I/O)
- *	Console interface:
- *	  "l1_cons", the glue that allows the L1 to act
- *		as the system console for the stdio libraries
- *
- * Routines making use of the system controller "message"-style interface
- * can be found in l1_command.c.
- */
-
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/spinlock.h>
-#include <linux/delay.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/uart16550.h>
-#include <asm/sn/simulator.h>
-
-
-/* Make all console writes atomic */
-#define SYNC_CONSOLE_WRITE	1
-
-
-/*********************************************************************
- * Hardware-level (UART) driver routines.
- */
-
-/* macros for reading/writing registers */
-
-#define LD(x)			(*(volatile uint64_t *)(x))
-#define SD(x, v)        	(LD(x) = (uint64_t) (v))
-
-/* location of uart receive/xmit data register */
-#if defined(CONFIG_IA64_SGI_SN1)
-#define L1_UART_BASE(n)		((ulong)REMOTE_HSPEC_ADDR((n), 0x00000080))
-#define LOCK_HUB		REMOTE_HUB_ADDR
-#elif defined(CONFIG_IA64_SGI_SN2)
-#define L1_UART_BASE(n)		((ulong)REMOTE_HUB((n), SH_JUNK_BUS_UART0))
-#define LOCK_HUB		REMOTE_HUB
-typedef u64 rtc_time_t;
-#endif
-
-
-#define ADDR_L1_REG(n, r)	( L1_UART_BASE(n) | ( (r) << 3 ) )
-#define READ_L1_UART_REG(n, r)	( LD(ADDR_L1_REG((n), (r))) )
-#define WRITE_L1_UART_REG(n, r, v) ( SD(ADDR_L1_REG((n), (r)), (v)) )
-
-/* upper layer interface calling methods */
-#define SERIAL_INTERRUPT_MODE	0
-#define SERIAL_POLLED_MODE	1
-
-
-/* UART-related #defines */
-
-#define UART_BAUD_RATE		57600
-#define UART_FIFO_DEPTH		16
-#define UART_DELAY_SPAN		10
-#define UART_PUTC_TIMEOUT	50000
-#define UART_INIT_TIMEOUT	100000
-
-/* error codes */
-#define UART_SUCCESS		  0
-#define UART_TIMEOUT		(-1)
-#define UART_LINK		(-2)
-#define UART_NO_CHAR		(-3)
-#define UART_VECTOR		(-4)
-
-#define UART_DELAY(x)		udelay(x)
-
-/* Some debug counters */
-#define L1C_INTERRUPTS		0
-#define L1C_OUR_R_INTERRUPTS	1
-#define L1C_OUR_X_INTERRUPTS	2
-#define L1C_SEND_CALLUPS	3
-#define L1C_RECEIVE_CALLUPS	4
-#define L1C_SET_BAUD		5
-#define L1C_ALREADY_LOCKED	L1C_SET_BAUD
-#define L1C_R_IRQ		6
-#define L1C_R_IRQ_RET		7
-#define L1C_LOCK_TIMEOUTS	8
-#define L1C_LOCK_COUNTER	9
-#define L1C_UNLOCK_COUNTER	10
-#define L1C_REC_STALLS		11
-#define L1C_CONNECT_CALLS	12
-#define L1C_SIZE		L1C_CONNECT_CALLS	/* Set to the last one */
-
-uint64_t L1_collectibles[L1C_SIZE + 1];
-
-
-/*
- *	Some macros for handling Endian-ness
- */
-
-#define COPY_INT_TO_BUFFER(_b, _i, _n)		\
-	{					\
-		_b[_i++] = (_n >> 24) & 0xff;	\
-		_b[_i++] = (_n >> 16) & 0xff;	\
-		_b[_i++] = (_n >>  8) & 0xff;	\
-		_b[_i++] =  _n        & 0xff;	\
-	}
-
-#define COPY_BUFFER_TO_INT(_b, _i, _n)		\
-	{					\
-		_n  = (_b[_i++] << 24) & 0xff;	\
-		_n |= (_b[_i++] << 16) & 0xff;	\
-		_n |= (_b[_i++] <<  8) & 0xff;	\
-		_n |=  _b[_i++]        & 0xff;	\
-	}
-
-#define COPY_BUFFER_TO_BUFFER(_b, _i, _bn)	\
-	{					\
-	    char *_xyz = (char *)_bn;		\
-	    _xyz[3] = _b[_i++];			\
-	    _xyz[2] = _b[_i++];			\
-	    _xyz[1] = _b[_i++];			\
-	    _xyz[0] = _b[_i++];			\
-	}
-
-void snia_kmem_free(void *where, int size);
-
-#define ALREADY_LOCKED		1
-#define NOT_LOCKED		0
-static int early_l1_serial_out(nasid_t, char *, int, int /* defines above*/ );
-
-#define BCOPY(x,y,z)	memcpy(y,x,z)
-
-uint8_t L1_interrupts_connected;		/* Non-zero when we are in interrupt mode */
-
-
-/*
- * Console locking defines and functions.
- *
- */
-
-uint8_t L1_cons_is_inited = 0;			/* non-zero when console is init'd */
-nasid_t Master_console_nasid = (nasid_t)-1;
-extern nasid_t console_nasid;
-
-u64 ia64_sn_get_console_nasid(void);
-
-inline nasid_t
-get_master_nasid(void)
-{
-#if defined(CONFIG_IA64_SGI_SN1)
-	nasid_t nasid = Master_console_nasid;
-
-	if ( nasid == (nasid_t)-1 ) {
-		nasid = (nasid_t)ia64_sn_get_console_nasid();
-		if ( (nasid < 0) || (nasid >= MAX_NASIDS) ) {
-			/* Out of bounds, use local */
-			console_nasid = nasid = get_nasid();
-		}
-		else {
-			/* Got a valid nasid, set the console_nasid */
-			char xx[100];
-/* zzzzzz - force nasid to 0 for now */
-			sprintf(xx, "Master console is set to nasid %d (%d)\n", 0, (int)nasid);
-nasid = 0;
-/* end zzzzzz */
-			xx[99] = (char)0;
-			early_l1_serial_out(nasid, xx, strlen(xx), NOT_LOCKED);
-			Master_console_nasid = console_nasid = nasid;
-		}
-	}
-	return(nasid);
-#else
-	return((nasid_t)0);
-#endif	/* CONFIG_IA64_SGI_SN1 */
-}
-
-
-#if defined(CONFIG_IA64_SGI_SN1)
-
-#define HUB_LOCK		16
-
-#define PRIMARY_LOCK_TIMEOUT    10000000
-#define HUB_LOCK_REG(n)         LOCK_HUB(n, MD_PERF_CNT0)
-
-#define SET_BITS(reg, bits)     SD(reg, LD(reg) |  (bits))
-#define CLR_BITS(reg, bits)     SD(reg, LD(reg) & ~(bits))
-#define TST_BITS(reg, bits)     ((LD(reg) & (bits)) != 0)
-
-#define HUB_TEST_AND_SET(n)	LD(LOCK_HUB(n,LB_SCRATCH_REG3_RZ))
-#define HUB_CLEAR(n)		SD(LOCK_HUB(n,LB_SCRATCH_REG3),0)
-
-#define RTC_TIME_MAX		((rtc_time_t) ~0ULL)
-
-/*
- * primary_lock
- *
- *   Allows CPU's 0-3  to mutually exclude the hub from one another by
- *   obtaining a blocking lock.  Does nothing if only one CPU is active.
- *
- *   This lock should be held just long enough to set or clear a global
- *   lock bit.  After a relatively short timeout period, this routine
- *   figures something is wrong, and steals the lock. It does not set
- *   any other CPU to "dead".
- */
-inline void
-primary_lock(nasid_t nasid)
-{
-	rtc_time_t          expire;
-
-	expire = rtc_time() + PRIMARY_LOCK_TIMEOUT;
-
-	while (HUB_TEST_AND_SET(nasid)) {
-		if (rtc_time() > expire) {
-			HUB_CLEAR(nasid);
-		}
-	}
-}
-
-/*
- * primary_unlock (internal)
- *
- *   Counterpart to primary_lock
- */
-
-inline void
-primary_unlock(nasid_t nasid)
-{
-	HUB_CLEAR(nasid);
-}
-
-/*
- * hub_unlock
- *
- *   Counterpart to hub_lock_timeout and hub_lock
- */
-
-inline void
-hub_unlock(nasid_t nasid, int level)
-{
-	uint64_t mask = 1ULL << level;
-
-	primary_lock(nasid);
-	CLR_BITS(HUB_LOCK_REG(nasid), mask);
-	primary_unlock(nasid);
-}
-
-/*
- * hub_lock_timeout
- *
- *   Uses primary_lock to implement multiple lock levels.
- *
- *   There are 20 lock levels from 0 to 19 (limited by the number of bits
- *   in HUB_LOCK_REG).  To prevent deadlock, multiple locks should be
- *   obtained in order of increasingly higher level, and released in the
- *   reverse order.
- *
- *   A timeout value of 0 may be used for no timeout.
- *
- *   Returns 0 if successful, -1 if lock times out.
- */
-
-inline int
-hub_lock_timeout(nasid_t nasid, int level, rtc_time_t timeout)
-{
-	uint64_t mask = 1ULL << level;
-	rtc_time_t expire = (timeout ?  rtc_time() + timeout : RTC_TIME_MAX);
-	int done    = 0;
-
-	while (! done) {
-		while (TST_BITS(HUB_LOCK_REG(nasid), mask)) {
-			if (rtc_time() > expire)
-				return -1;
-		}
-
-		primary_lock(nasid);
-
-		if (! TST_BITS(HUB_LOCK_REG(nasid), mask)) {
-			SET_BITS(HUB_LOCK_REG(nasid), mask);
-			done = 1;
-		}
-		primary_unlock(nasid);
-	}
-	return 0;
-}
-
-
-#define LOCK_TIMEOUT	(0x1500000 * 1) /* 0x1500000 is ~30 sec */
-
-void
-lock_console(nasid_t nasid)
-{
-	int ret;
-
-	/* If we already have it locked, just return */
-	L1_collectibles[L1C_LOCK_COUNTER]++;
-
-	ret = hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT);
-	if ( ret != 0 ) {
-		L1_collectibles[L1C_LOCK_TIMEOUTS]++;
-		/* timeout */
-		hub_unlock(nasid, HUB_LOCK);
-		/* If the 2nd lock fails, just pile ahead.... */
-		hub_lock_timeout(nasid, HUB_LOCK, (rtc_time_t)LOCK_TIMEOUT);
-		L1_collectibles[L1C_LOCK_TIMEOUTS]++;
-	}
-}
-
-inline void
-unlock_console(nasid_t nasid)
-{
-	L1_collectibles[L1C_UNLOCK_COUNTER]++;
-	hub_unlock(nasid, HUB_LOCK);
-}
-
-#else /* SN2 */
-inline void lock_console(nasid_t n)	{}
-inline void unlock_console(nasid_t n)	{}
-
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-int 
-get_L1_baud(void)
-{
-    return UART_BAUD_RATE;
-}
-
-
-/* uart driver functions */
-
-static inline void
-uart_delay( rtc_time_t delay_span )
-{
-    UART_DELAY( delay_span );
-}
-
-#define UART_PUTC_READY(n)      (READ_L1_UART_REG((n), REG_LSR) & LSR_XHRE)
-
-static int
-uart_putc( l1sc_t *sc ) 
-{
-    WRITE_L1_UART_REG( sc->nasid, REG_DAT, sc->send[sc->sent] );
-    return UART_SUCCESS;
-}
-
-
-static int
-uart_getc( l1sc_t *sc )
-{
-    u_char lsr_reg = 0;
-    nasid_t nasid = sc->nasid;
-
-    if( (lsr_reg = READ_L1_UART_REG( nasid, REG_LSR )) & 
-	(LSR_RCA | LSR_PARERR | LSR_FRMERR) ) 
-    {
-	if( lsr_reg & LSR_RCA ) 
-	    return( (u_char)READ_L1_UART_REG( nasid, REG_DAT ) );
-	else if( lsr_reg & (LSR_PARERR | LSR_FRMERR) ) {
-	    return UART_LINK;
-	}
-    }
-
-    return UART_NO_CHAR;
-}
-
-
-#define PROM_SER_CLK_SPEED	12000000
-#define PROM_SER_DIVISOR(x)	(PROM_SER_CLK_SPEED / ((x) * 16))
-
-static void
-uart_init( l1sc_t *sc, int baud )
-{
-    rtc_time_t expire;
-    int clkdiv;
-    nasid_t nasid;
-
-    clkdiv = PROM_SER_DIVISOR(baud);
-    expire = rtc_time() + UART_INIT_TIMEOUT;
-    nasid = sc->nasid;
-    
-    /* make sure the transmit FIFO is empty */
-    while( !(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XSRE) ) {
-	uart_delay( UART_DELAY_SPAN );
-	if( rtc_time() > expire ) {
-	    break;
-	}
-    }
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(nasid);
-
-    /* Setup for the proper baud rate */
-    WRITE_L1_UART_REG( nasid, REG_LCR, LCR_DLAB );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_DLH, (clkdiv >> 8) & 0xff );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_DLL, clkdiv & 0xff );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* set operating parameters and set DLAB to 0 */
-
-    /* 8bit, one stop, clear request to send, auto flow control */
-    WRITE_L1_UART_REG( nasid, REG_LCR, LCR_BITS8 | LCR_STOP1 );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_MCR, MCR_RTS | MCR_AFE );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* disable interrupts */
-    WRITE_L1_UART_REG( nasid, REG_ICR, 0x0 );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* enable FIFO mode and reset both FIFOs, trigger on 1 */
-    WRITE_L1_UART_REG( nasid, REG_FCR, FCR_FIFOEN );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_L1_UART_REG( nasid, REG_FCR, FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO | RxLVL0);
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(nasid);
-}
-
-/* This requires the console lock */
-
-#if	defined(CONFIG_IA64_SGI_SN1)
-
-static void
-uart_intr_enable( l1sc_t *sc, u_char mask )
-{
-    u_char lcr_reg, icr_reg;
-    nasid_t nasid = sc->nasid;
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(nasid);
-
-    /* make sure that the DLAB bit in the LCR register is 0
-     */
-    lcr_reg = READ_L1_UART_REG( nasid, REG_LCR );
-    lcr_reg &= ~(LCR_DLAB);
-    WRITE_L1_UART_REG( nasid, REG_LCR, lcr_reg );
-
-    /* enable indicated interrupts
-     */
-    icr_reg = READ_L1_UART_REG( nasid, REG_ICR );
-    icr_reg |= mask;
-    WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ );
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(nasid);
-}
-
-/* This requires the console lock */
-static void
-uart_intr_disable( l1sc_t *sc, u_char mask )
-{
-    u_char lcr_reg, icr_reg;
-    nasid_t nasid = sc->nasid;
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(nasid);
-
-    /* make sure that the DLAB bit in the LCR register is 0
-     */
-    lcr_reg = READ_L1_UART_REG( nasid, REG_LCR );
-    lcr_reg &= ~(LCR_DLAB);
-    WRITE_L1_UART_REG( nasid, REG_LCR, lcr_reg );
-
-    /* enable indicated interrupts
-     */
-    icr_reg = READ_L1_UART_REG( nasid, REG_ICR );
-    icr_reg &= mask;
-    WRITE_L1_UART_REG( nasid, REG_ICR, icr_reg /*(ICR_RIEN | ICR_TIEN)*/ );
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(nasid);
-}
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-#define uart_enable_xmit_intr(sc) \
-	uart_intr_enable((sc), ICR_TIEN)
-
-#define uart_disable_xmit_intr(sc) \
-        uart_intr_disable((sc), ~(ICR_TIEN))
-
-#define uart_enable_recv_intr(sc) \
-        uart_intr_enable((sc), ICR_RIEN)
-
-#define uart_disable_recv_intr(sc) \
-        uart_intr_disable((sc), ~(ICR_RIEN))
-
-
-/*********************************************************************
- * Routines for accessing a remote (router) UART
- */
-
-#define READ_RTR_L1_UART_REG(p, n, r, v)		\
-    {							\
-	if( vector_read_node( (p), (n), 0,		\
-			      RR_JBUS1(r), (v) ) ) {	\
-	    return UART_VECTOR;				\
-	}						\
-    }
-
-#define WRITE_RTR_L1_UART_REG(p, n, r, v)		\
-    {							\
-	if( vector_write_node( (p), (n), 0,		\
-			       RR_JBUS1(r), (v) ) ) {	\
-	    return UART_VECTOR;				\
-	}						\
-    }
-
-#define RTR_UART_PUTC_TIMEOUT	UART_PUTC_TIMEOUT*10
-#define RTR_UART_DELAY_SPAN	UART_DELAY_SPAN
-#define RTR_UART_INIT_TIMEOUT	UART_INIT_TIMEOUT*10
-
-static int
-rtr_uart_putc( l1sc_t *sc )
-{
-    uint64_t regval, c;
-    nasid_t nasid = sc->nasid;
-    net_vec_t path = sc->uart;
-    rtc_time_t expire = rtc_time() + RTR_UART_PUTC_TIMEOUT;
-
-    c = (sc->send[sc->sent] & 0xffULL);
-    
-    while( 1 ) 
-    {
-        /* Check for "tx hold reg empty" bit. */
-	READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
-	if( regval & LSR_XHRE )
-	{
-	    WRITE_RTR_L1_UART_REG( path, nasid, REG_DAT, c );
-	    return UART_SUCCESS;
-	}
-
-	if( rtc_time() >= expire ) 
-	{
-	    return UART_TIMEOUT;
-	}
-	uart_delay( RTR_UART_DELAY_SPAN );
-    }
-}
-
-
-static int
-rtr_uart_getc( l1sc_t *sc )
-{
-    uint64_t regval;
-    nasid_t nasid = sc->nasid;
-    net_vec_t path = sc->uart;
-
-    READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
-    if( regval & (LSR_RCA | LSR_PARERR | LSR_FRMERR) )
-    {
-	if( regval & LSR_RCA )
-	{
-	    READ_RTR_L1_UART_REG( path, nasid, REG_DAT, &regval );
-	    return( (int)regval );
-	}
-	else
-	{
-	    return UART_LINK;
-	}
-    }
-
-    return UART_NO_CHAR;
-}
-
-
-static int
-rtr_uart_init( l1sc_t *sc, int baud )
-{
-    rtc_time_t expire;
-    int clkdiv;
-    nasid_t nasid;
-    net_vec_t path;
-    uint64_t regval;
-
-    clkdiv = PROM_SER_DIVISOR(baud);
-    expire = rtc_time() + RTR_UART_INIT_TIMEOUT;
-    nasid = sc->nasid;
-    path = sc->uart;
-
-    /* make sure the transmit FIFO is empty */
-    while(1) {
-	READ_RTR_L1_UART_REG( path, nasid, REG_LSR, &regval );
-	if( regval & LSR_XSRE ) {
-	    break;
-	}
-	if( rtc_time() > expire ) {
-	    break;
-	}
-	uart_delay( RTR_UART_DELAY_SPAN );
-    }
-
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_LCR, LCR_DLAB  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_DLH, (clkdiv >> 8) & 0xff  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_DLL, clkdiv & 0xff  );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* set operating parameters and set DLAB to 0 */
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_LCR, LCR_BITS8 | LCR_STOP1  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_MCR, MCR_RTS | MCR_AFE  );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* disable interrupts */
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_ICR, 0x0  );
-	uart_delay( UART_DELAY_SPAN );
-
-    /* enable FIFO mode and reset both FIFOs */
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_FCR, FCR_FIFOEN  );
-	uart_delay( UART_DELAY_SPAN );
-    WRITE_RTR_L1_UART_REG( path, nasid, REG_FCR,
-	FCR_FIFOEN | FCR_RxFIFO | FCR_TxFIFO );
-
-    return 0;
-}
-
-/*********************************************************************
- * locking macros 
- */
-
-#define L1SC_SEND_LOCK(l,p)   { if ((l)->uart == BRL1_LOCALHUB_UART) spin_lock_irqsave(&((l)->send_lock),p); }
-#define L1SC_SEND_UNLOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_unlock_irqrestore(&((l)->send_lock), p); }
-#define L1SC_RECV_LOCK(l,p)   { if ((l)->uart == BRL1_LOCALHUB_UART) spin_lock_irqsave(&((l)->recv_lock), p); } 
-#define L1SC_RECV_UNLOCK(l,p) { if ((l)->uart == BRL1_LOCALHUB_UART) spin_unlock_irqrestore(&((l)->recv_lock), p); }
-
-
-/*********************************************************************
- * subchannel manipulation 
- *
- * The SUBCH_[UN]LOCK macros are used to arbitrate subchannel
- * allocation.  SUBCH_DATA_[UN]LOCK control access to data structures
- * associated with particular subchannels (e.g., receive queues).
- *
- */
-#define SUBCH_LOCK(sc, p)		spin_lock_irqsave( &((sc)->subch_lock), p )
-#define SUBCH_UNLOCK(sc, p)		spin_unlock_irqrestore( &((sc)->subch_lock), p )
-#define SUBCH_DATA_LOCK(sbch, p) 	spin_lock_irqsave( &((sbch)->data_lock), p )
-#define SUBCH_DATA_UNLOCK(sbch, p)	spin_unlock_irqrestore( &((sbch)->data_lock), p )
-
-
-/*
- * set a function to be called for subchannel ch in the event of
- * a transmission low-water interrupt from the uart
- */
-void
-subch_set_tx_notify( l1sc_t *sc, int ch, brl1_notif_t func )
-{
-    unsigned long pl = 0;
-
-    L1SC_SEND_LOCK( sc, pl );
-#if	!defined(SYNC_CONSOLE_WRITE)
-    if ( func && !sc->send_in_use )
-	uart_enable_xmit_intr( sc );
-#endif
-    sc->subch[ch].tx_notify = func;
-    L1SC_SEND_UNLOCK(sc, pl );
-}
-
-/*
- * set a function to be called for subchannel ch when data is received
- */
-void
-subch_set_rx_notify( l1sc_t *sc, int ch, brl1_notif_t func )
-{
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    SUBCH_DATA_LOCK( subch, pl );
-    sc->subch[ch].rx_notify = func;
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
-/*********************************************************************
- * Queue manipulation macros
- *
- *
- */
-#define NEXT(p)         (((p) + 1) & (BRL1_QSIZE-1)) /* assume power of 2 */
-
-#define cq_init(q)      bzero((q), sizeof (*(q)))
-#define cq_empty(q)     ((q)->ipos == (q)->opos)
-#define cq_full(q)      (NEXT((q)->ipos) == (q)->opos)
-#define cq_used(q)      ((q)->opos <= (q)->ipos ?                       \
-                         (q)->ipos - (q)->opos :                        \
-                         BRL1_QSIZE + (q)->ipos - (q)->opos)
-#define cq_room(q)      ((q)->opos <= (q)->ipos ?                       \
-                         BRL1_QSIZE - 1 + (q)->opos - (q)->ipos :       \
-                         (q)->opos - (q)->ipos - 1)
-#define cq_add(q, c)    ((q)->buf[(q)->ipos] = (u_char) (c),            \
-                         (q)->ipos = NEXT((q)->ipos))
-#define cq_rem(q, c)    ((c) = (q)->buf[(q)->opos],                     \
-                         (q)->opos = NEXT((q)->opos))
-#define cq_discard(q)	((q)->opos = NEXT((q)->opos))
-
-#define cq_tent_full(q)	(NEXT((q)->tent_next) == (q)->opos)
-#define cq_tent_len(q)	((q)->ipos <= (q)->tent_next ?			\
-			 (q)->tent_next - (q)->ipos :			\
-			 BRL1_QSIZE + (q)->tent_next - (q)->ipos)
-#define cq_tent_add(q, c)						\
-			((q)->buf[(q)->tent_next] = (u_char) (c),	\
-			 (q)->tent_next = NEXT((q)->tent_next))
-#define cq_commit_tent(q)						\
-			((q)->ipos = (q)->tent_next)
-#define cq_discard_tent(q)						\
-			((q)->tent_next = (q)->ipos)
-
-
-
-
-/*********************************************************************
- * CRC-16 (for checking bedrock/L1 packets).
- *
- * These are based on RFC 1662 ("PPP in HDLC-like framing").
- */
-
-static unsigned short fcstab[256] = {
-      0x0000, 0x1189, 0x2312, 0x329b, 0x4624, 0x57ad, 0x6536, 0x74bf,
-      0x8c48, 0x9dc1, 0xaf5a, 0xbed3, 0xca6c, 0xdbe5, 0xe97e, 0xf8f7,
-      0x1081, 0x0108, 0x3393, 0x221a, 0x56a5, 0x472c, 0x75b7, 0x643e,
-      0x9cc9, 0x8d40, 0xbfdb, 0xae52, 0xdaed, 0xcb64, 0xf9ff, 0xe876,
-      0x2102, 0x308b, 0x0210, 0x1399, 0x6726, 0x76af, 0x4434, 0x55bd,
-      0xad4a, 0xbcc3, 0x8e58, 0x9fd1, 0xeb6e, 0xfae7, 0xc87c, 0xd9f5,
-      0x3183, 0x200a, 0x1291, 0x0318, 0x77a7, 0x662e, 0x54b5, 0x453c,
-      0xbdcb, 0xac42, 0x9ed9, 0x8f50, 0xfbef, 0xea66, 0xd8fd, 0xc974,
-      0x4204, 0x538d, 0x6116, 0x709f, 0x0420, 0x15a9, 0x2732, 0x36bb,
-      0xce4c, 0xdfc5, 0xed5e, 0xfcd7, 0x8868, 0x99e1, 0xab7a, 0xbaf3,
-      0x5285, 0x430c, 0x7197, 0x601e, 0x14a1, 0x0528, 0x37b3, 0x263a,
-      0xdecd, 0xcf44, 0xfddf, 0xec56, 0x98e9, 0x8960, 0xbbfb, 0xaa72,
-      0x6306, 0x728f, 0x4014, 0x519d, 0x2522, 0x34ab, 0x0630, 0x17b9,
-      0xef4e, 0xfec7, 0xcc5c, 0xddd5, 0xa96a, 0xb8e3, 0x8a78, 0x9bf1,
-      0x7387, 0x620e, 0x5095, 0x411c, 0x35a3, 0x242a, 0x16b1, 0x0738,
-      0xffcf, 0xee46, 0xdcdd, 0xcd54, 0xb9eb, 0xa862, 0x9af9, 0x8b70,
-      0x8408, 0x9581, 0xa71a, 0xb693, 0xc22c, 0xd3a5, 0xe13e, 0xf0b7,
-      0x0840, 0x19c9, 0x2b52, 0x3adb, 0x4e64, 0x5fed, 0x6d76, 0x7cff,
-      0x9489, 0x8500, 0xb79b, 0xa612, 0xd2ad, 0xc324, 0xf1bf, 0xe036,
-      0x18c1, 0x0948, 0x3bd3, 0x2a5a, 0x5ee5, 0x4f6c, 0x7df7, 0x6c7e,
-      0xa50a, 0xb483, 0x8618, 0x9791, 0xe32e, 0xf2a7, 0xc03c, 0xd1b5,
-      0x2942, 0x38cb, 0x0a50, 0x1bd9, 0x6f66, 0x7eef, 0x4c74, 0x5dfd,
-      0xb58b, 0xa402, 0x9699, 0x8710, 0xf3af, 0xe226, 0xd0bd, 0xc134,
-      0x39c3, 0x284a, 0x1ad1, 0x0b58, 0x7fe7, 0x6e6e, 0x5cf5, 0x4d7c,
-      0xc60c, 0xd785, 0xe51e, 0xf497, 0x8028, 0x91a1, 0xa33a, 0xb2b3,
-      0x4a44, 0x5bcd, 0x6956, 0x78df, 0x0c60, 0x1de9, 0x2f72, 0x3efb,
-      0xd68d, 0xc704, 0xf59f, 0xe416, 0x90a9, 0x8120, 0xb3bb, 0xa232,
-      0x5ac5, 0x4b4c, 0x79d7, 0x685e, 0x1ce1, 0x0d68, 0x3ff3, 0x2e7a,
-      0xe70e, 0xf687, 0xc41c, 0xd595, 0xa12a, 0xb0a3, 0x8238, 0x93b1,
-      0x6b46, 0x7acf, 0x4854, 0x59dd, 0x2d62, 0x3ceb, 0x0e70, 0x1ff9,
-      0xf78f, 0xe606, 0xd49d, 0xc514, 0xb1ab, 0xa022, 0x92b9, 0x8330,
-      0x7bc7, 0x6a4e, 0x58d5, 0x495c, 0x3de3, 0x2c6a, 0x1ef1, 0x0f78
-};
-
-#define INIT_CRC	0xFFFF	/* initial CRC value	  */
-#define	GOOD_CRC	0xF0B8	/* "good" final CRC value */
-
-static unsigned short crc16_calc( unsigned short crc, u_char c )
-{
-    return( (crc >> 8) ^ fcstab[(crc ^ c) & 0xff] );
-}
-
-
-/***********************************************************************
- * The following functions implement the PPP-like bedrock/L1 protocol
- * layer.
- *
- */
-
-#define BRL1_FLAG_CH	0x7e
-#define BRL1_ESC_CH	0x7d
-#define BRL1_XOR_CH	0x20
-
-/* L1<->Bedrock packet types */
-#define BRL1_REQUEST    0x00
-#define BRL1_RESPONSE   0x20
-#define BRL1_EVENT      0x40
-
-#define BRL1_PKT_TYPE_MASK      0xE0
-#define BRL1_SUBCH_MASK         0x1F
-
-#define PKT_TYPE(tsb)   ((tsb) & BRL1_PKT_TYPE_MASK)
-#define SUBCH(tsb)	((tsb) & BRL1_SUBCH_MASK)
-
-/* timeouts */
-#define BRL1_INIT_TIMEOUT	500000
-
-/*
- * brl1_discard_packet is a dummy "receive callback" used to get rid
- * of packets we don't want
- */
-void brl1_discard_packet( int dummy0, void *dummy1, struct pt_regs *dummy2, l1sc_t *sc, int ch )
-{
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &sc->subch[ch];
-
-    sc_cq_t *q = subch->iqp;
-    SUBCH_DATA_LOCK( subch, pl );
-    q->opos = q->ipos;
-    atomic_set(&(subch->packet_arrived), 0);
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
-
-/*
- * brl1_send_chars sends the send buffer in the l1sc_t structure
- * out through the uart.  Assumes that the caller has locked the
- * UART (or send buffer in the kernel).
- *
- * This routine doesn't block-- if you want it to, call it in
- * a loop.
- */
-static int
-brl1_send_chars( l1sc_t *sc )
-{
-    /* We track the depth of the C brick's UART's
-     * fifo in software, and only check if the UART is accepting
-     * characters when our count indicates that the fifo should
-     * be full.
-     *
-     * For remote (router) UARTs, we check with the UART before sending every
-     * character.
-     */
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	if( !(sc->fifo_space) && UART_PUTC_READY( sc->nasid ) )
-	    sc->fifo_space = UART_FIFO_DEPTH;
-	
-	while( (sc->sent < sc->send_len) && (sc->fifo_space) ) {
-	    uart_putc( sc );
-	    sc->fifo_space--;
-	    sc->sent++;
-	}
-    }
-    else {
-
-	/* remote (router) UARTs */
-
-	int result;
-	int tries = 0;
-
-	while( sc->sent < sc->send_len ) {
-	    result = sc->putc_f( sc );
-	    if( result >= 0 ) {
-		(sc->sent)++;
-		continue;
-	    }
-	    if( result == UART_TIMEOUT ) {
-		tries++;
-		/* send this character in TIMEOUT_RETRIES... */
-		if( tries < 30 /* TIMEOUT_RETRIES */ ) {
-		    continue;
-		}
-		/* ...or else... */
-		else {
-		    /* ...drop the packet. */
-		    sc->sent = sc->send_len;
-		    return sc->send_len;
-		}
-	    }
-	    if( result < 0 ) {
-		return result;
-	    }
-	}
-    }
-    return sc->sent;
-}
-
-
-/* brl1_send formats up a packet and (at least begins to) send it
- * to the uart.  If the send buffer is in use when this routine obtains
- * the lock, it will behave differently depending on the "wait" parameter.
- * For wait == 0 (most I/O), it will return 0 (as in "zero bytes sent"),
- * hopefully encouraging the caller to back off (unlock any high-level 
- * spinlocks) and allow the buffer some time to drain.  For wait==1 (high-
- * priority I/O along the lines of kernel error messages), we will flush
- * the current contents of the send buffer and beat on the uart
- * until our message has been completely transmitted.
- */
-
-static int
-brl1_send( l1sc_t *sc, char *msg, int len, u_char type_and_subch, int wait )
-{
-    unsigned long pl = 0;
-    int index;
-    int pkt_len = 0;
-    unsigned short crc = INIT_CRC;
-    char *send_ptr = sc->send;
-
-
-    if( sc->send_in_use && !(wait) ) {
-	/* We are in the middle of sending, but can wait until done */
-	return 0;
-    }
-    else if( sc->send_in_use ) {
-	/* buffer's in use, but we're synchronous I/O, so we're going
-	 * to send whatever's in there right now and take the buffer
-	 */
-	int counter = 0;
-
-	if ( sc->uart == BRL1_LOCALHUB_UART )
-		lock_console(sc->nasid);
-	L1SC_SEND_LOCK(sc, pl);
-	while( sc->sent < sc->send_len ) {
-		brl1_send_chars( sc );
-		if ( counter++ > 0xfffff ) {
-			char *str = "Looping waiting for uart to clear (1)\n";
-			early_l1_serial_out(sc->nasid, str, strlen(str), ALREADY_LOCKED);
-			break;
-		}
-	}
-    }
-    else {
-	if ( sc->uart == BRL1_LOCALHUB_UART )
-		lock_console(sc->nasid);
-	L1SC_SEND_LOCK(sc, pl);
-	sc->send_in_use = 1;
-    }
-    *send_ptr++ = BRL1_FLAG_CH;
-    *send_ptr++ = type_and_subch;
-    pkt_len += 2;
-    crc = crc16_calc( crc, type_and_subch );
-
-    /* limit number of characters accepted to max payload size */
-    if( len > (BRL1_QSIZE - 1) )
-	len = (BRL1_QSIZE - 1);
-
-    /* copy in the message buffer (inserting PPP 
-     * framing info where necessary)
-     */
-    for( index = 0; index < len; index++ ) {
-
-	switch( *msg ) {
-	    
-	  case BRL1_FLAG_CH:
-	    *send_ptr++ = BRL1_ESC_CH;
-	    *send_ptr++ = (*msg) ^ BRL1_XOR_CH;
-	    pkt_len += 2;
-	    break;
-	    
-	  case BRL1_ESC_CH:
-	    *send_ptr++ = BRL1_ESC_CH;
-	    *send_ptr++ = (*msg) ^ BRL1_XOR_CH;
-	    pkt_len += 2;
-	    break;
-	    
-	  default:
-	    *send_ptr++ = *msg;
-	    pkt_len++;
-	}
-	crc = crc16_calc( crc, *msg );
-	msg++;
-    }
-    crc ^= 0xffff;
-
-    for( index = 0; index < sizeof(crc); index++ ) {
-	char crc_char = (char)(crc & 0x00FF);
-	if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
-	    *send_ptr++ = BRL1_ESC_CH;
-	    pkt_len++;
-	    crc_char ^= BRL1_XOR_CH;
-	}
-	*send_ptr++ = crc_char;
-	pkt_len++;
-	crc >>= 8;
-    }
-    
-    *send_ptr++ = BRL1_FLAG_CH;
-    pkt_len++;
-
-    sc->send_len = pkt_len;
-    sc->sent = 0;
-
-    {
-	int counter = 0;
-	do {
-		brl1_send_chars( sc );
-		if ( counter++ > 0xfffff ) {
-			char *str = "Looping waiting for uart to clear (2)\n";
-			early_l1_serial_out(sc->nasid, str, strlen(str), ALREADY_LOCKED);
-			break;
-		}
-	} while( (sc->sent < sc->send_len) && wait );
-    }
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(sc->nasid);
-
-    if( sc->sent == sc->send_len ) {
-	/* success! release the send buffer and call the callup */
-#if	!defined(SYNC_CONSOLE_WRITE)
-	brl1_notif_t callup;
-#endif
-
-	sc->send_in_use = 0;
-	/* call any upper layer that's asked for notification */
-#if	defined(XX_SYNC_CONSOLE_WRITE)
-	/*
-	 * This is probably not a good idea - since the l1_ write func can be called multiple
-	 * time within the callup function.
-	 */
-	callup = subch->tx_notify;
-	if( callup && (SUBCH(type_and_subch) == SC_CONS_SYSTEM) ) {
-		L1_collectibles[L1C_SEND_CALLUPS]++;
-		(*callup)(sc->subch[SUBCH(type_and_subch)].irq_frame.bf_irq,
-				sc->subch[SUBCH(type_and_subch)].irq_frame.bf_dev_id,
-				sc->subch[SUBCH(type_and_subch)].irq_frame.bf_regs, sc, SUBCH(type_and_subch));
-	}
-#endif	/* SYNC_CONSOLE_WRITE */
-    }
-#if	!defined(SYNC_CONSOLE_WRITE)
-    else if ( !wait ) {
-	/* enable low-water interrupts so buffer will be drained */
-	uart_enable_xmit_intr(sc);
-    }
-#endif
-
-    L1SC_SEND_UNLOCK(sc, pl);
-
-    return len;
-}
-
-/* brl1_send_cont is intended to be called as an interrupt service
- * routine.  It sends until the UART won't accept any more characters,
- * or until an error is encountered (in which case we surrender the
- * send buffer and give up trying to send the packet).  Once the
- * last character in the packet has been sent, this routine releases
- * the send buffer and calls any previously-registered "low-water"
- * output routines.
- */
-
-#if	!defined(SYNC_CONSOLE_WRITE)
-
-int
-brl1_send_cont( l1sc_t *sc )
-{
-    unsigned long pl = 0;
-    int done = 0;
-    brl1_notif_t callups[BRL1_NUM_SUBCHANS];
-    brl1_notif_t *callup;
-    brl1_sch_t *subch;
-    int index;
-
-    /*
-     * I'm not sure how I think this is to be handled - whether the lock is held
-     * over the interrupt - but it seems like it is a bad idea....
-     */
-
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	lock_console(sc->nasid);
-    L1SC_SEND_LOCK(sc, pl);
-    brl1_send_chars( sc );
-    done = (sc->sent == sc->send_len);
-    if( done ) {
-	sc->send_in_use = 0;
-#if	!defined(SYNC_CONSOLE_WRITE)
-	uart_disable_xmit_intr(sc);
-#endif
-    }
-    if ( sc->uart == BRL1_LOCALHUB_UART )
-	unlock_console(sc->nasid);
-    /* Release the lock */
-    L1SC_SEND_UNLOCK(sc, pl);
-
-    return 0;
-}
-#endif	/* SYNC_CONSOLE_WRITE */
-
-/* internal function -- used by brl1_receive to read a character 
- * from the uart and check whether errors occurred in the process.
- */
-static int
-read_uart( l1sc_t *sc, int *c, int *result )
-{
-    *c = sc->getc_f( sc );
-
-    /* no character is available */
-    if( *c == UART_NO_CHAR ) {
-	*result = BRL1_NO_MESSAGE;
-	return 0;
-    }
-
-    /* some error in UART */
-    if( *c < 0 ) {
-	*result = BRL1_LINK;
-	return 0;
-    }
-
-    /* everything's fine */
-    *result = BRL1_VALID;
-    return 1;
-}
-
-
-/*
- * brl1_receive
- *
- * This function reads a Bedrock-L1 protocol packet into the l1sc_t
- * response buffer.
- *
- * The operation of this function can be expressed as a finite state
- * machine:
- *
-
-START STATE			INPUT		TRANSITION
-==========================================================
-BRL1_IDLE (reset or error)	flag		BRL1_FLAG
-				other		BRL1_IDLE@
-
-BRL1_FLAG (saw a flag (0x7e))	flag		BRL1_FLAG
-				escape		BRL1_IDLE@
-				header byte	BRL1_HDR
-				other		BRL1_IDLE@
-
-BRL1_HDR (saw a type/subch byte)(see below)	BRL1_BODY
-						BRL1_HDR
-
-BRL1_BODY (reading packet body)	flag		BRL1_FLAG
-				escape		BRL1_ESC
-				other		BRL1_BODY
-
-BRL1_ESC (saw an escape (0x7d))	flag		BRL1_FLAG@
-				escape		BRL1_IDLE@
-				other		BRL1_BODY
-==========================================================
-
-"@" denotes an error transition.
-
- * The BRL1_HDR state is a transient state which doesn't read input,
- * but just provides a way in to code which decides to whom an
- * incoming packet should be directed.
- *
- * brl1_receive can be used to poll for input from the L1, or as 
- * an interrupt service routine.  It reads as much data as is
- * ready from the junk bus UART and places into the appropriate
- * input queues according to subchannel.  The header byte is
- * stripped from console-type data, but is retained for message-
- * type data (L1 responses).  A length byte will also be
- * prepended to message-type packets.
- *
- * This routine is non-blocking; if the caller needs to block
- * for input, it must call brl1_receive in a loop.
- *
- * brl1_receive returns when there is no more input, the queue
- * for the current incoming message is full, or there is an
- * error (parity error, bad header, bad CRC, etc.).
- */
-
-#define STATE_SET(l,s)		((l)->brl1_state = (s))
-#define STATE_GET(l)		((l)->brl1_state)
-
-#define LAST_HDR_SET(l,h)	((l)->brl1_last_hdr = (h))
-#define LAST_HDR_GET(l)		((l)->brl1_last_hdr)
-
-#define VALID_HDR(c)				\
-    ( SUBCH((c)) <= SC_CONS_SYSTEM		\
-	? PKT_TYPE((c)) == BRL1_REQUEST		\
-	: ( PKT_TYPE((c)) == BRL1_RESPONSE ||	\
-	    PKT_TYPE((c)) == BRL1_EVENT ) )
-
-#define IS_TTY_PKT(l)		( SUBCH(LAST_HDR_GET(l)) <= SC_CONS_SYSTEM ? 1 : 0 )
-
-
-int
-brl1_receive( l1sc_t *sc, int mode )
-{
-    int result;		/* value to be returned by brl1_receive */
-    int c;		/* most-recently-read character	     	*/
-    int done;		/* set done to break out of recv loop	*/
-    unsigned long pl = 0, cpl = 0;
-    sc_cq_t *q;		/* pointer to queue we're working with	*/
-
-    result = BRL1_NO_MESSAGE;
-
-    L1SC_RECV_LOCK(sc, cpl);
-
-    done = 0;
-    while( !done )
-    {
-	switch( STATE_GET(sc) )
-	{
-
-	  case BRL1_IDLE:
-	    /* Initial or error state.  Waiting for a flag character
-             * to resynchronize with the L1.
-             */
-
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		done = 1;
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* saw a flag character */
-		STATE_SET( sc, BRL1_FLAG );
-		continue;
-	    }
-	    break;
-	    
-	  case BRL1_FLAG:
-	    /* One or more flag characters have been read; look for
-	     * the beginning of a packet (header byte).
-	     */
-	    
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		if( c != UART_NO_CHAR )
-		    STATE_SET( sc, BRL1_IDLE );
-
-		done = 1;
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* multiple flags are OK */
-		continue;
-	    }
-
-	    if( !VALID_HDR( c ) ) {
-		/* if c isn't a flag it should have been
-		 * a valid header, so we have an error
-		 */
-		result = BRL1_PROTOCOL;
-		STATE_SET( sc, BRL1_IDLE );
-		done = 1;
-		continue;
-	    }
-
-	    /* we have a valid header byte */
-	    LAST_HDR_SET( sc, c );
-	    STATE_SET( sc, BRL1_HDR );
-
-	    break; 
-
-	  case BRL1_HDR:
-	    /* A header byte has been read. Do some bookkeeping. */
-	    q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp;
-	    ASSERT(q);
-	    
-	    if( !IS_TTY_PKT(sc) ) {
-		/* if this is an event or command response rather
-		 * than console I/O, we need to reserve a couple
-		 * of extra spaces in the queue for the header
-		 * byte and a length byte; if we can't, stay in
-		 * the BRL1_HDR state.
-		 */
-		if( cq_room( q ) < 2 ) {
-		    result = BRL1_FULL_Q;
-		    done = 1;
-		    continue;
-		}
-		cq_tent_add( q, 0 );			/* reserve length byte */
-		cq_tent_add( q, LAST_HDR_GET( sc ) );	/* record header byte  */
-	    }
-	    STATE_SET( sc, BRL1_BODY );
-
-	    break;
-
-	  case BRL1_BODY:
-	    /* A header byte has been read.  We are now attempting
-	     * to receive the packet body.
-	     */
-
-	    q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp;
-	    ASSERT(q);
-
-	    /* if the queue we want to write into is full, don't read from
-	     * the uart (this provides backpressure to the L1 side)
-	     */
-	    if( cq_tent_full( q ) ) {
-		result = BRL1_FULL_Q;
-		done = 1;
-		continue;
-	    }
-	    
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		if( c != UART_NO_CHAR )
-		    STATE_SET( sc, BRL1_IDLE );
-		done = 1;
-		continue;
-	    }
-
-	    if( c == BRL1_ESC_CH ) {
-		/* prepare to unescape the next character */
-		STATE_SET( sc, BRL1_ESC );
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* flag signifies the end of a packet */
-
-		unsigned short crc;	/* holds the crc as we calculate it */
-		int i;			/* index variable */
-		brl1_sch_t *subch;      /* subchannel for received packet */
-		brl1_notif_t callup;	/* "data ready" callup */
-
-		/* whatever else may happen, we've seen a flag and we're
-		 * starting a new packet
-		 */
-		STATE_SET( sc, BRL1_FLAG );
-
-		/* if the packet body has less than 2 characters,
-		 * it can't be a well-formed packet.  Discard it.
-		 */
-		if( cq_tent_len( q ) < /* 2 + possible length byte */
-		    (2 + (IS_TTY_PKT(sc) ? 0 : 1)) )
-		{
-		    result = BRL1_PROTOCOL;
-		    cq_discard_tent( q );
-		    STATE_SET( sc, BRL1_FLAG );
-		    done = 1;
-		    continue;
-		}
-		
-		/* check CRC */
-
-		/* accumulate CRC, starting with the header byte and
-		 * ending with the transmitted CRC.  This should
-		 * result in a known good value.
-		 */
-		crc = crc16_calc( INIT_CRC, LAST_HDR_GET(sc) );
-		for( i = (q->ipos + (IS_TTY_PKT(sc) ? 0 : 2)) % BRL1_QSIZE;
-		     i != q->tent_next;
-		     i = (i + 1) % BRL1_QSIZE )
-		{
-		    crc = crc16_calc( crc, q->buf[i] );
-		}
-
-		/* verify the caclulated crc against the "good" crc value;
-		 * if we fail, discard the bad packet and return an error.
-		 */
-		if( crc != (unsigned short)GOOD_CRC ) {
-		    result = BRL1_CRC;
-		    cq_discard_tent( q );
-		    STATE_SET( sc, BRL1_FLAG );
-		    done = 1;
-		    continue;
-		}
-		
-		/* so the crc check was ok.  Now we discard the CRC
-		 * from the end of the received bytes.
-		 */
-		q->tent_next += (BRL1_QSIZE - 2);
-		q->tent_next %= BRL1_QSIZE;
-
-		/* get the subchannel and lock it */
-		subch = &(sc->subch[SUBCH( LAST_HDR_GET(sc) )]);
-		SUBCH_DATA_LOCK( subch, pl );
-		
-		/* if this isn't a console packet, we need to record
-		 * a length byte
-		 */
-		if( !IS_TTY_PKT(sc) ) {
-		    q->buf[q->ipos] = cq_tent_len( q ) - 1;
-		}
-		
-		/* record packet for posterity */
-		cq_commit_tent( q );
-		result = BRL1_VALID;
-
-		/* notify subchannel owner that there's something
-		 * on the queue for them
-		 */
-		atomic_inc(&(subch->packet_arrived));
-		callup = subch->rx_notify;
-		SUBCH_DATA_UNLOCK( subch, pl );
-
-		if( callup && (mode == SERIAL_INTERRUPT_MODE) ) {
-		    L1SC_RECV_UNLOCK( sc, cpl );
-		    L1_collectibles[L1C_RECEIVE_CALLUPS]++;
-		    (*callup)( sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_irq,
-				sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_dev_id,
-				sc->subch[SUBCH(LAST_HDR_GET(sc))].irq_frame.bf_regs,
-				sc, SUBCH(LAST_HDR_GET(sc)) );
-		    L1SC_RECV_LOCK( sc, cpl );
-		}
-		continue;	/* go back for more! */
-	    }
-	    
-	    /* none of the special cases applied; we've got a normal
-	     * body character
-	     */
-	    cq_tent_add( q, c );
-
-	    break;
-
-	  case BRL1_ESC:
-	    /* saw an escape character.  The next character will need
-	     * to be unescaped.
-	     */
-
-	    q = sc->subch[ SUBCH( LAST_HDR_GET(sc) ) ].iqp;
-	    ASSERT(q);
-
-	    /* if the queue we want to write into is full, don't read from
-	     * the uart (this provides backpressure to the L1 side)
-	     */
-	    if( cq_tent_full( q ) ) {
-		result = BRL1_FULL_Q;
-		done = 1;
-		continue;
-	    }
-	    
-	    if( !read_uart( sc, &c, &result ) ) {
-
-		/* error reading uart */
-		if( c != UART_NO_CHAR ) {
-		    cq_discard_tent( q );
-		    STATE_SET( sc, BRL1_IDLE );
-		}
-		done = 1;
-		continue;
-	    }
-	    
-	    if( c == BRL1_FLAG_CH ) {
-		/* flag after escape is an error */
-		STATE_SET( sc, BRL1_FLAG );
-		cq_discard_tent( q );
-		result = BRL1_PROTOCOL;
-		done = 1;
-		continue;
-	    }
-
-	    if( c == BRL1_ESC_CH ) {
-		/* two consecutive escapes is an error */
-		STATE_SET( sc, BRL1_IDLE );
-		cq_discard_tent( q );
-		result = BRL1_PROTOCOL;
-		done = 1;
-		continue;
-	    }
-	    
-	    /* otherwise, we've got a character that needs
-	     * to be unescaped
-	     */
-	    cq_tent_add( q, (c ^ BRL1_XOR_CH) );
-	    STATE_SET( sc, BRL1_BODY );
-
-	    break;
-
-	} /* end of switch( STATE_GET(sc) ) */
-    } /* end of while(!done) */
-
-    L1SC_RECV_UNLOCK( sc, cpl );
-
-    return result;
-}	    
-
-
-/* brl1_init initializes the Bedrock/L1 protocol layer.  This includes
- * zeroing out the send and receive state information.
- */
-
-void
-brl1_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart )
-{
-    int i;
-    brl1_sch_t *subch;
-
-    bzero( sc, sizeof( *sc ) );
-    sc->nasid = nasid;
-    sc->uart = uart;
-    sc->getc_f = (uart == BRL1_LOCALHUB_UART ? uart_getc : rtr_uart_getc);
-    sc->putc_f = (uart == BRL1_LOCALHUB_UART ? uart_putc : rtr_uart_putc);
-    sc->sol = 1;
-    subch = sc->subch;
-
-    /* initialize L1 subchannels
-     */
-
-    /* assign processor TTY channels */
-    for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_RSVD;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	spin_lock_init( &(subch->data_lock) );
-	sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ );
-	subch->tx_notify = NULL;
-	/* (for now, drop elscuart packets in the kernel) */
-	subch->rx_notify = brl1_discard_packet;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* assign system TTY channel (first free subchannel after each
-     * processor's individual TTY channel has been assigned)
-     */
-    subch->use = BRL1_SUBCH_RSVD;
-    subch->packet_arrived = ATOMIC_INIT(0);
-    spin_lock_init( &(subch->data_lock) );
-    sv_init( &(subch->arrive_sv), &subch->data_lock, SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */ );
-    subch->tx_notify = NULL;
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP, NASID_TO_COMPACT_NODEID(nasid) );
-	ASSERT( subch->iqp );
-	cq_init( subch->iqp );
-	subch->rx_notify = NULL;
-    }
-    else {
-	/* we shouldn't be getting console input from remote UARTs */
-	subch->iqp = &sc->garbage_q;
-	subch->rx_notify = brl1_discard_packet;
-    }
-    subch++; i++;
-
-    /* "reserved" subchannels (0x05-0x0F); for now, throw away
-     * incoming packets
-     */
-    for( ; i < 0x10; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = brl1_discard_packet;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* remaining subchannels are free */
-    for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = brl1_discard_packet;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* initialize synchronization structures
-     */
-    spin_lock_init( &(sc->subch_lock) );
-    spin_lock_init( &(sc->send_lock) );
-    spin_lock_init( &(sc->recv_lock) );
-
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	uart_init( sc, UART_BAUD_RATE );
-    }
-    else {
-	rtr_uart_init( sc, UART_BAUD_RATE );
-    }
-
-    /* Set up remaining fields using L1 command functions-- elsc_module_get
-     * to read the module id, elsc_debug_get to see whether or not we're
-     * in verbose mode.
-     */
-    {
-	extern int elsc_module_get(l1sc_t *);
-
-	sc->modid = elsc_module_get( sc );
-	sc->modid = (sc->modid < 0 ? INVALID_MODULE : sc->modid);
-	sc->verbose = 1;
-    }
-}
-
-/*********************************************************************
- * These are interrupt-related functions used in the kernel to service
- * the L1.
- */
-
-/*
- * brl1_intrd is the function which is called on a console interrupt.
- */
-
-#if defined(CONFIG_IA64_SGI_SN1)
-
-static void
-brl1_intrd(int irq, void *dev_id, struct pt_regs *stuff)
-{
-    u_char isr_reg;
-    l1sc_t *sc = get_elsc();
-    int ret;
-
-    L1_collectibles[L1C_INTERRUPTS]++;
-    isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);
-
-    /* Save for callup args in console */
-    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_irq = irq;
-    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_dev_id = dev_id;
-    sc->subch[SC_CONS_SYSTEM].irq_frame.bf_regs = stuff;
-
-#if	defined(SYNC_CONSOLE_WRITE)
-    while( isr_reg & ISR_RxRDY )
-#else
-    while( isr_reg & (ISR_RxRDY | ISR_TxRDY) )
-#endif
-    {
-	if( isr_reg & ISR_RxRDY ) {
-	    L1_collectibles[L1C_OUR_R_INTERRUPTS]++;
-	    ret = brl1_receive(sc, SERIAL_INTERRUPT_MODE);
-	    if ( (ret != BRL1_VALID) && (ret != BRL1_NO_MESSAGE) && (ret != BRL1_PROTOCOL) && (ret != BRL1_CRC) )
-		L1_collectibles[L1C_REC_STALLS] = ret;
-	}
-#if	!defined(SYNC_CONSOLE_WRITE)
-	if( (isr_reg & ISR_TxRDY) || (sc->send_in_use && UART_PUTC_READY(sc->nasid)) ) {
-	    L1_collectibles[L1C_OUR_X_INTERRUPTS]++;
-	    brl1_send_cont(sc);
-	}
-#endif	/* SYNC_CONSOLE_WRITE */
-	isr_reg = READ_L1_UART_REG(sc->nasid, REG_ISR);
-    }
-}
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-
-/*
- * Install a callback function for the system console subchannel 
- * to allow an upper layer to be notified when the send buffer 
- * has been emptied.
- */
-static inline void
-l1_tx_notif( brl1_notif_t func )
-{
-	subch_set_tx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc,
-			SC_CONS_SYSTEM, func );
-}
-
-
-/*
- * Install a callback function for the system console subchannel
- * to allow an upper layer to be notified when a packet has been
- * received.
- */
-static inline void
-l1_rx_notif( brl1_notif_t func )
-{
-	subch_set_rx_notify( &NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid()))->module->elsc,
-				SC_CONS_SYSTEM, func );
-}
-
-
-/* brl1_intr is called directly from the uart interrupt; after it runs, the
- * interrupt "daemon" xthread is signalled to continue.
- */
-void
-brl1_intr( void )
-{
-}
-
-#define BRL1_INTERRUPT_LEVEL	65	/* linux request_irq() value */
-
-/* Return the current interrupt level */
-
-//#define CONSOLE_POLLING_ALSO
-
-int
-l1_get_intr_value( void )
-{
-#ifdef	CONSOLE_POLLING_ALSO
-	return(0);
-#else
-	return(BRL1_INTERRUPT_LEVEL);
-#endif
-}
-
-/* Disconnect the callup functions - throw away interrupts */
-
-void
-l1_unconnect_intr(void)
-{
-	/* UnRegister the upper-level callup functions */
-	l1_rx_notif((brl1_notif_t)NULL);
-	l1_tx_notif((brl1_notif_t)NULL);
-	/* We do NOT unregister the interrupts */
-}
-
-/* Set up uart interrupt handling for this node's uart */
-
-void
-l1_connect_intr(void *rx_notify, void *tx_notify)
-{
-	l1sc_t *sc;
-	nasid_t nasid;
-#if defined(CONFIG_IA64_SGI_SN1)
-	int tmp;
-#endif
-	nodepda_t *console_nodepda;
-	int intr_connect_level(cpuid_t, int, ilvl_t, intr_func_t);
-
-	if ( L1_interrupts_connected ) {
-		/* Interrupts are connected, so just register the callups */
-		l1_rx_notif((brl1_notif_t)rx_notify);
-		l1_tx_notif((brl1_notif_t)tx_notify);
-
-		L1_collectibles[L1C_CONNECT_CALLS]++;
-		return;
-	}
-	else
-		L1_interrupts_connected = 1;
-
-	nasid = get_master_nasid();
-	console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(nasid));
-	sc = &console_nodepda->module->elsc;
-	sc->intr_cpu = console_nodepda->node_first_cpu;
-
-#if defined(CONFIG_IA64_SGI_SN1)
-	if ( intr_connect_level(sc->intr_cpu, UART_INTR, INTPEND0_MAXMASK, (intr_func_t)brl1_intr) ) {
-		L1_interrupts_connected = 0; /* FAILS !! */
-	}
-	else {
-		void synergy_intr_connect(int, int);
-
-		synergy_intr_connect(UART_INTR, sc->intr_cpu);
-		L1_collectibles[L1C_R_IRQ]++;
-		tmp = request_irq(BRL1_INTERRUPT_LEVEL, brl1_intrd, SA_INTERRUPT | SA_SHIRQ, "l1_protocol_driver", (void *)sc);
-		L1_collectibles[L1C_R_IRQ_RET] = (uint64_t)tmp;
-		if ( tmp ) {
-			L1_interrupts_connected = 0; /* FAILS !! */
-		}
-		else {
-			/* Register the upper-level callup functions */
-			l1_rx_notif((brl1_notif_t)rx_notify);
-			l1_tx_notif((brl1_notif_t)tx_notify);
-
-			/* Set the uarts the way we like it */
-			uart_enable_recv_intr( sc );
-			uart_disable_xmit_intr( sc );
-		}
-	}
-#endif	/* CONFIG_IA64_SGI_SN1 */
-}
-
-
-/* Set the line speed */
-
-void
-l1_set_baud(int baud)
-{
-#if 0
-	nasid_t nasid;
-	static void uart_init(l1sc_t *, int);
-#endif
-
-	L1_collectibles[L1C_SET_BAUD]++;
-
-#if 0
-	if ( L1_cons_is_inited ) {
-		nasid = get_master_nasid();
-		if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 )
-			uart_init(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, baud);
-	}
-#endif
-	return;
-}
-
-
-/* These are functions to use from serial_in/out when in protocol
- * mode to send and receive uart control regs. These are external
- * interfaces into the protocol driver.
- */
-
-void
-l1_control_out(int offset, int value)
-{
-	nasid_t nasid = get_master_nasid();
-	WRITE_L1_UART_REG(nasid, offset, value); 
-}
-
-/* Console input exported interface. Return a register value.  */
-
-int
-l1_control_in_polled(int offset)
-{
-	static int l1_control_in_local(int, int);
-
-	return(l1_control_in_local(offset, SERIAL_POLLED_MODE));
-}
-
-int
-l1_control_in(int offset)
-{
-	static int l1_control_in_local(int, int);
-
-	return(l1_control_in_local(offset, SERIAL_INTERRUPT_MODE));
-}
-
-static int
-l1_control_in_local(int offset, int mode)
-{
-	nasid_t nasid;
-	int ret, input;
-	static int l1_poll(l1sc_t *, int);
-
-	nasid = get_master_nasid();
-	ret = READ_L1_UART_REG(nasid, offset); 
-
-	if ( offset == REG_LSR ) {
-		ret |= (LSR_XHRE | LSR_XSRE);	/* can send anytime */
-		if ( L1_cons_is_inited ) {
-			if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) {
-				input = l1_poll(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, mode);
-				if ( input ) {
-					ret |= LSR_RCA;
-				}
-			}
-		}
-	}
-	return(ret);
-}
-
-/*
- * Console input exported interface. Return a character (if one is available)
- */
-
-int
-l1_serial_in_polled(void)
-{
-	static int l1_serial_in_local(int mode);
-
-	return(l1_serial_in_local(SERIAL_POLLED_MODE));
-}
-
-int
-l1_serial_in(void)
-{
-	static int l1_serial_in_local(int mode);
-
-	return(l1_serial_in_local(SERIAL_INTERRUPT_MODE));
-}
-
-static int
-l1_serial_in_local(int mode)
-{
-	nasid_t nasid;
-	l1sc_t *sc;
-	int value;
-	static int l1_getc( l1sc_t *, int );
-	static inline l1sc_t *early_sc_init(nasid_t);
-
-	nasid = get_master_nasid();
-	sc = early_sc_init(nasid);
-	if ( L1_cons_is_inited ) {
-		if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 ) {
-			sc = &NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc;
-		}
-	}
-	value = l1_getc(sc, mode);
-	return(value);
-}
-
-/* Console output exported interface. Write message to the console.  */
-
-int
-l1_serial_out( char *str, int len )
-{
-	nasid_t nasid = get_master_nasid();
-	int l1_write(l1sc_t *, char *, int, int);
-
-	if ( L1_cons_is_inited ) {
-		if ( NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module != (module_t *)0 )
-			return(l1_write(&NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->module->elsc, str, len,
-#if	defined(SYNC_CONSOLE_WRITE)
-					1
-#else
-					!L1_interrupts_connected
-#endif
-							));
-	}
-	return(early_l1_serial_out(nasid, str, len, NOT_LOCKED));
-}
-
-
-/*
- * These are the 'early' functions - when we need to do things before we have
- * all the structs setup.
- */
-
-static l1sc_t Early_console;		/* fake l1sc_t */
-static int Early_console_inited = 0;
-
-static void
-early_brl1_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart )
-{
-    int i;
-    brl1_sch_t *subch;
-
-    bzero( sc, sizeof( *sc ) );
-    sc->nasid = nasid;
-    sc->uart = uart;
-    sc->getc_f = (uart == BRL1_LOCALHUB_UART ? uart_getc : rtr_uart_getc);
-    sc->putc_f = (uart == BRL1_LOCALHUB_UART ? uart_putc : rtr_uart_putc);
-    sc->sol = 1;
-    subch = sc->subch;
-
-    /* initialize L1 subchannels
-     */
-
-    /* assign processor TTY channels */
-    for( i = 0; i < CPUS_PER_NODE; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_RSVD;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = NULL;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* assign system TTY channel (first free subchannel after each
-     * processor's individual TTY channel has been assigned)
-     */
-    subch->use = BRL1_SUBCH_RSVD;
-    subch->packet_arrived = ATOMIC_INIT(0);
-    subch->tx_notify = NULL;
-    subch->rx_notify = NULL;
-    if( sc->uart == BRL1_LOCALHUB_UART ) {
-	static sc_cq_t x_iqp;
-
-	subch->iqp = &x_iqp;
-	ASSERT( subch->iqp );
-	cq_init( subch->iqp );
-    }
-    else {
-	/* we shouldn't be getting console input from remote UARTs */
-	subch->iqp = &sc->garbage_q;
-    }
-    subch++; i++;
-
-    /* "reserved" subchannels (0x05-0x0F); for now, throw away
-     * incoming packets
-     */
-    for( ; i < 0x10; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = NULL;
-	subch->iqp = &sc->garbage_q;
-    }
-
-    /* remaining subchannels are free */
-    for( ; i < BRL1_NUM_SUBCHANS; i++, subch++ ) {
-	subch->use = BRL1_SUBCH_FREE;
-	subch->packet_arrived = ATOMIC_INIT(0);
-	subch->tx_notify = NULL;
-	subch->rx_notify = NULL;
-	subch->iqp = &sc->garbage_q;
-    }
-}
-
-static inline l1sc_t *
-early_sc_init(nasid_t nasid)
-{
-	/* This is for early I/O */
-	if ( Early_console_inited == 0 ) {
-    		early_brl1_init(&Early_console, nasid,  BRL1_LOCALHUB_UART);
-		Early_console_inited = 1;
-	}
-	return(&Early_console);
-}
-
-#define PUTCHAR(ch) \
-    { \
-        while( (!(READ_L1_UART_REG( nasid, REG_LSR ) & LSR_XHRE)) || \
-                (!(READ_L1_UART_REG( nasid, REG_MSR ) & MSR_CTS)) ); \
-        WRITE_L1_UART_REG( nasid, REG_DAT, (ch) ); \
-    }
-
-static int
-early_l1_serial_out( nasid_t nasid, char *str, int len, int lock_state )
-{
-	int ret, sent = 0;
-	char *msg = str;
-	static int early_l1_send( nasid_t nasid, char *str, int len, int lock_state );
-
-	while ( sent < len ) {
-		ret = early_l1_send(nasid, msg, len - sent, lock_state);
-		sent += ret;
-		msg += ret;
-	}
-	return(len);
-}
-
-static inline int
-early_l1_send( nasid_t nasid, char *str, int len, int lock_state )
-{
-    int sent;
-    char crc_char;
-    unsigned short crc = INIT_CRC;
-
-    if( len > (BRL1_QSIZE - 1) )
-	len = (BRL1_QSIZE - 1);
-
-    sent = len;
-    if ( lock_state == NOT_LOCKED )
-    	lock_console(nasid);
-
-    PUTCHAR( BRL1_FLAG_CH );
-    PUTCHAR( BRL1_EVENT | SC_CONS_SYSTEM );
-    crc = crc16_calc( crc, (BRL1_EVENT | SC_CONS_SYSTEM) );
-
-    while( len ) {
-
-	if( (*str == BRL1_FLAG_CH) || (*str == BRL1_ESC_CH) ) {
-	    PUTCHAR( BRL1_ESC_CH );
-	    PUTCHAR( (*str) ^ BRL1_XOR_CH );
-	}
-	else {
-	    PUTCHAR( *str );
-	}
-	
-	crc = crc16_calc( crc, *str );
-
-	str++; len--;
-    }
-    
-    crc ^= 0xffff;
-    crc_char = crc & 0xff;
-    if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
-	crc_char ^= BRL1_XOR_CH;
-	PUTCHAR( BRL1_ESC_CH );
-    }
-    PUTCHAR( crc_char );
-    crc_char = (crc >> 8) & 0xff;
-    if( (crc_char == BRL1_ESC_CH) || (crc_char == BRL1_FLAG_CH) ) {
-	crc_char ^= BRL1_XOR_CH;
-	PUTCHAR( BRL1_ESC_CH );
-    }
-    PUTCHAR( crc_char );
-    PUTCHAR( BRL1_FLAG_CH );
-
-    if ( lock_state == NOT_LOCKED )
-    	unlock_console(nasid);
-    return sent;
-}
-
-
-/*********************************************************************
- * l1_cons functions
- *
- * These allow the L1 to act as the system console.  They're intended
- * to abstract away most of the br/l1 internal details from the
- * _L1_cons_* functions (in the prom-- see "l1_console.c") and
- * l1_* functions (in the kernel-- see "sio_l1.c") that they support.
- *
- */
-
-static int
-l1_poll( l1sc_t *sc, int mode )
-{
-    int ret;
-
-    /* in case this gets called before the l1sc_t structure for the module_t
-     * struct for this node is initialized (i.e., if we're called with a
-     * zero l1sc_t pointer)...
-     */
-
-
-    if( !sc ) {
-	return 0;
-    }
-
-    if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) {
-	return 1;
-    }
-
-    ret = brl1_receive( sc, mode );
-    if ( (ret != BRL1_VALID) && (ret != BRL1_NO_MESSAGE) && (ret != BRL1_PROTOCOL) && (ret != BRL1_CRC) )
-	L1_collectibles[L1C_REC_STALLS] = ret;
-
-    if( atomic_read(&sc->subch[SC_CONS_SYSTEM].packet_arrived) ) {
-	return 1;
-    }
-    return 0;
-}
-
-
-/* pull a character off of the system console queue (if one is available)
- */
-static int
-l1_getc( l1sc_t *sc, int mode )
-{
-    unsigned long pl = 0;
-    int c;
-
-    brl1_sch_t *subch = &(sc->subch[SC_CONS_SYSTEM]);
-    sc_cq_t *q = subch->iqp;
-
-    if( !l1_poll( sc, mode ) ) {
-	return 0;
-    }
-
-    SUBCH_DATA_LOCK( subch, pl );
-    if( cq_empty( q ) ) {
-	atomic_set(&subch->packet_arrived, 0);
-	SUBCH_DATA_UNLOCK( subch, pl );
-	return 0;
-    }
-    cq_rem( q, c );
-    if( cq_empty( q ) )
-	atomic_set(&subch->packet_arrived, 0);
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-    return c;
-}
-
-/*
- * Write a message to the L1 on the system console subchannel.
- *
- * Danger: don't use a non-zero value for the wait parameter unless you're
- * someone important (like a kernel error message).
- */
-
-int
-l1_write( l1sc_t *sc, char *msg, int len, int wait )
-{
-	int sent = 0, ret = 0;
-
-	if ( wait ) {
-		while ( sent < len ) {
-			ret = brl1_send( sc, msg, len - sent, (SC_CONS_SYSTEM | BRL1_EVENT), wait );
-			sent += ret;
-			msg += ret;
-		}
-		ret = len;
-	}
-	else {
-		ret = brl1_send( sc, msg, len, (SC_CONS_SYSTEM | BRL1_EVENT), wait );
-	}
-	return(ret);
-}
-
-/* initialize the system console subchannel
- */
-void
-l1_init(void)
-{
-	/* All we do now is remember that we have been called */
-	L1_cons_is_inited = 1;
-}
-
-
-/*********************************************************************
- * The following functions and definitions implement the "message"-
- * style interface to the L1 system controller.
- *
- * Note that throughout this file, "sc" generally stands for "system
- * controller", while "subchannels" tend to be represented by
- * variables with names like subch or ch.
- *
- */
-
-#ifdef L1_DEBUG
-#define L1_DBG_PRF(x) printf x
-#else
-#define L1_DBG_PRF(x)
-#endif
-
-/*
- * sc_data_ready is called to signal threads that are blocked on l1 input.
- */
-void
-sc_data_ready( int dummy0, void *dummy1, struct pt_regs *dummy2, l1sc_t *sc, int ch )
-{
-    unsigned long pl = 0;
-
-    brl1_sch_t *subch = &(sc->subch[ch]);
-    SUBCH_DATA_LOCK( subch, pl );
-    sv_signal( &(subch->arrive_sv) );
-    SUBCH_DATA_UNLOCK( subch, pl );
-}
-
-/* sc_open reserves a subchannel to send a request to the L1 (the
- * L1's response will arrive on the same channel).  The number
- * returned by sc_open is the system controller subchannel
- * acquired.
- */
-int
-sc_open( l1sc_t *sc, uint target )
-{
-    /* The kernel version implements a locking scheme to arbitrate
-     * subchannel assignment.
-     */
-    int ch;
-    unsigned long pl = 0;
-    brl1_sch_t *subch;
-
-    SUBCH_LOCK( sc, pl );
-
-    /* Look for a free subchannel. Subchannels 0-15 are reserved
-     * for other purposes.
-     */
-    for( subch = &(sc->subch[BRL1_CMD_SUBCH]), ch = BRL1_CMD_SUBCH; 
-			ch < BRL1_NUM_SUBCHANS; subch++, ch++ ) {
-        if( subch->use == BRL1_SUBCH_FREE )
-            break;
-    }
-
-    if( ch == BRL1_NUM_SUBCHANS ) {
-        /* there were no subchannels available! */
-        SUBCH_UNLOCK( sc, pl );
-        return SC_NSUBCH;
-    }
-
-    subch->use = BRL1_SUBCH_RSVD;
-    SUBCH_UNLOCK( sc, pl );
-
-    atomic_set(&subch->packet_arrived, 0);
-    subch->target = target;
-    spin_lock_init( &(subch->data_lock) );
-    sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */);
-    subch->tx_notify = NULL;
-    subch->rx_notify = sc_data_ready;
-    subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
-				   NASID_TO_COMPACT_NODEID(sc->nasid) );
-    ASSERT( subch->iqp );
-    cq_init( subch->iqp );
-
-    return ch;
-}
-
-
-/* sc_close frees a Bedrock<->L1 subchannel.
- */
-int
-sc_close( l1sc_t *sc, int ch )
-{
-    unsigned long pl = 0;
-    brl1_sch_t *subch;
-
-    SUBCH_LOCK( sc, pl );
-    subch = &(sc->subch[ch]);
-    if( subch->use != BRL1_SUBCH_RSVD ) {
-        /* we're trying to close a subchannel that's not open */
-	SUBCH_UNLOCK( sc, pl );
-        return SC_NOPEN;
-    }
-
-    atomic_set(&subch->packet_arrived, 0);
-    subch->use = BRL1_SUBCH_FREE;
-
-    sv_broadcast( &(subch->arrive_sv) );
-    sv_destroy( &(subch->arrive_sv) );
-    spin_lock_destroy( &(subch->data_lock) );
-
-    ASSERT( subch->iqp && (subch->iqp != &sc->garbage_q) );
-    snia_kmem_free( subch->iqp, sizeof(sc_cq_t) );
-    subch->iqp = &sc->garbage_q;
-    subch->tx_notify = NULL;
-    subch->rx_notify = brl1_discard_packet;
-
-    SUBCH_UNLOCK( sc, pl );
-
-    return SC_SUCCESS;
-}
-
-
-/* sc_construct_msg builds a bedrock-to-L1 request in the supplied
- * buffer.  Returns the length of the message.  The
- * safest course when passing a buffer to be filled in is to use
- * BRL1_QSIZE as the buffer size.
- *
- * Command arguments are passed as type/argument pairs, i.e., to
- * pass the number 5 as an argument to an L1 command, call
- * sc_construct_msg as follows:
- *
- *    char msg[BRL1_QSIZE];
- *    msg_len = sc_construct_msg( msg,
- *				  BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                2,
- *                                L1_ARG_INT, 5 );
- *
- * To pass an additional ASCII argument, you'd do the following:
- *
- *    char *str;
- *    ... str points to a null-terminated ascii string ...
- *    msg_len = sc_construct_msg( msg,
- *                                BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                4,
- *                                L1_ARG_INT, 5,
- *                                L1_ARG_ASCII, str );
- *
- * Finally, arbitrary data of unknown type is passed using the argtype
- * code L1_ARG_UNKNOWN, a data length, and a buffer pointer, e.g.
- *
- *    msg_len = sc_construct_msg( msg,
- *                                BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                3,
- *                                L1_ARG_UNKNOWN, 32, bufptr );
- *
- * ...passes 32 bytes of data starting at bufptr.  Note that no string or
- * "unknown"-type argument should be long enough to overflow the message
- * buffer.
- *
- * To construct a message for an L1 command that requires no arguments,
- * you'd use the following:
- *
- *    msg_len = sc_construct_msg( msg,
- *                                BRL1_QSIZE,
- *				  target_component,
- *                                L1_ADDR_TASK_BOGUSTASK,
- *                                L1_BOGUSTASK_REQ_BOGUSREQ,
- *                                0 );
- *
- * The final 0 means "no varargs".  Notice that this parameter is used to hold
- * the number of additional arguments to sc_construct_msg, _not_ the actual
- * number of arguments used by the L1 command (so 2 per L1_ARG_[INT,ASCII]
- * type argument, and 3 per L1_ARG_UNKOWN type argument).  A call to construct
- * an L1 command which required three integer arguments and two arguments of
- * some arbitrary (unknown) type would pass 12 as the value for this parameter.
- *
- * ENDIANNESS WARNING: The following code does a lot of copying back-and-forth
- * between byte arrays and four-byte big-endian integers.  Depending on the
- * system controller connection and endianness of future architectures, some
- * rewriting might be necessary.
- */
-int
-sc_construct_msg( l1sc_t  *sc,		/* system controller struct */
-		  int	   ch,           /* subchannel for this message */
-		  char    *msg,          /* message buffer */
-		  int      msg_len,      /* size of message buffer */
-                  l1addr_t addr_task,    /* target system controller task */
-                  short    req_code,     /* 16-bit request code */
-                  int      req_nargs,    /* # of arguments (varargs) passed */
-                  ... )                 /* any additional parameters */
-{
-    uint32_t buf32;   /* 32-bit buffer used to bounce things around */
-    void *bufptr;       /* used to hold command argument addresses */
-    va_list al;         /* variable argument list */
-    int index;          /* current index into msg buffer */
-    int argno;          /* current position in varargs list */
-    int l1_argno;       /* running total of arguments to l1 */
-    int l1_arg_t;       /* argument type/length */
-    int l1_argno_byte;  /* offset of argument count byte */
-
-    index = argno = 0;
-
-    /* set up destination address */
-    if( (msg_len -= sizeof( buf32 )) < 0 )
-	return -1;
-    L1_ADDRESS_TO_TASK( &buf32, sc->subch[ch].target, addr_task );
-    COPY_INT_TO_BUFFER(msg, index, buf32);
-
-    /* copy request code */
-    if( (msg_len -= 2) < 0 )
-	return( -1 );
-    msg[index++] = ((req_code >> 8) & 0xff);
-    msg[index++] = (req_code & 0xff);
-
-    if( !req_nargs ) {
-        return index;
-    }
-
-    /* reserve a byte for the argument count */
-    if( (msg_len -= 1) < 0 )
-	return( -1 );
-    l1_argno_byte = index++;
-    l1_argno = 0;
-
-    /* copy additional arguments */
-    va_start( al, req_nargs );
-    while( argno < req_nargs ) {
-        l1_argno++;
-        l1_arg_t = va_arg( al, int ); argno++;
-        switch( l1_arg_t )
-        {
-          case L1_ARG_INT:
-	    if( (msg_len -= (sizeof( buf32 ) + 1)) < 0 )
-		return( -1 );
-            msg[index++] = L1_ARG_INT;
-            buf32 = (unsigned)va_arg( al, int ); argno++;
-	    COPY_INT_TO_BUFFER(msg, index, buf32);
-            break;
-
-          case L1_ARG_ASCII:
-            bufptr = va_arg( al, char* ); argno++;
-	    if( (msg_len -= (strlen( bufptr ) + 2)) < 0 )
-		return( -1 );
-            msg[index++] = L1_ARG_ASCII;
-            strcpy( (char *)&(msg[index]), (char *)bufptr );
-            index += (strlen( bufptr ) + 1); /* include terminating null */
-            break;
-
-	  case L1_ARG_UNKNOWN:
-              {
-                  int arglen;
-		  
-                  arglen = va_arg( al, int ); argno++;
-                  bufptr = va_arg( al, void* ); argno++;
-		  if( (msg_len -= (arglen + 1)) < 0 )
-		      return( -1 );
-                  msg[index++] = L1_ARG_UNKNOWN | arglen;
-                  BCOPY( bufptr, &(msg[index]), arglen  );
-                  index += arglen;
-		  break;
-              }
-	  
-	  default: /* unhandled argument type */
-	    return -1;
-        }
-    }
-
-    va_end( al );
-    msg[l1_argno_byte] = l1_argno;
-
-    return index;
-}
-
-
-
-/* sc_interpret_resp verifies an L1 response to a bedrock request, and
- * breaks the response data up into the constituent parts.  If the
- * response message indicates error, or if a mismatch is found in the
- * expected number and type of arguments, an error is returned.  The
- * arguments to this function work very much like the arguments to
- * sc_construct_msg, above, except that L1_ARG_INTs must be followed
- * by a _pointer_ to an integer that can be filled in by this function.
- */
-int
-sc_interpret_resp( char *resp,          /* buffer received from L1 */
-                   int   resp_nargs,    /* number of _varargs_ passed in */
-                   ... )
-{
-    uint32_t buf32;   /* 32-bit buffer used to bounce things around */
-    void *bufptr;       /* used to hold response field addresses */
-    va_list al;         /* variable argument list */
-    int index;          /* current index into response buffer */
-    int argno;          /* current position in varargs list */
-    int l1_fldno;       /* number of resp fields received from l1 */
-    int l1_fld_t;       /* field type/length */
-
-    index = argno = 0;
-
-#if defined(L1_DEBUG)
-#define DUMP_RESP							  \
-    {									  \
-	int ix;								  \
-        char outbuf[512];						  \
-        sprintf( outbuf, "sc_interpret_resp error line %d: ", __LINE__ ); \
-	for( ix = 0; ix < 16; ix++ ) {					  \
-	    sprintf( &outbuf[strlen(outbuf)], "%x ", resp[ix] );	  \
-	}								  \
-	printk( "%s\n", outbuf );					  \
-    }
-#else
-#define DUMP_RESP
-#endif /* L1_DEBUG */
-
-    /* check response code */
-    COPY_BUFFER_TO_INT(resp, index, buf32);
-    if( buf32 != L1_RESP_OK ) {
-	DUMP_RESP;
-        return buf32;
-    }
-
-    /* get number of response fields */
-    l1_fldno = resp[index++];
-
-    va_start( al, resp_nargs );
-
-    /* copy out response fields */
-    while( argno < resp_nargs ) {
-        l1_fldno--;
-        l1_fld_t = va_arg( al, int ); argno++;
-        switch( l1_fld_t )
-        {
-          case L1_ARG_INT:
-            if( resp[index++] != L1_ARG_INT ) {
-                /* type mismatch */
-		va_end( al );
-		DUMP_RESP;
-		return -1;
-            }
-            bufptr = va_arg( al, int* ); argno++;
-	    COPY_BUFFER_TO_BUFFER(resp, index, bufptr);
-            break;
-
-          case L1_ARG_ASCII:
-            if( resp[index++] != L1_ARG_ASCII ) {
-                /* type mismatch */
-		va_end( al );
-		DUMP_RESP;
-                return -1;
-            }
-            bufptr = va_arg( al, char* ); argno++;
-            strcpy( (char *)bufptr, (char *)&(resp[index]) );
-            /* include terminating null */
-            index += (strlen( &(resp[index]) ) + 1);
-            break;
-
-          default:
-	    if( (l1_fld_t & L1_ARG_UNKNOWN) == L1_ARG_UNKNOWN )
-	    {
-		int *arglen;
-		
-		arglen = va_arg( al, int* ); argno++;
-		bufptr = va_arg( al, void* ); argno++;
-		*arglen = ((resp[index++] & ~L1_ARG_UNKNOWN) & 0xff);
-		BCOPY( &(resp[index]), bufptr, *arglen  );
-		index += (*arglen);
-	    }
-	    
-	    else {
-		/* unhandled type */
-		va_end( al );
-		DUMP_RESP;
-		return -1;
-	    }
-        }
-    }
-    va_end( al );
-  
-    if( (l1_fldno != 0) || (argno != resp_nargs) ) {
-        /* wrong number of arguments */
-	DUMP_RESP;
-        return -1;
-    }
-    return 0;
-}
-
-
-
-
-/* sc_send takes as arguments a system controller struct, a
- * buffer which contains a Bedrock<->L1 "request" message,
- * the message length, and the subchannel (presumably obtained
- * from an earlier invocation of sc_open) over which the
- * message is to be sent.  The final argument ("wait") indicates
- * whether the send is to be performed synchronously or not.
- *
- * sc_send returns either zero or an error value.  Synchronous sends 
- * (wait != 0) will not return until the data has actually been sent
- * to the UART.  Synchronous sends generally receive privileged
- * treatment.  The intent is that they be used sparingly, for such
- * purposes as kernel printf's (the "ducons" routines).  Run-of-the-mill
- * console output and L1 requests should NOT use a non-zero value
- * for wait.
- */
-int
-sc_send( l1sc_t *sc, int ch, char *msg, int len, int wait )
-{
-    char type_and_subch;
-    int result;
-
-    if( (ch < 0) || ( ch >= BRL1_NUM_SUBCHANS) ) {
-        return SC_BADSUBCH;
-    }
-
-    /* Verify that this is an open subchannel
-     */
-    if( sc->subch[ch].use == BRL1_SUBCH_FREE ) {
-        return SC_NOPEN;
-    }
-
-    type_and_subch = (BRL1_REQUEST | ((u_char)ch));
-    result = brl1_send( sc, msg, len, type_and_subch, wait );
-
-    /* If we sent as much as we asked to, return "ok". */
-    if( result == len )
-	return( SC_SUCCESS );
-
-    /* Or, if we sent less, than either the UART is busy or
-     * we're trying to send too large a packet anyway.
-     */
-    else if( result >= 0 && result < len )
-	return( SC_BUSY );
-
-    /* Or, if something else went wrong (result < 0), then
-     * return that error value.
-     */
-    else
-	return( result );
-}
-
-
-
-/* subch_pull_msg pulls a message off the receive queue for subch
- * and places it the buffer pointed to by msg.  This routine should only
- * be called when the caller already knows a message is available on the
- * receive queue (and, in the kernel, only when the subchannel data lock
- * is held by the caller).
- */
-static void
-subch_pull_msg( brl1_sch_t *subch, char *msg, int *len )
-{
-    sc_cq_t *q;         /* receive queue */
-    int before_wrap,    /* packet may be split into two different       */
-        after_wrap;     /*   pieces to accommodate queue wraparound      */
-
-    /* pull message off the receive queue */
-    q = subch->iqp;
-
-    cq_rem( q, *len );   /* remove length byte and store */
-    cq_discard( q );     /* remove type/subch byte and discard */
-
-    if ( *len > 0 )
-	(*len)--;        /* don't count type/subch byte in length returned */
-
-    if( (q->opos + (*len)) > BRL1_QSIZE ) {
-        before_wrap = BRL1_QSIZE - q->opos;
-        after_wrap = (*len) - before_wrap;
-    }
-    else {
-        before_wrap = (*len);
-        after_wrap = 0;
-    }
-
-    BCOPY( q->buf + q->opos, msg, before_wrap  );
-    if( after_wrap ) {
-        BCOPY( q->buf, msg + before_wrap, after_wrap  );
-	q->opos = after_wrap;
-    }
-    else {
-	q->opos = ((q->opos + before_wrap) & (BRL1_QSIZE - 1));
-    }
-    atomic_dec(&(subch->packet_arrived));
-}
-
-
-/* sc_recv_poll can be called as a blocking or non-blocking function;
- * it attempts to pull a message off of the subchannel specified
- * in the argument list (ch).
- *
- * The "block" argument, if non-zero, is interpreted as a timeout
- * delay (to avoid permanent waiting).
- */
-
-int
-sc_recv_poll( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block )
-{
-    int is_msg = 0;
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    rtc_time_t exp_time = rtc_time() + block;
-
-    /* sanity check-- make sure this is an open subchannel */
-    if( subch->use == BRL1_SUBCH_FREE )
-	return( SC_NOPEN );
-
-    do {
-
-        /* kick the next lower layer and see if it pulls anything in
-         */
-	brl1_receive( sc, SERIAL_POLLED_MODE );
-	is_msg = atomic_read(&subch->packet_arrived);
-
-    } while( block && !is_msg && (rtc_time() < exp_time) );
-
-    if( !is_msg ) {
-	/* no message and we didn't care to wait for one */
-	return( SC_NMSG );
-    }
-
-    SUBCH_DATA_LOCK( subch, pl );
-    subch_pull_msg( subch, msg, len );
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-    return( SC_SUCCESS );
-}
-    
-
-/* Like sc_recv_poll, sc_recv_intr can be called in either a blocking
- * or non-blocking mode.  Rather than polling until an appointed timeout,
- * however, sc_recv_intr sleeps on a syncrhonization variable until a
- * signal from the lower layer tells us that a packet has arrived.
- *
- * sc_recv_intr can't be used with remote (router) L1s.
- */
-int
-sc_recv_intr( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block )
-{
-    int is_msg = 0;
-    unsigned long pl = 0;
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    do {
-	SUBCH_DATA_LOCK(subch, pl);
-	is_msg = atomic_read(&subch->packet_arrived);
-	if( !is_msg && block ) {
-	    /* wake me when you've got something */
-	    subch->rx_notify = sc_data_ready;
-	    sv_wait( &(subch->arrive_sv), 0, 0);
-	    if( subch->use == BRL1_SUBCH_FREE ) {
-		/* oops-- somebody closed our subchannel while we were
-		 * sleeping!
-		 */
-
-		/* no need to unlock since the channel's closed anyhow */
-		return( SC_NOPEN );
-	    }
-	}
-    } while( !is_msg && block );
-
-    if( !is_msg ) {
-	/* no message and we didn't care to wait for one */
-	SUBCH_DATA_UNLOCK( subch, pl );
-	return( SC_NMSG );
-    }
-
-    subch_pull_msg( subch, msg, len );
-    SUBCH_DATA_UNLOCK( subch, pl );
-
-    return( SC_SUCCESS );
-}
-
-/* sc_command implements a (blocking) combination of sc_send and sc_recv.
- * It is intended to be the SN1 equivalent of SN0's "elsc_command", which
- * issued a system controller command and then waited for a response from
- * the system controller before returning.
- *
- * cmd points to the outgoing command; resp points to the buffer in
- * which the response is to be stored.  Both buffers are assumed to
- * be the same length; if there is any doubt as to whether the
- * response buffer is long enough to hold the L1's response, then
- * make it BRL1_QSIZE bytes-- no Bedrock<->L1 message can be any
- * bigger.
- *
- * Be careful using the same buffer for both cmd and resp; it could get
- * hairy if there were ever an L1 command request that spanned multiple
- * packets.  (On the other hand, that would require some additional
- * rewriting of the L1 command interface anyway.)
- */
-#define __RETRIES	50
-#define __WAIT_SEND	1	// ( sc->uart != BRL1_LOCALHUB_UART )
-#define __WAIT_RECV	10000000
-
-
-int
-sc_command( l1sc_t *sc, int ch, char *cmd, char *resp, int *len )
-{
-#ifndef CONFIG_SERIAL_SGI_L1_PROTOCOL
-    return SC_NMSG;
-#else
-    int result;
-    int retries;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-    	return SC_NMSG;
-
-    retries = __RETRIES;
-
-    while( (result = sc_send( sc, ch, cmd, *len, __WAIT_SEND )) < 0 ) {
-	if( result == SC_BUSY ) {
-	    retries--;
-	    if( retries <= 0 )
-		return result;
-	    uart_delay(500);
-	}
-	else {
-	    return result;
-	}
-    }
-    
-    /* block on sc_recv_* */
-    if( (sc->uart == BRL1_LOCALHUB_UART) && L1_interrupts_connected ) {
-	return( sc_recv_intr( sc, ch, resp, len, __WAIT_RECV ) );
-    }
-    else {
-	return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) );
-    }
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
-}
-
-/* sc_command_kern is a knuckle-dragging, no-patience version of sc_command
- * used in situations where the kernel has a command that shouldn't be
- * delayed until the send buffer clears.  sc_command should be used instead
- * under most circumstances.
- */
-
-int
-sc_command_kern( l1sc_t *sc, int ch, char *cmd, char *resp, int *len )
-{
-#ifndef CONFIG_SERIAL_SGI_L1_PROTOCOL
-    return SC_NMSG;
-#else
-    int result;
-
-    if ( IS_RUNNING_ON_SIMULATOR() )
-    	return SC_NMSG;
-
-    if( (result = sc_send( sc, ch, cmd, *len, 1 )) < 0 ) {
-	return result;
-    }
-
-    return( sc_recv_poll( sc, ch, resp, len, __WAIT_RECV ) );
-#endif /* CONFIG_SERIAL_SGI_L1_PROTOCOL */
-}
-
-
-
-/* sc_poll checks the queue corresponding to the given
- * subchannel to see if there's anything available.  If
- * not, it kicks the brl1 layer and then checks again.
- *
- * Returns 1 if input is available on the given queue,
- * 0 otherwise.
- */
-
-int
-sc_poll( l1sc_t *sc, int ch )
-{
-    brl1_sch_t *subch = &(sc->subch[ch]);
-
-    if( atomic_read(&subch->packet_arrived) )
-	return 1;
-
-    brl1_receive( sc, SERIAL_POLLED_MODE );
-
-    if( atomic_read(&subch->packet_arrived) )
-	return 1;
-
-    return 0;
-}
-
-/* for now, sc_init just calls brl1_init */
-
-void
-sc_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart )
-{
-    if ( !IS_RUNNING_ON_SIMULATOR() )
-    	brl1_init( sc, nasid, uart );
-}
-
-/* sc_dispatch_env_event handles events sent from the system control
- * network's environmental monitor tasks.
- */
-
-#if	defined(LINUX_KERNEL_THREADS)
-
-static void
-sc_dispatch_env_event( uint code, int argc, char *args, int maxlen )
-{
-    int j, i = 0;
-    uint32_t ESPcode;
-
-    switch( code ) {
-	/* for now, all codes do the same thing: grab two arguments
-	 * and print a cmn_err_tag message */
-      default:
-	/* check number of arguments */
-	if( argc != 2 ) {
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "expected 2 arguments, got %d\n", argc ));
-	    return;
-	}
-	
-	/* get ESP code (integer argument) */
-	if( args[i++] != L1_ARG_INT ) {
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "expected integer argument\n" ));
-	    return;
-	}
-	/* WARNING: highly endian */
-	COPY_BUFFER_TO_INT(args, i, ESPcode);
-
-	/* verify string argument */
-	if( args[i++] != L1_ARG_ASCII ) {
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "expected an ASCII string\n" ));
-	    return;
-	}
-	for( j = i; j < maxlen; j++ ) {
-	    if( args[j] == '\0' ) break; /* found string termination */
-	}
-	if( j == maxlen ) {
-	    j--;
-	    L1_DBG_PRF(( "sc_dispatch_env_event: "
-			 "message too long-- truncating\n" ));
-	}
-
-	/* strip out trailing cr/lf */
-	for( ; 
-	     j > 1 && ((args[j-1] == 0xd) || (args[j-1] == 0xa)); 
-	     j-- );
-	args[j] = '\0';
-	
-	/* strip out leading cr/lf */
-	for( ;
-	     i < j && ((args[i] == 0xd) || (args[i] == 0xa));
-	     i++ );
-    }
-}
-
-
-/* sc_event waits for events to arrive from the system controller, and
- * prints appropriate messages to the syslog.
- */
-
-static void
-sc_event( l1sc_t *sc, int ch )
-{
-    char event[BRL1_QSIZE];
-    int i;
-    int result;
-    int event_len;
-    uint32_t ev_src;
-    uint32_t ev_code;
-    int ev_argc;
-
-    while(1) {
-	
-	bzero( event, BRL1_QSIZE );
-
-	/*
-	 * wait for an event 
-	 */
-	result = sc_recv_intr( sc, ch, event, &event_len, 1 );
-	if( result != SC_SUCCESS ) {
-	    printk(KERN_WARNING  "Error receiving sysctl event on nasid %d\n",
-		     sc->nasid );
-	}
-	else {
-	    /*
-	     * an event arrived; break it down into useful pieces
-	     */
-#if defined(L1_DEBUG) && 0
-	    int ix;
-	    printf( "Event packet received:\n" );
-	    for (ix = 0; ix < 64; ix++) {
-		printf( "%x%x ", ((event[ix] >> 4) & ((uint64_t)0xf)),
-			(event[ix] & ((uint64_t)0xf)) );
-		if( (ix % 16) == 0xf ) printf( "\n" );
-	    }
-#endif /* L1_DEBUG */
-
-	    i = 0;
-
-	    /* get event source */
-	    COPY_BUFFER_TO_INT(event, i, ev_src);
-	    COPY_BUFFER_TO_INT(event, i, ev_code);
-
-	    /* get arg count */
-	    ev_argc = (event[i++] & 0xffUL);
-	    
-	    /* dispatch events by task */
-	    switch( (ev_src & L1_ADDR_TASK_MASK) >> L1_ADDR_TASK_SHFT )
-	    {
-	      case L1_ADDR_TASK_ENV: /* environmental monitor event */
-		sc_dispatch_env_event( ev_code, ev_argc, &(event[i]), 
-				       BRL1_QSIZE - i );
-		break;
-
-	      default: /* unhandled task type */
-		L1_DBG_PRF(( "Unhandled event type received from system "
-			     "controllers: source task %x\n",
-			     (ev_src & L1_ADDR_TASK_MASK) >> L1_ADDR_TASK_SHFT
-			   ));
-	    }
-	}
-	
-    }			
-}
-
-/* sc_listen sets up a service thread to listen for incoming events.
- */
-
-void
-sc_listen( l1sc_t *sc )
-{
-    int result;
-    unsigned long pl = 0;
-    brl1_sch_t *subch;
-
-    char        msg[BRL1_QSIZE];
-    int         len;    /* length of message being sent */
-    int         ch;     /* system controller subchannel used */
-
-    extern int msc_shutdown_pri;
-
-    /* grab the designated "event subchannel" */
-    SUBCH_LOCK( sc, pl );
-    subch = &(sc->subch[BRL1_EVENT_SUBCH]);
-    if( subch->use != BRL1_SUBCH_FREE ) {
-	SUBCH_UNLOCK( sc, pl );
-	printk(KERN_WARNING  "sysctl event subchannel in use! "
-		 "Not monitoring sysctl events.\n" );
-	return;
-    }
-    subch->use = BRL1_SUBCH_RSVD;
-    SUBCH_UNLOCK( sc, pl );
-
-    atomic_set(&subch->packet_arrived, 0);
-    subch->target = BRL1_LOCALHUB_UART;
-    spin_lock_init( &(subch->data_lock) );
-    sv_init( &(subch->arrive_sv), &(subch->data_lock), SV_MON_SPIN | SV_ORDER_FIFO /* | SV_INTS */);
-    subch->tx_notify = NULL;
-    subch->rx_notify = sc_data_ready;
-    subch->iqp = snia_kmem_zalloc_node( sizeof(sc_cq_t), KM_NOSLEEP,
-				   NASID_TO_COMPACT_NODEID(sc->nasid) );
-    ASSERT( subch->iqp );
-    cq_init( subch->iqp );
-
-    /* set up a thread to listen for events */
-    sthread_create( "sysctl event handler", 0, 0, 0, msc_shutdown_pri,
-		    KT_PS, (st_func_t *) sc_event,
-		    (void *)sc, (void *)(uint64_t)BRL1_EVENT_SUBCH, 0, 0 );
-
-    /* signal the L1 to begin sending events */
-    bzero( msg, BRL1_QSIZE );
-    ch = sc_open( sc, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( sc, ch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_EVENT_SUBCH, 2,
-				 L1_ARG_INT, BRL1_EVENT_SUBCH )) < 0 )
-    {
-	sc_close( sc, ch );
-	L1_DBG_PRF(( "Failure in sc_construct_msg (%d)\n", len ));
-	goto err_return;
-    }
-
-    result = sc_command_kern( sc, ch, msg, msg, &len );
-    if( result < 0 )
-    {
-	sc_close( sc, ch );
-	L1_DBG_PRF(( "Failure in sc_command_kern (%d)\n", result ));
-	goto err_return;
-    }
-
-    sc_close( sc, ch );
-
-    result = sc_interpret_resp( msg, 0 );
-    if( result < 0 )
-    {
-	L1_DBG_PRF(( "Failure in sc_interpret_resp (%d)\n", result ));
-	goto err_return;
-    }
-
-    /* everything went fine; just return */
-    return;
-	
-err_return:
-    /* there was a problem; complain */
-    printk(KERN_WARNING  "failed to set sysctl event-monitoring subchannel.  "
-	     "Sysctl events will not be monitored.\n" );
-}
-
-#endif	/* LINUX_KERNEL_THREADS */
diff -Nru a/arch/ia64/sn/io/l1_command.c b/arch/ia64/sn/io/l1_command.c
--- a/arch/ia64/sn/io/l1_command.c	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1377 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000 - 2001 Silicon Graphics, Inc.
- * All rights reserved.
- */ 
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/router.h>
-#include <asm/sn/module.h>
-#include <asm/sn/ksys/l1.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/clksupport.h>
-
-#define ELSC_TIMEOUT	1000000		/* ELSC response timeout (usec) */
-#define LOCK_TIMEOUT	5000000		/* Hub lock timeout (usec) */
-
-#define LD(x)		(*(volatile uint64_t *)(x))
-#define SD(x, v)	(LD(x) = (uint64_t) (v))
-
-#define hub_cpu_get()	0
-
-#define LBYTE(caddr)	(*(char *) caddr)
-
-extern char *bcopy(const char * src, char * dest, int count);
-
-#define LDEBUG		0
-
-/*
- * ELSC data is in NVRAM page 7 at the following offsets.
- */
-
-#define NVRAM_MAGIC_AD	0x700		/* magic number used for init */
-#define NVRAM_PASS_WD	0x701		/* password (4 bytes in length) */
-#define NVRAM_DBG1	0x705		/* virtual XOR debug switches */
-#define NVRAM_DBG2	0x706		/* physical XOR debug switches */
-#define NVRAM_CFG	0x707		/* ELSC Configuration info */
-#define NVRAM_MODULE	0x708		/* system module number */
-#define NVRAM_BIST_FLG	0x709		/* BIST flags (2 bits per nodeboard) */
-#define NVRAM_PARTITION 0x70a		/* module's partition id */
-#define	NVRAM_DOMAIN	0x70b		/* module's domain id */
-#define	NVRAM_CLUSTER	0x70c		/* module's cluster id */
-#define	NVRAM_CELL	0x70d		/* module's cellid */
-
-#define NVRAM_MAGIC_NO	0x37		/* value of magic number */
-#define NVRAM_SIZE	16		/* 16 bytes in nvram */
-
-/*
- * Declare a static ELSC NVRAM buffer to hold all data read from
- * and written to NVRAM.  This nvram "cache" will be used only during the
- * IP27prom execution.
- */
-static char elsc_nvram_buffer[NVRAM_SIZE];
-
-#define SC_COMMAND sc_command
-
-/*
- * elsc_init
- *
- *   Initialize ELSC structure
- */
-
-void elsc_init(elsc_t *e, nasid_t nasid)
-{
-    sc_init((l1sc_t *)e, nasid, BRL1_LOCALHUB_UART);
-}
-
-
-/*
- * elsc_errmsg
- *
- *   Given a negative error code,
- *   returns a corresponding static error string.
- */
-
-char *elsc_errmsg(int code)
-{
-    switch (code) {
-    case ELSC_ERROR_CMD_SEND:
-	return "Command send error";
-    case ELSC_ERROR_CMD_CHECKSUM:
-	return "Command packet checksum error";
-    case ELSC_ERROR_CMD_UNKNOWN:
-	return "Unknown command";
-    case ELSC_ERROR_CMD_ARGS:
-	return "Invalid command argument(s)";
-    case ELSC_ERROR_CMD_PERM:
-	return "Permission denied";
-    case ELSC_ERROR_RESP_TIMEOUT:
-	return "System controller response timeout";
-    case ELSC_ERROR_RESP_CHECKSUM:
-	return "Response packet checksum error";
-    case ELSC_ERROR_RESP_FORMAT:
-	return "Response format error";
-    case ELSC_ERROR_RESP_DIR:
-	return "Response direction error";
-    case ELSC_ERROR_MSG_LOST:
-	return "Message lost because queue is full";
-    case ELSC_ERROR_LOCK_TIMEOUT:
-	return "Timed out getting ELSC lock";
-    case ELSC_ERROR_DATA_SEND:
-	return "Error sending data";
-    case ELSC_ERROR_NIC:
-	return "NIC protocol error";
-    case ELSC_ERROR_NVMAGIC:
-	return "Bad magic number in NVRAM";
-    case ELSC_ERROR_MODULE:
-	return "Module location protocol error";
-    default:
-	return "Unknown error";
-    }
-}
-
-/*
- * elsc_nvram_init
- *
- *   Initializes reads and writes to NVRAM.  This will perform a single
- *   read to NVRAM, getting all data at once.  When the PROM tries to
- *   read NVRAM, it returns the data from the buffer being read.  If the
- *   PROM tries to write out to NVRAM, the write is done, and the internal
- *   buffer is updated.
- */
-
-void elsc_nvram_init(nasid_t nasid, uchar_t *elsc_nvram_data)
-{
-    /* This might require implementation of multiple-packet request/responses
-     * if it's to provide the same behavior that was available in SN0.
-     */
-    nasid = nasid;
-    elsc_nvram_data = elsc_nvram_data;
-}
-
-/*
- * elsc_nvram_copy
- *
- *   Copies the content of a buffer into the static buffer in this library.
- */
-
-void elsc_nvram_copy(uchar_t *elsc_nvram_data)
-{
-    memcpy(elsc_nvram_buffer, elsc_nvram_data, NVRAM_SIZE);
-}
-
-/*
- * elsc_nvram_write
- *
- *   Copies bytes from 'buf' into NVRAM, starting at NVRAM address
- *   'addr' which must be between 0 and 2047.
- *
- *   If 'len' is non-negative, the routine copies 'len' bytes.
- *
- *   If 'len' is negative, the routine treats the data as a string and
- *   copies bytes up to and including a NUL-terminating zero, but not
- *   to exceed '-len' bytes.
- */
-
-int elsc_nvram_write(elsc_t *e, int addr, char *buf, int len)
-{
-    /* Here again, we might need to work out the details of a
-     * multiple-packet protocol.
-     */
-
-    /* For now, pretend it worked. */
-    e = e;
-    addr = addr;
-    buf = buf;
-    return (len < 0 ? -len : len);
-}
-
-/*
- * elsc_nvram_read
- *
- *   Copies bytes from NVRAM into 'buf', starting at NVRAM address
- *   'addr' which must be between 0 and 2047.
- *
- *   If 'len' is non-negative, the routine copies 'len' bytes.
- *
- *   If 'len' is negative, the routine treats the data as a string and
- *   copies bytes up to and including a NUL-terminating zero, but not
- *   to exceed '-len' bytes.  NOTE:  This method is no longer supported.
- *   It was never used in the first place.
- */
-
-int elsc_nvram_read(elsc_t *e, int addr, char *buf, int len)
-{
-    /* multiple packets? */
-    e = e;
-    addr = addr;
-    buf = buf;
-    len = len;
-    return -1;
-}
-
-
-/*
- * Command Set
- */
-
-int elsc_version(elsc_t *e, char *result)
-{
-    char	msg[BRL1_QSIZE];
-    int		len;    /* length of message being sent */
-    int		subch;  /* system controller subchannel used */
-    int		major,  /* major rev number */
-	        minor,  /* minor rev number */
-                bugfix; /* bugfix rev number */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_FW_REV, 0 )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( (l1sc_t *)e, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( (l1sc_t *)e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 6, L1_ARG_INT, &major,
-			   L1_ARG_INT, &minor, L1_ARG_INT, &bugfix )
-	< 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    sprintf( result, "%d.%d.%d", major, minor, bugfix );
-
-    return 0;
-}
-
-int elsc_debug_set(elsc_t *e, u_char byte1, u_char byte2)
-{
-    /* shush compiler */
-    e = e;
-    byte1 = byte1;
-    byte2 = byte2;
-
-    /* fill in a buffer with the opcode & params; call sc_command */
-
-    return 0;
-}
-
-int elsc_debug_get(elsc_t *e, u_char *byte1, u_char *byte2)
-{
-    char	msg[BRL1_QSIZE];
-    int		subch;  /* system controller subchannel used */
-    int		dbg_sw; /* holds debug switch settings */
-    int		len;	/* number of msg buffer bytes used */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RDBG, 0 ) ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( (l1sc_t *)e, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( (l1sc_t *)e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_INT, &dbg_sw ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* copy out debug switch settings (last two bytes of the
-     * integer response)
-     */
-    *byte1 = ((dbg_sw >> 8) & 0xFF);
-    *byte2 = (dbg_sw & 0xFF);
-
-    return 0;
-}
-
-
-/*
- * elsc_rack_bay_get fills in the two int * arguments with the
- * rack number and bay number of the L1 being addressed
- */
-int elsc_rack_bay_get(elsc_t *e, uint *rack, uint *bay)
-{
-    char msg[BRL1_QSIZE];	/* L1 request/response info */
-    int subch;			/* system controller subchannel used */
-    int len;			/* length of message */
-    uint32_t	buf32;		/* used to copy 32-bit rack/bay out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RRACK, 0 )) < 0 ) 
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-
-    /* send the request to the L1 */
-    if( sc_command( (l1sc_t *)e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close(e, subch);
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_INT, &buf32 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* extract rack/bay info
-     *
-     * note that the 32-bit value returned by the L1 actually
-     * only uses the low-order sixteen bits for rack and bay
-     * information.  A "normal" L1 address puts rack and bay
-     * information in bit positions 12 through 28.  So if
-     * we initially shift the value returned 12 bits to the left,
-     * we can use the L1 addressing #define's to extract the
-     * values we need (see ksys/l1.h for a complete list of the
-     * various fields of an L1 address).
-     */
-    buf32 <<= L1_ADDR_BAY_SHFT;
-
-    *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-    *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-
-    return 0;
-}
-
-
-/* elsc_rack_bay_type_get fills in the three int * arguments with the
- * rack number, bay number and brick type of the L1 being addressed.  Note
- * that if the L1 operation fails and this function returns an error value, 
- * garbage may be written to brick_type.
- */
-int elsc_rack_bay_type_get( l1sc_t *sc, uint *rack, 
-			       uint *bay, uint *brick_type )
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    uint32_t buf32;	        /* used to copy 32-bit rack & bay out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( sc, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RRBT, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( sc, subch, msg, msg, &len ) ) {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 4, L1_ARG_INT, &buf32, 
-			           L1_ARG_INT, brick_type ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* extract rack/bay info
-     *
-     * note that the 32-bit value returned by the L1 actually
-     * only uses the low-order sixteen bits for rack and bay
-     * information.  A "normal" L1 address puts rack and bay
-     * information in bit positions 12 through 28.  So if
-     * we initially shift the value returned 12 bits to the left,
-     * we can use the L1 addressing #define's to extract the
-     * values we need (see ksys/l1.h for a complete list of the
-     * various fields of an L1 address).
-     */
-    buf32 <<= L1_ADDR_BAY_SHFT;
-
-    *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-    *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-
-    /* convert brick_type to lower case */
-    *brick_type = *brick_type - 'A' + 'a';
-
-    return 0;
-}
-
-
-int elsc_module_get(elsc_t *e)
-{
-    extern char brick_types[];
-    uint rnum, rack, bay, bricktype, t;
-    int ret;
-
-    /* construct module ID from rack and slot info */
-
-    if ((ret = elsc_rack_bay_type_get(e, &rnum, &bay, &bricktype)) < 0) {
-	return ret;
-    }
-
-    /* report unset location info. with a special, otherwise invalid modid */
-    if (rnum == 0 && bay == 0)
-	return MODULE_NOT_SET;
-
-    if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-	return ELSC_ERROR_MODULE;
-
-    /* Build a moduleid_t-compatible rack number */
-
-    rack = 0;		
-    t = rnum / 100;		/* rack class (CPU/IO) */
-    if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_CLASS(rack, t);
-    rnum %= 100;
-
-    t = rnum / 10;		/* rack group */
-    if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_GROUP(rack, t);
-
-    t = rnum % 10;		/* rack number (one-based) */
-    if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_NUM(rack, t);
-
-    for( t = 0; t < MAX_BRICK_TYPES; t++ ) {
-	if( brick_types[t] == bricktype )
-	    return RBT_TO_MODULE(rack, bay, t);
-    }
-    
-    return ELSC_ERROR_MODULE;
-}
-
-int elsc_partition_set(elsc_t *e, int partition)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_PARTITION_SET, 2,
-				 L1_ARG_INT, partition )) < 0 )
-    {
-	
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-    
-    return( 0 );
-}
-
-int elsc_partition_get(elsc_t *e)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    uint32_t partition_id;    /* used to copy partition id out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_PARTITION_GET, 0 )) < 0 )
-
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 2, L1_ARG_INT, &partition_id ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-    
-    return( partition_id );
-}
-
-
-/*
- * elsc_cons_subch selects the "active" console subchannel for this node
- * (i.e., the one that will currently receive input)
- */
-int elsc_cons_subch(elsc_t *e, uint ch)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( e, L1_ADDR_LOCAL );
-    
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_CONS_SUBCH, 2,
-				 L1_ARG_INT, ch)) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-
-/*
- * elsc_cons_node should only be executed by one node.  It declares to
- * the system controller that the node from which it is called will be
- * the owner of the system console.
- */
-int elsc_cons_node(elsc_t *e)
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( e, L1_ADDR_LOCAL );
-    
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_CONS_NODE, 0 )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( e, subch, msg, msg, &len ) ) {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-    
-
-/* elsc_display_line writes up to 12 characters to either the top or bottom
- * line of the L1 display.  line points to a buffer containing the message
- * to be displayed.  The zero-based line number is specified by lnum (so
- * lnum == 0 specifies the top line and lnum == 1 specifies the bottom).
- * Lines longer than 12 characters, or line numbers not less than
- * L1_DISPLAY_LINES, cause elsc_display_line to return an error.
- */
-int elsc_display_line(elsc_t *e, char *line, int lnum)
-{
-    char	msg[BRL1_QSIZE];
-    int		subch;  /* system controller subchannel used */
-    int		len;	/* number of msg buffer bytes used */
-
-    /* argument sanity checking */
-    if( !(lnum < L1_DISPLAY_LINES) )
-	return( ELSC_ERROR_CMD_ARGS );
-    if( !(strlen( line ) <= L1_DISPLAY_LINE_LENGTH) )
-	return( ELSC_ERROR_CMD_ARGS );
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( (l1sc_t *)e, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( (l1sc_t *)e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 (L1_REQ_DISP1+lnum), 2,
-				 L1_ARG_ASCII, line )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND( (l1sc_t *)e, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( (l1sc_t *)e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-
-/* elsc_display_mesg silently drops message characters beyond the 12th.
- */
-int elsc_display_mesg(elsc_t *e, char *chr)
-{
-
-    char line[L1_DISPLAY_LINE_LENGTH+1];
-    int numlines, i;
-    int result;
-
-    numlines = (strlen( chr ) + L1_DISPLAY_LINE_LENGTH - 1) /
-	L1_DISPLAY_LINE_LENGTH;
-
-    if( numlines > L1_DISPLAY_LINES )
-	numlines = L1_DISPLAY_LINES;
-
-    for( i = 0; i < numlines; i++ )
-    {
-	strlcpy( line, chr, sizeof(line) );
-
-	/* generally we want to leave the first line of the L1 display
-	 * alone (so the L1 can manipulate it).  If you need to be able
-	 * to display to both lines (for debugging purposes), define
-	 * L1_DISP_2LINES in irix/kern/ksys/l1.h, or add -DL1_DISP_2LINES
-	 * to your 'defs file.
-	 */
-#if defined(L1_DISP_2LINES)
-	if( (result = elsc_display_line( e, line, i )) < 0 )
-#else
-	if( (result = elsc_display_line( e, line, i+1 )) < 0 )
-#endif
-
-	    return result;
-
-	chr += L1_DISPLAY_LINE_LENGTH;
-    }
-    
-    return 0;
-}
-
-
-int elsc_password_set(elsc_t *e, char *password)
-{
-    /* shush compiler */
-    e = e;
-    password = password;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-int elsc_password_get(elsc_t *e, char *password)
-{
-    /* shush compiler */
-    e = e;
-    password = password;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-
-/*
- * sc_portspeed_get
- *
- * retrieve the current portspeed setting for the bedrock II
- */
-int sc_portspeed_get(l1sc_t *sc)
-{
-    char	msg[BRL1_QSIZE];
-    int         len;    /* length of message being sent */
-    int         subch;  /* system controller subchannel used */
-    int		portspeed_a, portspeed_b;
-			/* ioport clock rates */
-
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( sc, L1_ADDR_LOCAL );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-                                 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_PORTSPEED,
-				 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-    
-    /* send the request to the L1 */
-    if( sc_command( sc, subch, msg, msg, &len ) < 0 )
-    {
-        sc_close( sc, subch );
-        return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 4, 
-			   L1_ARG_INT, &portspeed_a,
-			   L1_ARG_INT, &portspeed_b ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* for the c-brick, we ignore the portspeed_b value */
-    return (portspeed_a ? 600 : 400);
-}
-
-/*
- * elsc_power_query
- *
- *   To be used after system reset, this command returns 1 if the reset
- *   was the result of a power-on, 0 otherwise.
- *
- *   The power query status is cleared to 0 after it is read.
- */
-
-int elsc_power_query(elsc_t *e)
-{
-    e = e; /* shush the compiler */
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 1;
-}
-
-int elsc_rpwr_query(elsc_t *e, int is_master)
-{
-    /* shush the compiler */
-    e = e;
-    is_master = is_master;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-} 
-
-/*
- * elsc_power_down
- *
- *   Sets up system to shut down in "sec" seconds (or modifies the
- *   shutdown time if one is already in effect).  Use 0 to power
- *   down immediately.
- */
-
-int elsc_power_down(elsc_t *e, int sec)
-{
-    /* shush compiler */
-    e = e;
-    sec = sec;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-
-int elsc_system_reset(elsc_t *e)
-{
-    char	msg[BRL1_QSIZE];
-    int		subch;  /* system controller subchannel used */
-    int		len;	/* number of msg buffer bytes used */
-    int		result;
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( e, L1_ADDR_LOCAL )) < 0 ) {
-	return ELSC_ERROR_CMD_SEND;
-    }
-
-    if( (len = sc_construct_msg( e, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RESET, 0 )) < 0 )
-    {
-	sc_close( e, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( (result = sc_command( e, subch, msg, msg, &len )) ) {
-	sc_close( e, subch );
-	if( result == SC_NMSG ) {
-	    /* timeout is OK.  We've sent the reset.  Now it's just
-	     * a matter of time...
-	     */
-	    return( 0 );
-	}
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( e, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-
-int elsc_power_cycle(elsc_t *e)
-{
-    /* shush compiler */
-    e = e;
-
-    /* fill in buffer with the opcode & params; call sc_command */
-
-    return 0;
-}
-
-
-/*
- * L1 Support for reading 
- * cbrick uid.
- */
-
-int elsc_nic_get(elsc_t *e, uint64_t *nic, int verbose)
-{
-    /* this parameter included only for SN0 compatibility */
-    verbose = verbose;
-
-    /* We don't go straight to the bedrock/L1 protocol on this one, but let
-     * the eeprom layer prepare the eeprom data as we would like it to
-     * appear to the caller
-     */
-    return cbrick_uid_get( e->nasid, nic );
-}
-
-
-int _elsc_hbt(elsc_t *e, int ival, int rdly)
-{
-    e = e;
-    ival = ival;
-    rdly = rdly;
-
-    /* fill in buffer with the opcode & params; call elsc_command */
-
-    return 0;
-}
-
-
-/* send a command string to an L1 */
-int sc_command_interp( l1sc_t *sc, l1addr_t compt, l1addr_t rack, l1addr_t bay,
-		       char *cmd )
-{
-    char        msg[BRL1_QSIZE];
-    int         len;    /* length of message being sent */
-    int         subch;  /* system controller subchannel used */
-    l1addr_t	target; /* target system controller for command */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-
-    L1_BUILD_ADDR( &target, compt, rack, bay, 0 );
-    subch = sc_open( sc, target );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_CMD, L1_REQ_EXEC_CMD, 2,
-				 L1_ARG_ASCII, cmd )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-		   
-    /* send the request to the L1 */
-    if( SC_COMMAND( sc, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-    
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-}
-
-/*
- * sc_power_down
- *
- * Shuts down the c-brick associated with sc, and any attached I/O bricks
- * or other c-bricks (won't go through r-bricks).
- */
-
-int sc_power_down(l1sc_t *sc)
-{
-    return sc_command_interp( sc, L1_ADDR_TYPE_L1, L1_ADDR_RACK_LOCAL, 
-			      L1_ADDR_BAY_LOCAL, "* pwr d" );
-}
-
-
-/*
- * sc_power_down_all
- *
- * Works similarly to sc_power_down, except that the request is sent to the
- * closest L2 and EVERYBODY gets turned off.
- */
-
-int sc_power_down_all(l1sc_t *sc)
-{
-    if( nodepda->num_routers > 0 ) {
-	return sc_command_interp( sc, L1_ADDR_TYPE_L2, L1_ADDR_RACK_LOCAL, 
-				  L1_ADDR_BAY_LOCAL, "* pwr d" );
-    }
-    else {
-	return sc_power_down( sc );
-    }
-}
-
-
-/*
- * Routines for reading the R-brick's L1
- */
-
-int router_module_get( nasid_t nasid, net_vec_t path )
-{
-    uint rnum, rack, bay, t;
-    int ret;
-    l1sc_t sc;
-
-    /* prepare l1sc_t struct */
-    sc_init( &sc, nasid, path );
-
-    /* construct module ID from rack and slot info */
-
-    if ((ret = elsc_rack_bay_get(&sc, &rnum, &bay)) < 0)
-	return ret;
-
-    /* report unset location info. with a special, otherwise invalid modid */
-    if (rnum == 0 && bay == 0)
-	return MODULE_NOT_SET;
-
-    if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-	return ELSC_ERROR_MODULE;
-
-    /* Build a moduleid_t-compatible rack number */
-
-    rack = 0;		
-    t = rnum / 100;		/* rack class (CPU/IO) */
-    if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_CLASS(rack, t);
-    rnum %= 100;
-
-    t = rnum / 10;		/* rack group */
-    if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_GROUP(rack, t);
-
-    t = rnum % 10;		/* rack number (one-based) */
-    if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-	return ELSC_ERROR_MODULE;
-    RACK_ADD_NUM(rack, t);
-
-    ret = RBT_TO_MODULE(rack, bay, MODULE_RBRICK);
-    return ret;
-}
-    
-
-/*
- * iobrick routines
- */
-
-/* iobrick_rack_bay_type_get fills in the three int * arguments with the
- * rack number, bay number and brick type of the L1 being addressed.  Note
- * that if the L1 operation fails and this function returns an error value, 
- * garbage may be written to brick_type.
- */
-int iobrick_rack_bay_type_get( l1sc_t *sc, uint *rack, 
-			       uint *bay, uint *brick_type )
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    uint32_t buf32;	        /* used to copy 32-bit rack & bay out of msg */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_RRBT, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( sc, subch, msg, msg, &len ) ) {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 4, L1_ARG_INT, &buf32, 
-			           L1_ARG_INT, brick_type ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    /* extract rack/bay info
-     *
-     * note that the 32-bit value returned by the L1 actually
-     * only uses the low-order sixteen bits for rack and bay
-     * information.  A "normal" L1 address puts rack and bay
-     * information in bit positions 12 through 28.  So if
-     * we initially shift the value returned 12 bits to the left,
-     * we can use the L1 addressing #define's to extract the
-     * values we need (see ksys/l1.h for a complete list of the
-     * various fields of an L1 address).
-     */
-    buf32 <<= L1_ADDR_BAY_SHFT;
-
-    *rack = (buf32 & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-    *bay = (buf32 & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-
-    return 0;
-}
-
-
-int iobrick_module_get(l1sc_t *sc)
-{
-    uint rnum, rack, bay, brick_type, t;
-    int ret;
-
-    /* construct module ID from rack and slot info */
-
-    if ((ret = iobrick_rack_bay_type_get(sc, &rnum, &bay, &brick_type)) < 0)
-        return ret;
-
-    if (bay > MODULE_BPOS_MASK >> MODULE_BPOS_SHFT)
-        return ELSC_ERROR_MODULE;
-
-    /* Build a moduleid_t-compatible rack number */
-
-    rack = 0;           
-    t = rnum / 100;             /* rack class (CPU/IO) */
-    if (t > RACK_CLASS_MASK(rack) >> RACK_CLASS_SHFT(rack))
-        return ELSC_ERROR_MODULE;
-    RACK_ADD_CLASS(rack, t);
-    rnum %= 100;
-
-    t = rnum / 10;              /* rack group */
-    if (t > RACK_GROUP_MASK(rack) >> RACK_GROUP_SHFT(rack))
-        return ELSC_ERROR_MODULE;
-    RACK_ADD_GROUP(rack, t);
-
-    t = rnum % 10;              /* rack number (one-based) */
-    if (t-1 > RACK_NUM_MASK(rack) >> RACK_NUM_SHFT(rack))
-        return ELSC_ERROR_MODULE;
-    RACK_ADD_NUM(rack, t);
-
-    switch( brick_type ) {
-      case 'I': 
-	brick_type = MODULE_IBRICK; break;
-      case 'P':
-	brick_type = MODULE_PBRICK; break;
-      case 'X':
-	brick_type = MODULE_XBRICK; break;
-    }
-
-    ret = RBT_TO_MODULE(rack, bay, brick_type);
-
-    return ret;
-}
-
-/* iobrick_get_sys_snum asks the attached iobrick for the system
- * serial number.  This function will only be relevant to the master
- * cbrick (the one attached to the bootmaster ibrick); other nodes
- * may call the function, but the value returned to the master node
- * will be the one used as the system serial number by the kernel.
- */
-
-int
-iobrick_get_sys_snum( l1sc_t *sc, char *snum_str )
-{
-    char msg[BRL1_QSIZE];       /* L1 request/response info */
-    int subch;                  /* system controller subchannel used */
-    int len;                    /* length of message */
-    
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    if( (subch = sc_open( sc, L1_ADDR_LOCALIO )) < 0 ) {
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_SYS_SERIAL, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( sc_command( sc, subch, msg, msg, &len ) ) {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    return( sc_interpret_resp( msg, 2, L1_ARG_ASCII, snum_str ) );
-}
-
-
-/*
- * The following functions apply (or cut off) power to the specified
- * pci bus or slot.
- */
-
-int
-iobrick_pci_pwr( l1sc_t *sc, int bus, int slot, int req_code )
-{
-#if 0 /* The "bedrock request" method of performing this function
-       * seems to be broken in the L1, so for now use the command-
-       * interpreter method
-       */
-
-    char	msg[BRL1_QSIZE];
-    int		len;    /* length of message being sent */
-    int		subch;  /* system controller subchannel used */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( sc, L1_ADDR_LOCALIO );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 req_code, 4,
-				 L1_ARG_INT, bus,
-				 L1_ARG_INT, slot )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND(sc, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 0 ) < 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    return 0;
-
-#else
-    char cmd[64];
-    char *fxn;
-
-    switch( req_code )
-    {
-    case L1_REQ_PCI_UP:
-	fxn = "u";
-	break;
-    case L1_REQ_PCI_DOWN:
-	fxn = "d";
-	break;
-    case L1_REQ_PCI_RESET:
-	fxn = "rst";
-	break;
-    default:
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    if( slot == -1 ) 
-	sprintf( cmd, "pci %d %s", bus, fxn );
-    else
-        sprintf( cmd, "pci %d %d %s", bus, slot, fxn );
-	
-    return sc_command_interp( sc, L1_ADDR_TYPE_IOBRICK,
-	L1_ADDR_RACK_LOCAL, L1_ADDR_BAY_LOCAL, cmd );
-#endif
-}
-				 
-int
-iobrick_pci_slot_pwr( l1sc_t *sc, int bus, int slot, int up )
-{
-    return iobrick_pci_pwr( sc, bus, slot, up );
-}
-
-int
-iobrick_pci_bus_pwr( l1sc_t *sc, int bus, int up )
-{
-    return iobrick_pci_pwr( sc, bus, -1, up );
-}
-
-
-int
-iobrick_pci_slot_rst( l1sc_t *sc, int bus, int slot )
-{
-    return iobrick_pci_pwr( sc, bus, slot, L1_REQ_PCI_RESET );
-}
-
-int
-iobrick_pci_bus_rst( l1sc_t *sc, int bus )
-{
-    return iobrick_pci_pwr( sc, bus, -1, L1_REQ_PCI_RESET );
-}
-
-
-/* get the L1 firmware version for an iobrick */
-int
-iobrick_sc_version( l1sc_t *sc, char *result )
-{
-    char	msg[BRL1_QSIZE];
-    int		len;    /* length of message being sent */
-    int		subch;  /* system controller subchannel used */
-    int		major,  /* major rev number */
-	        minor,  /* minor rev number */
-                bugfix; /* bugfix rev number */
-
-    /* fill in msg with the opcode & params */
-    bzero( msg, BRL1_QSIZE );
-    subch = sc_open( sc, L1_ADDR_LOCALIO );
-
-    if( (len = sc_construct_msg( sc, subch, msg, BRL1_QSIZE,
-				 L1_ADDR_TASK_GENERAL,
-				 L1_REQ_FW_REV, 0 )) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_ARGS );
-    }
-
-    /* send the request to the L1 */
-    if( SC_COMMAND(sc, subch, msg, msg, &len ) < 0 )
-    {
-	sc_close( sc, subch );
-	return( ELSC_ERROR_CMD_SEND );
-    }
-
-    /* free up subchannel */
-    sc_close( sc, subch );
-
-    /* check response */
-    if( sc_interpret_resp( msg, 6, L1_ARG_INT, &major,
-			   L1_ARG_INT, &minor, L1_ARG_INT, &bugfix )
-	< 0 )
-    {
-	return( ELSC_ERROR_RESP_FORMAT );
-    }
-
-    sprintf( result, "%d.%d.%d", major, minor, bugfix );
-
-    return 0;
-}
diff -Nru a/arch/ia64/sn/io/labelcl.c b/arch/ia64/sn/io/labelcl.c
--- a/arch/ia64/sn/io/labelcl.c	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,654 +0,0 @@
-/*  labelcl - SGI's Hwgraph Compatibility Layer.
- *
- * 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) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
-*/
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <linux/devfs_fs.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-
-/*
-** Very simple and dumb string table that supports only find/insert.
-** In practice, if this table gets too large, we may need a more
-** efficient data structure.   Also note that currently there is no 
-** way to delete an item once it's added.  Therefore, name collision 
-** will return an error.
-*/
-
-struct string_table label_string_table;
-
-
-
-/*
- * string_table_init - Initialize the given string table.
- */
-void
-string_table_init(struct string_table *string_table)
-{
-	string_table->string_table_head = NULL;
-	string_table->string_table_generation = 0;
-
-	/*
-	 * We nedd to initialize locks here!
-	 */
-
-	return;
-}
-
-
-/*
- * string_table_destroy - Destroy the given string table.
- */
-void
-string_table_destroy(struct string_table *string_table)
-{
-	struct string_table_item *item, *next_item;
-
-	item = string_table->string_table_head;
-	while (item) {
-		next_item = item->next;
-
-		STRTBL_FREE(item);
-		item = next_item;
-	}
-
-	/*
-	 * We need to destroy whatever lock we have here
-	 */
-
-	return;
-}
-
-
-
-/*
- * string_table_insert - Insert an entry in the string table .. duplicate 
- *	names are not allowed.
- */
-char *
-string_table_insert(struct string_table *string_table, char *name)
-{
-	struct string_table_item *item, *new_item = NULL, *last_item = NULL;
-
-again:
-	/*
-	 * Need to lock the table ..
-	 */
-	item = string_table->string_table_head;
-	last_item = NULL;
-
-	while (item) {
-		if (!strcmp(item->string, name)) {
-			/*
-			 * If we allocated space for the string and the found that
-			 * someone else already entered it into the string table,
-			 * free the space we just allocated.
-			 */
-			if (new_item)
-				STRTBL_FREE(new_item);
-
-
-			/*
-			 * Search optimization: move the found item to the head
-			 * of the list.
-			 */
-			if (last_item != NULL) {
-				last_item->next = item->next;
-				item->next = string_table->string_table_head;
-				string_table->string_table_head = item;
-			}
-			goto out;
-		}
-		last_item = item;
-		item=item->next;
-	}
-
-	/*
-	 * name was not found, so add it to the string table.
-	 */
-	if (new_item == NULL) {
-		long old_generation = string_table->string_table_generation;
-
-		new_item = STRTBL_ALLOC(strlen(name));
-
-		strcpy(new_item->string, name);
-
-		/*
-		 * While we allocated memory for the new string, someone else 
-		 * changed the string table.
-		 */
-		if (old_generation != string_table->string_table_generation) {
-			goto again;
-		}
-	} else {
-		/* At this we only have the string table lock in access mode.
-		 * Promote the access lock to an update lock for the string
-		 * table insertion below.
-		 */
-			long old_generation = 
-				string_table->string_table_generation;
-
-			/*
-			 * After we did the unlock and wer waiting for update
-			 * lock someone could have potentially updated
-			 * the string table. Check the generation number
-			 * for this case. If it is the case we have to
-			 * try all over again.
-			 */
-			if (old_generation != 
-			    string_table->string_table_generation) {
-				goto again;
-			}
-		}
-
-	/*
-	 * At this point, we're committed to adding new_item to the string table.
-	 */
-	new_item->next = string_table->string_table_head;
-	item = string_table->string_table_head = new_item;
-	string_table->string_table_generation++;
-
-out:
-	/*
-	 * Need to unlock here.
-	 */
-	return(item->string);
-}
-
-/*
- * labelcl_info_create - Creates the data structure that will hold the
- *	device private information asscoiated with a devfs entry.
- *	The pointer to this structure is what gets stored in the devfs 
- *	(void * info).
- */
-labelcl_info_t *
-labelcl_info_create()
-{
-
-	labelcl_info_t *new = NULL;
-
-	/* Initial allocation does not include any area for labels */
-	if ( ( new = (labelcl_info_t *)kmalloc (sizeof(labelcl_info_t), GFP_KERNEL) ) == NULL )
-		return NULL;
-
-	memset (new, 0, sizeof(labelcl_info_t));
-	new->hwcl_magic = LABELCL_MAGIC;
-	return( new);
-
-}
-
-/*
- * labelcl_info_destroy - Frees the data structure that holds the
- *      device private information asscoiated with a devfs entry.  This 
- *	data structure was created by device_info_create().
- *
- *	The caller is responsible for nulling the (void *info) in the 
- *	corresponding devfs entry.
- */
-int
-labelcl_info_destroy(labelcl_info_t *labelcl_info)
-{
-
-	if (labelcl_info == NULL)
-		return(0);
-
-	/* Free the label list */
-	if (labelcl_info->label_list)
-		kfree(labelcl_info->label_list);
-
-	/* Now free the label info area */
-	labelcl_info->hwcl_magic = 0;
-	kfree(labelcl_info);
-
-	return(0);
-}
-
-/*
- * labelcl_info_add_LBL - Adds a new label entry in the labelcl info 
- *	structure.
- *
- *	Error is returned if we find another label with the same name.
- */
-int
-labelcl_info_add_LBL(devfs_handle_t de,
-			char *info_name,
-			arb_info_desc_t info_desc,
-			arbitrary_info_t info)
-{
-	labelcl_info_t	*labelcl_info = NULL;
-	int num_labels;
-	int new_label_list_size;
-	label_info_t *old_label_list, *new_label_list = NULL;
-	char *name;
-	int i;
-
-	if (de == NULL)
-		return(-1);
-
-        labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	if (info_name == NULL)
-		return(-1);
-
-	if (strlen(info_name) >= LABEL_LENGTH_MAX)
-		return(-1);
-
-	name = string_table_insert(&label_string_table, info_name);
-
-	num_labels = labelcl_info->num_labels;
-	new_label_list_size = sizeof(label_info_t) * (num_labels+1);
-
-	/*
-	 * Create a new label info area.
-	 */
-	if (new_label_list_size != 0) {
-		new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
-
-		if (new_label_list == NULL)
-			return(-1);
-	}
-
-	/*
-	 * At this point, we are committed to adding the labelled info, 
-	 * if there isn't already information there with the same name.
-	 */
-	old_label_list = labelcl_info->label_list;
-
-	/* 
-	 * Look for matching info name.
-	 */
-	for (i=0; i<num_labels; i++) {
-		if (!strcmp(info_name, old_label_list[i].name)) {
-			/* Not allowed to add duplicate labelled info names. */
-			kfree(new_label_list);
-			printk(KERN_WARNING "labelcl_info_add_LBL: Duplicate label name %s for vertex 0x%p\n", info_name, (void *)de);
-			return(-1);
-		}
-		new_label_list[i] = old_label_list[i]; /* structure copy */
-	}
-
-	new_label_list[num_labels].name = name;
-	new_label_list[num_labels].desc = info_desc;
-	new_label_list[num_labels].info = info;
-
-	labelcl_info->num_labels = num_labels+1;
-	labelcl_info->label_list = new_label_list;
-
-	if (old_label_list != NULL)
-		kfree(old_label_list);
-
-	return(0);
-}
-
-/*
- * labelcl_info_remove_LBL - Remove a label entry.
- */
-int
-labelcl_info_remove_LBL(devfs_handle_t de,
-			 char *info_name,
-			 arb_info_desc_t *info_desc,
-			 arbitrary_info_t *info)
-{
-	labelcl_info_t	*labelcl_info = NULL;
-	int num_labels;
-	int new_label_list_size;
-	label_info_t *old_label_list, *new_label_list = NULL;
-	arb_info_desc_t label_desc_found;
-	arbitrary_info_t label_info_found;
-	int i;
-
-	if (de == NULL)
-		return(-1);
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	num_labels = labelcl_info->num_labels;
-	if (num_labels == 0) {
-		return(-1);
-	}
-
-	/*
-	 * Create a new info area.
-	 */
-	new_label_list_size = sizeof(label_info_t) * (num_labels-1);
-	if (new_label_list_size) {
-		new_label_list = (label_info_t *) kmalloc(new_label_list_size, GFP_KERNEL);
-		if (new_label_list == NULL)
-			return(-1);
-	}
-
-	/*
-	 * At this point, we are committed to removing the labelled info, 
-	 * if it still exists.
-	 */
-	old_label_list = labelcl_info->label_list;
-
-	/* 
-	 * Find matching info name.
-	 */
-	for (i=0; i<num_labels; i++) {
-		if (!strcmp(info_name, old_label_list[i].name)) {
-			label_desc_found = old_label_list[i].desc;
-			label_info_found = old_label_list[i].info;
-			goto found;
-		}
-		if (i < num_labels-1) /* avoid walking off the end of the new vertex */
-			new_label_list[i] = old_label_list[i]; /* structure copy */
-	}
-
-	/* The named info doesn't exist. */
-	if (new_label_list)
-		kfree(new_label_list);
-
-	return(-1);
-
-found:
-	/* Finish up rest of labelled info */
-	for (i=i+1; i<num_labels; i++)
-		new_label_list[i-1] = old_label_list[i]; /* structure copy */
-
-	labelcl_info->num_labels = num_labels+1;
-	labelcl_info->label_list = new_label_list;
-
-	kfree(old_label_list);
-
-	if (info != NULL)
-		*info = label_info_found;
-
-	if (info_desc != NULL)
-		*info_desc = label_desc_found;
-
-	return(0);
-}
-
-
-/*
- * labelcl_info_replace_LBL - Replace an existing label entry with the 
- *	given new information.
- *
- *	Label entry must exist.
- */
-int
-labelcl_info_replace_LBL(devfs_handle_t de,
-			char *info_name,
-			arb_info_desc_t info_desc,
-			arbitrary_info_t info,
-			arb_info_desc_t *old_info_desc,
-			arbitrary_info_t *old_info)
-{
-	labelcl_info_t	*labelcl_info = NULL;
-	int num_labels;
-	label_info_t *label_list;
-	int i;
-
-	if (de == NULL)
-		return(-1);
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	num_labels = labelcl_info->num_labels;
-	if (num_labels == 0) {
-		return(-1);
-	}
-
-	if (info_name == NULL)
-		return(-1);
-
-	label_list = labelcl_info->label_list;
-
-	/* 
-	 * Verify that information under info_name already exists.
-	 */
-	for (i=0; i<num_labels; i++)
-		if (!strcmp(info_name, label_list[i].name)) {
-			if (old_info != NULL)
-				*old_info = label_list[i].info;
-
-			if (old_info_desc != NULL)
-				*old_info_desc = label_list[i].desc;
-
-			label_list[i].info = info;
-			label_list[i].desc = info_desc;
-
-			return(0);
-		}
-
-
-	return(-1);
-}
-
-/*
- * labelcl_info_get_LBL - Retrieve and return the information for the 
- *	given label entry.
- */
-int
-labelcl_info_get_LBL(devfs_handle_t de,
-		      char *info_name,
-		      arb_info_desc_t *info_desc,
-		      arbitrary_info_t *info)
-{
-	labelcl_info_t	*labelcl_info = NULL;
-	int num_labels;
-	label_info_t *label_list;
-	int i;
-
-	if (de == NULL)
-		return(-1);
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	num_labels = labelcl_info->num_labels;
-	if (num_labels == 0) {
-		return(-1);
-	}
-
-	label_list = labelcl_info->label_list;
-
-	/* 
-	 * Find information under info_name.
-	 */
-	for (i=0; i<num_labels; i++)
-		if (!strcmp(info_name, label_list[i].name)) {
-			if (info != NULL)
-				*info = label_list[i].info;
-			if (info_desc != NULL)
-				*info_desc = label_list[i].desc;
-
-			return(0);
-		}
-
-	return(-1);
-}
-
-/*
- * labelcl_info_get_next_LBL - returns the next label entry on the list.
- */
-int
-labelcl_info_get_next_LBL(devfs_handle_t de,
-			   char *buffer,
-			   arb_info_desc_t *info_descp,
-			   arbitrary_info_t *infop,
-			   labelcl_info_place_t *placeptr)
-{
-	labelcl_info_t	*labelcl_info = NULL;
-	uint which_info;
-	label_info_t *label_list;
-
-	if ((buffer == NULL) && (infop == NULL))
-		return(-1);
-
-	if (placeptr == NULL)
-		return(-1);
-
-	if (de == NULL)
-		return(-1);
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	which_info = *placeptr;
-
-	if (which_info >= labelcl_info->num_labels) {
-		return(-1);
-	}
-
-	label_list = (label_info_t *) labelcl_info->label_list;
-
-	if (buffer != NULL)
-		strcpy(buffer, label_list[which_info].name);
-
-	if (infop)
-		*infop = label_list[which_info].info;
-
-	if (info_descp)
-		*info_descp = label_list[which_info].desc;
-
-	*placeptr = which_info + 1;
-
-	return(0);
-}
-
-
-int
-labelcl_info_replace_IDX(devfs_handle_t de,
-			int index,
-			arbitrary_info_t info,
-			arbitrary_info_t *old_info)
-{
-	arbitrary_info_t *info_list_IDX;
-	labelcl_info_t	*labelcl_info = NULL;
-
-	if (de == NULL) {
-		printk(KERN_ALERT "labelcl: NULL devfs handle given.\n");
-		return(-1);
-	}
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL) {
-		printk(KERN_ALERT "labelcl: Entry does not have info pointer.\n");
-		return(-1);
-	}
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
-		return(-1);
-
-	/*
-	 * Replace information at the appropriate index in this vertex with 
-	 * the new info.
-	 */
-	info_list_IDX = labelcl_info->IDX_list;
-	if (old_info != NULL)
-		*old_info = info_list_IDX[index];
-	info_list_IDX[index] = info;
-
-	return(0);
-
-}
-
-/*
- * labelcl_info_connectpt_set - Sets the connectpt.
- */
-int
-labelcl_info_connectpt_set(struct devfs_entry *de,
-			  struct devfs_entry *connect_de)
-{
-	arbitrary_info_t old_info;
-	int	rv;
-
-	rv = labelcl_info_replace_IDX(de, HWGRAPH_CONNECTPT, 
-		(arbitrary_info_t) connect_de, &old_info);
-
-	if (rv) {
-		return(rv);
-	}
-
-	return(0);
-}
-
-
-/*
- * labelcl_info_get_IDX - Returns the information pointed at by index.
- *
- */
-int
-labelcl_info_get_IDX(devfs_handle_t de,
-			int index,
-			arbitrary_info_t *info)
-{
-	arbitrary_info_t *info_list_IDX;
-	labelcl_info_t	*labelcl_info = NULL;
-
-	if (de == NULL)
-		return(-1);
-
-	labelcl_info = devfs_get_info(de);
-	if (labelcl_info == NULL)
-		return(-1);
-
-	if (labelcl_info->hwcl_magic != LABELCL_MAGIC)
-		return(-1);
-
-	if ( (index < 0) || (index >= HWGRAPH_NUM_INDEX_INFO) )
-		return(-1);
-
-	/*
-	 * Return information at the appropriate index in this vertex.
-	 */
-	info_list_IDX = labelcl_info->IDX_list;
-	if (info != NULL)
-		*info = info_list_IDX[index];
-
-	return(0);
-}
-
-/*
- * labelcl_info_connectpt_get - Retrieve the connect point for a device entry.
- */
-struct devfs_entry *
-labelcl_info_connectpt_get(struct devfs_entry *de)
-{
-	int rv;
-	arbitrary_info_t info;
-
-	rv = labelcl_info_get_IDX(de, HWGRAPH_CONNECTPT, &info);
-	if (rv)
-		return(NULL);
-
-	return((struct devfs_entry *)info);
-}
diff -Nru a/arch/ia64/sn/io/machvec/Makefile b/arch/ia64/sn/io/machvec/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/machvec/Makefile	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,12 @@
+#
+# 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) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# Makefile for the sn2 io routines.
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+obj-y				+= pci.o pci_dma.o pci_bus_cvlink.o iomv.o
diff -Nru a/arch/ia64/sn/io/machvec/iomv.c b/arch/ia64/sn/io/machvec/iomv.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/machvec/iomv.c	Wed Jun 18 23:42:07 2003
@@ -0,0 +1,71 @@
+/* 
+ * 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) 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/pci.h>
+#include <linux/module.h>
+#include <asm/io.h>
+#include <asm/delay.h>
+#include <asm/sn/simulator.h>
+#include <asm/sn/pda.h>
+#include <asm/sn/sn_cpuid.h>
+
+/**
+ * sn_io_addr - convert an in/out port to an i/o address
+ * @port: port to convert
+ *
+ * Legacy in/out instructions are converted to ld/st instructions
+ * on IA64.  This routine will convert a port number into a valid 
+ * SN i/o address.  Used by sn_in*() and sn_out*().
+ */
+void *
+sn_io_addr(unsigned long port)
+{
+	if (!IS_RUNNING_ON_SIMULATOR()) {
+		return( (void *)  (port | __IA64_UNCACHED_OFFSET));
+	} else {
+		unsigned long io_base;
+		unsigned long addr;
+ 
+		/*
+ 		 * word align port, but need more than 10 bits
+ 		 * for accessing registers in bedrock local block
+ 		 * (so we don't do port&0xfff)
+ 		 */
+		if ((port >= 0x1f0 && port <= 0x1f7) ||
+			port == 0x3f6 || port == 0x3f7) {
+			io_base = (0xc000000fcc000000 | ((unsigned long)get_nasid() << 38));
+			addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
+		} else {
+			addr = __ia64_get_io_port_base() | ((port >> 2) << 2);
+		}
+		return(void *) addr;
+	}
+}
+
+EXPORT_SYMBOL(sn_io_addr);
+
+/**
+ * sn_mmiob - I/O space memory barrier
+ *
+ * Acts as a memory mapped I/O barrier for platforms that queue writes to 
+ * I/O space.  This ensures that subsequent writes to I/O space arrive after
+ * all previous writes.  For most ia64 platforms, this is a simple
+ * 'mf.a' instruction.  For other platforms, mmiob() may have to read
+ * a chipset register to ensure ordering.
+ *
+ * On SN2, we wait for the PIO_WRITE_STATUS SHub register to clear.
+ * See PV 871084 for details about the WAR about zero value.
+ *
+ */
+void
+sn_mmiob (void)
+{
+	while ((((volatile unsigned long) (*pda->pio_write_status_addr)) & SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK) != 
+				SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK)
+		udelay(1);
+}
diff -Nru a/arch/ia64/sn/io/machvec/pci.c b/arch/ia64/sn/io/machvec/pci.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/machvec/pci.c	Wed Jun 18 23:42:06 2003
@@ -0,0 +1,135 @@
+/* 
+ *
+ * SNI64 specific PCI support for SNI IO.
+ *
+ * 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) 1997, 1998, 2000-2003 Silicon Graphics, Inc.  All rights reserved.
+ */
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/pci.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/iograph.h>
+#include <asm/param.h>
+#include <asm/sn/pio.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/hcl_util.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/bridge.h>
+
+#ifdef DEBUG_CONFIG
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif
+
+
+
+#ifdef CONFIG_PCI
+
+extern vertex_hdl_t pci_bus_to_vertex(unsigned char);
+extern vertex_hdl_t devfn_to_vertex(unsigned char bus, unsigned char devfn);
+
+int sn_read_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 *val)
+{
+	unsigned long res = 0;
+	vertex_hdl_t device_vertex;
+
+	device_vertex = devfn_to_vertex(bus->number, devfn);
+	res = pciio_config_get(device_vertex, (unsigned) where, size);
+	*val = (unsigned int) res;
+	return PCIBIOS_SUCCESSFUL;
+}
+
+int sn_write_config(struct pci_bus *bus, unsigned int devfn, int where, int size, u32 val)
+{
+	vertex_hdl_t device_vertex;
+
+	device_vertex = devfn_to_vertex(bus->number, devfn);
+	pciio_config_set( device_vertex, (unsigned)where, size, (uint64_t) val);
+	return PCIBIOS_SUCCESSFUL;
+}
+
+struct pci_ops sn_pci_ops = {
+	.read = sn_read_config,
+	.write = sn_write_config
+};
+
+/*
+ * sn_pci_find_bios - SNIA64 pci_find_bios() platform specific code.
+ */
+void __init
+sn_pci_find_bios(void)
+{
+	extern struct pci_ops *pci_root_ops;
+	/*
+	 * Go initialize our IO Infrastructure ..
+	 */
+	extern void sgi_master_io_infr_init(void);
+
+	sgi_master_io_infr_init();
+
+	/* sn_io_infrastructure_init(); */
+	pci_root_ops = &sn_pci_ops;
+}
+
+void
+pci_fixup_ioc3(struct pci_dev *d)
+{
+        int 		i;
+	unsigned int 	size;
+
+        /* IOC3 only decodes 0x20 bytes of the config space, reading
+	 * beyond that is relatively benign but writing beyond that
+	 * (especially the base address registers) will shut down the
+	 * pci bus...so avoid doing so.
+	 * NOTE: this means we can't program the intr_pin into the device,
+	 *       currently we hack this with special code in 
+	 *	 sgi_pci_intr_support()
+	 */
+        DBG("pci_fixup_ioc3: Fixing base addresses for ioc3 device %s\n", d->slot_name);
+
+	/* I happen to know from the spec that the ioc3 needs only 0xfffff 
+	 * The standard pci trick of writing ~0 to the baddr and seeing
+	 * what comes back doesn't work with the ioc3
+	 */
+	size = 0xfffff;
+	d->resource[0].end = (unsigned long) d->resource[0].start + (unsigned long) size;
+
+	/*
+	 * Zero out the resource structure .. because we did not go through 
+	 * the normal PCI Infrastructure Init, garbbage are left in these 
+	 * fileds.
+	 */
+        for (i = 1; i <= PCI_ROM_RESOURCE; i++) {
+                d->resource[i].start = 0UL;
+                d->resource[i].end = 0UL;
+                d->resource[i].flags = 0UL;
+        }
+
+        d->subsystem_vendor = 0;
+        d->subsystem_device = 0;
+
+}
+
+#else
+void sn_pci_find_bios(void) {}
+void pci_fixup_ioc3(struct pci_dev *d) {}
+struct list_head pci_root_buses;
+struct list_head pci_root_buses;
+struct list_head pci_devices;
+
+#endif /* CONFIG_PCI */
diff -Nru a/arch/ia64/sn/io/machvec/pci_bus_cvlink.c b/arch/ia64/sn/io/machvec/pci_bus_cvlink.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/machvec/pci_bus_cvlink.c	Wed Jun 18 23:42:08 2003
@@ -0,0 +1,930 @@
+/*
+ * 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) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/config.h>
+#include <linux/init.h>
+#include <linux/types.h>
+#include <linux/pci.h>
+#include <linux/pci_ids.h>
+#include <linux/sched.h>
+#include <linux/ioport.h>
+#include <asm/sn/types.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/iograph.h>
+#include <asm/param.h>
+#include <asm/sn/pio.h>
+#include <asm/sn/xtalk/xwidget.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/addrs.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/hcl_util.h>
+#include <asm/sn/intr.h>
+#include <asm/sn/xtalk/xtalkaddrs.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/nodepda.h>
+#include <asm/sn/pci/pciio.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/pci/pci_bus_cvlink.h>
+#include <asm/sn/simulator.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/arch.h>
+
+extern int bridge_rev_b_data_check_disable;
+
+vertex_hdl_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET];
+nasid_t busnum_to_nid[MAX_PCI_XWIDGET];
+void * busnum_to_atedmamaps[MAX_PCI_XWIDGET];
+unsigned char num_bridges;
+static int done_probing;
+extern irqpda_t *irqpdaindr;
+
+static int pci_bus_map_create(vertex_hdl_t xtalk, char * io_moduleid);
+vertex_hdl_t devfn_to_vertex(unsigned char busnum, unsigned int devfn);
+
+extern void register_pcibr_intr(int irq, pcibr_intr_t intr);
+
+void sn_dma_flush_init(unsigned long start, unsigned long end, int idx, int pin, int slot);
+
+
+/*
+ * For the given device, initialize whether it is a PIC device.
+ */
+static void
+set_isPIC(struct sn_device_sysdata *device_sysdata)
+{
+	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
+	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+
+	device_sysdata->isPIC = IS_PIC_SOFT(pcibr_soft);;
+}
+
+/*
+ * pci_bus_cvlink_init() - To be called once during initialization before 
+ *	SGI IO Infrastructure init is called.
+ */
+void
+pci_bus_cvlink_init(void)
+{
+
+	extern void ioconfig_bus_init(void);
+
+	memset(busnum_to_pcibr_vhdl, 0x0, sizeof(vertex_hdl_t) * MAX_PCI_XWIDGET);
+	memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET);
+
+	memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET);
+
+	num_bridges = 0;
+
+	ioconfig_bus_init();
+}
+
+/*
+ * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated 
+ *	pci bus vertex from the SGI IO Infrastructure.
+ */
+vertex_hdl_t
+pci_bus_to_vertex(unsigned char busnum)
+{
+
+	vertex_hdl_t	pci_bus = NULL;
+
+
+	/*
+	 * First get the xwidget vertex.
+	 */
+	pci_bus = busnum_to_pcibr_vhdl[busnum];
+	return(pci_bus);
+}
+
+/*
+ * devfn_to_vertex() - returns the vertex of the device given the bus, slot, 
+ *	and function numbers.
+ */
+vertex_hdl_t
+devfn_to_vertex(unsigned char busnum, unsigned int devfn)
+{
+
+	int slot = 0;
+	int func = 0;
+	char	name[16];
+	vertex_hdl_t  pci_bus = NULL;
+	vertex_hdl_t	device_vertex = (vertex_hdl_t)NULL;
+
+	/*
+	 * Go get the pci bus vertex.
+	 */
+	pci_bus = pci_bus_to_vertex(busnum);
+	if (!pci_bus) {
+		/*
+		 * During probing, the Linux pci code invents non-existent
+		 * bus numbers and pci_dev structures and tries to access
+		 * them to determine existence. Don't crib during probing.
+		 */
+		if (done_probing)
+			printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum);
+		return(NULL);
+	}
+
+
+	/*
+	 * Go get the slot&function vertex.
+	 * Should call pciio_slot_func_to_name() when ready.
+	 */
+	slot = PCI_SLOT(devfn);
+	func = PCI_FUNC(devfn);
+
+	/*
+	 * For a NON Multi-function card the name of the device looks like:
+	 * ../pci/1, ../pci/2 ..
+	 */
+	if (func == 0) {
+        	sprintf(name, "%d", slot);
+		if (hwgraph_traverse(pci_bus, name, &device_vertex) == 
+			GRAPH_SUCCESS) {
+			if (device_vertex) {
+				return(device_vertex);
+			}
+		}
+	}
+			
+	/*
+	 * This maybe a multifunction card.  It's names look like:
+	 * ../pci/1a, ../pci/1b, etc.
+	 */
+	sprintf(name, "%d%c", slot, 'a'+func);
+	if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) {
+		if (!device_vertex) {
+			return(NULL);
+		}
+	}
+
+	return(device_vertex);
+}
+
+/*
+ * For the given device, initialize the addresses for both the Device(x) Flush 
+ * Write Buffer register and the Xbow Flush Register for the port the PCI bus 
+ * is connected.
+ */
+static void
+set_flush_addresses(struct pci_dev *device_dev, 
+	struct sn_device_sysdata *device_sysdata)
+{
+	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
+	pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info);
+	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
+    	bridge_t               *bridge = pcibr_soft->bs_base;
+	nasid_t			nasid;
+
+	/*
+	 * Get the nasid from the bridge.
+	 */
+	nasid = NASID_GET(device_sysdata->dma_buf_sync);
+	if (IS_PIC_DEVICE(device_dev)) {
+		device_sysdata->dma_buf_sync = (volatile unsigned int *)
+			&bridge->b_wr_req_buf[pciio_slot].reg;
+		device_sysdata->xbow_buf_sync = (volatile unsigned int *)
+			XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(nasid, 0),
+			pcibr_soft->bs_xid);
+	} else {
+		/*
+		 * Accessing Xbridge and Xbow register when SHUB swapoper is on!.
+		 */
+		device_sysdata->dma_buf_sync = (volatile unsigned int *)
+			((uint64_t)&(bridge->b_wr_req_buf[pciio_slot].reg)^4);
+		device_sysdata->xbow_buf_sync = (volatile unsigned int *)
+			((uint64_t)(XBOW_PRIO_LINKREGS_PTR(
+			NODE_SWIN_BASE(nasid, 0), pcibr_soft->bs_xid)) ^ 4);
+	}
+
+#ifdef DEBUG
+	printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", 
+		device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync);
+
+printk("set_flush_addresses: dma_buf_sync\n");
+	while((volatile unsigned int )*device_sysdata->dma_buf_sync);
+printk("set_flush_addresses: xbow_buf_sync\n");
+	while((volatile unsigned int )*device_sysdata->xbow_buf_sync);
+#endif
+
+}
+
+struct sn_flush_nasid_entry flush_nasid_list[MAX_NASIDS];
+
+// Initialize the data structures for flushing write buffers after a PIO read.
+// The theory is: 
+// Take an unused int. pin and associate it with a pin that is in use.
+// After a PIO read, force an interrupt on the unused pin, forcing a write buffer flush
+// on the in use pin.  This will prevent the race condition between PIO read responses and 
+// DMA writes.
+void
+sn_dma_flush_init(unsigned long start, unsigned long end, int idx, int pin, int slot) {
+	nasid_t nasid; 
+	unsigned long dnasid;
+	int wid_num;
+	int bus;
+	struct sn_flush_device_list *p;
+	bridge_t *b;
+	bridgereg_t dev_sel;
+	extern int isIO9(int);
+	int bwin;
+	int i;
+
+	nasid = NASID_GET(start);
+	wid_num = SWIN_WIDGETNUM(start);
+	bus = (start >> 23) & 0x1;
+	bwin = BWIN_WINDOWNUM(start);
+
+	if (flush_nasid_list[nasid].widget_p == NULL) {
+		flush_nasid_list[nasid].widget_p = (struct sn_flush_device_list **)kmalloc((HUB_WIDGET_ID_MAX+1) *
+			sizeof(struct sn_flush_device_list *), GFP_KERNEL);
+		memset(flush_nasid_list[nasid].widget_p, 0, (HUB_WIDGET_ID_MAX+1) * sizeof(struct sn_flush_device_list *));
+	}
+	if (bwin > 0) {
+		bwin--;
+		switch (bwin) {
+			case 0:
+				flush_nasid_list[nasid].iio_itte1 = HUB_L(IIO_ITTE_GET(nasid, 0));
+				wid_num = ((flush_nasid_list[nasid].iio_itte1) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte1 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 1:
+				flush_nasid_list[nasid].iio_itte2 = HUB_L(IIO_ITTE_GET(nasid, 1));
+				wid_num = ((flush_nasid_list[nasid].iio_itte2) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte2 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 2:
+				flush_nasid_list[nasid].iio_itte3 = HUB_L(IIO_ITTE_GET(nasid, 2));
+				wid_num = ((flush_nasid_list[nasid].iio_itte3) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte3 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 3:
+				flush_nasid_list[nasid].iio_itte4 = HUB_L(IIO_ITTE_GET(nasid, 3));
+				wid_num = ((flush_nasid_list[nasid].iio_itte4) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte4 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 4:
+				flush_nasid_list[nasid].iio_itte5 = HUB_L(IIO_ITTE_GET(nasid, 4));
+				wid_num = ((flush_nasid_list[nasid].iio_itte5) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte5 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 5:
+				flush_nasid_list[nasid].iio_itte6 = HUB_L(IIO_ITTE_GET(nasid, 5));
+				wid_num = ((flush_nasid_list[nasid].iio_itte6) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte6 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+			case 6:
+				flush_nasid_list[nasid].iio_itte7 = HUB_L(IIO_ITTE_GET(nasid, 6));
+				wid_num = ((flush_nasid_list[nasid].iio_itte7) >> 8) & 0xf;
+				bus = flush_nasid_list[nasid].iio_itte7 & 0xf;
+				if (bus == 0x4 || bus == 0x8)
+					bus = 0;
+				else
+					bus = 1;
+				break;
+		}
+	}
+
+	// if it's IO9, bus 1, we don't care about slots 1, 3, and 4.  This is
+	// because these are the IOC4 slots and we don't flush them.
+	if (isIO9(nasid) && bus == 0 && (slot == 1 || slot == 4)) {
+		return;
+	}
+	if (flush_nasid_list[nasid].widget_p[wid_num] == NULL) {
+		flush_nasid_list[nasid].widget_p[wid_num] = (struct sn_flush_device_list *)kmalloc(
+			DEV_PER_WIDGET * sizeof (struct sn_flush_device_list), GFP_KERNEL);
+		memset(flush_nasid_list[nasid].widget_p[wid_num], 0, 
+			DEV_PER_WIDGET * sizeof (struct sn_flush_device_list));
+		p = &flush_nasid_list[nasid].widget_p[wid_num][0];
+		for (i=0; i<DEV_PER_WIDGET;i++) {
+			p->bus = -1;
+			p->pin = -1;
+			p++;
+		}
+	}
+
+	p = &flush_nasid_list[nasid].widget_p[wid_num][0];
+	for (i=0;i<DEV_PER_WIDGET; i++) {
+		if (p->pin == pin && p->bus == bus) break;
+		if (p->pin < 0) {
+			p->pin = pin;
+			p->bus = bus;
+			break;
+		}
+		p++;
+	}
+
+	for (i=0; i<PCI_ROM_RESOURCE; i++) {
+		if (p->bar_list[i].start == 0) {
+			p->bar_list[i].start = start;
+			p->bar_list[i].end = end;
+			break;
+		}
+	}
+	b = (bridge_t *)(NODE_SWIN_BASE(nasid, wid_num) | (bus << 23) );
+
+	// If it's IO9, then slot 2 maps to slot 7 and slot 6 maps to slot 8.
+	// To see this is non-trivial.  By drawing pictures and reading manuals and talking
+	// to HW guys, we can see that on IO9 bus 1, slots 7 and 8 are always unused.
+	// Further, since we short-circuit slots  1, 3, and 4 above, we only have to worry
+	// about the case when there is a card in slot 2.  A multifunction card will appear
+	// to be in slot 6 (from an interrupt point of view) also.  That's the  most we'll
+	// have to worry about.  A four function card will overload the interrupt lines in
+	// slot 2 and 6.  
+	// We also need to special case the 12160 device in slot 3.  Fortunately, we have
+	// a spare intr. line for pin 4, so we'll use that for the 12160.
+	// All other buses have slot 3 and 4 and slots 7 and 8 unused.  Since we can only
+	// see slots 1 and 2 and slots 5 and 6 coming through here for those buses (this
+	// is true only on Pxbricks with 2 physical slots per bus), we just need to add
+	// 2 to the slot number to find an unused slot.
+	// We have convinced ourselves that we will never see a case where two different cards
+	// in two different slots will ever share an interrupt line, so there is no need to
+	// special case this.
+
+	if (isIO9(nasid) && wid_num == 0xc && bus == 0) {
+		if (slot == 2) {
+			p->force_int_addr = (unsigned long)&b->b_force_always[6].intr;
+			dev_sel = b->b_int_device;
+			dev_sel |= (1<<18);
+			b->b_int_device = dev_sel;
+			dnasid = NASID_GET(virt_to_phys(&p->flush_addr));
+			b->p_int_addr_64[6] = (virt_to_phys(&p->flush_addr) & 0xfffffffff) | 
+				(dnasid << 36) | (0xfUL << 48);
+		} else  if (slot == 3) { /* 12160 SCSI device in IO9 */
+			p->force_int_addr = (unsigned long)&b->b_force_always[4].intr;
+			dev_sel = b->b_int_device;
+			dev_sel |= (2<<12);
+			b->b_int_device = dev_sel;
+			dnasid = NASID_GET(virt_to_phys(&p->flush_addr));
+			b->p_int_addr_64[4] = (virt_to_phys(&p->flush_addr) & 0xfffffffff) | 
+				(dnasid << 36) | (0xfUL << 48);
+		} else { /* slot == 6 */
+			p->force_int_addr = (unsigned long)&b->b_force_always[7].intr;
+			dev_sel = b->b_int_device;
+			dev_sel |= (5<<21);
+			b->b_int_device = dev_sel;
+			dnasid = NASID_GET(virt_to_phys(&p->flush_addr));
+			b->p_int_addr_64[7] = (virt_to_phys(&p->flush_addr) & 0xfffffffff) | 
+				(dnasid << 36) | (0xfUL << 48);
+		}
+	} else {
+		p->force_int_addr = (unsigned long)&b->b_force_always[pin + 2].intr;
+		dev_sel = b->b_int_device;
+		dev_sel |= ((slot - 1) << ( pin * 3) );
+		b->b_int_device = dev_sel;
+		dnasid = NASID_GET(virt_to_phys(&p->flush_addr));
+		b->p_int_addr_64[pin + 2] = (virt_to_phys(&p->flush_addr) & 0xfffffffff) | 
+			(dnasid << 36) | (0xfUL << 48);
+	}
+}
+
+/*
+ * Most drivers currently do not properly tell the arch specific pci dma
+ * interfaces whether they can handle A64. Here is where we privately
+ * keep track of this.
+ */
+static void __init
+set_sn_pci64(struct pci_dev *dev)
+{
+	unsigned short vendor = dev->vendor;
+	unsigned short device = dev->device;
+
+	if (vendor == PCI_VENDOR_ID_QLOGIC) {
+		if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) ||
+				(device == PCI_DEVICE_ID_QLOGIC_ISP2200)) {
+			SET_PCIA64(dev);
+			return;
+		}
+	}
+
+	if (vendor == PCI_VENDOR_ID_SGI) {
+		if (device == PCI_DEVICE_ID_SGI_IOC3) {
+			SET_PCIA64(dev);
+			return;
+		}
+	}
+
+}
+
+/*
+ * sn_pci_fixup() - This routine is called when platform_pci_fixup() is 
+ *	invoked at the end of pcibios_init() to link the Linux pci 
+ *	infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c
+ *
+ *	Other platform specific fixup can also be done here.
+ */
+void
+sn_pci_fixup(int arg)
+{
+	struct list_head *ln;
+	struct pci_bus *pci_bus = NULL;
+	struct pci_dev *device_dev = NULL;
+	struct sn_widget_sysdata *widget_sysdata;
+	struct sn_device_sysdata *device_sysdata;
+	pciio_intr_t intr_handle;
+	int cpuid, bit;
+	vertex_hdl_t device_vertex;
+	pciio_intr_line_t lines;
+	extern void sn_pci_find_bios(void);
+	extern int numnodes;
+	int cnode;
+
+	if (arg == 0) {
+#ifdef CONFIG_PROC_FS
+		extern void register_sn_procfs(void);
+#endif
+
+		sn_pci_find_bios();
+		for (cnode = 0; cnode < numnodes; cnode++) {
+			extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int);
+			intr_init_vecblk(NODEPDA(cnode), cnode, 0);
+		} 
+#ifdef CONFIG_PROC_FS
+		register_sn_procfs();
+#endif
+		return;
+	}
+
+
+	done_probing = 1;
+
+	/*
+	 * Initialize the pci bus vertex in the pci_bus struct.
+	 */
+	for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
+		pci_bus = pci_bus_b(ln);
+		widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), 
+					GFP_KERNEL);
+		widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number);
+		pci_bus->sysdata = (void *)widget_sysdata;
+	}
+
+	/*
+ 	 * set the root start and end so that drivers calling check_region()
+	 * won't see a conflict
+	 */
+	ioport_resource.start  = 0xc000000000000000;
+	ioport_resource.end =    0xcfffffffffffffff;
+
+	/*
+	 * Set the root start and end for Mem Resource.
+	 */
+	iomem_resource.start = 0;
+	iomem_resource.end = 0xffffffffffffffff;
+
+	/*
+	 * Initialize the device vertex in the pci_dev struct.
+	 */
+	while ((device_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device_dev)) != NULL) {
+		unsigned int irq;
+		int idx;
+		u16 cmd;
+		vertex_hdl_t vhdl;
+		unsigned long size;
+		extern int bit_pos_to_irq(int);
+
+		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
+				device_dev->device == PCI_DEVICE_ID_SGI_IOC3) {
+			extern void pci_fixup_ioc3(struct pci_dev *d);
+			pci_fixup_ioc3(device_dev);
+		}
+
+		/* Set the device vertex */
+
+		device_sysdata = kmalloc(sizeof(struct sn_device_sysdata),
+					GFP_KERNEL);
+		device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn);
+		device_sysdata->isa64 = 0;
+		/*
+		 * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush 
+		 * register addresses.
+		 */
+		(void) set_flush_addresses(device_dev, device_sysdata);
+
+		device_dev->sysdata = (void *) device_sysdata;
+		set_sn_pci64(device_dev);
+		set_isPIC(device_sysdata);
+
+		pci_read_config_word(device_dev, PCI_COMMAND, &cmd);
+
+		/*
+		 * Set the resources address correctly.  The assumption here 
+		 * is that the addresses in the resource structure has been
+		 * read from the card and it was set in the card by our
+		 * Infrastructure ..
+		 */
+		vhdl = device_sysdata->vhdl;
+		for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
+			size = 0;
+			size = device_dev->resource[idx].end -
+				device_dev->resource[idx].start;
+			if (size) {
+				device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
+				device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET;
+			}
+			else
+				continue;
+
+			device_dev->resource[idx].end = 
+				device_dev->resource[idx].start + size;
+
+			if (device_dev->resource[idx].flags & IORESOURCE_IO)
+				cmd |= PCI_COMMAND_IO;
+
+			if (device_dev->resource[idx].flags & IORESOURCE_MEM)
+				cmd |= PCI_COMMAND_MEMORY;
+		}
+#if 0
+	/*
+	 * Software WAR for a Software BUG.
+	 * This is only temporary.
+	 * See PV 872791
+	 */
+
+		/*
+		 * Now handle the ROM resource ..
+		 */
+		size = device_dev->resource[PCI_ROM_RESOURCE].end -
+			device_dev->resource[PCI_ROM_RESOURCE].start;
+
+		if (size) {
+			device_dev->resource[PCI_ROM_RESOURCE].start =
+			(unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, 
+				size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
+			device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET;
+			device_dev->resource[PCI_ROM_RESOURCE].end =
+			device_dev->resource[PCI_ROM_RESOURCE].start + size;
+		}
+#endif
+
+		/*
+		 * Update the Command Word on the Card.
+		 */
+		cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */
+					   /* bit gets dropped .. no harm */
+		pci_write_config_word(device_dev, PCI_COMMAND, cmd);
+
+		pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines);
+		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
+			device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
+				lines = 1;
+		}
+ 
+		device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata;
+		device_vertex = device_sysdata->vhdl;
+ 
+		irqpdaindr->current = device_dev;
+		intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);
+
+		irq = intr_handle->pi_irq;
+		irqpdaindr->device_dev[irq] = device_dev;
+		cpuid = intr_handle->pi_cpu;
+		pciio_intr_connect(intr_handle, (intr_func_t)0, (intr_arg_t)0);
+		device_dev->irq = irq;
+		register_pcibr_intr(irq, (pcibr_intr_t)intr_handle);
+
+		for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
+			int ibits = ((pcibr_intr_t)intr_handle)->bi_ibits;
+			int i;
+
+			size = device_dev->resource[idx].end -
+				device_dev->resource[idx].start;
+			if (size == 0) continue;
+
+			for (i=0; i<8; i++) {
+				if (ibits & (1 << i) ) {
+					sn_dma_flush_init(device_dev->resource[idx].start, 
+							device_dev->resource[idx].end,
+							idx,
+							i,
+							PCI_SLOT(device_dev->devfn));
+				}
+			}
+		}
+
+	}
+#ifdef ajmtestintr
+		{
+			int slot = PCI_SLOT(device_dev->devfn);
+			static int timer_set = 0;
+			pcibr_intr_t	pcibr_intr = (pcibr_intr_t)intr_handle;
+			pcibr_soft_t	pcibr_soft = pcibr_intr->bi_soft;
+			extern void intr_test_handle_intr(int, void*, struct pt_regs *);
+
+			if (!timer_set) {
+				intr_test_set_timer();
+				timer_set = 1;
+			}
+			intr_test_register_irq(irq, pcibr_soft, slot);
+			request_irq(irq, intr_test_handle_intr,0,NULL, NULL);
+		}
+#endif
+}
+
+/*
+ * linux_bus_cvlink() Creates a link between the Linux PCI Bus number 
+ *	to the actual hardware component that it represents:
+ *	/dev/hw/linux/busnum/0 -> ../../../hw/module/001c01/slab/0/Ibrick/xtalk/15/pci
+ *
+ *	The bus vertex, when called to devfs_generate_path() returns:
+ *		hw/module/001c01/slab/0/Ibrick/xtalk/15/pci
+ *		hw/module/001c01/slab/1/Pbrick/xtalk/12/pci-x/0
+ *		hw/module/001c01/slab/1/Pbrick/xtalk/12/pci-x/1
+ */
+void
+linux_bus_cvlink(void)
+{
+	char name[8];
+	int index;
+	
+	for (index=0; index < MAX_PCI_XWIDGET; index++) {
+		if (!busnum_to_pcibr_vhdl[index])
+			continue;
+
+		sprintf(name, "%x", index);
+		(void) hwgraph_edge_add(linux_busnum, busnum_to_pcibr_vhdl[index], 
+				name);
+	}
+}
+
+/*
+ * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job.
+ *
+ *	Linux PCI Bus numbers are assigned from lowest module_id numbers
+ *	(rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to 
+ *	HUB_WIDGET_ID_MIN:
+ *		widgetnum 15 gets lower Bus Number than widgetnum 14 etc.
+ *
+ *	Given 2 modules 001c01 and 001c02 we get the following mappings:
+ *		001c01, widgetnum 15 = Bus number 0
+ *		001c01, widgetnum 14 = Bus number 1
+ *		001c02, widgetnum 15 = Bus number 3
+ *		001c02, widgetnum 14 = Bus number 4
+ *		etc.
+ *
+ * The rational for starting Bus Number 0 with Widget number 15 is because 
+ * the system boot disks are always connected via Widget 15 Slot 0 of the 
+ * I-brick.  Linux creates /dev/sd* devices(naming) strating from Bus Number 0 
+ * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest 
+ * module id(Master Cnode) of the system.
+ *	
+ */
+static int 
+pci_bus_map_create(vertex_hdl_t xtalk, char * io_moduleid)
+{
+
+	vertex_hdl_t master_node_vertex = NULL;
+	vertex_hdl_t xwidget = NULL;
+	vertex_hdl_t pci_bus = NULL;
+	hubinfo_t hubinfo = NULL;
+	xwidgetnum_t widgetnum;
+	char pathname[128];
+	graph_error_t rv;
+	int bus;
+	int basebus_num;
+	extern void ioconfig_get_busnum(char *, int *);
+
+	int bus_number;
+
+	/*
+	 * Loop throught this vertex and get the Xwidgets ..
+	 */
+
+
+	/* PCI devices */
+
+	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
+		sprintf(pathname, "%d", widgetnum);
+		xwidget = NULL;
+		
+		/*
+		 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
+		 *	     /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device
+		 */
+		rv = hwgraph_traverse(xtalk, pathname, &xwidget);
+		if ( (rv != GRAPH_SUCCESS) ) {
+			if (!xwidget) {
+				continue;
+			}
+		}
+
+		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
+		pci_bus = NULL;
+		if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
+			if (!pci_bus) {
+				continue;
+}
+
+		/*
+		 * Assign the correct bus number and also the nasid of this 
+		 * pci Xwidget.
+		 * 
+		 * Should not be any race here ...
+		 */
+		num_bridges++;
+		busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;
+
+		/*
+		 * Get the master node and from there get the NASID.
+		 */
+		master_node_vertex = device_master_get(xwidget);
+		if (!master_node_vertex) {
+			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
+		}
+	
+		hubinfo_get(master_node_vertex, &hubinfo);
+		if (!hubinfo) {
+			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
+			return(1);
+		} else {
+			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
+		}
+
+		/*
+		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
+		 */
+		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
+			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
+		if (!busnum_to_atedmamaps[num_bridges - 1])
+			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
+
+		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
+			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
+
+	}
+
+	/*
+	 * PCIX devices
+	 * We number busses differently for PCI-X devices.
+	 * We start from Lowest Widget on up ..
+	 */
+
+        (void) ioconfig_get_busnum((char *)io_moduleid, &basebus_num);
+
+	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
+
+		/* Do both buses */
+		for ( bus = 0; bus < 2; bus++ ) {
+			sprintf(pathname, "%d", widgetnum);
+			xwidget = NULL;
+			
+			/*
+			 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
+			 *	     /hw/module/001c16/Pbrick/xtalk/8/pci-x/0 is the bus
+			 *	     /hw/module/001c16/Pbrick/xtalk/8/pci-x/0/1 is device
+			 */
+			rv = hwgraph_traverse(xtalk, pathname, &xwidget);
+			if ( (rv != GRAPH_SUCCESS) ) {
+				if (!xwidget) {
+					continue;
+				}
+			}
+	
+			if ( bus == 0 )
+				sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum);
+			else
+				sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum);
+			pci_bus = NULL;
+			if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
+				if (!pci_bus) {
+					continue;
+				}
+	
+			/*
+			 * Assign the correct bus number and also the nasid of this 
+			 * pci Xwidget.
+			 * 
+			 * Should not be any race here ...
+			 */
+			bus_number = basebus_num + bus + io_brick_map_widget(MODULE_PXBRICK, widgetnum);
+#ifdef DEBUG
+			printk("bus_number %d basebus_num %d bus %d io %d\n", 
+				bus_number, basebus_num, bus, 
+				io_brick_map_widget(MODULE_PXBRICK, widgetnum));
+#endif
+			busnum_to_pcibr_vhdl[bus_number] = pci_bus;
+	
+			/*
+			 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
+			 */
+			busnum_to_atedmamaps[bus_number] = (void *) kmalloc(
+				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
+			if (!busnum_to_atedmamaps[bus_number])
+				printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
+	
+			memset(busnum_to_atedmamaps[bus_number], 0x0, 
+				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
+		}
+	}
+
+        return(0);
+}
+
+/*
+ * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure   
+ *      initialization has completed to set up the mappings between Xbridge
+ *      and logical pci bus numbers.  We also set up the NASID for each of these
+ *      xbridges.
+ *
+ *      Must be called before pci_init() is invoked.
+ */
+int
+pci_bus_to_hcl_cvlink(void) 
+{
+
+	vertex_hdl_t devfs_hdl = NULL;
+	vertex_hdl_t xtalk = NULL;
+	int rv = 0;
+	char name[256];
+	char tmp_name[256];
+	int i, ii, j;
+	char *brick_name;
+	extern void ioconfig_bus_new_entries(void);
+
+	/*
+	 * Figure out which IO Brick is connected to the Compute Bricks.
+	 */
+	for (i = 0; i < nummodules; i++) {
+		extern int iomoduleid_get(nasid_t);
+		moduleid_t iobrick_id;
+		nasid_t nasid = -1;
+		int nodecnt;
+		int n = 0;
+
+		nodecnt = modules[i]->nodecnt;
+		for ( n = 0; n < nodecnt; n++ ) {
+			nasid = cnodeid_to_nasid(modules[i]->nodes[n]);
+			iobrick_id = iomoduleid_get(nasid);
+			if ((int)iobrick_id > 0) { /* Valid module id */
+				char name[12];
+				memset(name, 0, 12);
+				format_module_id((char *)&(modules[i]->io[n].moduleid), iobrick_id, MODULE_FORMAT_BRIEF);
+			}
+		}
+	}
+				
+	devfs_hdl = hwgraph_path_to_vertex("hw/module");
+	for (i = 0; i < nummodules ; i++) {
+	    for ( j = 0; j < 3; j++ ) {
+		if ( j == 0 )
+			brick_name = EDGE_LBL_PBRICK;
+		else if ( j == 1 )
+			brick_name = EDGE_LBL_PXBRICK;
+		else
+			brick_name = EDGE_LBL_IXBRICK;
+
+		for ( ii = 0; ii < 2 ; ii++ ) {
+			memset(name, 0, 256);
+			memset(tmp_name, 0, 256);
+			format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF);
+			sprintf(tmp_name, "/slab/%d/%s/xtalk", geo_slab(modules[i]->geoid[ii]), brick_name);
+			strcat(name, tmp_name);
+			xtalk = NULL;
+			rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
+			if ( rv == 0 ) 
+				pci_bus_map_create(xtalk, (char *)&(modules[i]->io[ii].moduleid));
+		}
+	    }
+	}
+
+	/*
+	 * Create the Linux PCI bus number vertex link.
+	 */
+	(void)linux_bus_cvlink();
+	(void)ioconfig_bus_new_entries();
+
+	return(0);
+}
diff -Nru a/arch/ia64/sn/io/machvec/pci_dma.c b/arch/ia64/sn/io/machvec/pci_dma.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/machvec/pci_dma.c	Wed Jun 18 23:42:06 2003
@@ -0,0 +1,705 @@
+/*
+ * 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) 2000,2002-2003 Silicon Graphics, Inc. All rights reserved.
+ *
+ * Routines for PCI DMA mapping.  See Documentation/DMA-mapping.txt for
+ * a description of how these routines should be used.
+ */
+
+#include <linux/config.h>
+#include <linux/types.h>
+#include <linux/mm.h>
+#include <linux/string.h>
+#include <linux/pci.h>
+#include <linux/slab.h>
+#include <linux/devfs_fs_kernel.h>
+#include <linux/module.h>
+
+#include <asm/delay.h>
+#include <asm/io.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/invent.h>
+#include <asm/sn/hcl.h>
+#include <asm/sn/pci/pcibr.h>
+#include <asm/sn/pci/pcibr_private.h>
+#include <asm/sn/driver.h>
+#include <asm/sn/types.h>
+#include <asm/sn/alenlist.h>
+#include <asm/sn/pci/pci_bus_cvlink.h>
+#include <asm/sn/nag.h>
+
+/*
+ * For ATE allocations
+ */
+pciio_dmamap_t get_free_pciio_dmamap(vertex_hdl_t);
+void free_pciio_dmamap(pcibr_dmamap_t);
+static struct sn_dma_maps_s *find_sn_dma_map(dma_addr_t, unsigned char);
+void sn_pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction);
+
+/*
+ * Toplogy stuff
+ */
+extern vertex_hdl_t busnum_to_pcibr_vhdl[];
+extern nasid_t busnum_to_nid[];
+extern void * busnum_to_atedmamaps[];
+
+/**
+ * get_free_pciio_dmamap - find and allocate an ATE
+ * @pci_bus: PCI bus to get an entry for
+ *
+ * Finds and allocates an ATE on the PCI bus specified
+ * by @pci_bus.
+ */
+pciio_dmamap_t
+get_free_pciio_dmamap(vertex_hdl_t pci_bus)
+{
+	int i;
+	struct sn_dma_maps_s *sn_dma_map = NULL;
+
+	/*
+	 * Darn, we need to get the maps allocated for this bus.
+	 */
+	for (i = 0; i < MAX_PCI_XWIDGET; i++) {
+		if (busnum_to_pcibr_vhdl[i] == pci_bus) {
+			sn_dma_map = busnum_to_atedmamaps[i];
+		}
+	}
+
+	/*
+	 * Now get a free dmamap entry from this list.
+	 */
+	for (i = 0; i < MAX_ATE_MAPS; i++, sn_dma_map++) {
+		if (!sn_dma_map->dma_addr) {
+			sn_dma_map->dma_addr = -1;
+			return( (pciio_dmamap_t) sn_dma_map );
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * free_pciio_dmamap - free an ATE
+ * @dma_map: ATE to free
+ *
+ * Frees the ATE specified by @dma_map.
+ */
+void
+free_pciio_dmamap(pcibr_dmamap_t dma_map)
+{
+	struct sn_dma_maps_s *sn_dma_map;
+
+	sn_dma_map = (struct sn_dma_maps_s *) dma_map;
+	sn_dma_map->dma_addr = 0;
+}
+
+/**
+ * find_sn_dma_map - find an ATE associated with @dma_addr and @busnum
+ * @dma_addr: DMA address to look for
+ * @busnum: PCI bus to look on
+ *
+ * Finds the ATE associated with @dma_addr and @busnum.
+ */
+static struct sn_dma_maps_s *
+find_sn_dma_map(dma_addr_t dma_addr, unsigned char busnum)
+{
+
+	struct sn_dma_maps_s *sn_dma_map = NULL;
+	int i;
+
+	sn_dma_map = busnum_to_atedmamaps[busnum];
+
+	for (i = 0; i < MAX_ATE_MAPS; i++, sn_dma_map++) {
+		if (sn_dma_map->dma_addr == dma_addr) {
+			return sn_dma_map;
+		}
+	}
+
+	return NULL;
+}
+
+/**
+ * sn_pci_alloc_consistent - allocate memory for coherent DMA
+ * @hwdev: device to allocate for
+ * @size: size of the region
+ * @dma_handle: DMA (bus) address
+ *
+ * pci_alloc_consistent() returns a pointer to a memory region suitable for
+ * coherent DMA traffic to/from a PCI device.  On SN platforms, this means
+ * that @dma_handle will have the %PCIIO_DMA_CMD flag set.
+ *
+ * This interface is usually used for "command" streams (e.g. the command
+ * queue for a SCSI controller).  See Documentation/DMA-mapping.txt for
+ * more information.  Note that this routine will always put a 32 bit
+ * DMA address into @dma_handle.  This is because most devices
+ * that are capable of 64 bit PCI DMA transactions can't do 64 bit _coherent_
+ * DMAs, and unfortunately this interface has to cater to the LCD.  Oh well.
+ *
+ * Also known as platform_pci_alloc_consistent() by the IA64 machvec code.
+ */
+void *
+sn_pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
+{
+        void *cpuaddr;
+	vertex_hdl_t vhdl;
+	struct sn_device_sysdata *device_sysdata;
+	unsigned long phys_addr;
+	pciio_dmamap_t dma_map = 0;
+	struct sn_dma_maps_s *sn_dma_map;
+
+	*dma_handle = 0;
+
+	/* We can't easily support < 32 bit devices */
+	if (IS_PCI32L(hwdev))
+		return NULL;
+
+	/*
+	 * Get hwgraph vertex for the device
+	 */
+	device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata;
+	vhdl = device_sysdata->vhdl;
+
+	/*
+	 * Allocate the memory.  FIXME: if we're allocating for
+	 * two devices on the same bus, we should at least try to
+	 * allocate memory in the same 2 GB window to avoid using
+	 * ATEs for the translation.  See the comment above about the
+	 * 32 bit requirement for this function.
+	 */
+	if(!(cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size))))
+		return NULL;
+
+	memset(cpuaddr, 0, size); /* have to zero it out */
+
+	/* physical addr. of the memory we just got */
+	phys_addr = __pa(cpuaddr);
+
+	/*
+	 * This will try to use a Direct Map register to do the
+	 * 32 bit DMA mapping, but it may not succeed if another
+	 * device on the same bus is already mapped with different
+	 * attributes or to a different memory region.
+	 */
+	*dma_handle = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
+			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+					  PCIIO_DMA_CMD);
+
+	/*
+	 * It is a 32 bit card and we cannot do direct mapping,
+	 * so we try to use an ATE.
+	 */
+	if (!(*dma_handle)) {
+		dma_map = pciio_dmamap_alloc(vhdl, NULL, size,
+				((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+					     PCIIO_DMA_CMD);
+		if (!dma_map) {
+			printk(KERN_ERR "sn_pci_alloc_consistent: Unable to "
+			       "allocate anymore 32 bit page map entries.\n");
+			return 0;
+		}
+		*dma_handle = (dma_addr_t) pciio_dmamap_addr(dma_map,phys_addr,
+							     size);
+		sn_dma_map = (struct sn_dma_maps_s *)dma_map;
+		sn_dma_map->dma_addr = *dma_handle;
+	}
+
+        return cpuaddr;
+}
+
+/**
+ * sn_pci_free_consistent - free memory associated with coherent DMAable region
+ * @hwdev: device to free for
+ * @size: size to free
+ * @vaddr: kernel virtual address to free
+ * @dma_handle: DMA address associated with this region
+ *
+ * Frees the memory allocated by pci_alloc_consistent().  Also known
+ * as platform_pci_free_consistent() by the IA64 machvec code.
+ */
+void
+sn_pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
+{
+	struct sn_dma_maps_s *sn_dma_map = NULL;
+
+	/*
+	 * Get the sn_dma_map entry.
+	 */
+	if (IS_PCI32_MAPPED(dma_handle))
+		sn_dma_map = find_sn_dma_map(dma_handle, hwdev->bus->number);
+
+	/*
+	 * and free it if necessary...
+	 */
+	if (sn_dma_map) {
+		pciio_dmamap_done((pciio_dmamap_t)sn_dma_map);
+		pciio_dmamap_free((pciio_dmamap_t)sn_dma_map);
+		sn_dma_map->dma_addr = (dma_addr_t)NULL;
+	}
+	free_pages((unsigned long) vaddr, get_order(size));
+}
+
+/**
+ * sn_pci_map_sg - map a scatter-gather list for DMA
+ * @hwdev: device to map for
+ * @sg: scatterlist to map
+ * @nents: number of entries
+ * @direction: direction of the DMA transaction
+ *
+ * Maps each entry of @sg for DMA.  Also known as platform_pci_map_sg by the
+ * IA64 machvec code.
+ */
+int
+sn_pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
+{
+
+	int i;
+	vertex_hdl_t vhdl;
+	unsigned long phys_addr;
+	struct sn_device_sysdata *device_sysdata;
+	pciio_dmamap_t dma_map;
+	struct sn_dma_maps_s *sn_dma_map;
+	struct scatterlist *saved_sg = sg;
+
+	/* can't go anywhere w/o a direction in life */
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	/*
+	 * Get the hwgraph vertex for the device
+	 */
+	device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata;
+	vhdl = device_sysdata->vhdl;
+
+	/*
+	 * Setup a DMA address for each entry in the
+	 * scatterlist.
+	 */
+	for (i = 0; i < nents; i++, sg++) {
+		phys_addr = __pa(sg->dma_address ? sg->dma_address :
+			page_address(sg->page) + sg->offset);
+
+		/*
+		 * Handle the most common case: 64 bit cards.  This
+		 * call should always succeed.
+		 */
+		if (IS_PCIA64(hwdev)) {
+			sg->dma_address = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
+						       sg->length,
+			       ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+						       PCIIO_DMA_DATA |
+						       PCIIO_DMA_A64);
+			sg->dma_length = sg->length;
+			continue;
+		}
+
+		/*
+		 * Handle 32-63 bit cards via direct mapping
+		 */
+		if (IS_PCI32G(hwdev)) {
+			sg->dma_address = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
+						       sg->length,
+					((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+						       PCIIO_DMA_DATA);
+			sg->dma_length = sg->length;
+			/*
+			 * See if we got a direct map entry
+			 */
+			if (sg->dma_address) {
+				continue;
+			}
+
+		}
+
+		/*
+		 * It is a 32 bit card and we cannot do direct mapping,
+		 * so we use an ATE.
+		 */
+		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length,
+				((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+					     PCIIO_DMA_DATA);
+		if (!dma_map) {
+			printk(KERN_ERR "sn_pci_map_sg: Unable to allocate "
+			       "anymore 32 bit page map entries.\n");
+			/*
+			 * We will need to free all previously allocated entries.
+			 */
+			if (i > 0) {
+				sn_pci_unmap_sg(hwdev, saved_sg, i, direction);
+			}
+			return (0);
+		}
+
+		sg->dma_address = pciio_dmamap_addr(dma_map, phys_addr, sg->length);
+		sg->dma_length = sg->length;
+		sn_dma_map = (struct sn_dma_maps_s *)dma_map;
+		sn_dma_map->dma_addr = sg->dma_address;
+	}
+
+	return nents;
+
+}
+
+/**
+ * sn_pci_unmap_sg - unmap a scatter-gather list
+ * @hwdev: device to unmap
+ * @sg: scatterlist to unmap
+ * @nents: number of scatterlist entries
+ * @direction: DMA direction
+ *
+ * Unmap a set of streaming mode DMA translations.  Again, cpu read rules
+ * concerning calls here are the same as for pci_unmap_single() below.  Also
+ * known as sn_pci_unmap_sg() by the IA64 machvec code.
+ */
+void
+sn_pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
+{
+	int i;
+	struct sn_dma_maps_s *sn_dma_map;
+
+	/* can't go anywhere w/o a direction in life */
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	for (i = 0; i < nents; i++, sg++){
+
+		if (IS_PCI32_MAPPED(sg->dma_address)) {
+			sn_dma_map = NULL;
+                	sn_dma_map = find_sn_dma_map(sg->dma_address, hwdev->bus->number);
+        		if (sn_dma_map) {
+                		pciio_dmamap_done((pciio_dmamap_t)sn_dma_map);
+                		pciio_dmamap_free((pciio_dmamap_t)sn_dma_map);
+                		sn_dma_map->dma_addr = (dma_addr_t)NULL;
+			}
+        	}
+
+		sg->dma_address = (dma_addr_t)NULL;
+		sg->dma_length = 0;
+	}
+}
+
+/**
+ * sn_pci_map_single - map a single region for DMA
+ * @hwdev: device to map for
+ * @ptr: kernel virtual address of the region to map
+ * @size: size of the region
+ * @direction: DMA direction
+ *
+ * Map the region pointed to by @ptr for DMA and return the
+ * DMA address.   Also known as platform_pci_map_single() by
+ * the IA64 machvec code.
+ *
+ * We map this to the one step pciio_dmamap_trans interface rather than
+ * the two step pciio_dmamap_alloc/pciio_dmamap_addr because we have
+ * no way of saving the dmamap handle from the alloc to later free
+ * (which is pretty much unacceptable).
+ *
+ * TODO: simplify our interface;
+ *       get rid of dev_desc and vhdl (seems redundant given a pci_dev);
+ *       figure out how to save dmamap handle so can use two step.
+ */
+dma_addr_t
+sn_pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
+{
+	vertex_hdl_t vhdl;
+	dma_addr_t dma_addr;
+	unsigned long phys_addr;
+	struct sn_device_sysdata *device_sysdata;
+	pciio_dmamap_t dma_map = NULL;
+	struct sn_dma_maps_s *sn_dma_map;
+
+	if (direction == PCI_DMA_NONE)
+		BUG();
+
+	/* SN cannot support DMA addresses smaller than 32 bits. */
+	if (IS_PCI32L(hwdev))
+		return 0;
+
+	/*
+	 * find vertex for the device
+	 */
+	device_sysdata = (struct sn_device_sysdata *)hwdev->sysdata;
+	vhdl = device_sysdata->vhdl;
+
+	/*
+	 * Call our dmamap interface
+	 */
+	dma_addr = 0;
+	phys_addr = __pa(ptr);
+
+	if (IS_PCIA64(hwdev)) {
+		/* This device supports 64 bit DMA addresses. */
+		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
+		       ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+					       PCIIO_DMA_DATA |
+					       PCIIO_DMA_A64);
+		return dma_addr;
+	}
+
+	/*
+	 * Devices that support 32 bit to 63 bit DMA addresses get
+	 * 32 bit DMA addresses.
+	 *
+	 * First try to get a 32 bit direct map register.
+	 */
+	if (IS_PCI32G(hwdev)) {
+		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
+			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+					       PCIIO_DMA_DATA);
+		if (dma_addr)
+			return dma_addr;
+	}
+
+	/*
+	 * It's a 32 bit card and we cannot do direct mapping so
+	 * let's use the PMU instead.
+	 */
+	dma_map = NULL;
+	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, 
+			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
+			PCIIO_DMA_DATA);
+
+	if (!dma_map) {
+		printk(KERN_ERR "pci_map_single: Unable to allocate anymore "
+		       "32 bit page map entries.\n");
+		return 0;
+	}
+
+	dma_addr = (dma_addr_t) pciio_dmamap_addr(dma_map, phys_addr, size);
+	sn_dma_map = (struct sn_dma_maps_s *)dma_map;
+	sn_dma_map->dma_addr = dma_addr;
+
+	return ((dma_addr_t)dma_addr);
+}
+
+/**
+ * sn_pci_unmap_single - unmap a region used for DMA
+ * @hwdev: device to unmap
+ * @dma_addr: DMA address to unmap
+ * @size: size of region
+ * @direction: DMA direction
+ *
+ * Unmaps the region pointed to by @dma_addr.  Also known as
+ * platform_pci_unmap_single() by the IA64 machvec code.
+ */
+void
+sn_pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction)
+{
+	struct sn_dma_maps_s *sn_dma_map = NULL;
+
+        if (direction == PCI_DMA_NONE)
+		BUG();
+
+	/*
+	 * Get the sn_dma_map entry.
+	 */
+	if (IS_PCI32_MAPPED(dma_addr))
+		sn_dma_map = find_sn_dma_map(dma_addr, hwdev->bus->number);
+
+	/*
+	 * and free it if necessary...
+	 */
+	if (sn_dma_map) {
+		pciio_dmamap_done((pciio_dmamap_t)sn_dma_map);
+		pciio_dmamap_free((pciio_dmamap_t)sn_dma_map);
+		sn_dma_map->dma_addr = (dma_addr_t)NULL;
+	}
+}
+
+/**
+ * sn_pci_dma_sync_single - make sure all DMAs have completed
+ * @hwdev: device to sync
+ * @dma_handle: DMA address to sync
+ * @size: size of region
+ * @direction: DMA direction
+ *
+ * This routine is supposed to sync the DMA region specified
+ * by @dma_handle into the 'coherence domain'.  We do not need to do 
+ * anything on our platform.
+ */
+void
+sn_pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction)
+{
+	return;
+
+}
+
+/**
+ * sn_pci_dma_sync_sg - make sure all DMAs have completed
+ * @hwdev: device to sync
+ * @sg: scatterlist to sync
+ * @nents: number of entries in the scatterlist
+ * @direction: DMA direction
+ *
+ * This routine is supposed to sync the DMA regions specified
+ * by @sg into the 'coherence domain'.  We do not need to do anything 
+ * on our platform.
+ */
+void
+sn_pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
+{
+	return;
+
+}
+
+/**
+ * sn_dma_supported - test a DMA mask
+ * @hwdev: device to test
+ * @mask: DMA mask to test
+ *
+ * Return whether the given PCI device DMA address mask can be supported
+ * properly.  For example, if your device can only drive the low 24-bits
+ * during PCI bus mastering, then you would pass 0x00ffffff as the mask to
+ * this function.  Of course, SN only supports devices that have 32 or more
+ * address bits when using the PMU.  We could theoretically support <32 bit
+ * cards using direct mapping, but we'll worry about that later--on the off
+ * chance that someone actually wants to use such a card.
+ */
+int
+sn_pci_dma_supported(struct pci_dev *hwdev, u64 mask)
+{
+	if (mask < 0xffffffff)
+		return 0;
+	return 1;
+}
+
+#ifdef CONFIG_PCI
+
+/*
+ * New generic DMA routines just wrap sn2 PCI routines until we
+ * support other bus types (if ever).
+ */
+
+int
+sn_dma_supported(struct device *dev, u64 mask)
+{
+	BUG_ON(dev->bus != &pci_bus_type);
+
+	return pci_dma_supported(to_pci_dev(dev), mask);
+}
+EXPORT_SYMBOL(sn_dma_supported);
+
+int
+sn_dma_set_mask(struct device *dev, u64 dma_mask)
+{
+	BUG_ON(dev->bus != &pci_bus_type);
+
+	return pci_set_dma_mask(to_pci_dev(dev), dma_mask);
+}
+EXPORT_SYMBOL(sn_dma_set_mask);
+
+void *
+sn_dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle,
+		   int flag)
+{
+	BUG_ON(dev->bus != &pci_bus_type);
+
+	return pci_alloc_consistent(to_pci_dev(dev), size, dma_handle);
+}
+EXPORT_SYMBOL(sn_dma_alloc_coherent);
+
+void
+sn_dma_free_coherent(struct device *dev, size_t size, void *cpu_addr,
+		    dma_addr_t dma_handle)
+{
+	BUG_ON(dev->bus != &pci_bus_type);
+
+	pci_free_consistent(to_pci_dev(dev), size, cpu_addr, dma_handle);
+}
+EXPORT_SYMBOL(sn_dma_free_coherent);
+
+dma_addr_t
+sn_dma_map_single(struct device *dev, void *cpu_addr, size_t size,
+	       int direction)
+{
+	BUG_ON(dev->bus != &pci_bus_type);
+
+	return pci_map_single(to_pci_dev(dev), cpu_addr, size, (int)direction);
+}
+EXPORT_SYMBOL(sn_dma_map_single);
+
+void
+sn_dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
+		 int direction)
+{
+	BUG_ON(dev->bus != &pci_bus_type);
+
+	pci_unmap_single(to_pci_dev(dev), dma_addr, size, (int)direction);
+}
+EXPORT_SYMBOL(sn_dma_unmap_single);
+
+dma_addr_t
+sn_dma_map_page(struct device *dev, struct page *page,
+	     unsigned long offset, size_t size,
+	     int direction)
+{
+	BUG_ON(dev->bus != &pci_bus_type);
+
+	return pci_map_page(to_pci_dev(dev), page, offset, size, (int)direction);
+}
+EXPORT_SYMBOL(sn_dma_map_page);
+
+void
+sn_dma_unmap_page(struct device *dev, dma_addr_t dma_address, size_t size,
+	       int direction)
+{
+	BUG_ON(dev->bus != &pci_bus_type);
+
+	pci_unmap_page(to_pci_dev(dev), dma_address, size, (int)direction);
+}
+EXPORT_SYMBOL(sn_dma_unmap_page);
+
+int
+sn_dma_map_sg(struct device *dev, struct scatterlist *sg, int nents,
+	   int direction)
+{
+	BUG_ON(dev->bus != &pci_bus_type);
+
+	return pci_map_sg(to_pci_dev(dev), sg, nents, (int)direction);
+}
+EXPORT_SYMBOL(sn_dma_map_sg);
+
+void
+sn_dma_unmap_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
+	     int direction)
+{
+	BUG_ON(dev->bus != &pci_bus_type);
+
+	pci_unmap_sg(to_pci_dev(dev), sg, nhwentries, (int)direction);
+}
+EXPORT_SYMBOL(sn_dma_unmap_sg);
+
+void
+sn_dma_sync_single(struct device *dev, dma_addr_t dma_handle, size_t size,
+		int direction)
+{
+	BUG_ON(dev->bus != &pci_bus_type);
+
+	pci_dma_sync_single(to_pci_dev(dev), dma_handle, size, (int)direction);
+}
+EXPORT_SYMBOL(sn_dma_sync_single);
+
+void
+sn_dma_sync_sg(struct device *dev, struct scatterlist *sg, int nelems,
+	    int direction)
+{
+	BUG_ON(dev->bus != &pci_bus_type);
+
+	pci_dma_sync_sg(to_pci_dev(dev), sg, nelems, (int)direction);
+}
+EXPORT_SYMBOL(sn_dma_sync_sg);
+
+#endif /* CONFIG_PCI */
+
+EXPORT_SYMBOL(sn_pci_unmap_single);
+EXPORT_SYMBOL(sn_pci_map_single);
+EXPORT_SYMBOL(sn_pci_dma_sync_single);
+EXPORT_SYMBOL(sn_pci_map_sg);
+EXPORT_SYMBOL(sn_pci_unmap_sg);
+EXPORT_SYMBOL(sn_pci_alloc_consistent);
+EXPORT_SYMBOL(sn_pci_free_consistent);
+EXPORT_SYMBOL(sn_pci_dma_supported);
+
diff -Nru a/arch/ia64/sn/io/ml_SN_init.c b/arch/ia64/sn/io/ml_SN_init.c
--- a/arch/ia64/sn/io/ml_SN_init.c	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,235 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/bootmem.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/snconfig.h>
-
-extern int numcpus;
-extern char arg_maxnodes[];
-extern cpuid_t master_procid;
-#if defined(CONFIG_IA64_SGI_SN1)
-extern synergy_da_t    *Synergy_da_indr[];
-#endif
-
-extern int hasmetarouter;
-
-int		maxcpus;
-cpumask_t	boot_cpumask;
-hubreg_t	region_mask = 0;
-
-
-extern xwidgetnum_t hub_widget_id(nasid_t);
-
-extern int valid_icache_reasons;	/* Reasons to flush the icache */
-extern int valid_dcache_reasons;	/* Reasons to flush the dcache */
-extern u_char miniroot;
-extern volatile int	need_utlbmiss_patch;
-extern void iograph_early_init(void);
-
-nasid_t master_nasid = INVALID_NASID;
-
-
-/*
- * mlreset(int slave)
- * 	very early machine reset - at this point NO interrupts have been
- * 	enabled; nor is memory, tlb, p0, etc setup.
- *
- * 	slave is zero when mlreset is called for the master processor and
- *	is nonzero thereafter.
- */
-
-
-void
-mlreset(int slave)
-{
-	if (!slave) {
-		/*
-		 * We are the master cpu and node.
-		 */ 
-		master_nasid = get_nasid();
-		set_master_bridge_base();
-
-		/* We're the master processor */
-		master_procid = smp_processor_id();
-		master_nasid = cpuid_to_nasid(master_procid);
-
-		/*
-		 * master_nasid we get back better be same as one from
-		 * get_nasid()
-		 */
-		ASSERT_ALWAYS(master_nasid == get_nasid());
-
-		/* early initialization of iograph */
-		iograph_early_init();
-
-		/* Initialize Hub Pseudodriver Management */
-		hubdev_init();
-
-	} else { /* slave != 0 */
-		/*
-		 * This code is performed ONLY by slave processors.
-		 */
-
-	}
-}
-
-
-/* XXX - Move the meat of this to intr.c ? */
-/*
- * Set up the platform-dependent fields in the nodepda.
- */
-void init_platform_nodepda(nodepda_t *npda, cnodeid_t node)
-{
-	hubinfo_t hubinfo;
-#ifdef CONFIG_IA64_SGI_SN1
-	int	  sn;
-#endif
-
-	extern void router_map_init(nodepda_t *);
-	extern void router_queue_init(nodepda_t *,cnodeid_t);
-	extern void intr_init_vecblk(nodepda_t *, cnodeid_t, int);
-
-	/* Allocate per-node platform-dependent data */
-	hubinfo = (hubinfo_t)alloc_bootmem_node(NODE_DATA(node), sizeof(struct hubinfo_s));
-
-	npda->pdinfo = (void *)hubinfo;
-	hubinfo->h_nodepda = npda;
-	hubinfo->h_cnodeid = node;
-	hubinfo->h_nasid = COMPACT_TO_NASID_NODEID(node);
-
-	spin_lock_init(&hubinfo->h_crblock);
-
-	hubinfo->h_widgetid = hub_widget_id(hubinfo->h_nasid);
-	npda->xbow_peer = INVALID_NASID;
-
-	/* 
-	 * Initialize the linked list of
-	 * router info pointers to the dependent routers
-	 */
-	npda->npda_rip_first = NULL;
-
-	/*
-	 * npda_rip_last always points to the place
-	 * where the next element is to be inserted
-	 * into the list 
-	 */
-	npda->npda_rip_last = &npda->npda_rip_first;
-	npda->module_id = INVALID_MODULE;
-
-#ifdef CONFIG_IA64_SGI_SN1
-	/*
-	* Initialize the interrupts.
-	* On sn2, this is done at pci init time,
-	* because sn2 needs the cpus checked in
-	* when it initializes interrupts.  This is
-	* so we don't see all the nodes as headless.
-	*/
-	for (sn=0; sn<NUM_SUBNODES; sn++) {
-		intr_init_vecblk(npda, node, sn);
-	}
-#endif /* CONFIG_IA64_SGI_SN1 */
-
-	mutex_init_locked(&npda->xbow_sema); /* init it locked? */
-
-#ifdef	LATER
-
-	/* Setup the (module,slot) --> nic mapping for all the routers
-	 * in the system. This is useful during error handling when
-	 * there is no shared memory.
-	 */
-	router_map_init(npda);
-
-	/* Allocate memory for the per-node router traversal queue */
-	router_queue_init(npda,node);
-	npda->sbe_info = alloc_bootmem_node(NODE_DATA(node), sizeof (sbe_info_t));
-	ASSERT(npda->sbe_info);
-
-#endif /* LATER */
-}
-
-/* XXX - Move the interrupt stuff to intr.c ? */
-/*
- * Set up the platform-dependent fields in the processor pda.
- * Must be done _after_ init_platform_nodepda().
- * If we need a lock here, something else is wrong!
- */
-void init_platform_pda(cpuid_t cpu)
-{
-#if defined(CONFIG_IA64_SGI_SN1)
-	hub_intmasks_t *intmasks;
-	int i, subnode;
-	cnodeid_t	cnode;
-	synergy_da_t	*sda;
-	int	which_synergy;
-
-
-	cnode = cpuid_to_cnodeid(cpu);
-	which_synergy = cpuid_to_synergy(cpu);
-
-	sda = Synergy_da_indr[(cnode * 2) + which_synergy];
-	intmasks = &sda->s_intmasks;
-
-	/* Clear INT_PEND0 masks. */
-	for (i = 0; i < N_INTPEND0_MASKS; i++)
-		intmasks->intpend0_masks[i] = 0;
-
-	/* Set up pointer to the vector block in the nodepda. */
-	/* (Cant use SUBNODEPDA - not working yet) */
-	subnode = cpuid_to_subnode(cpu);
-	intmasks->dispatch0 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch0;
-	intmasks->dispatch1 = &NODEPDA(cnode)->snpda[cpuid_to_subnode(cpu)].intr_dispatch1;
-	if (intmasks->dispatch0 !=  &SUBNODEPDA(cnode, subnode)->intr_dispatch0 ||
-	   intmasks->dispatch1 !=  &SUBNODEPDA(cnode, subnode)->intr_dispatch1)
-	   	panic("xxx");
-	intmasks->dispatch0 = &SUBNODEPDA(cnode, subnode)->intr_dispatch0;
-	intmasks->dispatch1 = &SUBNODEPDA(cnode, subnode)->intr_dispatch1;
-
-	/* Clear INT_PEND1 masks. */
-	for (i = 0; i < N_INTPEND1_MASKS; i++)
-		intmasks->intpend1_masks[i] = 0;
-#endif	/* CONFIG_IA64_SGI_SN1 */
-}
-
-void
-update_node_information(cnodeid_t cnodeid)
-{
-	nodepda_t *npda = NODEPDA(cnodeid);
-	nodepda_router_info_t *npda_rip;
-	
-	/* Go through the list of router info 
-	 * structures and copy some frequently
-	 * accessed info from the info hanging
-	 * off the corresponding router vertices
-	 */
-	npda_rip = npda->npda_rip_first;
-	while(npda_rip) {
-		if (npda_rip->router_infop) {
-			npda_rip->router_portmask = 
-				npda_rip->router_infop->ri_portmask;
-			npda_rip->router_slot = 
-				npda_rip->router_infop->ri_slotnum;
-		} else {
-			/* No router, no ports. */
-			npda_rip->router_portmask = 0;
-		}
-		npda_rip = npda_rip->router_next;
-	}
-}
diff -Nru a/arch/ia64/sn/io/ml_iograph.c b/arch/ia64/sn/io/ml_iograph.c
--- a/arch/ia64/sn/io/ml_iograph.c	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1570 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <linux/ctype.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/xtalk/xtalk_private.h>
-#include <asm/sn/xtalk/xtalkaddrs.h>
-
-/* #define IOGRAPH_DEBUG */
-#ifdef IOGRAPH_DEBUG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* IOGRAPH_DEBUG */
-
-/* #define PROBE_TEST */
-
-/* At most 2 hubs can be connected to an xswitch */
-#define NUM_XSWITCH_VOLUNTEER 2
-
-/*
- * Track which hubs have volunteered to manage devices hanging off of
- * a Crosstalk Switch (e.g. xbow).  This structure is allocated,
- * initialized, and hung off the xswitch vertex early on when the
- * xswitch vertex is created.
- */
-typedef struct xswitch_vol_s {
-	mutex_t xswitch_volunteer_mutex;
-	int		xswitch_volunteer_count;
-	devfs_handle_t	xswitch_volunteer[NUM_XSWITCH_VOLUNTEER];
-} *xswitch_vol_t;
-
-void
-xswitch_vertex_init(devfs_handle_t xswitch)
-{
-	xswitch_vol_t xvolinfo;
-	int rc;
-
-	xvolinfo = kmalloc(sizeof(struct xswitch_vol_s), GFP_KERNEL);
-	mutex_init(&xvolinfo->xswitch_volunteer_mutex);
-	xvolinfo->xswitch_volunteer_count = 0;
-	rc = hwgraph_info_add_LBL(xswitch, 
-			INFO_LBL_XSWITCH_VOL,
-			(arbitrary_info_t)xvolinfo);
-	ASSERT(rc == GRAPH_SUCCESS); rc = rc;
-}
-
-
-/*
- * When assignment of hubs to widgets is complete, we no longer need the
- * xswitch volunteer structure hanging around.  Destroy it.
- */
-static void
-xswitch_volunteer_delete(devfs_handle_t xswitch)
-{
-	xswitch_vol_t xvolinfo;
-	int rc;
-
-	rc = hwgraph_info_remove_LBL(xswitch, 
-				INFO_LBL_XSWITCH_VOL,
-				(arbitrary_info_t *)&xvolinfo);
-#ifdef LATER
-	ASSERT(rc == GRAPH_SUCCESS); rc = rc;
-#endif
-
-	kfree(xvolinfo);
-}
-/*
- * A Crosstalk master volunteers to manage xwidgets on the specified xswitch.
- */
-/* ARGSUSED */
-static void
-volunteer_for_widgets(devfs_handle_t xswitch, devfs_handle_t master)
-{
-	xswitch_vol_t xvolinfo = NULL;
-
-	(void)hwgraph_info_get_LBL(xswitch, 
-				INFO_LBL_XSWITCH_VOL, 
-				(arbitrary_info_t *)&xvolinfo);
-	if (xvolinfo == NULL) {
-#ifdef LATER
-	    if (!is_headless_node_vertex(master)) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-		printk(KERN_WARNING  "volunteer for widgets: vertex %v has no info label",
-			xswitch);
-#else
-		printk(KERN_WARNING  "volunteer for widgets: vertex 0x%x has no info label",
-			xswitch);
-#endif
-	    }
-#endif	/* LATER */
-	    return;
-	}
-
-	mutex_lock(&xvolinfo->xswitch_volunteer_mutex);
-	ASSERT(xvolinfo->xswitch_volunteer_count < NUM_XSWITCH_VOLUNTEER);
-	xvolinfo->xswitch_volunteer[xvolinfo->xswitch_volunteer_count] = master;
-	xvolinfo->xswitch_volunteer_count++;
-	mutex_unlock(&xvolinfo->xswitch_volunteer_mutex);
-}
-
-extern int xbow_port_io_enabled(nasid_t nasid, int widgetnum);
-
-/*
- * Assign all the xwidgets hanging off the specified xswitch to the
- * Crosstalk masters that have volunteered for xswitch duty.
- */
-/* ARGSUSED */
-static void
-assign_widgets_to_volunteers(devfs_handle_t xswitch, devfs_handle_t hubv)
-{
-	int curr_volunteer, num_volunteer;
-	xwidgetnum_t widgetnum;
-	xswitch_info_t xswitch_info;
-	xswitch_vol_t xvolinfo = NULL;
-	nasid_t nasid;
-	hubinfo_t hubinfo;
-
-	hubinfo_get(hubv, &hubinfo);
-	nasid = hubinfo->h_nasid;
-	
-	xswitch_info = xswitch_info_get(xswitch);
-	ASSERT(xswitch_info != NULL);
-
-	(void)hwgraph_info_get_LBL(xswitch, 
-				INFO_LBL_XSWITCH_VOL, 
-				(arbitrary_info_t *)&xvolinfo);
-	if (xvolinfo == NULL) {
-#ifdef LATER
-	    if (!is_headless_node_vertex(hubv)) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-		printk(KERN_WARNING  "assign_widgets_to_volunteers:vertex %v has "
-			" no info label",
-			xswitch);
-#else
-		printk(KERN_WARNING  "assign_widgets_to_volunteers:vertex 0x%x has "
-			" no info label",
-			xswitch);
-#endif
-	    }
-#endif	/* LATER */
-	    return;
-	}
-
-	num_volunteer = xvolinfo->xswitch_volunteer_count;
-	ASSERT(num_volunteer > 0);
-	curr_volunteer = 0;
-
-	/* Assign master hub for xswitch itself.  */
-	if (HUB_WIDGET_ID_MIN > 0) {
-		hubv = xvolinfo->xswitch_volunteer[0];
-		xswitch_info_master_assignment_set(xswitch_info, (xwidgetnum_t)0, hubv);
-	}
-
-	/*
-	 * TBD: Use administrative information to alter assignment of
-	 * widgets to hubs.
-	 */
-	for (widgetnum=HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
-
-		/*
-		 * Ignore disabled/empty ports.
-		 */
-		if (!xbow_port_io_enabled(nasid, widgetnum)) 
-		    continue;
-
-		/*
-		 * If this is the master IO board, assign it to the same 
-		 * hub that owned it in the prom.
-		 */
-		if (is_master_nasid_widget(nasid, widgetnum)) {
-			int i;
-
-			for (i=0; i<num_volunteer; i++) {
-				hubv = xvolinfo->xswitch_volunteer[i];
-				hubinfo_get(hubv, &hubinfo);
-				nasid = hubinfo->h_nasid;
-				if (nasid == get_console_nasid())
-					goto do_assignment;
-			}
-#ifdef LATER
-			PRINT_PANIC("Nasid == %d, console nasid == %d",
-				nasid, get_console_nasid());
-#endif
-		}
-
-
-		/*
-		 * Do a round-robin assignment among the volunteer nodes.
-		 */
-		hubv = xvolinfo->xswitch_volunteer[curr_volunteer];
-		curr_volunteer = (curr_volunteer + 1) % num_volunteer;
-		/* fall through */
-
-do_assignment:
-		/*
-		 * At this point, we want to make hubv the master of widgetnum.
-		 */
-		xswitch_info_master_assignment_set(xswitch_info, widgetnum, hubv);
-	}
-
-	xswitch_volunteer_delete(xswitch);
-}
-
-/*
- * Early iograph initialization.  Called by master CPU in mlreset().
- * Useful for including iograph.o in kernel.o.
- */
-void
-iograph_early_init(void)
-{
-/*
- * Need new way to get this information ..
- */
-	cnodeid_t cnode;
-	nasid_t nasid;
-	lboard_t *board;
-	
-	/*
-	 * Init. the board-to-hwgraph link early, so FRU analyzer
-	 * doesn't trip on leftover values if we panic early on.
-	 */
-	for(cnode = 0; cnode < numnodes; cnode++) {
-		nasid = COMPACT_TO_NASID_NODEID(cnode);
-		board = (lboard_t *)KL_CONFIG_INFO(nasid);
-		DBG("iograph_early_init: Found board 0x%p\n", board);
-
-		/* Check out all the board info stored on a node */
-		while(board) {
-			board->brd_graph_link = GRAPH_VERTEX_NONE;
-			board = KLCF_NEXT(board);
-			DBG("iograph_early_init: Found board 0x%p\n", board);
-
-
-		}
-	}
-
-	hubio_init();
-}
-
-#ifdef LINUX_KERNEL_THREADS
-static struct semaphore io_init_sema;
-#endif
-
-/*
- * Let boot processor know that we're done initializing our node's IO
- * and then exit.
- */
-/* ARGSUSED */
-static void
-io_init_done(cnodeid_t cnodeid,cpu_cookie_t c)
-{
-	/* Let boot processor know that we're done. */
-#ifdef LINUX_KERNEL_THREADS
-	up(&io_init_sema);
-#endif
-#ifdef LATER
-	/* This is for the setnoderun done when the io_init thread
-	 * started 
-	 */
-	restorenoderun(c);
-	sthread_exit();
-#endif
-}
-
-/* 
- * Probe to see if this hub's xtalk link is active.  If so,
- * return the Crosstalk Identification of the widget that we talk to.  
- * This is called before any of the Crosstalk infrastructure for 
- * this hub is set up.  It's usually called on the node that we're
- * probing, but not always.
- *
- * TBD: Prom code should actually do this work, and pass through 
- * hwid for our use.
- */
-static void
-early_probe_for_widget(devfs_handle_t hubv, xwidget_hwid_t hwid)
-{
-	hubreg_t llp_csr_reg;
-	nasid_t nasid;
-	hubinfo_t hubinfo;
-
-	hubinfo_get(hubv, &hubinfo);
-	nasid = hubinfo->h_nasid;
-
-	llp_csr_reg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
-	/* 
-	 * If link is up, read the widget's part number.
-	 * A direct connect widget must respond to widgetnum=0.
-	 */
-	if (llp_csr_reg & IIO_LLP_CSR_IS_UP) {
-		/* TBD: Put hub into "indirect" mode */
-		/*
-		 * We're able to read from a widget because our hub's 
-		 * WIDGET_ID was set up earlier.
-		 */
-		widgetreg_t widget_id = *(volatile widgetreg_t *)
-			(RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID);
-
-		DBG("early_probe_for_widget: Hub Vertex 0x%p is UP widget_id = 0x%x Register 0x%p\n", hubv, widget_id,
-		(volatile widgetreg_t *)(RAW_NODE_SWIN_BASE(nasid, 0x0) + WIDGET_ID) );
-
-		hwid->part_num = XWIDGET_PART_NUM(widget_id);
-		hwid->rev_num = XWIDGET_REV_NUM(widget_id);
-		hwid->mfg_num = XWIDGET_MFG_NUM(widget_id);
-
-		/* TBD: link reset */
-	} else {
-
-		hwid->part_num = XWIDGET_PART_NUM_NONE;
-		hwid->rev_num = XWIDGET_REV_NUM_NONE;
-		hwid->mfg_num = XWIDGET_MFG_NUM_NONE;
-	}
-
-}
-
-/* Add inventory information to the widget vertex 
- * Right now (module,slot,revision) is being
- * added as inventory information.
- */
-static void
-xwidget_inventory_add(devfs_handle_t 		widgetv,
-		      lboard_t 			*board,
-		      struct xwidget_hwid_s 	hwid)
-{
-	if (!board)
-		return;
-	/* Donot add inventory information for the baseio
-	 * on a speedo with an xbox. It has already been
-	 * taken care of in SN00_vmc.
-	 * Speedo with xbox's baseio comes in at slot io1 (widget 9)
-	 */
-	device_inventory_add(widgetv,INV_IOBD,board->brd_type,
-			     board->brd_module,
-			     SLOTNUM_GETSLOT(board->brd_slot),
-			     hwid.rev_num);
-}
-
-/*
- * io_xswitch_widget_init
- *	
- */
-
-/* defined in include/linux/ctype.h  */
-/* #define toupper(c)	(islower(c) ? (c) - 'a' + 'A' : (c)) */
-
-void
-io_xswitch_widget_init(devfs_handle_t  	xswitchv,
-		       devfs_handle_t	hubv,
-		       xwidgetnum_t	widgetnum,
-		       async_attach_t	aa)
-{
-	xswitch_info_t		xswitch_info;
-	xwidgetnum_t		hub_widgetid;
-	devfs_handle_t		widgetv;
-	cnodeid_t		cnode;
-	widgetreg_t		widget_id;
-	nasid_t			nasid, peer_nasid;
-	struct xwidget_hwid_s 	hwid;
-	hubinfo_t		hubinfo;
-	/*REFERENCED*/
-	int			rc;
-	char			slotname[SLOTNUM_MAXLENGTH];
-	char 			pathname[128];
-	char			new_name[64];
-	moduleid_t		module;
-	slotid_t		slot;
-	lboard_t		*board = NULL;
-	char			buffer[16];
-	slotid_t get_widget_slotnum(int xbow, int widget);
-	
-	DBG("\nio_xswitch_widget_init: hubv 0x%p, xswitchv 0x%p, widgetnum 0x%x\n", hubv, xswitchv, widgetnum);
-	/*
-	 * Verify that xswitchv is indeed an attached xswitch.
-	 */
-	xswitch_info = xswitch_info_get(xswitchv);
-	ASSERT(xswitch_info != NULL);
-
-	hubinfo_get(hubv, &hubinfo);
-	nasid = hubinfo->h_nasid;
-	cnode = NASID_TO_COMPACT_NODEID(nasid);
-	hub_widgetid = hubinfo->h_widgetid;
-
-
-	/* Who's the other guy on out crossbow (if anyone) */
-	peer_nasid = NODEPDA(cnode)->xbow_peer;
-	if (peer_nasid == INVALID_NASID)
-		/* If I don't have a peer, use myself. */
-		peer_nasid = nasid;
-
-
-	/* Check my xbow structure and my peer's */
-	if (!xbow_port_io_enabled(nasid, widgetnum) &&
-	    !xbow_port_io_enabled(peer_nasid, widgetnum)) {
-		return;
-	}
-
-	if (xswitch_info_link_ok(xswitch_info, widgetnum)) {
-		char			name[4];
-		/*
-		 * If the current hub is not supposed to be the master 
-		 * for this widgetnum, then skip this widget.
-		 */
-		if (xswitch_info_master_assignment_get(xswitch_info,
-						       widgetnum) != hubv) {
-			return;
-		}
-
-		module  = NODEPDA(cnode)->module_id;
-#ifdef XBRIDGE_REGS_SIM
-		/* hardwire for now...could do this with something like:
-		 * xbow_soft_t soft = hwgraph_fastinfo_get(vhdl);
-		 * xbow_t xbow = soft->base;
-		 * xbowreg_t xwidget_id = xbow->xb_wid_id;
-		 * but I don't feel like figuring out vhdl right now..
-		 * and I know for a fact the answer is 0x2d000049 
-		 */
-		DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n");
-		DBG("XWIDGET_PART_NUM(0x2d000049)= 0x%x\n", XWIDGET_PART_NUM(0x2d000049));
-		if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM) {
-#else
-		if (nasid_has_xbridge(nasid)) {
-#endif /* XBRIDGE_REGS_SIM */
-			board = find_lboard_module_class(
-				(lboard_t *)KL_CONFIG_INFO(nasid),
-				module,
-				KLTYPE_IOBRICK);
-
-DBG("io_xswitch_widget_init: Board 0x%p\n", board);
-{
-		lboard_t dummy;
-
-
-			if (board) {
-				DBG("io_xswitch_widget_init: Found KLTYPE_IOBRICK Board 0x%p brd_type 0x%x\n", board, board->brd_type);
-			} else {
-				DBG("io_xswitch_widget_init: FIXME did not find IOBOARD\n");
-				board = &dummy;
-			}
-				
-}
-
-			/*
-	 		 * Make sure we really want to say xbrick, pbrick,
-			 * etc. rather than XIO, graphics, etc.
-	 		 */
-
-#ifdef SUPPORT_PRINTING_M_FORMAT
-			sprintf(pathname, EDGE_LBL_MODULE "/%M/"
-				"%cbrick" "/%s/%d",
-				NODEPDA(cnode)->module_id,
-				
-#else
-			memset(buffer, 0, 16);
-			format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF);
-			sprintf(pathname, EDGE_LBL_MODULE "/%s/"
-				"%cbrick" "/%s/%d",
-				buffer,
-#endif
-
-				(board->brd_type == KLTYPE_IBRICK) ? 'I' :
-				(board->brd_type == KLTYPE_PBRICK) ? 'P' :
-				(board->brd_type == KLTYPE_XBRICK) ? 'X' : '?',
-				EDGE_LBL_XTALK, widgetnum);
-		} 
-		
-		DBG("io_xswitch_widget_init: path= %s\n", pathname);
-		rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv);
-		
-		ASSERT(rc == GRAPH_SUCCESS);
-
-		/* This is needed to let the user programs to map the
-		 * module,slot numbers to the corresponding widget numbers
-		 * on the crossbow.
-		 */
-		rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv);
-
-		/* If we are looking at the global master io6
-		 * then add information about the version of
-		 * the io6prom as a part of "detailed inventory"
-		 * information.
-		 */
-		if (is_master_baseio(nasid,
-				     NODEPDA(cnode)->module_id,
- 				     get_widget_slotnum(0,widgetnum))) {
-			extern void klhwg_baseio_inventory_add(devfs_handle_t,
-							       cnodeid_t);
-			module 	= NODEPDA(cnode)->module_id;
-
-#ifdef XBRIDGE_REGS_SIM
-			DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: reading xwidget id: hardwired to xbridge (0x2d000049).\n");
-			if (XWIDGET_PART_NUM(0x2d000049)==XXBOW_WIDGET_PART_NUM) {
-#else
-			if (nasid_has_xbridge(nasid)) {
-#endif /* XBRIDGE_REGS_SIM */
-				board = find_lboard_module(
-					(lboard_t *)KL_CONFIG_INFO(nasid),
-					module);
-				/*
-				 * Change iobrick to correct i/o brick
-				 */
-#ifdef SUPPORT_PRINTING_M_FORMAT
-				sprintf(pathname, EDGE_LBL_MODULE "/%M/"
-#else
-				sprintf(pathname, EDGE_LBL_MODULE "/%x/"
-#endif
-					"iobrick" "/%s/%d",
-					NODEPDA(cnode)->module_id,
-					EDGE_LBL_XTALK, widgetnum);
-			} else {
-				slot = get_widget_slotnum(0, widgetnum);
-				board = get_board_name(nasid, module, slot,
-								new_name);
-				/*
-			 	 * Create the vertex for the widget, 
-				 * using the decimal 
-			 	 * widgetnum as the name of the primary edge.
-			 	 */
-#ifdef SUPPORT_PRINTING_M_FORMAT
-				sprintf(pathname, EDGE_LBL_MODULE "/%M/"
-                                                EDGE_LBL_SLOT "/%s/%s",
-                                        NODEPDA(cnode)->module_id,
-                                        slotname, new_name);
-#else
-				memset(buffer, 0, 16);
-				format_module_id(buffer, NODEPDA(cnode)->module_id, MODULE_FORMAT_BRIEF);
-				sprintf(pathname, EDGE_LBL_MODULE "/%s/"
-					  	EDGE_LBL_SLOT "/%s/%s",
-					buffer,
-					slotname, new_name);
-#endif
-			}
-
-			rc = hwgraph_path_add(hwgraph_root, pathname, &widgetv);
-			DBG("io_xswitch_widget_init: (2) path= %s\n", pathname);
-		        /*
-		         * This is a weird ass code needed for error injection
-		         * purposes.
-		         */
-		        rc = device_master_set(hwgraph_connectpt_get(widgetv), hubv);
-			
-			klhwg_baseio_inventory_add(widgetv,cnode);
-		}
-		sprintf(name, "%d", widgetnum);
-		DBG("io_xswitch_widget_init: FIXME hwgraph_edge_add %s xswitchv 0x%p, widgetv 0x%p\n", name, xswitchv, widgetv);
-		rc = hwgraph_edge_add(xswitchv, widgetv, name);
-		
-		/*
-		 * crosstalk switch code tracks which
-		 * widget is attached to each link.
-		 */
-		xswitch_info_vhdl_set(xswitch_info, widgetnum, widgetv);
-		
-		/*
-		 * Peek at the widget to get its crosstalk part and
-		 * mfgr numbers, then present it to the generic xtalk
-		 * bus provider to have its driver attach routine
-		 * called (or not).
-		 */
-#ifdef XBRIDGE_REGS_SIM
-		widget_id = 0x2d000049;
-		DBG("io_xswitch_widget_init: XBRIDGE_REGS_SIM FIXME: id hardwired to widget_id\n");
-#else
-		widget_id = XWIDGET_ID_READ(nasid, widgetnum);
-#endif /* XBRIDGE_REGS_SIM */
-		hwid.part_num = XWIDGET_PART_NUM(widget_id);
-		hwid.rev_num = XWIDGET_REV_NUM(widget_id);
-		hwid.mfg_num = XWIDGET_MFG_NUM(widget_id);
-		/* Store some inventory information about
-		 * the xwidget in the hardware graph.
-		 */
-		xwidget_inventory_add(widgetv,board,hwid);
-		
-		(void)xwidget_register(&hwid, widgetv, widgetnum,
-				       hubv, hub_widgetid,
-				       aa);
-
-#ifdef	SN0_USE_BTE
-		bte_bpush_war(cnode, (void *)board);
-#endif
-	}
-
-}
-
-
-static void
-io_init_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnode)
-{
-	xwidgetnum_t		widgetnum;
-	async_attach_t          aa;
-
-	aa = async_attach_new();
-	
-	DBG("io_init_xswitch_widgets: xswitchv 0x%p for cnode %d\n", xswitchv, cnode);
-
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; 
-	     widgetnum++) {
-		io_xswitch_widget_init(xswitchv,
-				       cnodeid_to_vertex(cnode),
-				       widgetnum, aa);
-	}
-	/* 
-	 * Wait for parallel attach threads, if any, to complete.
-	 */
-	async_attach_waitall(aa);
-	async_attach_free(aa);
-}
-
-/*
- * For each PCI bridge connected to the xswitch, add a link from the
- * board's klconfig info to the bridge's hwgraph vertex.  This lets
- * the FRU analyzer find the bridge without traversing the hardware
- * graph and risking hangs.
- */
-static void
-io_link_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnodeid)
-{
-	xwidgetnum_t		widgetnum;
-	char 			pathname[128];
-	devfs_handle_t		vhdl;
-	nasid_t			nasid, peer_nasid;
-	lboard_t		*board;
-
-
-
-	/* And its connected hub's nasids */
-	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
-	peer_nasid = NODEPDA(cnodeid)->xbow_peer;
-
-	/* 
-	 * Look for paths matching "<widgetnum>/pci" under xswitchv.
-	 * For every widget, init. its lboard's hwgraph link.  If the
-	 * board has a PCI bridge, point the link to it.
-	 */
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX;
-		 widgetnum++) {
-		sprintf(pathname, "%d", widgetnum);
-		if (hwgraph_traverse(xswitchv, pathname, &vhdl) !=
-		    GRAPH_SUCCESS)
-			continue;
-
-		board = find_lboard_module((lboard_t *)KL_CONFIG_INFO(nasid),
-				NODEPDA(cnodeid)->module_id);
-		if (board == NULL && peer_nasid != INVALID_NASID) {
-			/*
-			 * Try to find the board on our peer
-			 */
-			board = find_lboard_module(
-				(lboard_t *)KL_CONFIG_INFO(peer_nasid),
-				NODEPDA(cnodeid)->module_id);
-		}
-		if (board == NULL) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-			printk(KERN_WARNING  "Could not find PROM info for vertex %v, "
-				"FRU analyzer may fail",
-				vhdl);
-#else
-			printk(KERN_WARNING  "Could not find PROM info for vertex 0x%p, "
-				"FRU analyzer may fail",
-				(void *)vhdl);
-#endif
-			return;
-		}
-
-		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
-		if (hwgraph_traverse(xswitchv, pathname, &vhdl) == 
-		    GRAPH_SUCCESS)
-			board->brd_graph_link = vhdl;
-		else
-			board->brd_graph_link = GRAPH_VERTEX_NONE;
-	}
-}
-
-/*
- * Initialize all I/O on the specified node.
- */
-static void
-io_init_node(cnodeid_t cnodeid)
-{
-	/*REFERENCED*/
-	devfs_handle_t hubv, switchv, widgetv;
-	struct xwidget_hwid_s hwid;
-	hubinfo_t hubinfo;
-	int is_xswitch;
-	nodepda_t	*npdap;
-	struct semaphore *peer_sema = 0;
-	uint32_t	widget_partnum;
-	nodepda_router_info_t *npda_rip;
-	cpu_cookie_t	c = 0;
-	extern int hubdev_docallouts(devfs_handle_t);
-
-#ifdef LATER
-	/* Try to execute on the node that we're initializing. */
-	c = setnoderun(cnodeid);
-#endif
-	npdap = NODEPDA(cnodeid);
-
-	/*
-	 * Get the "top" vertex for this node's hardware
-	 * graph; it will carry the per-hub hub-specific
-	 * data, and act as the crosstalk provider master.
-	 * It's canonical path is probably something of the
-	 * form /hw/module/%M/slot/%d/node
-	 */
-	hubv = cnodeid_to_vertex(cnodeid);
-	DBG("io_init_node: Initialize IO for cnode %d hubv(node) 0x%p npdap 0x%p\n", cnodeid, hubv, npdap);
-
-	ASSERT(hubv != GRAPH_VERTEX_NONE);
-
-	hubdev_docallouts(hubv);
-
-	/*
-	 * Set up the dependent routers if we have any.
-	 */
-	npda_rip = npdap->npda_rip_first;
-
-	while(npda_rip) {
-		/* If the router info has not been initialized
-		 * then we need to do the router initialization
-		 */
-		if (!npda_rip->router_infop) {
-			router_init(cnodeid,0,npda_rip);
-		}
-		npda_rip = npda_rip->router_next;
-	}
-
-	/*
-	 * Read mfg info on this hub
-	 */
-#ifdef LATER
-	printk("io_init_node: FIXME need to implement HUB_VERTEX_MFG_INFO\n");
-	HUB_VERTEX_MFG_INFO(hubv);
-#endif /* LATER */
-
-	/* 
-	 * If nothing connected to this hub's xtalk port, we're done.
-	 */
-	early_probe_for_widget(hubv, &hwid);
-	if (hwid.part_num == XWIDGET_PART_NUM_NONE) {
-#ifdef PROBE_TEST
-		if ((cnodeid == 1) || (cnodeid == 2)) {
-			int index;
-
-			for (index = 0; index < 600; index++)
-				DBG("Interfering with device probing!!!\n");
-		}
-#endif
-		/* io_init_done takes cpu cookie as 2nd argument 
-		 * to do a restorenoderun for the setnoderun done 
-		 * at the start of this thread 
-		 */
-		
-		DBG("**** io_init_node: Node's 0x%p hub widget has XWIDGET_PART_NUM_NONE ****\n", hubv);
-		return;
-		/* NOTREACHED */
-	}
-
-	/* 
-	 * attach our hub_provider information to hubv,
-	 * so we can use it as a crosstalk provider "master"
-	 * vertex.
-	 */
-	xtalk_provider_register(hubv, &hub_provider);
-	xtalk_provider_startup(hubv);
-
-	/*
-	 * Create a vertex to represent the crosstalk bus
-	 * attached to this hub, and a vertex to be used
-	 * as the connect point for whatever is out there
-	 * on the other side of our crosstalk connection.
-	 *
-	 * Crosstalk Switch drivers "climb up" from their
-	 * connection point to try and take over the switch
-	 * point.
-	 *
-	 * Of course, the edges and verticies may already
-	 * exist, in which case our net effect is just to
-	 * associate the "xtalk_" driver with the connection
-	 * point for the device.
-	 */
-
-	(void)hwgraph_path_add(hubv, EDGE_LBL_XTALK, &switchv);
-
-	DBG("io_init_node: Created 'xtalk' entry to '../node/' xtalk vertex 0x%p\n", switchv);
-
-	ASSERT(switchv != GRAPH_VERTEX_NONE);
-
-	(void)hwgraph_edge_add(hubv, switchv, EDGE_LBL_IO);
-
-	DBG("io_init_node: Created symlink 'io' from ../node/io to ../node/xtalk \n");
-
-	/*
-	 * We need to find the widget id and update the basew_id field
-	 * accordingly. In particular, SN00 has direct connected bridge,
-	 * and hence widget id is Not 0.
-	 */
-
-	widget_partnum = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + WIDGET_ID))) & WIDGET_PART_NUM) >> WIDGET_PART_NUM_SHFT;
-
-	if (widget_partnum == BRIDGE_WIDGET_PART_NUM ||
-				widget_partnum == XBRIDGE_WIDGET_PART_NUM){
-		npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID);
-
-		DBG("io_init_node: Found XBRIDGE widget_partnum= 0x%x\n", widget_partnum);
-
-	} else if (widget_partnum == XBOW_WIDGET_PART_NUM ||
-				widget_partnum == XXBOW_WIDGET_PART_NUM) {
-		/* 
-		 * Xbow control register does not have the widget ID field.
-		 * So, hard code the widget ID to be zero.
-		 */
-		DBG("io_init_node: Found XBOW widget_partnum= 0x%x\n", widget_partnum);
-		npdap->basew_id = 0;
-
-	} else if (widget_partnum == XG_WIDGET_PART_NUM) {
-		/* 
-		 * OK, WTF do we do here if we have an XG direct connected to a HUB/Bedrock???
-		 * So, hard code the widget ID to be zero?
-		 */
-		npdap->basew_id = 0;
-		npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID);
-	} else { 
-		npdap->basew_id = (((*(volatile int32_t *)(NODE_SWIN_BASE(COMPACT_TO_NASID_NODEID(cnodeid), 0) + BRIDGE_WID_CONTROL))) & WIDGET_WIDGET_ID);
-
-		panic(" ****io_init_node: Unknown Widget Part Number 0x%x Widgt ID 0x%x attached to Hubv 0x%p ****\n", widget_partnum, npdap->basew_id, (void *)hubv);
-
-		/*NOTREACHED*/
-	}
-	{
-		char widname[10];
-		sprintf(widname, "%x", npdap->basew_id);
-		(void)hwgraph_path_add(switchv, widname, &widgetv);
-		DBG("io_init_node: Created '%s' to '..node/xtalk/' vertex 0x%p\n", widname, widgetv);
-		ASSERT(widgetv != GRAPH_VERTEX_NONE);
-	}
-	
-	nodepda->basew_xc = widgetv;
-
-	is_xswitch = xwidget_hwid_is_xswitch(&hwid);
-
-	/* 
-	 * Try to become the master of the widget.  If this is an xswitch
-	 * with multiple hubs connected, only one will succeed.  Mastership
-	 * of an xswitch is used only when touching registers on that xswitch.
-	 * The slave xwidgets connected to the xswitch can be owned by various
-	 * masters.
-	 */
-	if (device_master_set(widgetv, hubv) == 0) {
-
-		/* Only one hub (thread) per Crosstalk device or switch makes
-		 * it to here.
-		 */
-
-		/* 
-		 * Initialize whatever xwidget is hanging off our hub.
-		 * Whatever it is, it's accessible through widgetnum 0.
-		 */
-		hubinfo_get(hubv, &hubinfo);
-
-		(void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid, NULL);
-
-		if (!is_xswitch) {
-			/* io_init_done takes cpu cookie as 2nd argument 
-			 * to do a restorenoderun for the setnoderun done 
-			 * at the start of this thread 
-			 */
-			io_init_done(cnodeid,c);
-			/* NOTREACHED */
-		}
-
-		/* 
-		 * Special handling for Crosstalk Switches (e.g. xbow).
-		 * We need to do things in roughly the following order:
-		 *	1) Initialize xswitch hardware (done above)
-		 *	2) Determine which hubs are available to be widget masters
-		 *	3) Discover which links are active from the xswitch
-		 *	4) Assign xwidgets hanging off the xswitch to hubs
-		 *	5) Initialize all xwidgets on the xswitch
-		 */
-
-		volunteer_for_widgets(switchv, hubv);
-
-		/* If there's someone else on this crossbow, recognize him */
-		if (npdap->xbow_peer != INVALID_NASID) {
-			nodepda_t *peer_npdap = NODEPDA(NASID_TO_COMPACT_NODEID(npdap->xbow_peer));
-			peer_sema = &peer_npdap->xbow_sema;
-			volunteer_for_widgets(switchv, peer_npdap->node_vertex);
-		}
-
-		assign_widgets_to_volunteers(switchv, hubv);
-
-		/* Signal that we're done */
-		if (peer_sema) {
-			mutex_unlock(peer_sema);
-		}
-		
-	}
-	else {
-	    /* Wait 'til master is done assigning widgets. */
-	    mutex_lock(&npdap->xbow_sema);
-	}
-
-#ifdef PROBE_TEST
-	if ((cnodeid == 1) || (cnodeid == 2)) {
-		int index;
-
-		for (index = 0; index < 500; index++)
-			DBG("Interfering with device probing!!!\n");
-	}
-#endif
-	/* Now both nodes can safely inititialize widgets */
-	io_init_xswitch_widgets(switchv, cnodeid);
-	io_link_xswitch_widgets(switchv, cnodeid);
-
-	/* io_init_done takes cpu cookie as 2nd argument 
-	 * to do a restorenoderun for the setnoderun done 
-	 * at the start of this thread 
-	 */
-	io_init_done(cnodeid,c);
-
-	DBG("\nio_init_node: DONE INITIALIZED ALL I/O FOR CNODEID %d\n\n", cnodeid);
-}
-
-
-#define IOINIT_STKSZ	(16 * 1024)
-
-#define __DEVSTR1 	"/../.master/"
-#define __DEVSTR2 	"/target/"
-#define __DEVSTR3 	"/lun/0/disk/partition/"
-#define	__DEVSTR4	"/../ef"
-
-#if defined(CONFIG_IA64_SGI_SN1)
-/*
- * Currently, we need to allow for 5 IBrick slots with 1 FC each
- * plus an internal 1394.
- *
- * ioconfig starts numbering SCSI's at NUM_BASE_IO_SCSI_CTLR.
- */
-#define NUM_BASE_IO_SCSI_CTLR 6
-#else
-#define NUM_BASE_IO_SCSI_CTLR 6
-#endif
-/*
- * This tells ioconfig where it can start numbering scsi controllers.
- * Below this base number, platform-specific handles the numbering.
- * XXX Irix legacy..controller numbering should be part of devfsd's job
- */
-int num_base_io_scsi_ctlr = 2; /* used by syssgi */
-devfs_handle_t		base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR];
-static devfs_handle_t	baseio_enet_vhdl,baseio_console_vhdl;
-
-/*
- * Put the logical controller number information in the 
- * scsi controller vertices for each scsi controller that
- * is in a "fixed position".
- */
-static void
-scsi_ctlr_nums_add(devfs_handle_t pci_vhdl)
-{
-	{
-		int i;
-
-		num_base_io_scsi_ctlr = NUM_BASE_IO_SCSI_CTLR;
-
-		/* Initialize base_io_scsi_ctlr_vhdl array */
-		for (i=0; i<NUM_BASE_IO_SCSI_CTLR; i++)
-			base_io_scsi_ctlr_vhdl[i] = GRAPH_VERTEX_NONE;
-	}
-	{
-	/*
-	 * May want to consider changing the SN0 code, above, to work more like
-	 * the way this works.
-	 */
-	devfs_handle_t base_ibrick_xbridge_vhdl;
-	devfs_handle_t base_ibrick_xtalk_widget_vhdl;
-	devfs_handle_t scsi_ctlr_vhdl;
-	int i;
-	graph_error_t rv;
-
-	/*
-	 * This is a table of "well-known" SCSI controllers and their well-known
-	 * controller numbers.  The names in the table start from the base IBrick's
-	 * Xbridge vertex, so the first component is the xtalk widget number.
-	 */
-	static struct {
-		char	*base_ibrick_scsi_path;
-		int	controller_number;
-	} hardwired_scsi_controllers[] = {
-		{"15/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 0},
-		{"15/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 1},
-		{"15/" EDGE_LBL_PCI "/3/" EDGE_LBL_SCSI_CTLR "/0", 2},
-		{"14/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 3},
-		{"14/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 4},
-		{"15/" EDGE_LBL_PCI "/6/ohci/0/" EDGE_LBL_SCSI_CTLR "/0", 5},
-		{NULL, -1} /* must be last */
-	};
-
-	base_ibrick_xtalk_widget_vhdl = hwgraph_connectpt_get(pci_vhdl);
-	ASSERT_ALWAYS(base_ibrick_xtalk_widget_vhdl != GRAPH_VERTEX_NONE);
-
-	base_ibrick_xbridge_vhdl = hwgraph_connectpt_get(base_ibrick_xtalk_widget_vhdl);
-	ASSERT_ALWAYS(base_ibrick_xbridge_vhdl != GRAPH_VERTEX_NONE);
-	hwgraph_vertex_unref(base_ibrick_xtalk_widget_vhdl);
-
-	/*
-	 * Iterate through the list of well-known SCSI controllers.
-	 * For each controller found, set it's controller number according
-	 * to the table.
-	 */
-	for (i=0; hardwired_scsi_controllers[i].base_ibrick_scsi_path != NULL; i++) {
-		rv = hwgraph_path_lookup(base_ibrick_xbridge_vhdl,
-			hardwired_scsi_controllers[i].base_ibrick_scsi_path, &scsi_ctlr_vhdl, NULL);
-
-		if (rv != GRAPH_SUCCESS) /* No SCSI at this path */
-			continue;
-
-		ASSERT(hardwired_scsi_controllers[i].controller_number < NUM_BASE_IO_SCSI_CTLR);
-		base_io_scsi_ctlr_vhdl[hardwired_scsi_controllers[i].controller_number] = scsi_ctlr_vhdl;
-		device_controller_num_set(scsi_ctlr_vhdl, hardwired_scsi_controllers[i].controller_number);
-		hwgraph_vertex_unref(scsi_ctlr_vhdl); /* (even though we're actually keeping a reference) */
-	}
-
-	hwgraph_vertex_unref(base_ibrick_xbridge_vhdl);
-	}
-}
-
-
-#include <asm/sn/ioerror_handling.h>
-devfs_handle_t		sys_critical_graph_root = GRAPH_VERTEX_NONE;
-
-/* Define the system critical vertices and connect them through
- * a canonical parent-child relationships for easy traversal
- * during io error handling.
- */
-static void
-sys_critical_graph_init(void)
-{
-	devfs_handle_t		bridge_vhdl,master_node_vhdl;
-	devfs_handle_t  		xbow_vhdl = GRAPH_VERTEX_NONE;
-	extern devfs_handle_t	hwgraph_root;
-	devfs_handle_t		pci_slot_conn;
-	int			slot;
-	devfs_handle_t		baseio_console_conn;
-
-	DBG("sys_critical_graph_init: FIXME.\n");
-	baseio_console_conn = hwgraph_connectpt_get(baseio_console_vhdl);
-
-	if (baseio_console_conn == NULL) {
-		return;
-	}
-
-	/* Get the vertex handle for the baseio bridge */
-	bridge_vhdl = device_master_get(baseio_console_conn);
-
-	/* Get the master node of the baseio card */
-	master_node_vhdl = cnodeid_to_vertex(
-				master_node_get(baseio_console_vhdl));
-	
-	/* Add the "root->node" part of the system critical graph */
-
-	sys_critical_graph_vertex_add(hwgraph_root,master_node_vhdl);
-
-	/* Check if we have a crossbow */
-	if (hwgraph_traverse(master_node_vhdl,
-			     EDGE_LBL_XTALK"/0",
-			     &xbow_vhdl) == GRAPH_SUCCESS) {
-		/* We have a crossbow.Add "node->xbow" part of the system 
-		 * critical graph.
-		 */
-		sys_critical_graph_vertex_add(master_node_vhdl,xbow_vhdl);
-		
-		/* Add "xbow->baseio bridge" of the system critical graph */
-		sys_critical_graph_vertex_add(xbow_vhdl,bridge_vhdl);
-
-		hwgraph_vertex_unref(xbow_vhdl);
-	} else 
-		/* We donot have a crossbow. Add "node->baseio_bridge"
-		 * part of the system critical graph.
-		 */
-		sys_critical_graph_vertex_add(master_node_vhdl,bridge_vhdl);
-
-	/* Add all the populated PCI slot vertices to the system critical
-	 * graph with the bridge vertex as the parent.
-	 */
-	for (slot = 0 ; slot < 8; slot++) {
-		char	slot_edge[10];
-
-		sprintf(slot_edge,"%d",slot);
-		if (hwgraph_traverse(bridge_vhdl,slot_edge, &pci_slot_conn)
-		    != GRAPH_SUCCESS)
-			continue;
-		sys_critical_graph_vertex_add(bridge_vhdl,pci_slot_conn);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	hwgraph_vertex_unref(bridge_vhdl);
-
-	/* Add the "ioc3 pci connection point  -> console ioc3" part 
-	 * of the system critical graph
-	 */
-
-	if (hwgraph_traverse(baseio_console_vhdl,"..",&pci_slot_conn) ==
-	    GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      baseio_console_vhdl);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	/* Add the "ethernet pci connection point  -> base ethernet" part of 
-	 * the system  critical graph
-	 */
-	if (hwgraph_traverse(baseio_enet_vhdl,"..",&pci_slot_conn) ==
-	    GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      baseio_enet_vhdl);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	/* Add the "scsi controller pci connection point  -> base scsi 
-	 * controller" part of the system critical graph
-	 */
-	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[0],
-			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      base_io_scsi_ctlr_vhdl[0]);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[1],
-			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      base_io_scsi_ctlr_vhdl[1]);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-	hwgraph_vertex_unref(baseio_console_conn);
-
-}
-
-static void
-baseio_ctlr_num_set(void)
-{
-	char 			name[MAXDEVNAME];
-	devfs_handle_t		console_vhdl, pci_vhdl, enet_vhdl;
-	devfs_handle_t		ioc3_console_vhdl_get(void);
-
-
-	DBG("baseio_ctlr_num_set; FIXME\n");
-	console_vhdl = ioc3_console_vhdl_get();
-	if (console_vhdl == GRAPH_VERTEX_NONE)
-		return;
-	/* Useful for setting up the system critical graph */
-	baseio_console_vhdl = console_vhdl;
-
-	vertex_to_name(console_vhdl,name,MAXDEVNAME);
-
-	strcat(name,__DEVSTR1);
-	pci_vhdl =  hwgraph_path_to_vertex(name);
-	scsi_ctlr_nums_add(pci_vhdl);
-	/* Unref the pci_vhdl due to the reference by hwgraph_path_to_vertex
-	 */
-	hwgraph_vertex_unref(pci_vhdl);
-
-	vertex_to_name(console_vhdl, name, MAXDEVNAME);
-	strcat(name, __DEVSTR4);
-	enet_vhdl = hwgraph_path_to_vertex(name);
-
-	/* Useful for setting up the system critical graph */
-	baseio_enet_vhdl = enet_vhdl;
-
-	device_controller_num_set(enet_vhdl, 0);
-	/* Unref the enet_vhdl due to the reference by hwgraph_path_to_vertex
-	 */
-	hwgraph_vertex_unref(enet_vhdl);
-}
-/* #endif */
-
-void
-sn00_rrb_alloc(devfs_handle_t vhdl, int *vendor_list)
-{
-	/* REFERENCED */
-	int rtn_val;
-
-	/* 
-	** sn00 population:		errb	orrb
-	**	0- ql			3+?
-	**	1- ql			        2
-	**	2- ioc3 ethernet	2+?
-	**	3- ioc3 secondary	        1
-	**	4-                      0
-	** 	5- PCI slot
-	** 	6- PCI slot
-	** 	7- PCI slot
-	*/	
-	
-	/* The following code implements this heuristic for getting 
-	 * maximum usage out of the rrbs
-	 *
-	 * constraints:
-	 *  8 bit ql1 needs 1+1
-	 *  ql0 or ql5,6,7 wants 1+2
-	 *  ethernet wants 2 or more
-	 *
-	 * rules for even rrbs:
-	 *  if nothing in slot 6 
-	 *   4 rrbs to 0 and 2  (0xc8889999)
-	 *  else 
-         *   3 2 3 to slots 0 2 6  (0xc8899bbb)
-	 *
-         * rules for odd rrbs
-	 *  if nothing in slot 5 or 7  (0xc8889999)
-	 *   4 rrbs to 1 and 3
-	 *  else if 1 thing in 5 or 7  (0xc8899aaa) or (0xc8899bbb)
-         *   3 2 3 to slots 1 3 5|7
-         *  else
-         *   2 1 3 2 to slots 1 3 5 7 (note: if there's a ql card in 7 this
-	 *           (0xc89aaabb)      may short what it wants therefore the
-	 *			       rule should be to plug pci slots in order)
-	 */
-
-
-	if (vendor_list[6] != PCIIO_VENDOR_ID_NONE) {
-		/* something in slot 6 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 3,1, 2,0, 0,0, 3,0);
-	}
-	else {
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 0, 4,1, 4,0, 0,0, 0,0);
-	}
-	if (rtn_val)
-		printk(KERN_WARNING  "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
-
-	if ((vendor_list[5] != PCIIO_VENDOR_ID_NONE) && 
-	    (vendor_list[7] != PCIIO_VENDOR_ID_NONE)) {
-		/* soemthing in slot 5 and 7 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 2,1, 1,0, 3,0, 2,0);
-	}
-	else if (vendor_list[5] != PCIIO_VENDOR_ID_NONE) {
-		/* soemthing in slot 5 but not 7 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 3,0, 0,0);
-	}
-	else if (vendor_list[7] != PCIIO_VENDOR_ID_NONE) {
-		/* soemthing in slot 7 but not 5 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 3,1, 2,0, 0,0, 3,0);
-	}
-	else {
-		/* nothing in slot 5 or 7 */
-		rtn_val = pcibr_alloc_all_rrbs(vhdl, 1, 4,1, 4,0, 0,0, 0,0);
-	}
-	if (rtn_val)
-		printk(KERN_WARNING  "sn00_rrb_alloc: pcibr_alloc_all_rrbs failed");
-}
-
-
-/*
- * Initialize all I/O devices.  Starting closest to nodes, probe and
- * initialize outward.
- */
-void
-init_all_devices(void)
-{
-	/* Governor on init threads..bump up when safe 
-	 * (beware many devfs races) 
-	 */
-#ifdef LATER
-	int io_init_node_threads = 2;	
-#endif
-	cnodeid_t cnodeid, active;
-
-#ifdef LINUX_KERNEL_THREADS
-	sema_init(&io_init_sema, 0);
-#endif
-
-	active = 0;
-	for (cnodeid = 0; cnodeid < numnodes; cnodeid++) {
-#ifdef LINUX_KERNEL_THREADS
-		char thread_name[16];
-		extern int io_init_pri;
-
-		/*
-		 * Spawn a service thread for each node to initialize all
-		 * I/O on that node.  Each thread attempts to bind itself 
-		 * to the node whose I/O it's initializing.
-		 */
-		sprintf(thread_name, "IO_init[%d]", cnodeid);
-
-		(void)sthread_create(thread_name, 0, IOINIT_STKSZ, 0,
-			io_init_pri, KT_PS, (st_func_t *)io_init_node,
-			(void *)(long)cnodeid, 0, 0, 0);
-#else
-                DBG("init_all_devices: Calling io_init_node() for cnode %d\n", cnodeid);
-                io_init_node(cnodeid);
-
-		DBG("init_all_devices: Done io_init_node() for cnode %d\n", cnodeid);
-
-#endif /* LINUX_KERNEL_THREADS */
-
-#ifdef LINUX_KERNEL_THREADS
-		/* Limit how many nodes go at once, to not overload hwgraph */
-		/* TBD: Should timeout */
-		DBG("started thread for cnode %d\n", cnodeid);
-		active++;
-		if (io_init_node_threads && 
-			active >= io_init_node_threads) {
-			down(&io_init_sema);
-			active--;
-		}
-#endif /* LINUX_KERNEL_THREADS */
-	}
-
-#ifdef LINUX_KERNEL_THREADS
-	/* Wait until all IO_init threads are done */
-
-	while (active > 0) {
-#ifdef AA_DEBUG
-	    DBG("waiting, %d still active\n", active);
-#endif
-	    down(&io_init_sema);
-	    active--;
-	}
-
-#endif /* LINUX_KERNEL_THREADS */
-
-	for (cnodeid = 0; cnodeid < numnodes; cnodeid++)
-		/*
-	 	 * Update information generated by IO init.
-		 */
-		update_node_information(cnodeid);
-
-	baseio_ctlr_num_set();
-	/* Setup the system critical graph (which is a subgraph of the
-	 * main hwgraph). This information is useful during io error
-	 * handling.
-	 */
-	sys_critical_graph_init();
-
-#if HWG_PRINT
-	hwgraph_print();
-#endif
-
-}
-
-#define toint(x) ((int)(x) - (int)('0'))
-
-void
-devnamefromarcs(char *devnm)
-{
-	int 			val;
-	char 			tmpnm[MAXDEVNAME];
-	char 			*tmp1, *tmp2;
-	
-	val = strncmp(devnm, "dks", 3);
-	if (val != 0) 
-		return;
-	tmp1 = devnm + 3;
-	if (!isdigit(*tmp1))
-		return;
-
-	val = 0;
-	while (isdigit(*tmp1)) {
-		val = 10*val+toint(*tmp1);
-		tmp1++;
-	}
-
-	if(*tmp1 != 'd')
-		return;
-	else
-		tmp1++;
-
-	if ((val < 0) || (val >= NUM_BASE_IO_SCSI_CTLR)) {
-		int i;
-		int viable_found = 0;
-
-		DBG("Only controller numbers 0..%d  are supported for\n", NUM_BASE_IO_SCSI_CTLR-1);
-		DBG("prom \"root\" variables of the form dksXdXsX.\n");
-		DBG("To use another disk you must use the full hardware graph path\n\n");
-		DBG("Possible controller numbers for use in 'dksXdXsX' on this system: ");
-		for (i=0; i<NUM_BASE_IO_SCSI_CTLR; i++) {
-			if (base_io_scsi_ctlr_vhdl[i] != GRAPH_VERTEX_NONE) {
-				DBG("%d ", i);
-				viable_found=1;
-			}
-		}
-		if (viable_found)
-			DBG("\n");
-		else
-			DBG("none found!\n");
-
-#ifdef LATER
-		if (kdebug)
-			debug("ring");
-#endif
-		DELAY(15000000);
-		//prom_reboot();
-		panic("FIXME: devnamefromarcs: should call prom_reboot here.\n");
-		/* NOTREACHED */
-	}
-		
-	ASSERT(base_io_scsi_ctlr_vhdl[val] != GRAPH_VERTEX_NONE);
-	vertex_to_name(base_io_scsi_ctlr_vhdl[val],
-		       tmpnm,
-		       MAXDEVNAME);
-	tmp2 = 	tmpnm + strlen(tmpnm);
-	strcpy(tmp2, __DEVSTR2);
-	tmp2 += strlen(__DEVSTR2);
-	while (*tmp1 != 's') {
-		if((*tmp2++ = *tmp1++) == '\0')
-			return;
-	}	
-	tmp1++;
-	strcpy(tmp2, __DEVSTR3);
-	tmp2 += strlen(__DEVSTR3);
-	while ( (*tmp2++ = *tmp1++) )
-		;
-	tmp2--;
-	*tmp2++ = '/';
-	strcpy(tmp2, EDGE_LBL_BLOCK);
-	strcpy(devnm,tmpnm);
-}
-
-static
-struct io_brick_map_s io_brick_tab[] = {
-
-/* Ibrick widget number to PCI bus number map */
-  {
-        'I',                                    /* Ibrick type    */ 
-    /*  PCI Bus #                                  Widget #       */
-     {  0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
-        0,                                      /* 0x8            */
-        0,                                      /* 0x9            */
-        0, 0,                                   /* 0xa - 0xb      */
-        0,                                      /* 0xc            */
-        0,                                      /* 0xd            */
-        2,                                      /* 0xe            */
-        1                                       /* 0xf            */
-     }
-  },
-
-/* Pbrick widget number to PCI bus number map */
-  {
-        'P',                                    /* Pbrick type    */ 
-    /*  PCI Bus #                                  Widget #       */
-     {  0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
-        2,                                      /* 0x8            */
-        1,                                      /* 0x9            */
-        0, 0,                                   /* 0xa - 0xb      */
-        5,                                      /* 0xc            */
-        6,                                      /* 0xd            */
-        4,                                      /* 0xe            */
-        3                                       /* 0xf            */
-     }
-  },
-
-/* Xbrick widget to XIO slot map */
-  {
-        'X',                                    /* Xbrick type    */ 
-    /*  XIO Slot #                                 Widget #       */
-     {  0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
-        1,                                      /* 0x8            */
-        2,                                      /* 0x9            */
-        0, 0,                                   /* 0xa - 0xb      */
-        3,                                      /* 0xc            */
-        4,                                      /* 0xd            */
-        0,                                      /* 0xe            */
-        0                                       /* 0xf            */
-     }
-  }
-};
-
-/*
- * Use the brick's type to map a widget number to a meaningful int
- */
-int
-io_brick_map_widget(char brick_type, int widget_num)
-{
-        int num_bricks, i;
-
-        /* Calculate number of bricks in table */
-        num_bricks = sizeof(io_brick_tab)/sizeof(io_brick_tab[0]);
-
-        /* Look for brick prefix in table */
-        for (i = 0; i < num_bricks; i++) {
-               if (brick_type == io_brick_tab[i].ibm_type)
-                       return(io_brick_tab[i].ibm_map_wid[widget_num]);
-        }
-
-        return 0;
-
-}
-
-/*
- * Use the device's vertex to map the device's widget to a meaningful int
- */
-int
-io_path_map_widget(devfs_handle_t vertex)
-{
-        char hw_path_name[MAXDEVNAME];
-        char *wp, *bp, *sp = NULL;
-        int  widget_num;
-	long atoi(char *);
-	int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen);
-
-
-        /* Get the full path name of the vertex */
-        if (GRAPH_SUCCESS != hwgraph_vertex_name_get(vertex, hw_path_name,
-                                                     MAXDEVNAME))
-                return 0;
-
-        /* Find the widget number in the path name */
-        wp = strstr(hw_path_name, "/"EDGE_LBL_XTALK"/");
-        if (wp == NULL)
-                return 0;
-        widget_num = atoi(wp+7);
-        if (widget_num < XBOW_PORT_8 || widget_num > XBOW_PORT_F)
-                return 0;
-
-        /* Find "brick" in the path name */
-        bp = strstr(hw_path_name, "brick");
-        if (bp == NULL)
-                return 0;
-
-        /* Find preceding slash */
-        sp = bp;
-        while (sp > hw_path_name) {
-                sp--;
-                if (*sp == '/')
-                        break;
-        }
-
-        /* Invalid if no preceding slash */
-        if (!sp)
-                return 0;
-
-        /* Bump slash pointer to "brick" prefix */
-        sp++;
-        /*
-         * Verify "brick" prefix length;  valid exaples:
-         * 'I' from "/Ibrick"
-         * 'P' from "/Pbrick"
-         * 'X' from "/Xbrick"
-         */
-         if ((bp - sp) != 1)
-                return 0;
-
-        return (io_brick_map_widget(*sp, widget_num));
-
-}
diff -Nru a/arch/ia64/sn/io/module.c b/arch/ia64/sn/io/module.c
--- a/arch/ia64/sn/io/module.c	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,312 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn1/hubdev.h>
-#include <asm/sn/module.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/sn_cpuid.h>
-
-
-/* #define LDEBUG	1 */
-
-#ifdef LDEBUG
-#define DPRINTF		printk
-#define printf		printk
-#else
-#define DPRINTF(x...)
-#endif
-
-module_t	       *modules[MODULE_MAX];
-int			nummodules;
-
-#define SN00_SERIAL_FUDGE	0x3b1af409d513c2
-#define SN0_SERIAL_FUDGE	0x6e
-
-void
-encode_int_serial(uint64_t src,uint64_t *dest)
-{
-    uint64_t val;
-    int i;
-
-    val = src + SN00_SERIAL_FUDGE;
-
-
-    for (i = 0; i < sizeof(long long); i++) {
-	((char*)dest)[i] =
-	    ((char*)&val)[sizeof(long long)/2 +
-			 ((i%2) ? ((i/2 * -1) - 1) : (i/2))];
-    }
-}
-
-
-void
-decode_int_serial(uint64_t src, uint64_t *dest)
-{
-    uint64_t val;
-    int i;
-
-    for (i = 0; i < sizeof(long long); i++) {
-	((char*)&val)[sizeof(long long)/2 +
-		     ((i%2) ? ((i/2 * -1) - 1) : (i/2))] =
-	    ((char*)&src)[i];
-    }
-
-    *dest = val - SN00_SERIAL_FUDGE;
-}
-
-
-void
-encode_str_serial(const char *src, char *dest)
-{
-    int i;
-
-    for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) {
-
-	dest[i] = src[MAX_SERIAL_NUM_SIZE/2 +
-		     ((i%2) ? ((i/2 * -1) - 1) : (i/2))] +
-	    SN0_SERIAL_FUDGE;
-    }
-}
-
-void
-decode_str_serial(const char *src, char *dest)
-{
-    int i;
-
-    for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++) {
-	dest[MAX_SERIAL_NUM_SIZE/2 +
-	    ((i%2) ? ((i/2 * -1) - 1) : (i/2))] = src[i] -
-	    SN0_SERIAL_FUDGE;
-    }
-}
-
-
-module_t *module_lookup(moduleid_t id)
-{
-    int			i;
-
-    for (i = 0; i < nummodules; i++)
-	if (modules[i]->id == id) {
-	    DPRINTF("module_lookup: found m=0x%p\n", modules[i]);
-	    return modules[i];
-	}
-
-    return NULL;
-}
-
-/*
- * module_add_node
- *
- *   The first time a new module number is seen, a module structure is
- *   inserted into the module list in order sorted by module number
- *   and the structure is initialized.
- *
- *   The node number is added to the list of nodes in the module.
- */
-
-module_t *module_add_node(moduleid_t id, cnodeid_t n)
-{
-    module_t	       *m;
-    int			i;
-    char		buffer[16];
-
-#ifdef __ia64
-    memset(buffer, 0, 16);
-    format_module_id(buffer, id, MODULE_FORMAT_BRIEF);
-    DPRINTF("module_add_node: id=%s node=%d\n", buffer, n);
-#endif
-
-    if ((m = module_lookup(id)) == 0) {
-#ifdef LATER
-	m = kmem_zalloc_node(sizeof (module_t), KM_NOSLEEP, n);
-#else
-	m = kmalloc(sizeof (module_t), GFP_KERNEL);
-	memset(m, 0 , sizeof(module_t));
-#endif
-	ASSERT_ALWAYS(m);
-
-	m->id = id;
-	spin_lock_init(&m->lock);
-
-	mutex_init_locked(&m->thdcnt);
-
-// set_elsc(&m->elsc);
-	elsc_init(&m->elsc, COMPACT_TO_NASID_NODEID(n));
-	spin_lock_init(&m->elsclock);
-
-	/* Insert in sorted order by module number */
-
-	for (i = nummodules; i > 0 && modules[i - 1]->id > id; i--)
-	    modules[i] = modules[i - 1];
-
-	modules[i] = m;
-	nummodules++;
-    }
-
-    m->nodes[m->nodecnt++] = n;
-
-    DPRINTF("module_add_node: module %s now has %d nodes\n", buffer, m->nodecnt);
-
-    return m;
-}
-
-int module_probe_snum(module_t *m, nasid_t nasid)
-{
-    lboard_t	       *board;
-    klmod_serial_num_t *comp;
-    char * bcopy(const char * src, char * dest, int count);
-    char serial_number[16];
-
-    /*
-     * record brick serial number
-     */
-    board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-
-    if (! board || KL_CONFIG_DUPLICATE_BOARD(board))
-    {
-#if	LDEBUG
-	printf ("module_probe_snum: no IP35 board found!\n");
-#endif
-	return 0;
-    }
-
-    board_serial_number_get( board, serial_number );
-    if( serial_number[0] != '\0' ) {
-	encode_str_serial( serial_number, m->snum.snum_str );
-	m->snum_valid = 1;
-    }
-#if	LDEBUG
-    else {
-	printf("module_probe_snum: brick serial number is null!\n");
-    }
-    printf("module_probe_snum: brick serial number == %s\n", serial_number);
-#endif /* DEBUG */
-
-    board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid),
-			KLTYPE_IOBRICK_XBOW);
-
-    if (! board || KL_CONFIG_DUPLICATE_BOARD(board))
-	return 0;
-
-    comp = GET_SNUM_COMP(board);
-
-    if (comp) {
-#if LDEBUG
-	    int i;
-
-	    printf("********found module with id %x and string", m->id);
-
-	    for (i = 0; i < MAX_SERIAL_NUM_SIZE; i++)
-		printf(" %x ", comp->snum.snum_str[i]);
-
-	    printf("\n");	/* Fudged string is not ASCII */
-#endif
-
-	    if (comp->snum.snum_str[0] != '\0') {
-		bcopy(comp->snum.snum_str,
-		      m->sys_snum,
-		      MAX_SERIAL_NUM_SIZE);
-		m->sys_snum_valid = 1;
-	    }
-    }
-
-    if (m->sys_snum_valid)
-	return 1;
-    else {
-	DPRINTF("Invalid serial number for module %d, "
-		"possible missing or invalid NIC.", m->id);
-	return 0;
-    }
-}
-
-void
-io_module_init(void)
-{
-    cnodeid_t		node;
-    lboard_t	       *board;
-    nasid_t		nasid;
-    int			nserial;
-    module_t	       *m;
-
-    DPRINTF("*******module_init\n");
-
-    nserial = 0;
-
-    for (node = 0; node < numnodes; node++) {
-	nasid = COMPACT_TO_NASID_NODEID(node);
-
-	board = find_lboard((lboard_t *) KL_CONFIG_INFO(nasid), KLTYPE_SNIA);
-	ASSERT(board);
-
-	m = module_add_node(board->brd_module, node);
-
-	if (! m->snum_valid && module_probe_snum(m, nasid))
-	    nserial++;
-    }
-
-    DPRINTF("********found total of %d serial numbers in the system\n",
-	    nserial);
-
-    if (nserial == 0)
-	printk(KERN_WARNING  "io_module_init: No serial number found.\n");
-}
-
-elsc_t *get_elsc(void)
-{
-	return &NODEPDA(cpuid_to_cnodeid(smp_processor_id()))->module->elsc;
-}
-
-int
-get_kmod_info(cmoduleid_t cmod, module_info_t *mod_info)
-{
-    int i;
-
-    if (cmod < 0 || cmod >= nummodules)
-	return EINVAL;
-
-    if (! modules[cmod]->snum_valid)
-	return ENXIO;
-
-    mod_info->mod_num = modules[cmod]->id;
-    {
-	char temp[MAX_SERIAL_NUM_SIZE];
-
-	decode_str_serial(modules[cmod]->snum.snum_str, temp);
-
-	/* if this is an invalid serial number return an error */
-	if (temp[0] != 'K')
-	    return ENXIO;
-
-	mod_info->serial_num = 0;
-
-	for (i = 0; i < MAX_SERIAL_NUM_SIZE && temp[i] != '\0'; i++) {
-	    mod_info->serial_num <<= 4;
-	    mod_info->serial_num |= (temp[i] & 0xf);
-
-	    mod_info->serial_str[i] = temp[i];
-	}
-
-	mod_info->serial_str[i] = '\0';
-    }
-
-    return 0;
-}
diff -Nru a/arch/ia64/sn/io/pci.c b/arch/ia64/sn/io/pci.c
--- a/arch/ia64/sn/io/pci.c	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,294 +0,0 @@
-/* 
- *
- * SNI64 specific PCI support for SNI IO.
- *
- * 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) 1997, 1998, 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <asm/sn/types.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/iograph.h>
-#include <asm/param.h>
-#include <asm/sn/pio.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/bridge.h>
-
-#ifdef DEBUG_CONFIG
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif
-
-
-
-#ifdef CONFIG_PCI
-
-extern devfs_handle_t pci_bus_to_vertex(unsigned char);
-extern devfs_handle_t devfn_to_vertex(unsigned char bus, unsigned char devfn);
-
-/*
- * snia64_read_config_byte - Read a byte from the config area of the device.
- */
-static int snia64_read_config_byte (struct pci_dev *dev,
-                                   int where, unsigned char *val)
-{
-	unsigned long res = 0;
-	unsigned size = 1;
-	devfs_handle_t device_vertex;
-
-	if ( (dev == (struct pci_dev *)0) || (val == (unsigned char *)0) ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	res = pciio_config_get(device_vertex, (unsigned) where, size);
-	*val = (unsigned char) res;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-/*
- * snia64_read_config_word - Read 2 bytes from the config area of the device.
- */
-static int snia64_read_config_word (struct pci_dev *dev,
-                                   int where, unsigned short *val)
-{
-	unsigned long res = 0;
-	unsigned size = 2; /* 2 bytes */
-	devfs_handle_t device_vertex;
-
-	if ( (dev == (struct pci_dev *)0) || (val == (unsigned short *)0) ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	res = pciio_config_get(device_vertex, (unsigned) where, size);
-	*val = (unsigned short) res;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-/*
- * snia64_read_config_dword - Read 4 bytes from the config area of the device.
- */
-static int snia64_read_config_dword (struct pci_dev *dev,
-                                    int where, unsigned int *val)
-{
-	unsigned long res = 0;
-	unsigned size = 4; /* 4 bytes */
-	devfs_handle_t device_vertex;
-
-	if (where & 3) {
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-	if ( (dev == (struct pci_dev *)0) || (val == (unsigned int *)0) ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	res = pciio_config_get(device_vertex, (unsigned) where, size);
-	*val = (unsigned int) res;
-	return PCIBIOS_SUCCESSFUL;
-}
-
-/*
- * snia64_write_config_byte - Writes 1 byte to the config area of the device.
- */
-static int snia64_write_config_byte (struct pci_dev *dev,
-                                    int where, unsigned char val)
-{
-	devfs_handle_t device_vertex;
-
-	if ( dev == (struct pci_dev *)0 ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	/* 
-	 * if it's an IOC3 then we bail out, we special
-	 * case them with pci_fixup_ioc3
-	 */
-	if (dev->vendor == PCI_VENDOR_ID_SGI && 
-	    dev->device == PCI_DEVICE_ID_SGI_IOC3 )
-		return PCIBIOS_SUCCESSFUL;
-
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	pciio_config_set( device_vertex, (unsigned)where, 1, (uint64_t) val);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-/*
- * snia64_write_config_word - Writes 2 bytes to the config area of the device.
- */
-static int snia64_write_config_word (struct pci_dev *dev,
-                                    int where, unsigned short val)
-{
-	devfs_handle_t device_vertex = NULL;
-
-	if (where & 1) {
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-	if ( dev == (struct pci_dev *)0 ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	/* 
-	 * if it's an IOC3 then we bail out, we special
-	 * case them with pci_fixup_ioc3
-	 */
-	if (dev->vendor == PCI_VENDOR_ID_SGI && 
-	    dev->device == PCI_DEVICE_ID_SGI_IOC3)
-		return PCIBIOS_SUCCESSFUL;
-
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	pciio_config_set( device_vertex, (unsigned)where, 2, (uint64_t) val);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-/*
- * snia64_write_config_dword - Writes 4 bytes to the config area of the device.
- */
-static int snia64_write_config_dword (struct pci_dev *dev,
-                                     int where, unsigned int val)
-{
-	devfs_handle_t device_vertex;
-
-	if (where & 3) {
-		return PCIBIOS_BAD_REGISTER_NUMBER;
-	}
-	if ( dev == (struct pci_dev *)0 ) {
-		return PCIBIOS_DEVICE_NOT_FOUND;
-	}
-	/* 
-	 * if it's an IOC3 then we bail out, we special
-	 * case them with pci_fixup_ioc3
-	 */
-	if (dev->vendor == PCI_VENDOR_ID_SGI && 
-	    dev->device == PCI_DEVICE_ID_SGI_IOC3)
-		return PCIBIOS_SUCCESSFUL;
-
-	device_vertex = devfn_to_vertex(dev->bus->number, dev->devfn);
-	if (!device_vertex) {
-		DBG("%s : nonexistent device: bus= 0x%x  slot= 0x%x  func= 0x%x\n", 
-		__FUNCTION__, dev->bus->number, PCI_SLOT(dev->devfn), PCI_FUNC(dev->devfn));
-		return(-1);
-	}
-	pciio_config_set( device_vertex, (unsigned)where, 4, (uint64_t) val);
-
-	return PCIBIOS_SUCCESSFUL;
-}
-
-static struct pci_ops snia64_pci_ops = {
-	snia64_read_config_byte,
-	snia64_read_config_word,
-	snia64_read_config_dword,
-	snia64_write_config_byte,
-	snia64_write_config_word,
-	snia64_write_config_dword
-};
-
-/*
- * snia64_pci_find_bios - SNIA64 pci_find_bios() platform specific code.
- */
-void __init
-sn_pci_find_bios(void)
-{
-	extern struct pci_ops *pci_root_ops;
-	/*
-	 * Go initialize our IO Infrastructure ..
-	 */
-	extern void sgi_master_io_infr_init(void);
-
-	sgi_master_io_infr_init();
-
-	/* sn_io_infrastructure_init(); */
-	pci_root_ops = &snia64_pci_ops;
-}
-
-void
-pci_fixup_ioc3(struct pci_dev *d)
-{
-        int 		i;
-	unsigned int 	size;
-
-        /* IOC3 only decodes 0x20 bytes of the config space, reading
-	 * beyond that is relatively benign but writing beyond that
-	 * (especially the base address registers) will shut down the
-	 * pci bus...so avoid doing so.
-	 * NOTE: this means we can't program the intr_pin into the device,
-	 *       currently we hack this with special code in 
-	 *	 sgi_pci_intr_support()
-	 */
-        DBG("pci_fixup_ioc3: Fixing base addresses for ioc3 device %s\n", d->slot_name);
-
-	/* I happen to know from the spec that the ioc3 needs only 0xfffff 
-	 * The standard pci trick of writing ~0 to the baddr and seeing
-	 * what comes back doesn't work with the ioc3
-	 */
-	size = 0xfffff;
-	d->resource[0].end = (unsigned long) d->resource[0].start + (unsigned long) size;
-
-	/*
-	 * Zero out the resource structure .. because we did not go through 
-	 * the normal PCI Infrastructure Init, garbbage are left in these 
-	 * fileds.
-	 */
-        for (i = 1; i <= PCI_ROM_RESOURCE; i++) {
-                d->resource[i].start = 0UL;
-                d->resource[i].end = 0UL;
-                d->resource[i].flags = 0UL;
-        }
-
-#ifdef CONFIG_IA64_SGI_SN1
-	*(volatile u32 *)0xc0000a000f000220 |= 0x90000;
-#endif
-        d->subsystem_vendor = 0;
-        d->subsystem_device = 0;
-
-}
-
-#else
-void sn_pci_find_bios(void) {}
-void pci_fixup_ioc3(struct pci_dev *d) {}
-struct list_head pci_root_buses;
-struct list_head pci_root_buses;
-struct list_head pci_devices;
-
-#endif /* CONFIG_PCI */
diff -Nru a/arch/ia64/sn/io/pci_bus_cvlink.c b/arch/ia64/sn/io/pci_bus_cvlink.c
--- a/arch/ia64/sn/io/pci_bus_cvlink.c	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,737 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <asm/sn/types.h>
-#include <asm/sn/hack.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/iograph.h>
-#include <asm/param.h>
-#include <asm/sn/pio.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/xtalk/xtalkaddrs.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/sn_cpuid.h>
-
-extern int bridge_rev_b_data_check_disable;
-
-devfs_handle_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET];
-nasid_t busnum_to_nid[MAX_PCI_XWIDGET];
-void * busnum_to_atedmamaps[MAX_PCI_XWIDGET];
-unsigned char num_bridges;
-static int done_probing = 0;
-
-static int pci_bus_map_create(devfs_handle_t xtalk);
-devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn);
-
-#define SN1_IOPORTS_UNIT 256
-#define MAX_IOPORTS 0xffff
-#define MAX_IOPORTS_CHUNKS (MAX_IOPORTS / SN1_IOPORTS_UNIT)
-struct ioports_to_tlbs_s ioports_to_tlbs[MAX_IOPORTS_CHUNKS];
-unsigned long sn1_allocate_ioports(unsigned long pci_address);
-
-extern void sn1_init_irq_desc(void);
-
-
-
-/*
- * pci_bus_cvlink_init() - To be called once during initialization before 
- *	SGI IO Infrastructure init is called.
- */
-void
-pci_bus_cvlink_init(void)
-{
-	memset(busnum_to_pcibr_vhdl, 0x0, sizeof(devfs_handle_t) * MAX_PCI_XWIDGET);
-	memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET);
-
-	memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET);
-
-	memset(ioports_to_tlbs, 0x0, sizeof(ioports_to_tlbs));
-
-	num_bridges = 0;
-}
-
-/*
- * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated 
- *	pci bus vertex from the SGI IO Infrastructure.
- */
-devfs_handle_t
-pci_bus_to_vertex(unsigned char busnum)
-{
-
-	devfs_handle_t	pci_bus = NULL;
-
-
-	/*
-	 * First get the xwidget vertex.
-	 */
-	pci_bus = busnum_to_pcibr_vhdl[busnum];
-	return(pci_bus);
-}
-
-/*
- * devfn_to_vertex() - returns the vertex of the device given the bus, slot, 
- *	and function numbers.
- */
-devfs_handle_t
-devfn_to_vertex(unsigned char busnum, unsigned int devfn)
-{
-
-	int slot = 0;
-	int func = 0;
-	char	name[16];
-	devfs_handle_t  pci_bus = NULL;
-	devfs_handle_t	device_vertex = (devfs_handle_t)NULL;
-
-	/*
-	 * Go get the pci bus vertex.
-	 */
-	pci_bus = pci_bus_to_vertex(busnum);
-	if (!pci_bus) {
-		/*
-		 * During probing, the Linux pci code invents non-existent
-		 * bus numbers and pci_dev structures and tries to access
-		 * them to determine existence. Don't crib during probing.
-		 */
-		if (done_probing)
-			printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum);
-		return(NULL);
-	}
-
-
-	/*
-	 * Go get the slot&function vertex.
-	 * Should call pciio_slot_func_to_name() when ready.
-	 */
-	slot = PCI_SLOT(devfn);
-	func = PCI_FUNC(devfn);
-
-	/*
-	 * For a NON Multi-function card the name of the device looks like:
-	 * ../pci/1, ../pci/2 ..
-	 */
-	if (func == 0) {
-        	sprintf(name, "%d", slot);
-		if (hwgraph_traverse(pci_bus, name, &device_vertex) == 
-			GRAPH_SUCCESS) {
-			if (device_vertex) {
-				return(device_vertex);
-			}
-		}
-	}
-			
-	/*
-	 * This maybe a multifunction card.  It's names look like:
-	 * ../pci/1a, ../pci/1b, etc.
-	 */
-	sprintf(name, "%d%c", slot, 'a'+func);
-	if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) {
-		if (!device_vertex) {
-			return(NULL);
-		}
-	}
-
-	return(device_vertex);
-}
-
-/*
- * For the given device, initialize the addresses for both the Device(x) Flush 
- * Write Buffer register and the Xbow Flush Register for the port the PCI bus 
- * is connected.
- */
-static void
-set_flush_addresses(struct pci_dev *device_dev, 
-	struct sn1_device_sysdata *device_sysdata)
-{
-	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
-	pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info);
-	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    	bridge_t               *bridge = pcibr_soft->bs_base;
-
-	device_sysdata->dma_buf_sync = (volatile unsigned int *) 
-		&(bridge->b_wr_req_buf[pciio_slot].reg);
-	device_sysdata->xbow_buf_sync = (volatile unsigned int *)
-		XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(get_nasid(), 0), 
-		pcibr_soft->bs_xid);
-#ifdef DEBUG
-
-	printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", 
-		device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync);
-
-	while((volatile unsigned int )*device_sysdata->dma_buf_sync);
-	while((volatile unsigned int )*device_sysdata->xbow_buf_sync);
-#endif
-
-}
-
-/*
- * Most drivers currently do not properly tell the arch specific pci dma
- * interfaces whether they can handle A64. Here is where we privately
- * keep track of this.
- */
-static void __init
-set_sn1_pci64(struct pci_dev *dev)
-{
-	unsigned short vendor = dev->vendor;
-	unsigned short device = dev->device;
-
-	if (vendor == PCI_VENDOR_ID_QLOGIC) {
-		if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) ||
-				(device == PCI_DEVICE_ID_QLOGIC_ISP2200)) {
-			SET_PCIA64(dev);
-			return;
-		}
-	}
-
-	if (vendor == PCI_VENDOR_ID_SGI) {
-		if (device == PCI_DEVICE_ID_SGI_IOC3) {
-			SET_PCIA64(dev);
-			return;
-		}
-	}
-
-}
-
-/*
- * sn1_allocate_ioports() - This routine provides the allocation and 
- *	mappings between Linux style IOPORTs management.
- *
- *	For simplicity sake, SN1 will allocate IOPORTs in chunks of 
- *	256bytes .. irrespective of what the card desires.  This may 
- *	have to change when we understand how to deal with legacy ioports 
- *	which are hardcoded in some drivers e.g. SVGA.
- *
- *	Ofcourse, the SN1 IO Infrastructure has no concept of IOPORT numbers.
- *	It will remain so.  The IO Infrastructure will continue to map 
- *	IO Resource just like IRIX.  When this is done, we map IOPORT 
- *	chunks to these resources.  The Linux drivers will see and use real 
- *	IOPORT numbers.  The various IOPORT access macros e.g. inb/outb etc. 
- *	does the munging of these IOPORT numbers to make a Uncache Virtual 
- *	Address.  This address via the tlb entries generates the PCI Address 
- *	allocated by the SN1 IO Infrastructure Layer.
- */
-static unsigned long sn1_ioport_num = 0x1000; /* Reserve room for Legacy stuff */
-unsigned long
-sn1_allocate_ioports(unsigned long pci_address)
-{
-	
-	unsigned long ioport_index;
-
-	/*
-	 * Just some idiot checking ..
-	 */
-	if ( sn1_ioport_num > 0xffff ) {
-		printk("sn1_allocate_ioports: No more IO PORTS available\n");
-		return(-1);
-	}
-
-	/*
-	 * See Section 4.1.1.5 of Intel IA-64 Acrchitecture Software Developer's
-	 * Manual for details.
-	 */
-	ioport_index = sn1_ioport_num / SN1_IOPORTS_UNIT;
-
-	ioports_to_tlbs[ioport_index].p = 1; /* Present Bit */
-	ioports_to_tlbs[ioport_index].rv_1 = 0; /* 1 Bit */
-	ioports_to_tlbs[ioport_index].ma = 4; /* Memory Attributes 3 bits*/
-	ioports_to_tlbs[ioport_index].a = 1; /* Set Data Access Bit Fault 1 Bit*/
-	ioports_to_tlbs[ioport_index].d = 1; /* Dirty Bit */
-	ioports_to_tlbs[ioport_index].pl = 0;/* Privilege Level - All levels can R/W*/
-	ioports_to_tlbs[ioport_index].ar = 3; /* Access Rights - R/W only*/
-	ioports_to_tlbs[ioport_index].ppn = pci_address >> 12; /* 4K page size */
-	ioports_to_tlbs[ioport_index].ed = 0; /* Exception Deferral Bit */
-	ioports_to_tlbs[ioport_index].ig = 0; /* Ignored */
-
-	/* printk("sn1_allocate_ioports: ioport_index 0x%x ioports_to_tlbs 0x%p\n", ioport_index, ioports_to_tlbs[ioport_index]); */
-	
-	sn1_ioport_num += SN1_IOPORTS_UNIT;
-
-	return(sn1_ioport_num - SN1_IOPORTS_UNIT);
-}
-
-/*
- * sn1_pci_fixup() - This routine is called when platform_pci_fixup() is 
- *	invoked at the end of pcibios_init() to link the Linux pci 
- *	infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c
- *
- *	Other platform specific fixup can also be done here.
- */
-void
-sn1_pci_fixup(int arg)
-{
-	struct list_head *ln;
-	struct pci_bus *pci_bus = NULL;
-	struct pci_dev *device_dev = NULL;
-	struct sn1_widget_sysdata *widget_sysdata;
-	struct sn1_device_sysdata *device_sysdata;
-#ifdef SN1_IOPORTS
-	unsigned long ioport;
-#endif
-	pciio_intr_t intr_handle;
-	int cpuid, bit;
-	devfs_handle_t device_vertex;
-	pciio_intr_line_t lines;
-	extern void sn1_pci_find_bios(void);
-#ifdef CONFIG_IA64_SGI_SN2
-	extern int numnodes;
-	int cnode;
-#endif /* CONFIG_IA64_SGI_SN2 */
-
-
-	if (arg == 0) {
-		sn1_init_irq_desc();
-		sn1_pci_find_bios();
-#ifdef CONFIG_IA64_SGI_SN2
-		for (cnode = 0; cnode < numnodes; cnode++) {
-				extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int);
-				intr_init_vecblk(NODEPDA(cnode), cnode, 0);
-		} 
-#endif /* CONFIG_IA64_SGI_SN2 */
-		return;
-	}
-
-#if 0
-{
-        devfs_handle_t  bridge_vhdl = pci_bus_to_vertex(0);
-        pcibr_soft_t    pcibr_soft = (pcibr_soft_t) hwgraph_fastinfo_get(bridge_vhdl);
-	bridge_t        *bridge = pcibr_soft->bs_base;
-        printk("pci_fixup_ioc3: Before devreg fixup\n");
-        printk("pci_fixup_ioc3: Devreg 0 0x%x\n", bridge->b_device[0].reg);
-        printk("pci_fixup_ioc3: Devreg 1 0x%x\n", bridge->b_device[1].reg);
-        printk("pci_fixup_ioc3: Devreg 2 0x%x\n", bridge->b_device[2].reg);
-        printk("pci_fixup_ioc3: Devreg 3 0x%x\n", bridge->b_device[3].reg);
-        printk("pci_fixup_ioc3: Devreg 4 0x%x\n", bridge->b_device[4].reg);
-        printk("pci_fixup_ioc3: Devreg 5 0x%x\n", bridge->b_device[5].reg);
-        printk("pci_fixup_ioc3: Devreg 6 0x%x\n", bridge->b_device[6].reg);
-        printk("pci_fixup_ioc3: Devreg 7 0x%x\n", bridge->b_device[7].reg);
-}
-#endif
-	done_probing = 1;
-
-	/*
-	 * Initialize the pci bus vertex in the pci_bus struct.
-	 */
-	for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
-		pci_bus = pci_bus_b(ln);
-		widget_sysdata = kmalloc(sizeof(struct sn1_widget_sysdata), 
-					GFP_KERNEL);
-		widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number);
-		pci_bus->sysdata = (void *)widget_sysdata;
-	}
-
-	/*
- 	 * set the root start and end so that drivers calling check_region()
-	 * won't see a conflict
-	 */
-#ifdef SN1_IOPORTS
-	ioport_resource.start  = sn1_ioport_num;
-	ioport_resource.end = 0xffff;
-#else
-#if defined(CONFIG_IA64_SGI_SN1)
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		/*
-		 * IDE legacy IO PORTs are supported in Medusa.
-		 * Just open up IO PORTs from 0 .. ioport_resource.end.
-		 */
-		ioport_resource.start = 0;
-	} else {
-		/*
-		 * We do not support Legacy IO PORT numbers.
-		 */
-		ioport_resource.start |= IO_SWIZ_BASE | __IA64_UNCACHED_OFFSET;
-	}
-	ioport_resource.end |= (HSPEC_SWIZ_BASE-1) | __IA64_UNCACHED_OFFSET;
-#else
-	// Need something here for sn2.... ZXZXZX
-#endif
-#endif
-
-	/*
-	 * Initialize the device vertex in the pci_dev struct.
-	 */
-	while ((device_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device_dev)) != NULL) {
-		unsigned int irq;
-		int idx;
-		u16 cmd;
-		devfs_handle_t vhdl;
-		unsigned long size;
-		extern int bit_pos_to_irq(int);
-
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-				device_dev->device == PCI_DEVICE_ID_SGI_IOC3) {
-			extern void pci_fixup_ioc3(struct pci_dev *d);
-			pci_fixup_ioc3(device_dev);
-		}
-
-		/* Set the device vertex */
-
-		device_sysdata = kmalloc(sizeof(struct sn1_device_sysdata),
-					GFP_KERNEL);
-		device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn);
-		device_sysdata->isa64 = 0;
-		/*
-		 * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush 
-		 * register addresses.
-		 */
-		(void) set_flush_addresses(device_dev, device_sysdata);
-
-		device_dev->sysdata = (void *) device_sysdata;
-		set_sn1_pci64(device_dev);
-		pci_read_config_word(device_dev, PCI_COMMAND, &cmd);
-
-		/*
-		 * Set the resources address correctly.  The assumption here 
-		 * is that the addresses in the resource structure has been
-		 * read from the card and it was set in the card by our
-		 * Infrastructure ..
-		 */
-		vhdl = device_sysdata->vhdl;
-		for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
-			size = 0;
-			size = device_dev->resource[idx].end -
-				device_dev->resource[idx].start;
-			if (size) {
-				device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, PCIIO_BYTE_STREAM);
-				device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET;
-			}
-			else
-				continue;
-
-			device_dev->resource[idx].end = 
-				device_dev->resource[idx].start + size;
-
-#ifdef CONFIG_IA64_SGI_SN1
-			/*
-			 * Adjust the addresses to go to the SWIZZLE ..
-			 */
-			device_dev->resource[idx].start = 
-				device_dev->resource[idx].start & 0xfffff7ffffffffff;
-			device_dev->resource[idx].end = 
-				device_dev->resource[idx].end & 0xfffff7ffffffffff;
-#endif
-
-			if (device_dev->resource[idx].flags & IORESOURCE_IO) {
-				cmd |= PCI_COMMAND_IO;
-#ifdef SN1_IOPORTS
-				ioport = sn1_allocate_ioports(device_dev->resource[idx].start);
-				if (ioport < 0) {
-					printk("sn1_pci_fixup: PCI Device 0x%x on PCI Bus %d not mapped to IO PORTs .. IO PORTs exhausted\n", device_dev->devfn, device_dev->bus->number);
-					continue;
-				}
-				pciio_config_set(vhdl, (unsigned) PCI_BASE_ADDRESS_0 + (idx * 4), 4, (res + (ioport & 0xfff)));
-
-printk("sn1_pci_fixup: ioport number %d mapped to pci address 0x%lx\n", ioport, (res + (ioport & 0xfff)));
-
-				device_dev->resource[idx].start = ioport;
-				device_dev->resource[idx].end = ioport + SN1_IOPORTS_UNIT;
-#endif
-			}
-			if (device_dev->resource[idx].flags & IORESOURCE_MEM)
-				cmd |= PCI_COMMAND_MEMORY;
-		}
-		/*
-		 * Now handle the ROM resource ..
-		 */
-		size = device_dev->resource[PCI_ROM_RESOURCE].end -
-			device_dev->resource[PCI_ROM_RESOURCE].start;
-
-		if (size) {
-			device_dev->resource[PCI_ROM_RESOURCE].start =
-			(unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, 
-				size, 0, PCIIO_BYTE_STREAM);
-			device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET;
-			device_dev->resource[PCI_ROM_RESOURCE].end =
-			device_dev->resource[PCI_ROM_RESOURCE].start + size;
-
-#ifdef CONFIG_IA64_SGI_SN1
-                	/*
-                 	 * go through synergy swizzled space
-                 	 */
-			device_dev->resource[PCI_ROM_RESOURCE].start &= 0xfffff7ffffffffffUL;
-			device_dev->resource[PCI_ROM_RESOURCE].end   &= 0xfffff7ffffffffffUL;
-#endif
-
-		}
-
-		/*
-		 * Update the Command Word on the Card.
-		 */
-		cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */
-					   /* bit gets dropped .. no harm */
-		pci_write_config_word(device_dev, PCI_COMMAND, cmd);
-
-		pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines);
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-			device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
-				lines = 1;
-		}
- 
-		device_sysdata = (struct sn1_device_sysdata *)device_dev->sysdata;
-		device_vertex = device_sysdata->vhdl;
- 
-		intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);
-
-		bit = intr_handle->pi_irq;
-		cpuid = intr_handle->pi_cpu;
-#ifdef CONFIG_IA64_SGI_SN1
-		irq = bit_pos_to_irq(bit);
-#else /* SN2 */
-		irq = bit;
-#endif
-		irq = irq + (cpuid << 8);
-		pciio_intr_connect(intr_handle);
-		device_dev->irq = irq;
-#ifdef ajmtestintr
-		{
-			int slot = PCI_SLOT(device_dev->devfn);
-			static int timer_set = 0;
-			pcibr_intr_t	pcibr_intr = (pcibr_intr_t)intr_handle;
-			pcibr_soft_t	pcibr_soft = pcibr_intr->bi_soft;
-			extern void intr_test_handle_intr(int, void*, struct pt_regs *);
-
-			if (!timer_set) {
-				intr_test_set_timer();
-				timer_set = 1;
-			}
-			intr_test_register_irq(irq, pcibr_soft, slot);
-			request_irq(irq, intr_test_handle_intr,0,NULL, NULL);
-		}
-#endif
-
-	}
-
-#if 0
-
-{
-        devfs_handle_t  bridge_vhdl = pci_bus_to_vertex(0);
-        pcibr_soft_t    pcibr_soft = (pcibr_soft_t) hwgraph_fastinfo_get(bridge_vhdl);
-        bridge_t        *bridge = pcibr_soft->bs_base;
-
-        printk("pci_fixup_ioc3: Before devreg fixup\n");
-        printk("pci_fixup_ioc3: Devreg 0 0x%x\n", bridge->b_device[0].reg);
-        printk("pci_fixup_ioc3: Devreg 1 0x%x\n", bridge->b_device[1].reg);
-        printk("pci_fixup_ioc3: Devreg 2 0x%x\n", bridge->b_device[2].reg);
-        printk("pci_fixup_ioc3: Devreg 3 0x%x\n", bridge->b_device[3].reg);
-        printk("pci_fixup_ioc3: Devreg 4 0x%x\n", bridge->b_device[4].reg);
-        printk("pci_fixup_ioc3: Devreg 5 0x%x\n", bridge->b_device[5].reg);
-        printk("pci_fixup_ioc3: Devreg 6 0x%x\n", bridge->b_device[6].reg);
-        printk("pci_fixup_ioc3: Devreg 7 0x%x\n", bridge->b_device[7].reg);
-}
-
-printk("testing Big Window: 0xC0000200c0000000 %p\n", *( (volatile uint64_t *)0xc0000200a0000000));
-printk("testing Big Window: 0xC0000200c0000008 %p\n", *( (volatile uint64_t *)0xc0000200a0000008));
-
-#endif
-
-}
-
-/*
- * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job.
- *
- *	Linux PCI Bus numbers are assigned from lowest module_id numbers
- *	(rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to 
- *	HUB_WIDGET_ID_MIN:
- *		widgetnum 15 gets lower Bus Number than widgetnum 14 etc.
- *
- *	Given 2 modules 001c01 and 001c02 we get the following mappings:
- *		001c01, widgetnum 15 = Bus number 0
- *		001c01, widgetnum 14 = Bus number 1
- *		001c02, widgetnum 15 = Bus number 3
- *		001c02, widgetnum 14 = Bus number 4
- *		etc.
- *
- * The rational for starting Bus Number 0 with Widget number 15 is because 
- * the system boot disks are always connected via Widget 15 Slot 0 of the 
- * I-brick.  Linux creates /dev/sd* devices(naming) strating from Bus Number 0 
- * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest 
- * module id(Master Cnode) of the system.
- *	
- */
-static int 
-pci_bus_map_create(devfs_handle_t xtalk)
-{
-
-	devfs_handle_t master_node_vertex = NULL;
-	devfs_handle_t xwidget = NULL;
-	devfs_handle_t pci_bus = NULL;
-	hubinfo_t hubinfo = NULL;
-	xwidgetnum_t widgetnum;
-	char pathname[128];
-	graph_error_t rv;
-
-	/*
-	 * Loop throught this vertex and get the Xwidgets ..
-	 */
-	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
-#if 0
-        {
-                int pos;
-                char dname[256];
-                pos = devfs_generate_path(xtalk, dname, 256);
-                printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
-        }
-#endif
-
-		sprintf(pathname, "%d", widgetnum);
-		xwidget = NULL;
-		
-		/*
-		 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
-		 *	     /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device
-		 */
-		rv = hwgraph_traverse(xtalk, pathname, &xwidget);
-		if ( (rv != GRAPH_SUCCESS) ) {
-			if (!xwidget)
-				continue;
-		}
-
-		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
-		pci_bus = NULL;
-		if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
-			if (!pci_bus)
-				continue;
-
-		/*
-		 * Assign the correct bus number and also the nasid of this 
-		 * pci Xwidget.
-		 * 
-		 * Should not be any race here ...
-		 */
-		num_bridges++;
-		busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;
-
-		/*
-		 * Get the master node and from there get the NASID.
-		 */
-		master_node_vertex = device_master_get(xwidget);
-		if (!master_node_vertex) {
-			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
-		}
-	
-		hubinfo_get(master_node_vertex, &hubinfo);
-		if (!hubinfo) {
-			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
-			return(1);
-		} else {
-			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
-		}
-
-		/*
-		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
-		 */
-		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
-			sizeof(struct sn1_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
-		if (!busnum_to_atedmamaps[num_bridges - 1])
-			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
-
-		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
-			sizeof(struct sn1_dma_maps_s) * MAX_ATE_MAPS);
-
-	}
-
-        return(0);
-}
-
-/*
- * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure   
- *      initialization has completed to set up the mappings between Xbridge
- *      and logical pci bus numbers.  We also set up the NASID for each of these
- *      xbridges.
- *
- *      Must be called before pci_init() is invoked.
- */
-int
-pci_bus_to_hcl_cvlink(void) 
-{
-
-	devfs_handle_t devfs_hdl = NULL;
-	devfs_handle_t xtalk = NULL;
-	int rv = 0;
-	char name[256];
-	int master_iobrick;
-	int i;
-
-	/*
-	 * Iterate throught each xtalk links in the system ..
-	 * /hw/module/001c01/node/xtalk/ 8|9|10|11|12|13|14|15 
-	 *
-	 * /hw/module/001c01/node/xtalk/15 -> /hw/module/001c01/Ibrick/xtalk/15
-	 *
-	 * What if it is not pci?
-	 */
-	devfs_hdl = hwgraph_path_to_vertex("/dev/hw/module");
-
-	/*
-	 * To provide consistent(not persistent) device naming, we need to start 
-	 * bus number allocation from the C-Brick with the lowest module id e.g. 001c01 
-	 * with an attached I-Brick.  Find the master_iobrick.
-	 */
-	master_iobrick = -1;
-	for (i = 0; i < nummodules; i++) {
-		moduleid_t iobrick_id; 
-		iobrick_id = iobrick_module_get(&modules[i]->elsc);
-		if (iobrick_id > 0) { /* Valid module id */
-			if (MODULE_GET_BTYPE(iobrick_id) == MODULE_IBRICK) {
-				master_iobrick = i;
-				break;
-			}
-		}
-	}
-
-	/*
-	 * The master_iobrick gets bus 0 and 1.
-	 */
-	if (master_iobrick >= 0) {
-		memset(name, 0, 256);
-		format_module_id(name, modules[master_iobrick]->id, MODULE_FORMAT_BRIEF);
-		strcat(name, "/node/xtalk");
-		xtalk = NULL;
-		rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
-		pci_bus_map_create(xtalk);
-	}
-		
-	/*
-	 * Now go do the rest of the modules, starting from the C-Brick with the lowest 
-	 * module id, remembering to skip the master_iobrick, which was done above.
-	 */
-	for (i = 0; i < nummodules; i++) {
-		if (i == master_iobrick) {
-			continue; /* Did the master_iobrick already. */
-		}
-
-		memset(name, 0, 256);
-		format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF);
-		strcat(name, "/node/xtalk");
-		xtalk = NULL;
-		rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
-		pci_bus_map_create(xtalk);
-	}
-
-	return(0);
-}
diff -Nru a/arch/ia64/sn/io/pci_dma.c b/arch/ia64/sn/io/pci_dma.c
--- a/arch/ia64/sn/io/pci_dma.c	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,700 +0,0 @@
-/*
- * 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) 2000,2002 Silicon Graphics, Inc. All rights reserved.
- *
- * Routines for PCI DMA mapping.  See Documentation/DMA-mapping.txt for
- * a description of how these routines should be used.
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <linux/mm.h>
-#include <linux/string.h>
-#include <linux/pci.h>
-#include <linux/slab.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/module.h>
-
-#include <asm/delay.h>
-#include <asm/io.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/types.h>
-#include <asm/sn/alenlist.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/nag.h>
-
-/*
- * For ATE allocations
- */
-pciio_dmamap_t get_free_pciio_dmamap(devfs_handle_t);
-void free_pciio_dmamap(pcibr_dmamap_t);
-static struct sn_dma_maps_s *find_sn_dma_map(dma_addr_t, unsigned char);
-
-/*
- * Toplogy stuff
- */
-extern devfs_handle_t busnum_to_pcibr_vhdl[];
-extern nasid_t busnum_to_nid[];
-extern void * busnum_to_atedmamaps[];
-
-/**
- * get_free_pciio_dmamap - find and allocate an ATE
- * @pci_bus: PCI bus to get an entry for
- *
- * Finds and allocates an ATE on the PCI bus specified
- * by @pci_bus.
- */
-pciio_dmamap_t
-get_free_pciio_dmamap(devfs_handle_t pci_bus)
-{
-	int i;
-	struct sn_dma_maps_s *sn_dma_map = NULL;
-
-	/*
-	 * Darn, we need to get the maps allocated for this bus.
-	 */
-	for (i = 0; i < MAX_PCI_XWIDGET; i++) {
-		if (busnum_to_pcibr_vhdl[i] == pci_bus) {
-			sn_dma_map = busnum_to_atedmamaps[i];
-		}
-	}
-
-	/*
-	 * Now get a free dmamap entry from this list.
-	 */
-	for (i = 0; i < MAX_ATE_MAPS; i++, sn_dma_map++) {
-		if (!sn_dma_map->dma_addr) {
-			sn_dma_map->dma_addr = -1;
-			return( (pciio_dmamap_t) sn_dma_map );
-		}
-	}
-
-	return NULL;
-}
-
-/**
- * free_pciio_dmamap - free an ATE
- * @dma_map: ATE to free
- *
- * Frees the ATE specified by @dma_map.
- */
-void
-free_pciio_dmamap(pcibr_dmamap_t dma_map)
-{
-	struct sn_dma_maps_s *sn_dma_map;
-
-	sn_dma_map = (struct sn_dma_maps_s *) dma_map;
-	sn_dma_map->dma_addr = 0;
-}
-
-/**
- * find_sn_dma_map - find an ATE associated with @dma_addr and @busnum
- * @dma_addr: DMA address to look for
- * @busnum: PCI bus to look on
- *
- * Finds the ATE associated with @dma_addr and @busnum.
- */
-static struct sn_dma_maps_s *
-find_sn_dma_map(dma_addr_t dma_addr, unsigned char busnum)
-{
-
-	struct sn_dma_maps_s *sn_dma_map = NULL;
-	int i;
-
-	sn_dma_map = busnum_to_atedmamaps[busnum];
-
-	for (i = 0; i < MAX_ATE_MAPS; i++, sn_dma_map++) {
-		if (sn_dma_map->dma_addr == dma_addr) {
-			return sn_dma_map;
-		}
-	}
-
-	return NULL;
-}
-
-/**
- * sn_dma_sync - try to flush DMA buffers into the coherence domain
- * @hwdev: device to flush
- *
- * This routine flushes all DMA buffers for the device into the II of
- * the destination hub.
- *
- * NOTE!: this does not mean that the data is in the "coherence domain",
- * but it is very close.  In other words, this routine *does not work*
- * as advertised due to hardware bugs.  That said, it should be good enough for
- * most situations.
- */
-void
-sn_dma_sync(struct pci_dev *hwdev)
-{
-
-#ifdef SN_DMA_SYNC
-
-	struct sn_device_sysdata *device_sysdata;
-	volatile unsigned long dummy;
-
-	/*
-	 * A DMA sync is supposed to ensure that 
-	 * all the DMA from a particular device
-	 * is complete and coherent.  We
-	 * try to do this by
-	 *	1. flushing the write wuffers from Bridge
-	 *	2. flushing the Xbow port.
-	 * Unfortunately, this only gets the DMA transactions 'very close' to
-	 * the coherence domain, but not quite in it.
-	 */
-	device_sysdata = (struct sn_device_sysdata *)hwdev->sysdata;
-	dummy = (volatile unsigned long ) *device_sysdata->dma_buf_sync;
-
-	/*
-	 * For the Xbow port flush, we may be denied the request because 
-	 * someone else may be flushing the port .. try again.
-	 */
-	while((volatile unsigned long ) *device_sysdata->xbow_buf_sync) {
-		udelay(2);
-	}
-#endif
-}
-
-/**
- * sn_pci_alloc_consistent - allocate memory for coherent DMA
- * @hwdev: device to allocate for
- * @size: size of the region
- * @dma_handle: DMA (bus) address
- *
- * pci_alloc_consistent() returns a pointer to a memory region suitable for
- * coherent DMA traffic to/from a PCI device.  On SN platforms, this means
- * that @dma_handle will have the %PCIIO_DMA_CMD flag set.
- *
- * This interface is usually used for "command" streams (e.g. the command
- * queue for a SCSI controller).  See Documentation/DMA-mapping.txt for
- * more information.  Note that this routine will always put a 32 bit
- * DMA address into @dma_handle.  This is because most devices
- * that are capable of 64 bit PCI DMA transactions can't do 64 bit _coherent_
- * DMAs, and unfortunately this interface has to cater to the LCD.  Oh well.
- *
- * Also known as platform_pci_alloc_consistent() by the IA64 machvec code.
- */
-void *
-sn_pci_alloc_consistent(struct pci_dev *hwdev, size_t size, dma_addr_t *dma_handle)
-{
-        void *cpuaddr;
-	devfs_handle_t vhdl;
-	struct sn_device_sysdata *device_sysdata;
-	unsigned long phys_addr;
-	pciio_dmamap_t dma_map = 0;
-	struct sn_dma_maps_s *sn_dma_map;
-
-	*dma_handle = 0;
-
-	/* We can't easily support < 32 bit devices */
-	if (IS_PCI32L(hwdev))
-		return NULL;
-
-	/*
-	 * Get hwgraph vertex for the device
-	 */
-	device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata;
-	vhdl = device_sysdata->vhdl;
-
-	/*
-	 * Allocate the memory.  FIXME: if we're allocating for
-	 * two devices on the same bus, we should at least try to
-	 * allocate memory in the same 2 GB window to avoid using
-	 * ATEs for the translation.  See the comment above about the
-	 * 32 bit requirement for this function.
-	 */
-	if(!(cpuaddr = (void *)__get_free_pages(GFP_ATOMIC, get_order(size))))
-		return NULL;
-
-	memset(cpuaddr, 0, size); /* have to zero it out */
-
-	/* physical addr. of the memory we just got */
-	phys_addr = __pa(cpuaddr);
-
-	/*
-	 * This will try to use a Direct Map register to do the
-	 * 32 bit DMA mapping, but it may not succeed if another
-	 * device on the same bus is already mapped with different
-	 * attributes or to a different memory region.
-	 */
-#ifdef CONFIG_IA64_SGI_SN1
-	*dma_handle = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-					  PCIIO_BYTE_STREAM |
-					  PCIIO_DMA_CMD);
-#elif defined(CONFIG_IA64_SGI_SN2)
-	*dma_handle = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-					  PCIIO_DMA_CMD);
-#else
-#error unsupported platform
-#endif
-
-	/*
-	 * It is a 32 bit card and we cannot do direct mapping,
-	 * so we try to use an ATE.
-	 */
-	if (!(*dma_handle)) {
-#ifdef CONFIG_IA64_SGI_SN1
-		dma_map = pciio_dmamap_alloc(vhdl, NULL, size,
-					     PCIIO_BYTE_STREAM |
-					     PCIIO_DMA_CMD);
-#elif defined(CONFIG_IA64_SGI_SN2)
-		dma_map = pciio_dmamap_alloc(vhdl, NULL, size,
-				((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-					     PCIIO_DMA_CMD);
-#else
-#error unsupported platform
-#endif
-		if (!dma_map) {
-			printk(KERN_ERR "sn_pci_alloc_consistent: Unable to "
-			       "allocate anymore 32 bit page map entries.\n");
-			BUG();
-		}
-		*dma_handle = (dma_addr_t) pciio_dmamap_addr(dma_map,phys_addr,
-							     size);
-		sn_dma_map = (struct sn_dma_maps_s *)dma_map;
-		sn_dma_map->dma_addr = *dma_handle;
-	}
-
-        return cpuaddr;
-}
-
-/**
- * sn_pci_free_consistent - free memory associated with coherent DMAable region
- * @hwdev: device to free for
- * @size: size to free
- * @vaddr: kernel virtual address to free
- * @dma_handle: DMA address associated with this region
- *
- * Frees the memory allocated by pci_alloc_consistent().  Also known
- * as platform_pci_free_consistent() by the IA64 machvec code.
- */
-void
-sn_pci_free_consistent(struct pci_dev *hwdev, size_t size, void *vaddr, dma_addr_t dma_handle)
-{
-	struct sn_dma_maps_s *sn_dma_map = NULL;
-
-	/*
-	 * Get the sn_dma_map entry.
-	 */
-	if (IS_PCI32_MAPPED(dma_handle))
-		sn_dma_map = find_sn_dma_map(dma_handle, hwdev->bus->number);
-
-	/*
-	 * and free it if necessary...
-	 */
-	if (sn_dma_map) {
-		pciio_dmamap_done((pciio_dmamap_t)sn_dma_map);
-		pciio_dmamap_free((pciio_dmamap_t)sn_dma_map);
-		sn_dma_map->dma_addr = (dma_addr_t)NULL;
-	}
-	free_pages((unsigned long) vaddr, get_order(size));
-}
-
-/**
- * sn_pci_map_sg - map a scatter-gather list for DMA
- * @hwdev: device to map for
- * @sg: scatterlist to map
- * @nents: number of entries
- * @direction: direction of the DMA transaction
- *
- * Maps each entry of @sg for DMA.  Also known as platform_pci_map_sg by the
- * IA64 machvec code.
- */
-int
-sn_pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
-{
-
-	int i;
-	devfs_handle_t vhdl;
-	dma_addr_t dma_addr;
-	unsigned long phys_addr;
-	struct sn_device_sysdata *device_sysdata;
-	pciio_dmamap_t dma_map;
-
-	/* can't go anywhere w/o a direction in life */
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	/*
-	 * Get the hwgraph vertex for the device
-	 */
-	device_sysdata = (struct sn_device_sysdata *) hwdev->sysdata;
-	vhdl = device_sysdata->vhdl;
-
-	/*
-	 * Setup a DMA address for each entry in the
-	 * scatterlist.
-	 */
-	for (i = 0; i < nents; i++, sg++) {
-		/* this catches incorrectly written drivers that
-                   attempt to map scatterlists that they have
-                   previously mapped.  we print a warning and
-                   continue, but the driver should be fixed */
-		switch (((u64)sg->dma_address) >> 60) {
-		case 0xa:
-		case 0xb:
-#ifdef DEBUG
-/* This needs to be cleaned up at some point. */
-			NAG("A PCI driver (for device at%8s) has attempted to "
-			    "map a scatterlist that was previously mapped at "
-			    "%p - this is currently being worked around.\n",
-			    hwdev->slot_name, (void *)sg->dma_address);
-			phys_addr = (u64)sg->dma_address & TO_PHYS_MASK;
-			break;
-#endif
-		default: /* not previously mapped, get the phys. addr */
-			phys_addr = __pa(sg->dma_address);
-			break;
-		}
-		sg->page = NULL;
-		dma_addr = 0;
-
-		/*
-		 * Handle the most common case: 64 bit cards.  This
-		 * call should always succeed.
-		 */
-		if (IS_PCIA64(hwdev)) {
-			dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
-						       sg->length,
-			       ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-						       PCIIO_DMA_DATA |
-						       PCIIO_DMA_A64);
-			sg->dma_address = (char *)dma_addr;
-			continue;
-		}
-
-		/*
-		 * Handle 32-63 bit cards via direct mapping
-		 */
-		if (IS_PCI32G(hwdev)) {
-#ifdef CONFIG_IA64_SGI_SN1
-			dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
-						       sg->length,
-						       PCIIO_BYTE_STREAM |
-						       PCIIO_DMA_DATA);
-#elif defined(CONFIG_IA64_SGI_SN2)
-			dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr,
-						       sg->length,
-					((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-						       PCIIO_DMA_DATA);
-#else
-#error unsupported platform
-#endif
-			/*
-			 * See if we got a direct map entry
-			 */
-			if (dma_addr) {
-				sg->dma_address = (char *)dma_addr;
-				continue;
-			}
-
-		}
-
-		/*
-		 * It is a 32 bit card and we cannot do direct mapping,
-		 * so we use an ATE.
-		 */
-		dma_map = 0;
-#ifdef CONFIG_IA64_SGI_SN1
-		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length,
-					     PCIIO_BYTE_STREAM |
-					     PCIIO_DMA_DATA);
-#elif defined(CONFIG_IA64_SGI_SN2)
-		dma_map = pciio_dmamap_alloc(vhdl, NULL, sg->length,
-				((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-					     PCIIO_DMA_DATA);
-#else
-#error unsupported platform
-#endif
-		if (!dma_map) {
-			printk(KERN_ERR "sn_pci_map_sg: Unable to allocate "
-			       "anymore 32 bit page map entries.\n");
-			BUG();
-		}
-		dma_addr = pciio_dmamap_addr(dma_map, phys_addr, sg->length);
-		sg->dma_address = (char *)dma_addr;
-		sg->page = (struct page *)dma_map;
-		
-	}
-
-	return nents;
-
-}
-
-/**
- * sn_pci_unmap_sg - unmap a scatter-gather list
- * @hwdev: device to unmap
- * @sg: scatterlist to unmap
- * @nents: number of scatterlist entries
- * @direction: DMA direction
- *
- * Unmap a set of streaming mode DMA translations.  Again, cpu read rules
- * concerning calls here are the same as for pci_unmap_single() below.  Also
- * known as sn_pci_unmap_sg() by the IA64 machvec code.
- */
-void
-sn_pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
-{
-	int i;
-	struct sn_dma_maps_s *sn_dma_map;
-
-	/* can't go anywhere w/o a direction in life */
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	for (i = 0; i < nents; i++, sg++)
-		if (sg->page) {
-			/*
-			 * We maintain the DMA Map pointer in sg->page if 
-			 * it is ever allocated.
-			 */
-			sg->dma_address = 0;
-			sn_dma_map = (struct sn_dma_maps_s *)sg->page;
-			pciio_dmamap_done((pciio_dmamap_t)sn_dma_map);
-			pciio_dmamap_free((pciio_dmamap_t)sn_dma_map);
-			sn_dma_map->dma_addr = 0;
-			sg->page = 0;
-		}
-
-}
-
-/**
- * sn_pci_map_single - map a single region for DMA
- * @hwdev: device to map for
- * @ptr: kernel virtual address of the region to map
- * @size: size of the region
- * @direction: DMA direction
- *
- * Map the region pointed to by @ptr for DMA and return the
- * DMA address.   Also known as platform_pci_map_single() by
- * the IA64 machvec code.
- *
- * We map this to the one step pciio_dmamap_trans interface rather than
- * the two step pciio_dmamap_alloc/pciio_dmamap_addr because we have
- * no way of saving the dmamap handle from the alloc to later free
- * (which is pretty much unacceptable).
- *
- * TODO: simplify our interface;
- *       get rid of dev_desc and vhdl (seems redundant given a pci_dev);
- *       figure out how to save dmamap handle so can use two step.
- */
-dma_addr_t
-sn_pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int direction)
-{
-	devfs_handle_t vhdl;
-	dma_addr_t dma_addr;
-	unsigned long phys_addr;
-	struct sn_device_sysdata *device_sysdata;
-	pciio_dmamap_t dma_map = NULL;
-	struct sn_dma_maps_s *sn_dma_map;
-
-	if (direction == PCI_DMA_NONE)
-		BUG();
-
-	/* SN cannot support DMA addresses smaller than 32 bits. */
-	if (IS_PCI32L(hwdev))
-		return 0;
-
-	/*
-	 * find vertex for the device
-	 */
-	device_sysdata = (struct sn_device_sysdata *)hwdev->sysdata;
-	vhdl = device_sysdata->vhdl;
-
-	/*
-	 * Call our dmamap interface
-	 */
-	dma_addr = 0;
-	phys_addr = __pa(ptr);
-
-	if (IS_PCIA64(hwdev)) {
-		/* This device supports 64 bit DMA addresses. */
-		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-		       ((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-					       PCIIO_DMA_DATA |
-					       PCIIO_DMA_A64);
-		return dma_addr;
-	}
-
-	/*
-	 * Devices that support 32 bit to 63 bit DMA addresses get
-	 * 32 bit DMA addresses.
-	 *
-	 * First try to get a 32 bit direct map register.
-	 */
-	if (IS_PCI32G(hwdev)) {
-#ifdef CONFIG_IA64_SGI_SN1
-		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-					       PCIIO_BYTE_STREAM |
-					       PCIIO_DMA_DATA);
-#elif defined(CONFIG_IA64_SGI_SN2)
-		dma_addr = pciio_dmatrans_addr(vhdl, NULL, phys_addr, size,
-			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-					       PCIIO_DMA_DATA);
-#else
-#error unsupported platform
-#endif
-		if (dma_addr)
-			return dma_addr;
-	}
-
-	/*
-	 * It's a 32 bit card and we cannot do direct mapping so
-	 * let's use the PMU instead.
-	 */
-	dma_map = NULL;
-#ifdef CONFIG_IA64_SGI_SN1
-	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, PCIIO_BYTE_STREAM |
-				     PCIIO_DMA_DATA);
-#elif defined(CONFIG_IA64_SGI_SN2)
-	dma_map = pciio_dmamap_alloc(vhdl, NULL, size, 
-			((IS_PIC_DEVICE(hwdev)) ? 0 : PCIIO_BYTE_STREAM) |
-			PCIIO_DMA_DATA);
-#else
-#error unsupported platform
-#endif
-
-	if (!dma_map) {
-		printk(KERN_ERR "pci_map_single: Unable to allocate anymore "
-		       "32 bit page map entries.\n");
-		BUG();
-	}
-
-	dma_addr = (dma_addr_t) pciio_dmamap_addr(dma_map, phys_addr, size);
-	sn_dma_map = (struct sn_dma_maps_s *)dma_map;
-	sn_dma_map->dma_addr = dma_addr;
-
-	return ((dma_addr_t)dma_addr);
-}
-
-/**
- * sn_pci_unmap_single - unmap a region used for DMA
- * @hwdev: device to unmap
- * @dma_addr: DMA address to unmap
- * @size: size of region
- * @direction: DMA direction
- *
- * Unmaps the region pointed to by @dma_addr.  Also known as
- * platform_pci_unmap_single() by the IA64 machvec code.
- */
-void
-sn_pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction)
-{
-	struct sn_dma_maps_s *sn_dma_map = NULL;
-
-        if (direction == PCI_DMA_NONE)
-		BUG();
-
-	/*
-	 * Get the sn_dma_map entry.
-	 */
-	if (IS_PCI32_MAPPED(dma_addr))
-		sn_dma_map = find_sn_dma_map(dma_addr, hwdev->bus->number);
-
-	/*
-	 * and free it if necessary...
-	 */
-	if (sn_dma_map) {
-		pciio_dmamap_done((pciio_dmamap_t)sn_dma_map);
-		pciio_dmamap_free((pciio_dmamap_t)sn_dma_map);
-		sn_dma_map->dma_addr = (dma_addr_t)NULL;
-	}
-}
-
-/**
- * sn_pci_dma_sync_single - make sure all DMAs have completed
- * @hwdev: device to sync
- * @dma_handle: DMA address to sync
- * @size: size of region
- * @direction: DMA direction
- *
- * This routine is supposed to sync the DMA region specified
- * by @dma_handle into the 'coherence domain'.  See sn_dma_sync()
- * above for more information.   Also known as
- * platform_pci_dma_sync_single() by the IA64 machvec code.
- */
-void
-sn_pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t dma_handle, size_t size, int direction)
-{
-	if (direction == PCI_DMA_NONE)
-                BUG();
-
-	sn_dma_sync(hwdev);
-}
-
-/**
- * sn_pci_dma_sync_sg - make sure all DMAs have completed
- * @hwdev: device to sync
- * @sg: scatterlist to sync
- * @nents: number of entries in the scatterlist
- * @direction: DMA direction
- *
- * This routine is supposed to sync the DMA regions specified
- * by @sg into the 'coherence domain'.  See sn_dma_sync()
- * above for more information.   Also known as
- * platform_pci_dma_sync_sg() by the IA64 machvec code.
- */
-void
-sn_pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction)
-{
-        if (direction == PCI_DMA_NONE)
-                BUG();
-
-	sn_dma_sync(hwdev);
-}
-
-/**
- * sn_dma_address - get the DMA address for the first entry of a scatterlist
- * @sg: sg to look at
- *
- * Gets the DMA address for the scatterlist @sg.  Also known as
- * platform_dma_address() by the IA64 machvec code.
- */
-unsigned long
-sn_dma_address(struct scatterlist *sg)
-{
-	return ((unsigned long)sg->dma_address);
-}
-
-/**
- * sn_dma_supported - test a DMA mask
- * @hwdev: device to test
- * @mask: DMA mask to test
- *
- * Return whether the given PCI device DMA address mask can be supported
- * properly.  For example, if your device can only drive the low 24-bits
- * during PCI bus mastering, then you would pass 0x00ffffff as the mask to
- * this function.  Of course, SN only supports devices that have 32 or more
- * address bits when using the PMU.  We could theoretically support <32 bit
- * cards using direct mapping, but we'll worry about that later--on the off
- * chance that someone actually wants to use such a card.
- */
-int
-sn_pci_dma_supported(struct pci_dev *hwdev, u64 mask)
-{
-	if (mask < 0xffffffff)
-		return 0;
-	return 1;
-}
-
-EXPORT_SYMBOL(sn_pci_unmap_single);
-EXPORT_SYMBOL(sn_pci_map_single);
-EXPORT_SYMBOL(sn_pci_dma_sync_single);
-EXPORT_SYMBOL(sn_pci_map_sg);
-EXPORT_SYMBOL(sn_pci_unmap_sg);
-EXPORT_SYMBOL(sn_pci_alloc_consistent);
-EXPORT_SYMBOL(sn_pci_free_consistent);
-EXPORT_SYMBOL(sn_dma_address);
-EXPORT_SYMBOL(sn_pci_dma_supported);
-
diff -Nru a/arch/ia64/sn/io/pciba.c b/arch/ia64/sn/io/pciba.c
--- a/arch/ia64/sn/io/pciba.c	Wed Jun 18 23:42:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,950 +0,0 @@
-/*
- * arch/ia64/sn/io/pciba.c
- *
- * IRIX PCIBA-inspired user mode PCI interface
- *
- * requires: devfs
- *
- * device nodes show up in /dev/pci/BB/SS.F (where BB is the bus the
- * device is on, SS is the slot the device is in, and F is the
- * device's function on a multi-function card).
- *
- * when compiled into the kernel, it will only be initialized by the
- * sgi sn1 specific initialization code.  in this case, device nodes
- * are under /dev/hw/..../
- *
- * 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) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
- *
- * 03262001 - Initial version by Chad Talbott
- */
-
-
-/* jesse's beefs:
-
-   register_pci_device should be documented
-   
-   grossness with do_swap should be documented
-   
-   big, gross union'ized node_data should be replaced with independent
-   structures
-
-   replace global list of nodes with global lists of resources.  could
-   use object oriented approach of allocating and cleaning up
-   resources.
-   
-*/
-
-
-#include <linux/config.h>
-#ifndef CONFIG_DEVFS_FS
-#  error PCIBA requires devfs
-#endif
-
-#include <linux/module.h>
-#include <linux/devfs_fs_kernel.h>
-#include <linux/pci.h>
-#include <linux/list.h>
-
-#include <linux/mm.h>
-#include <linux/slab.h>
-#include <linux/vmalloc.h>
-#include <linux/mman.h>
-#include <linux/init.h>
-#include <linux/raw.h>
-#include <linux/capability.h>
-
-#include <asm/uaccess.h>
-#include <asm/io.h>
-#include <asm/pgalloc.h>
-#include <asm/page.h>
-
-#include <asm/sn/pci/pciba.h>
-
-
-MODULE_DESCRIPTION("User mode PCI interface");
-MODULE_AUTHOR("Chad Talbott");
-
-
-#undef DEBUG_PCIBA
-/* #define DEBUG_PCIBA */
-
-#undef TRACE_PCIBA
-/* #define TRACE_PCIBA */
-
-#if defined(DEBUG_PCIBA)
-#  define DPRINTF(x...) printk(KERN_DEBUG x)
-#else
-#  define DPRINTF(x...)
-#endif
-
-#if defined(TRACE_PCIBA)
-#  if defined(__GNUC__)
-#    define TRACE()	printk(KERN_DEBUG "%s:%d:%s\n", \
-			       __FILE__, __LINE__, __FUNCTION__)
-#  else
-#    define TRACE()	printk(KERN_DEBUG "%s:%d\n", __LINE__, __FILE__)
-#  endif
-#else
-#  define TRACE()
-#endif
-
-
-typedef enum { failure, success } status;
-typedef enum { false, true } boolean;
-
-
-/* major data structures:
-
-   struct node_data -
-   
-   	one for each file registered with devfs.  contains everything
-   	that any file's fops would need to know about.
-
-   struct dma_allocation -
-
-   	a single DMA allocation.  only the 'dma' nodes care about
-   	these.  they are there primarily to allow the driver to look
-   	up the kernel virtual address of dma buffers allocated by
-   	pci_alloc_consistent, as the application is only given the
-   	physical address (to program the device's dma, presumably) and
-   	cannot supply the kernel virtual address when freeing the
-   	buffer.
-
-	it's also useful to maintain a list of buffers allocated
-	through a specific node to allow some sanity checking by this
-	driver.  this prevents (for example) a broken application from
-	freeing buffers that it didn't allocate, or buffers allocated
-	on another node.
-   
-   global_node_list -
-
-   	a list of all nodes allocated.  this allows the driver to free
-   	all the memory it has 'kmalloc'd in case of an error, or on
-   	module removal.
-
-   global_dma_list -
-
-        a list of all dma buffers allocated by this driver.  this
-	allows the driver to 'pci_free_consistent' all buffers on
-	module removal or error.
-
-*/
-
-
-struct node_data {
-	/* flat list of all the device nodes.  makes it easy to free
-	   them all when we're unregistered */
-	struct list_head global_node_list;
-	devfs_handle_t devfs_handle;
-
-	void (* cleanup)(struct node_data *);
-
-	union {
-		struct {
-			struct pci_dev * dev;
-			struct list_head dma_allocs;
-			boolean mmapped;
-		} dma;
-		struct {
-			struct pci_dev * dev;
-			u32 saved_rom_base_reg;
-			boolean mmapped;
-		} rom;
-		struct {
-			struct resource * res;
-		} base;
-		struct {
-			struct pci_dev * dev;
-		} config;
-	} u;
-};
-
-struct dma_allocation {
-	struct list_head list;
-
-	dma_addr_t handle;
-	void * va;
-	size_t size;
-};
-
-
-static LIST_HEAD(global_node_list);
-static LIST_HEAD(global_dma_list);
-
-
-/* module entry points */
-int __init pciba_init(void);
-void __exit pciba_exit(void);
-
-static status __init register_with_devfs(void);
-static void __exit unregister_with_devfs(void);
-
-static status __init register_pci_device(devfs_handle_t device_dir_handle,
-					 struct pci_dev * dev);
-
-/* file operations */
-static int generic_open(struct inode * inode, struct file * file);
-static int rom_mmap(struct file * file, struct vm_area_struct * vma);
-static int rom_release(struct inode * inode, struct file * file);
-static int base_mmap(struct file * file, struct vm_area_struct * vma);
-static int config_ioctl(struct inode * inode, struct file * file, 
-			unsigned int cmd, 
-			unsigned long arg);
-static int dma_ioctl(struct inode * inode, struct file * file, 
-		     unsigned int cmd, 
-		     unsigned long arg);
-static int dma_mmap(struct file * file, struct vm_area_struct * vma);
-
-/* support routines */
-static int mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va);
-static int mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va);
-
-#ifdef DEBUG_PCIBA
-static void dump_nodes(struct list_head * nodes);
-static void dump_allocations(struct list_head * dalp);
-#endif
-
-/* file operations for each type of node */
-static struct file_operations rom_fops = {
-	owner:		THIS_MODULE,
-	mmap:		rom_mmap,
-	open:		generic_open,
-	release:	rom_release
-};
- 
-
-static struct file_operations base_fops = {
-	owner:		THIS_MODULE,
-	mmap:		base_mmap,
-	open:		generic_open
-};
-
-
-static struct file_operations config_fops = {
-	owner:		THIS_MODULE,
-	ioctl:		config_ioctl,
-	open:		generic_open
-};	
-
-static struct file_operations dma_fops = {
-	owner:		THIS_MODULE,
-	ioctl:		dma_ioctl,
-	mmap:		dma_mmap,
-	open:		generic_open
-};	
-
-
-module_init(pciba_init);
-module_exit(pciba_exit);
-
-
-int __init
-pciba_init(void)
-{
-	TRACE();
-
-	if (register_with_devfs() == failure)
-		return 1; /* failure */
-
-	printk("PCIBA (a user mode PCI interface) initialized.\n");
-
-	return 0; /* success */
-}
-
-
-void __exit
-pciba_exit(void)
-{
-	TRACE();
-
-	/* FIXME: should also free all that memory that we allocated
-           ;) */
-	unregister_with_devfs();
-}
-
-
-# if 0
-static void __exit
-free_nodes(void)
-{
-	struct node_data * nd;
-	
-	TRACE();
-
-	list_for_each(nd, &node_list) {
-		kfree(list_entry(nd, struct nd, node_list));
-	}
-}
-#endif
-
-#if !defined(CONFIG_IA64_SGI_SN1)
-
-static status __init
-register_with_devfs(void)
-{
-	struct pci_dev * dev = NULL;
-	devfs_handle_t device_dir_handle;
-	char devfs_path[40];
-
-	TRACE();
-
-	if (!devfs_mk_dir(NULL, "pci", NULL))
-		return failure;
-
-	/* FIXME: don't forget /dev/pci/mem & /dev/pci/io */
-
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-		sprintf(devfs_path, "pci/%02x/%02x.%x",
-			dev->bus->number,
-			PCI_SLOT(dev->devfn),
-			PCI_FUNC(dev->devfn));
-    
-		device_dir_handle =
-			devfs_mk_dir(NULL, devfs_path, NULL);
-		if (device_dir_handle == NULL)
-			return failure;
-
-		if (register_pci_device(device_dir_handle, dev) == failure) {
-			devfs_remove("pci");
-			return failure;
-		}
-	}
-
-	return success;
-}
-
-#else
-
-extern devfs_handle_t
-devfn_to_vertex(unsigned char busnum, unsigned int devfn);
-
-static status __init
-register_with_devfs(void)
-{
-	struct pci_dev * dev = NULL;
-	devfs_handle_t device_dir_handle;
-
-	TRACE();
-
-	/* FIXME: don't forget /dev/.../pci/mem & /dev/.../pci/io */
-
-	while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
-		device_dir_handle = devfn_to_vertex(dev->bus->number,
-						    dev->devfn);
-		if (device_dir_handle == NULL)
-			return failure;
-	
-		if (register_pci_device(device_dir_handle, dev) == failure) {
-			devfs_remove("pci");
-			return failure;
-		}
-	}
-
-	return success;
-}
-
-static void __exit
-unregister_with_devfs(void)
-{
-	struct list_head * lhp;
-	struct node_data * nd;
-	
-	TRACE();
-
-	list_for_each(lhp, &global_node_list) {
-		nd = list_entry(lhp, struct node_data, global_node_list);
-		devfs_unregister(nd->devfs_handle);
-	}
-
-}
-
-
-struct node_data * new_node(void)
-{
-	struct node_data * node;
-	
-	TRACE();
-	
-	node = kmalloc(sizeof(struct node_data), GFP_KERNEL);
-	if (node == NULL)
-		return NULL;
-	list_add(&node->global_node_list, &global_node_list);
-	return node;
-}
-
-
-void dma_cleanup(struct node_data * dma_node)
-{
-	TRACE();
-
-	/* FIXME: should free these allocations */
-#ifdef DEBUG_PCIBA
-	dump_allocations(&dma_node->u.dma.dma_allocs);
-#endif
-	devfs_unregister(dma_node->devfs_handle);
-}
-
-
-void init_dma_node(struct node_data * node,
-		   struct pci_dev * dev, devfs_handle_t dh)
-{
-	TRACE();
-
-	node->devfs_handle = dh;
-	node->u.dma.dev = dev;
-	node->cleanup = dma_cleanup;
-	INIT_LIST_HEAD(&node->u.dma.dma_allocs);
-}
-
-
-void rom_cleanup(struct node_data * rom_node)
-{
-	TRACE();
-
-	if (rom_node->u.rom.mmapped)
-		pci_write_config_dword(rom_node->u.rom.dev,
-				       PCI_ROM_ADDRESS,
-				       rom_node->u.rom.saved_rom_base_reg);
-	devfs_unregister(rom_node->devfs_handle);
-}
-
-
-void init_rom_node(struct node_data * node,
-		   struct pci_dev * dev, devfs_handle_t dh)
-{
-	TRACE();
-
-	node->devfs_handle = dh;
-	node->u.rom.dev = dev;
-	node->cleanup = rom_cleanup;
-	node->u.rom.mmapped = false;
-}
-
-
-static status __init
-register_pci_device(devfs_handle_t device_dir_handle, struct pci_dev * dev)
-{
-	struct node_data * nd;
-	char devfs_path[20];
-	devfs_handle_t node_devfs_handle;
-	int ri;
-
-	TRACE();
-
-
-	/* register nodes for all the device's base address registers */
-	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
-		if (pci_resource_len(dev, ri) != 0) {
-			sprintf(devfs_path, "base/%d", ri);
-			if (devfs_register(device_dir_handle, devfs_path,
-					   DEVFS_FL_NONE,
-					   0, 0,
-					   S_IFREG | S_IRUSR | S_IWUSR,
-					   &base_fops, 
-					   &dev->resource[ri]) == NULL)
-				return failure;
-		}
-	}
-	
-	/* register a node corresponding to the first MEM resource on
-           the device */
-	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
-		if (dev->resource[ri].flags & IORESOURCE_MEM &&
-		    pci_resource_len(dev, ri) != 0) {
-			if (devfs_register(device_dir_handle, "mem",
-					   DEVFS_FL_NONE, 0, 0,
-					   S_IFREG | S_IRUSR | S_IWUSR,
-					   &base_fops, 
-					   &dev->resource[ri]) == NULL)
-				return failure;
-			break;
-		}
-	}
-
-	/* also register a node corresponding to the first IO resource
-           on the device */
-	for (ri = 0; ri < PCI_ROM_RESOURCE; ri++) {
-		if (dev->resource[ri].flags & IORESOURCE_IO &&
-		    pci_resource_len(dev, ri) != 0) {
-			if (devfs_register(device_dir_handle, "io",
-					   DEVFS_FL_NONE, 0, 0,
-					   S_IFREG | S_IRUSR | S_IWUSR,
-					   &base_fops, 
-					   &dev->resource[ri]) == NULL)
-				return failure;
-			break;
-		}
-	}
-
-	/* register a node corresponding to the device's ROM resource,
-           if present */
-	if (pci_resource_len(dev, PCI_ROM_RESOURCE) != 0) {
-		nd = new_node();
-		if (nd == NULL)
-			return failure;
-		node_devfs_handle = devfs_register(device_dir_handle, "rom",
-						   DEVFS_FL_NONE, 0, 0,
-						   S_IFREG | S_IRUSR,
-						   &rom_fops, nd);
-		if (node_devfs_handle == NULL)
-			return failure;
-		init_rom_node(nd, dev, node_devfs_handle);
-	}
-
-	/* register a node that allows ioctl's to read and write to
-           the device's config space */
-	if (devfs_register(device_dir_handle, "config", DEVFS_FL_NONE,
-			   0, 0, S_IFREG | S_IRUSR | S_IWUSR,
-			   &config_fops, dev) == NULL)
-		return failure;
-
-
-	/* finally, register a node that allows ioctl's to allocate
-           and free DMA buffers, as well as memory map those
-           buffers. */
-	nd = new_node();
-	if (nd == NULL)
-		return failure;
-	node_devfs_handle =
-		devfs_register(device_dir_handle, "dma", DEVFS_FL_NONE,
-			       0, 0, S_IFREG | S_IRUSR | S_IWUSR,
-			       &dma_fops, nd);
-	if (node_devfs_handle == NULL)
-		return failure;
-	init_dma_node(nd, dev, node_devfs_handle);
-
-#ifdef DEBUG_PCIBA
-	dump_nodes(&global_node_list);
-#endif
-	
-	return success;
-}
-
-
-static int
-generic_open(struct inode * inode, struct file * file)
-{
-	TRACE();
-
-	/* FIXME: should check that they're not trying to open the ROM
-           writable */
-
-	return 0; /* success */
-}
-
-
-static int
-rom_mmap(struct file * file, struct vm_area_struct * vma)
-{
-	unsigned long pci_pa;
-	struct node_data * nd;
-
-	TRACE();
-
-	nd = (struct node_data * )file->private_data;
-
-	pci_pa = pci_resource_start(nd->u.rom.dev, PCI_ROM_RESOURCE);
-
-	if (!nd->u.rom.mmapped) {
-		nd->u.rom.mmapped = true;
-		DPRINTF("Enabling ROM address decoder.\n");
-		DPRINTF(
-"rom_mmap: FIXME: some cards do not allow both ROM and memory addresses to\n"
-"rom_mmap: FIXME: be enabled simultaneously, as they share a decoder.\n");
-		pci_read_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
-				      &nd->u.rom.saved_rom_base_reg);
-		DPRINTF("ROM base address contains %x\n",
-			nd->u.rom.saved_rom_base_reg);
-		pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
-				       nd->u.rom.saved_rom_base_reg |
-				       PCI_ROM_ADDRESS_ENABLE);
-	}
-	
-	return mmap_pci_address(vma, pci_pa);
-}
-
-
-static int
-rom_release(struct inode * inode, struct file * file)
-{
-	struct node_data * nd;
-
-	TRACE();
-
-	nd = (struct node_data * )file->private_data;
-
-	if (nd->u.rom.mmapped) {
-		nd->u.rom.mmapped = false;
-		DPRINTF("Disabling ROM address decoder.\n");
-		pci_write_config_dword(nd->u.rom.dev, PCI_ROM_ADDRESS,
-				       nd->u.rom.saved_rom_base_reg);
-	}
-	return 0; /* indicate success */
-}
-
-
-static int
-base_mmap(struct file * file, struct vm_area_struct * vma)
-{
-	struct resource * resource;
-
-	TRACE();
-
-	resource = (struct resource *)file->private_data;
-
-	return mmap_pci_address(vma, resource->start);
-}
-
-
-static int
-config_ioctl(struct inode * inode, struct file * file, 
-	     unsigned int cmd, 
-	     unsigned long arg)
-{
-	struct pci_dev * dev;
-
-	union cfg_data {
-		uint8_t byte;
-		uint16_t word;
-		uint32_t dword;
-	} read_data, write_data;
-
-	int dir, size, offset;
-
-	TRACE();
-
-	DPRINTF("cmd = %x (DIR = %x, TYPE = %x, NR = %x, SIZE = %x)\n", 
-		cmd, 
-		_IOC_DIR(cmd), _IOC_TYPE(cmd), _IOC_NR(cmd), _IOC_SIZE(cmd));
-	DPRINTF("arg = %lx\n", arg);
-
-	dev = (struct pci_dev *)file->private_data;
-
-	/* PCIIOCCFG{RD,WR}: read and/or write PCI configuration
-	   space. If both, the read happens first (this becomes a swap
-	   operation, atomic with respect to other updates through
-	   this path).  */
-
-	dir = _IOC_DIR(cmd);
-
-#define do_swap(suffix, type)	 					\
-	do {								\
-		if (dir & _IOC_READ) {					\
-			pci_read_config_##suffix(dev, _IOC_NR(cmd), 	\
-						 &read_data.suffix);	\
-		}							\
-		if (dir & _IOC_WRITE) {					\
-			get_user(write_data.suffix, (type)arg);		\
-			pci_write_config_##suffix(dev, _IOC_NR(cmd), 	\
-						  write_data.suffix);	\
-		}							\
-		if (dir & _IOC_READ) {					\
-			put_user(read_data.suffix, (type)arg);		\
-		}							\
-	} while (0)
-
-	size = _IOC_SIZE(cmd);
-	offset = _IOC_NR(cmd);
-
-	DPRINTF("sanity check\n");
-	if (((size > 0) || (size <= 4)) &&
-	    ((offset + size) <= 256) &&
-	    (dir & (_IOC_READ | _IOC_WRITE))) {
-
-		switch (size)
-		{
-		case 1:
-			do_swap(byte, uint8_t *);
-			break;
-		case 2:
-			do_swap(word, uint16_t *);
-			break;
-		case 4:
-			do_swap(dword, uint32_t *);
-			break;
-		default:
-			DPRINTF("invalid ioctl\n");
-			return -EINVAL;
-		}
-	} else
-		return -EINVAL;
-		
-	return 0;
-}
-
-
-#ifdef DEBUG_PCIBA
-static void
-dump_allocations(struct list_head * dalp)
-{
-	struct dma_allocation * dap;
-	struct list_head * p;
-	
-	printk("{\n");
-	list_for_each(p, dalp) {
-		dap = list_entry(p, struct dma_allocation, 
-				 list);
-		printk("  handle = %lx, va = %p\n",
-		       dap->handle, dap->va);
-	}
-	printk("}\n");
-}
-
-static void
-dump_nodes(struct list_head * nodes)
-{
-	struct node_data * ndp;
-	struct list_head * p;
-	
-	printk("{\n");
-	list_for_each(p, nodes) {
-		ndp = list_entry(p, struct node_data, 
-				 global_node_list);
-		printk("  %p\n", (void *)ndp);
-	}
-	printk("}\n");
-}
-
-
-#if 0
-#define NEW(ptr) (ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-
-static void
-test_list(void)
-{
-	u64 i;
-	LIST_HEAD(the_list);
-
-	for (i = 0; i < 5; i++) {
-		struct dma_allocation * new_alloc;
-		NEW(new_alloc);
-		new_alloc->va = (void *)i;
-		new_alloc->handle = 5*i;
-		printk("%d - the_list->next = %lx\n", i, the_list.next);
-		list_add(&new_alloc->list, &the_list);
-	}
-	dump_allocations(&the_list);
-}
-#endif
-#endif
-
-
-static LIST_HEAD(dma_buffer_list);
-
-
-static int
-dma_ioctl(struct inode * inode, struct file * file, 
-	  unsigned int cmd, 
-	  unsigned long arg)
-{
-	struct node_data * nd;
-	uint64_t argv;
-	int result;
-	struct dma_allocation * dma_alloc;
-	struct list_head * iterp;
-
-	TRACE();
-
-	DPRINTF("cmd = %x\n", cmd);
-	DPRINTF("arg = %lx\n", arg);
-
-	nd = (struct node_data *)file->private_data;
-
-#ifdef DEBUG_PCIBA
-	DPRINTF("at dma_ioctl entry\n");
-	dump_allocations(&nd->u.dma.dma_allocs);
-#endif
-
-	switch (cmd) {
-	case PCIIOCDMAALLOC:
-		/* PCIIOCDMAALLOC: allocate a chunk of physical memory
-		   and set it up for DMA. Return the PCI address that
-		   gets to it.  */
-		DPRINTF("case PCIIOCDMAALLOC (%lx)\n", PCIIOCDMAALLOC);
-		
-		if ( (result = get_user(argv, (uint64_t *)arg)) )
-			return result;
-		DPRINTF("argv (size of buffer) = %lx\n", argv);
-
-		dma_alloc = (struct dma_allocation *)
-			kmalloc(sizeof(struct dma_allocation), GFP_KERNEL);
-		if (dma_alloc == NULL)
-			return -ENOMEM;
-
-		dma_alloc->size = (size_t)argv;
-		dma_alloc->va = pci_alloc_consistent(nd->u.dma.dev,
-						     dma_alloc->size,
-						     &dma_alloc->handle);
-		DPRINTF("dma_alloc->va = %p, dma_alloc->handle = %lx\n",
-			dma_alloc->va, dma_alloc->handle);
-		if (dma_alloc->va == NULL) {
-			kfree(dma_alloc);
-			return -ENOMEM;
-		}
-
-		list_add(&dma_alloc->list, &nd->u.dma.dma_allocs);
-		if ( (result = put_user((uint64_t)dma_alloc->handle, 
-				      (uint64_t *)arg)) ) {
-			DPRINTF("put_user failed\n");
-			pci_free_consistent(nd->u.dma.dev, (size_t)argv,
-					    dma_alloc->va, dma_alloc->handle);
-			kfree(dma_alloc);
-			return result;
-		}
-
-#ifdef DEBUG_PCIBA
-		DPRINTF("after insertion\n");
-		dump_allocations(&nd->u.dma.dma_allocs);
-#endif
-		break;
-
-	case PCIIOCDMAFREE:
-		DPRINTF("case PCIIOCDMAFREE (%lx)\n", PCIIOCDMAFREE);
-
-		if ( (result = get_user(argv, (uint64_t *)arg)) ) {
-			DPRINTF("get_user failed\n");
-			return result;
-		}
-
-		DPRINTF("argv (physical address of DMA buffer) = %lx\n", argv);
-		list_for_each(iterp, &nd->u.dma.dma_allocs) {
-			struct dma_allocation * da =
-				list_entry(iterp, struct dma_allocation, list);
-			if (da->handle == argv) {
-				pci_free_consistent(nd->u.dma.dev, da->size,
-						    da->va, da->handle);
-				list_del(&da->list);
-				kfree(da);
-#ifdef DEBUG_PCIBA
-				DPRINTF("after deletion\n");
-				dump_allocations(&nd->u.dma.dma_allocs);
-#endif
-				return 0; /* success */
-			}
-		}
-		/* previously allocated dma buffer wasn't found */
-		DPRINTF("attempt to free invalid dma handle\n");
-		return -EINVAL;
-
-	default:
-		DPRINTF("undefined ioctl\n");
-		return -EINVAL;
-	}
-
-	DPRINTF("success\n");
-	return 0;
-}
-		
-
-static int
-dma_mmap(struct file * file, struct vm_area_struct * vma)
-{
-	struct node_data * nd;
-	struct list_head * iterp;
-	int result;
-	
-	TRACE();
-
-	nd = (struct node_data *)file->private_data;
-	
-	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
-	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
-	DPRINTF("offset = %lx\n", vma->vm_pgoff);
-
-	/* get kernel virtual address for the dma buffer (necessary
-	 * for the mmap). */
-	list_for_each(iterp, &nd->u.dma.dma_allocs) {
-		struct dma_allocation * da =
-			list_entry(iterp, struct dma_allocation, list);
-		/* why does mmap shift its offset argument? */
-		if (da->handle == vma->vm_pgoff << PAGE_SHIFT) {
-			DPRINTF("found dma handle\n");
-			if ( (result = mmap_kernel_address(vma,
-							   da->va)) ) {
-				return result; /* failure */
-			} else {
-				/* it seems like at least one of these
-				   should show up in user land....
-				   I'm missing something */
-				*(char *)da->va = 0xaa;
-				strncpy(da->va, "        Toastie!", da->size);
-				if (put_user(0x18badbeeful,
-					     (u64 *)vma->vm_start))
-					DPRINTF("put_user failed?!\n");
-				return 0; /* success */
-			}
-
-		}
-	}
-	DPRINTF("attempt to mmap an invalid dma handle\n");
-	return -EINVAL;
-}
-
-
-static int
-mmap_pci_address(struct vm_area_struct * vma, unsigned long pci_va)
-{
-	unsigned long pci_pa;
-
-	TRACE();
-
-	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
-	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
-
-	/* the size of the vma doesn't necessarily correspond to the
-           size specified in the mmap call.  So we can't really do any
-           kind of sanity check here.  This is a dangerous driver, and
-           it's very easy for a user process to kill the machine.  */
-
-	DPRINTF("PCI base at virtual address %lx\n", pci_va);
-	/* the __pa macro is intended for region 7 on IA64, so it
-	   doesn't work for region 6 */
-  	/* pci_pa = __pa(pci_va); */
-	/* should be replaced by __tpa or equivalent (preferably a
-	   generic equivalent) */
-	pci_pa = pci_va & ~0xe000000000000000ul;
-	DPRINTF("PCI base at physical address %lx\n", pci_pa);
-
-	/* there are various arch-specific versions of this function
-           defined in linux/drivers/char/mem.c, but it would be nice
-           if all architectures put it in pgtable.h.  it's defined
-           there for ia64.... */
-	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
-
-	vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
-
-	return io_remap_page_range(vma->vm_start, pci_pa, 
-				   vma->vm_end-vma->vm_start,
-				   vma->vm_page_prot);
-}
-
-
-static int
-mmap_kernel_address(struct vm_area_struct * vma, void * kernel_va)
-{
-	unsigned long kernel_pa;
-
-	TRACE();
-
-	DPRINTF("vma->vm_start is %lx\n", vma->vm_start);
-	DPRINTF("vma->vm_end is %lx\n", vma->vm_end);
-
-	/* the size of the vma doesn't necessarily correspond to the
-           size specified in the mmap call.  So we can't really do any
-           kind of sanity check here.  This is a dangerous driver, and
-           it's very easy for a user process to kill the machine.  */
-
-	DPRINTF("mapping virtual address %p\n", kernel_va);
-	kernel_pa = __pa(kernel_va);
-	DPRINTF("mapping physical address %lx\n", kernel_pa);
-
-	vma->vm_flags |= VM_NONCACHED | VM_RESERVED | VM_IO;
-
-	return remap_page_range(vma->vm_start, kernel_pa, 
-				vma->vm_end-vma->vm_start,
-				vma->vm_page_prot);
-}	
diff -Nru a/arch/ia64/sn/io/pciio.c b/arch/ia64/sn/io/pciio.c
--- a/arch/ia64/sn/io/pciio.c	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1507 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#define	USRPCI	0
-
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/xtalk/xbow.h>	/* Must be before iograph.h to get MAX_PORT_NUM */
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/ioerror_handling.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pciio_private.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/io.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/simulator.h>
-
-#define DEBUG_PCIIO
-#undef DEBUG_PCIIO	/* turn this on for yet more console output */
-
-
-#define GET_NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define DO_DEL(ptr)	(kfree(ptr))
-
-char                    pciio_info_fingerprint[] = "pciio_info";
-
-cdl_p                   pciio_registry = NULL;
-
-int
-badaddr_val(volatile void *addr, int len, volatile void *ptr)
-{
-	int ret = 0;
-	volatile void *new_addr;
-
-	switch (len) {
-		case 4:
-			new_addr = (void *)(((u64) addr)^4);
-			ret = ia64_sn_probe_io_slot((long)new_addr, len, (void *)ptr);
-			break;
-		default:
-			printk(KERN_WARNING "badaddr_val given len %x but supports len of 4 only\n", len);
-	}
-
-	if (ret < 0)
-		panic("badaddr_val: unexpected status (%d) in probing", ret);
-	return(ret);
-
-}
-
-
-nasid_t
-get_console_nasid(void)
-{
-	extern nasid_t console_nasid;
-	if (console_nasid < 0) {
-		console_nasid = ia64_sn_get_console_nasid();
-		if (console_nasid < 0) {
-// ZZZ What do we do if we don't get a console nasid on the hardware????
-			if (IS_RUNNING_ON_SIMULATOR() )
-				console_nasid = master_nasid;
-		}
-	} 
-	return console_nasid;
-}
-
-int
-hub_dma_enabled(devfs_handle_t xconn_vhdl)
-{
-	return(0);
-}
-
-int
-hub_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code)
-{
-	return(0);
-}
-
-void
-ioerror_dump(char *name, int error_code, int error_mode, ioerror_t *ioerror)
-{
-}
-
-/******
- ****** end hack defines ......
- ******/
-
-
-
-
-/* =====================================================================
- *    PCI Generic Bus Provider
- * Implement PCI provider operations.  The pciio* layer provides a
- * platform-independent interface for PCI devices.  This layer
- * switches among the possible implementations of a PCI adapter.
- */
-
-/* =====================================================================
- *    Provider Function Location SHORTCUT
- *
- * On platforms with only one possible PCI provider, macros can be
- * set up at the top that cause the table lookups and indirections to
- * completely disappear.
- */
-
-#if defined(CONFIG_IA64_SGI_SN1)
-/*
- *    For the moment, we will assume that IP27
- *      only use Bridge ASICs to provide PCI support.
- */
-#include <asm/sn/pci/pcibr.h>
-#define DEV_FUNC(dev,func)	pcibr_##func
-#define CAST_PIOMAP(x)		((pcibr_piomap_t)(x))
-#define CAST_DMAMAP(x)		((pcibr_dmamap_t)(x))
-#define CAST_INTR(x)		((pcibr_intr_t)(x))
-#endif /* CONFIG_IA64_SGI_SN1 */
-
-/* =====================================================================
- *    Function Table of Contents
- */
-
-#if !defined(DEV_FUNC)
-static pciio_provider_t *pciio_to_provider_fns(devfs_handle_t dev);
-#endif
-
-pciio_piomap_t          pciio_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
-void                    pciio_piomap_free(pciio_piomap_t);
-caddr_t                 pciio_piomap_addr(pciio_piomap_t, iopaddr_t, size_t);
-
-void                    pciio_piomap_done(pciio_piomap_t);
-caddr_t                 pciio_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-caddr_t			pciio_pio_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned);
-
-iopaddr_t               pciio_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
-void                    pciio_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
-
-pciio_dmamap_t          pciio_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
-void                    pciio_dmamap_free(pciio_dmamap_t);
-iopaddr_t               pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t);
-alenlist_t              pciio_dmamap_list(pciio_dmamap_t, alenlist_t, unsigned);
-void                    pciio_dmamap_done(pciio_dmamap_t);
-iopaddr_t               pciio_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              pciio_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
-void			pciio_dmamap_drain(pciio_dmamap_t);
-void			pciio_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
-void			pciio_dmalist_drain(devfs_handle_t, alenlist_t);
-iopaddr_t               pciio_dma_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned);
-
-pciio_intr_t            pciio_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
-void                    pciio_intr_free(pciio_intr_t);
-int                     pciio_intr_connect(pciio_intr_t);
-void                    pciio_intr_disconnect(pciio_intr_t);
-devfs_handle_t            pciio_intr_cpu_get(pciio_intr_t);
-
-void			pciio_slot_func_to_name(char *, pciio_slot_t, pciio_function_t);
-
-void                    pciio_provider_startup(devfs_handle_t);
-void                    pciio_provider_shutdown(devfs_handle_t);
-
-pciio_endian_t          pciio_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
-pciio_priority_t        pciio_priority_set(devfs_handle_t, pciio_priority_t);
-devfs_handle_t            pciio_intr_dev_get(pciio_intr_t);
-
-devfs_handle_t            pciio_pio_dev_get(pciio_piomap_t);
-pciio_slot_t            pciio_pio_slot_get(pciio_piomap_t);
-pciio_space_t           pciio_pio_space_get(pciio_piomap_t);
-iopaddr_t               pciio_pio_pciaddr_get(pciio_piomap_t);
-ulong                   pciio_pio_mapsz_get(pciio_piomap_t);
-caddr_t                 pciio_pio_kvaddr_get(pciio_piomap_t);
-
-devfs_handle_t            pciio_dma_dev_get(pciio_dmamap_t);
-pciio_slot_t            pciio_dma_slot_get(pciio_dmamap_t);
-
-pciio_info_t            pciio_info_chk(devfs_handle_t);
-pciio_info_t            pciio_info_get(devfs_handle_t);
-void                    pciio_info_set(devfs_handle_t, pciio_info_t);
-devfs_handle_t            pciio_info_dev_get(pciio_info_t);
-pciio_slot_t            pciio_info_slot_get(pciio_info_t);
-pciio_function_t        pciio_info_function_get(pciio_info_t);
-pciio_vendor_id_t       pciio_info_vendor_id_get(pciio_info_t);
-pciio_device_id_t       pciio_info_device_id_get(pciio_info_t);
-devfs_handle_t            pciio_info_master_get(pciio_info_t);
-arbitrary_info_t        pciio_info_mfast_get(pciio_info_t);
-pciio_provider_t       *pciio_info_pops_get(pciio_info_t);
-error_handler_f	       *pciio_info_efunc_get(pciio_info_t);
-error_handler_arg_t    *pciio_info_einfo_get(pciio_info_t);
-pciio_space_t		pciio_info_bar_space_get(pciio_info_t, int);
-iopaddr_t		pciio_info_bar_base_get(pciio_info_t, int);
-size_t			pciio_info_bar_size_get(pciio_info_t, int);
-iopaddr_t		pciio_info_rom_base_get(pciio_info_t);
-size_t			pciio_info_rom_size_get(pciio_info_t);
-
-void                    pciio_init(void);
-int                     pciio_attach(devfs_handle_t);
-
-void                    pciio_provider_register(devfs_handle_t, pciio_provider_t *pciio_fns);
-void                    pciio_provider_unregister(devfs_handle_t);
-pciio_provider_t       *pciio_provider_fns_get(devfs_handle_t);
-
-int                     pciio_driver_register(pciio_vendor_id_t, pciio_device_id_t, char *driver_prefix, unsigned);
-void                    pciio_driver_unregister(char *driver_prefix);
-
-devfs_handle_t            pciio_device_register(devfs_handle_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
-
-void			pciio_device_unregister(devfs_handle_t);
-pciio_info_t		pciio_device_info_new(pciio_info_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
-void			pciio_device_info_free(pciio_info_t);
-devfs_handle_t		pciio_device_info_register(devfs_handle_t, pciio_info_t);
-void			pciio_device_info_unregister(devfs_handle_t, pciio_info_t);
-int                     pciio_device_attach(devfs_handle_t, int);
-int			pciio_device_detach(devfs_handle_t, int);
-void                    pciio_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t);
-
-int                     pciio_reset(devfs_handle_t);
-int                     pciio_write_gather_flush(devfs_handle_t);
-int                     pciio_slot_inuse(devfs_handle_t);
-
-/* =====================================================================
- *    Provider Function Location
- *
- *      If there is more than one possible provider for
- *      this platform, we need to examine the master
- *      vertex of the current vertex for a provider
- *      function structure, and indirect through the
- *      appropriately named member.
- */
-
-#if !defined(DEV_FUNC)
-
-static pciio_provider_t *
-pciio_to_provider_fns(devfs_handle_t dev)
-{
-    pciio_info_t            card_info;
-    pciio_provider_t       *provider_fns;
-
-    /*
-     * We're called with two types of vertices, one is
-     * the bridge vertex (ends with "pci") and the other is the
-     * pci slot vertex (ends with "pci/[0-8]").  For the first type
-     * we need to get the provider from the PFUNCS label.  For
-     * the second we get it from fastinfo/c_pops.
-     */
-    provider_fns = pciio_provider_fns_get(dev);
-    if (provider_fns == NULL) {
-	card_info = pciio_info_get(dev);
-	if (card_info != NULL) {
-		provider_fns = pciio_info_pops_get(card_info);
-	}
-    }
-
-    if (provider_fns == NULL)
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-	PRINT_PANIC("%v: provider_fns == NULL", dev);
-#else
-	PRINT_PANIC("0x%p: provider_fns == NULL", (void *)dev);
-#endif
-
-    return provider_fns;
-
-}
-
-#define DEV_FUNC(dev,func)	pciio_to_provider_fns(dev)->func
-#define CAST_PIOMAP(x)		((pciio_piomap_t)(x))
-#define CAST_DMAMAP(x)		((pciio_dmamap_t)(x))
-#define CAST_INTR(x)		((pciio_intr_t)(x))
-#endif
-
-/*
- * Many functions are not passed their vertex
- * information directly; rather, they must
- * dive through a resource map. These macros
- * are available to coordinate this detail.
- */
-#define PIOMAP_FUNC(map,func)		DEV_FUNC((map)->pp_dev,func)
-#define DMAMAP_FUNC(map,func)		DEV_FUNC((map)->pd_dev,func)
-#define INTR_FUNC(intr_hdl,func)	DEV_FUNC((intr_hdl)->pi_dev,func)
-
-/* =====================================================================
- *          PIO MANAGEMENT
- *
- *      For mapping system virtual address space to
- *      pciio space on a specified card
- */
-
-pciio_piomap_t
-pciio_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
-		   iopaddr_t addr,	/* lowest address (or offset in window) */
-		   size_t byte_count,	/* size of region containing our mappings */
-		   size_t byte_count_max,	/* maximum size of a mapping */
-		   unsigned flags)
-{					/* defined in sys/pio.h */
-    return (pciio_piomap_t) DEV_FUNC(dev, piomap_alloc)
-	(dev, dev_desc, space, addr, byte_count, byte_count_max, flags);
-}
-
-void
-pciio_piomap_free(pciio_piomap_t pciio_piomap)
-{
-    PIOMAP_FUNC(pciio_piomap, piomap_free)
-	(CAST_PIOMAP(pciio_piomap));
-}
-
-caddr_t
-pciio_piomap_addr(pciio_piomap_t pciio_piomap,	/* mapping resources */
-		  iopaddr_t pciio_addr,	/* map for this pciio address */
-		  size_t byte_count)
-{					/* map this many bytes */
-    pciio_piomap->pp_kvaddr = PIOMAP_FUNC(pciio_piomap, piomap_addr)
-	(CAST_PIOMAP(pciio_piomap), pciio_addr, byte_count);
-
-    return pciio_piomap->pp_kvaddr;
-}
-
-void
-pciio_piomap_done(pciio_piomap_t pciio_piomap)
-{
-    PIOMAP_FUNC(pciio_piomap, piomap_done)
-	(CAST_PIOMAP(pciio_piomap));
-}
-
-caddr_t
-pciio_piotrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
-		    iopaddr_t addr,	/* starting address (or offset in window) */
-		    size_t byte_count,	/* map this many bytes */
-		    unsigned flags)
-{					/* (currently unused) */
-    return DEV_FUNC(dev, piotrans_addr)
-	(dev, dev_desc, space, addr, byte_count, flags);
-}
-
-caddr_t
-pciio_pio_addr(devfs_handle_t dev,	/* translate for this device */
-	       device_desc_t dev_desc,	/* device descriptor */
-	       pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
-	       iopaddr_t addr,		/* starting address (or offset in window) */
-	       size_t byte_count,	/* map this many bytes */
-	       pciio_piomap_t *mapp,	/* where to return the map pointer */
-	       unsigned flags)
-{					/* PIO flags */
-    pciio_piomap_t          map = 0;
-    int			    errfree = 0;
-    caddr_t                 res;
-
-    if (mapp) {
-	map = *mapp;			/* possible pre-allocated map */
-	*mapp = 0;			/* record "no map used" */
-    }
-
-    res = pciio_piotrans_addr
-	(dev, dev_desc, space, addr, byte_count, flags);
-    if (res)
-	return res;			/* pciio_piotrans worked */
-
-    if (!map) {
-	map = pciio_piomap_alloc
-	    (dev, dev_desc, space, addr, byte_count, byte_count, flags);
-	if (!map)
-	    return res;			/* pciio_piomap_alloc failed */
-	errfree = 1;
-    }
-
-    res = pciio_piomap_addr
-	(map, addr, byte_count);
-    if (!res) {
-	if (errfree)
-	    pciio_piomap_free(map);
-	return res;			/* pciio_piomap_addr failed */
-    }
-    if (mapp)
-	*mapp = map;			/* pass back map used */
-
-    return res;				/* pciio_piomap_addr succeeded */
-}
-
-iopaddr_t
-pciio_piospace_alloc(devfs_handle_t dev,	/* Device requiring space */
-		     device_desc_t dev_desc,	/* Device descriptor */
-		     pciio_space_t space,	/* MEM32/MEM64/IO */
-		     size_t byte_count,	/* Size of mapping */
-		     size_t align)
-{					/* Alignment needed */
-    if (align < NBPP)
-	align = NBPP;
-    return DEV_FUNC(dev, piospace_alloc)
-	(dev, dev_desc, space, byte_count, align);
-}
-
-void
-pciio_piospace_free(devfs_handle_t dev,	/* Device freeing space */
-		    pciio_space_t space,	/* Type of space        */
-		    iopaddr_t pciaddr,	/* starting address */
-		    size_t byte_count)
-{					/* Range of address   */
-    DEV_FUNC(dev, piospace_free)
-	(dev, space, pciaddr, byte_count);
-}
-
-/* =====================================================================
- *          DMA MANAGEMENT
- *
- *      For mapping from pci space to system
- *      physical space.
- */
-
-pciio_dmamap_t
-pciio_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   size_t byte_count_max,	/* max size of a mapping */
-		   unsigned flags)
-{					/* defined in dma.h */
-    return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
-	(dev, dev_desc, byte_count_max, flags);
-}
-
-void
-pciio_dmamap_free(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_free)
-	(CAST_DMAMAP(pciio_dmamap));
-}
-
-iopaddr_t
-pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap,	/* use these mapping resources */
-		  paddr_t paddr,	/* map for this address */
-		  size_t byte_count)
-{					/* map this many bytes */
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_addr)
-	(CAST_DMAMAP(pciio_dmamap), paddr, byte_count);
-}
-
-alenlist_t
-pciio_dmamap_list(pciio_dmamap_t pciio_dmamap,	/* use these mapping resources */
-		  alenlist_t alenlist,	/* map this Address/Length List */
-		  unsigned flags)
-{
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_list)
-	(CAST_DMAMAP(pciio_dmamap), alenlist, flags);
-}
-
-void
-pciio_dmamap_done(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_done)
-	(CAST_DMAMAP(pciio_dmamap));
-}
-
-iopaddr_t
-pciio_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    paddr_t paddr,	/* system physical address */
-		    size_t byte_count,	/* length */
-		    unsigned flags)
-{					/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_addr)
-	(dev, dev_desc, paddr, byte_count, flags);
-}
-
-alenlist_t
-pciio_dmatrans_list(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    alenlist_t palenlist,	/* system address/length list */
-		    unsigned flags)
-{					/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_list)
-	(dev, dev_desc, palenlist, flags);
-}
-
-iopaddr_t
-pciio_dma_addr(devfs_handle_t dev,	/* translate for this device */
-	       device_desc_t dev_desc,	/* device descriptor */
-	       paddr_t paddr,		/* system physical address */
-	       size_t byte_count,	/* length */
-	       pciio_dmamap_t *mapp,	/* map to use, then map we used */
-	       unsigned flags)
-{					/* PIO flags */
-    pciio_dmamap_t          map = 0;
-    int			    errfree = 0;
-    iopaddr_t               res;
-
-    if (mapp) {
-	map = *mapp;			/* possible pre-allocated map */
-	*mapp = 0;			/* record "no map used" */
-    }
-
-    res = pciio_dmatrans_addr
-	(dev, dev_desc, paddr, byte_count, flags);
-    if (res)
-	return res;			/* pciio_dmatrans worked */
-
-    if (!map) {
-	map = pciio_dmamap_alloc
-	    (dev, dev_desc, byte_count, flags);
-	if (!map)
-	    return res;			/* pciio_dmamap_alloc failed */
-	errfree = 1;
-    }
-
-    res = pciio_dmamap_addr
-	(map, paddr, byte_count);
-    if (!res) {
-	if (errfree)
-	    pciio_dmamap_free(map);
-	return res;			/* pciio_dmamap_addr failed */
-    }
-    if (mapp)
-	*mapp = map;			/* pass back map used */
-
-    return res;				/* pciio_dmamap_addr succeeded */
-}
-
-void
-pciio_dmamap_drain(pciio_dmamap_t map)
-{
-    DMAMAP_FUNC(map, dmamap_drain)
-	(CAST_DMAMAP(map));
-}
-
-void
-pciio_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
-{
-    DEV_FUNC(dev, dmaaddr_drain)
-	(dev, addr, size);
-}
-
-void
-pciio_dmalist_drain(devfs_handle_t dev, alenlist_t list)
-{
-    DEV_FUNC(dev, dmalist_drain)
-	(dev, list);
-}
-
-/* =====================================================================
- *          INTERRUPT MANAGEMENT
- *
- *      Allow crosstalk devices to establish interrupts
- */
-
-/*
- * Allocate resources required for an interrupt as specified in intr_desc.
- * Return resource handle in intr_hdl.
- */
-pciio_intr_t
-pciio_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */
-		 device_desc_t dev_desc,	/* device descriptor */
-		 pciio_intr_line_t lines,	/* INTR line(s) to attach */
-		 devfs_handle_t owner_dev)
-{					/* owner of this interrupt */
-    return (pciio_intr_t) DEV_FUNC(dev, intr_alloc)
-	(dev, dev_desc, lines, owner_dev);
-}
-
-/*
- * Free resources consumed by intr_alloc.
- */
-void
-pciio_intr_free(pciio_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_free)
-	(CAST_INTR(intr_hdl));
-}
-
-/*
- * Associate resources allocated with a previous pciio_intr_alloc call with the
- * described handler, arg, name, etc.
- *
- * Returns 0 on success, returns <0 on failure.
- */
-int
-pciio_intr_connect(pciio_intr_t intr_hdl)	/* pciio intr resource handle */
-{
-    return INTR_FUNC(intr_hdl, intr_connect)
-	(CAST_INTR(intr_hdl));
-}
-
-/*
- * Disassociate handler with the specified interrupt.
- */
-void
-pciio_intr_disconnect(pciio_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_disconnect)
-	(CAST_INTR(intr_hdl));
-}
-
-/*
- * Return a hwgraph vertex that represents the CPU currently
- * targeted by an interrupt.
- */
-devfs_handle_t
-pciio_intr_cpu_get(pciio_intr_t intr_hdl)
-{
-    return INTR_FUNC(intr_hdl, intr_cpu_get)
-	(CAST_INTR(intr_hdl));
-}
-
-void
-pciio_slot_func_to_name(char		       *name,
-			pciio_slot_t		slot,
-			pciio_function_t	func)
-{
-    /*
-     * standard connection points:
-     *
-     * PCIIO_SLOT_NONE:	.../pci/direct
-     * PCIIO_FUNC_NONE: .../pci/<SLOT>			ie. .../pci/3
-     * multifunction:   .../pci/<SLOT><FUNC>		ie. .../pci/3c
-     */
-
-    if (slot == PCIIO_SLOT_NONE)
-	sprintf(name, "direct");
-    else if (func == PCIIO_FUNC_NONE)
-	sprintf(name, "%d", slot);
-    else
-	sprintf(name, "%d%c", slot, 'a'+func);
-}
-
-/* =====================================================================
- *          CONFIGURATION MANAGEMENT
- */
-
-/*
- * Startup a crosstalk provider
- */
-void
-pciio_provider_startup(devfs_handle_t pciio_provider)
-{
-    DEV_FUNC(pciio_provider, provider_startup)
-	(pciio_provider);
-}
-
-/*
- * Shutdown a crosstalk provider
- */
-void
-pciio_provider_shutdown(devfs_handle_t pciio_provider)
-{
-    DEV_FUNC(pciio_provider, provider_shutdown)
-	(pciio_provider);
-}
-
-/*
- * Specify endianness constraints.  The driver tells us what the device
- * does and how it would like to see things in memory.  We reply with
- * how things will actually appear in memory.
- */
-pciio_endian_t
-pciio_endian_set(devfs_handle_t dev,
-		 pciio_endian_t device_end,
-		 pciio_endian_t desired_end)
-{
-    ASSERT((device_end == PCIDMA_ENDIAN_BIG) || (device_end == PCIDMA_ENDIAN_LITTLE));
-    ASSERT((desired_end == PCIDMA_ENDIAN_BIG) || (desired_end == PCIDMA_ENDIAN_LITTLE));
-
-#if DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-    printk(KERN_ALERT  "%v: pciio_endian_set is going away.\n"
-	    "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n"
-	    "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n",
-	    dev);
-#else
-    printk(KERN_ALERT  "0x%x: pciio_endian_set is going away.\n"
-	    "\tplease use PCIIO_BYTE_STREAM or PCIIO_WORD_VALUES in your\n"
-	    "\tpciio_dmamap_alloc and pciio_dmatrans calls instead.\n",
-	    dev);
-#endif
-#endif
-
-    return DEV_FUNC(dev, endian_set)
-	(dev, device_end, desired_end);
-}
-
-/*
- * Specify PCI arbitration priority.
- */
-pciio_priority_t
-pciio_priority_set(devfs_handle_t dev,
-		   pciio_priority_t device_prio)
-{
-    ASSERT((device_prio == PCI_PRIO_HIGH) || (device_prio == PCI_PRIO_LOW));
-
-    return DEV_FUNC(dev, priority_set)
-	(dev, device_prio);
-}
-
-/*
- * Read value of configuration register
- */
-uint64_t
-pciio_config_get(devfs_handle_t	dev,
-		 unsigned	reg,
-		 unsigned	size)
-{
-    uint64_t	value = 0;
-    unsigned	shift = 0;
-
-    /* handle accesses that cross words here,
-     * since that's common code between all
-     * possible providers.
-     */
-    while (size > 0) {
-	unsigned	biw = 4 - (reg&3);
-	if (biw > size)
-	    biw = size;
-
-	value |= DEV_FUNC(dev, config_get)
-	    (dev, reg, biw) << shift;
-
-	shift += 8*biw;
-	reg += biw;
-	size -= biw;
-    }
-    return value;
-}
-
-/*
- * Change value of configuration register
- */
-void
-pciio_config_set(devfs_handle_t	dev,
-		 unsigned	reg,
-		 unsigned	size,
-		 uint64_t	value)
-{
-    /* handle accesses that cross words here,
-     * since that's common code between all
-     * possible providers.
-     */
-    while (size > 0) {
-	unsigned	biw = 4 - (reg&3);
-	if (biw > size)
-	    biw = size;
-	    
-	DEV_FUNC(dev, config_set)
-	    (dev, reg, biw, value);
-	reg += biw;
-	size -= biw;
-	value >>= biw * 8;
-    }
-}
-
-/* =====================================================================
- *          GENERIC PCI SUPPORT FUNCTIONS
- */
-
-/*
- * Issue a hardware reset to a card.
- */
-int
-pciio_reset(devfs_handle_t dev)
-{
-    return DEV_FUNC(dev, reset) (dev);
-}
-
-/*
- * flush write gather buffers
- */
-int
-pciio_write_gather_flush(devfs_handle_t dev)
-{
-    return DEV_FUNC(dev, write_gather_flush) (dev);
-}
-
-devfs_handle_t
-pciio_intr_dev_get(pciio_intr_t pciio_intr)
-{
-    return (pciio_intr->pi_dev);
-}
-
-/****** Generic crosstalk pio interfaces ******/
-devfs_handle_t
-pciio_pio_dev_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_dev);
-}
-
-pciio_slot_t
-pciio_pio_slot_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_slot);
-}
-
-pciio_space_t
-pciio_pio_space_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_space);
-}
-
-iopaddr_t
-pciio_pio_pciaddr_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_pciaddr);
-}
-
-ulong
-pciio_pio_mapsz_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_mapsz);
-}
-
-caddr_t
-pciio_pio_kvaddr_get(pciio_piomap_t pciio_piomap)
-{
-    return (pciio_piomap->pp_kvaddr);
-}
-
-/****** Generic crosstalk dma interfaces ******/
-devfs_handle_t
-pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap)
-{
-    return (pciio_dmamap->pd_dev);
-}
-
-pciio_slot_t
-pciio_dma_slot_get(pciio_dmamap_t pciio_dmamap)
-{
-    return (pciio_dmamap->pd_slot);
-}
-
-/****** Generic pci slot information interfaces ******/
-
-pciio_info_t
-pciio_info_chk(devfs_handle_t pciio)
-{
-    arbitrary_info_t        ainfo = 0;
-
-    hwgraph_info_get_LBL(pciio, INFO_LBL_PCIIO, &ainfo);
-    return (pciio_info_t) ainfo;
-}
-
-pciio_info_t
-pciio_info_get(devfs_handle_t pciio)
-{
-    pciio_info_t            pciio_info;
-
-    pciio_info = (pciio_info_t) hwgraph_fastinfo_get(pciio);
-
-#ifdef DEBUG_PCIIO
-    {
-	int pos;
-	char dname[256];
-	pos = devfs_generate_path(pciio, dname, 256);
-	printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
-    }
-#endif /* DEBUG_PCIIO */
-
-    if ((pciio_info != NULL) &&
-	(pciio_info->c_fingerprint != pciio_info_fingerprint)
-	&& (pciio_info->c_fingerprint != NULL)) {
-
-	return((pciio_info_t)-1); /* Should panic .. */
-    }
-	
-
-    return pciio_info;
-}
-
-void
-pciio_info_set(devfs_handle_t pciio, pciio_info_t pciio_info)
-{
-    if (pciio_info != NULL)
-	pciio_info->c_fingerprint = pciio_info_fingerprint;
-    hwgraph_fastinfo_set(pciio, (arbitrary_info_t) pciio_info);
-
-    /* Also, mark this vertex as a PCI slot
-     * and use the pciio_info, so pciio_info_chk
-     * can work (and be fairly efficient).
-     */
-    hwgraph_info_add_LBL(pciio, INFO_LBL_PCIIO,
-			 (arbitrary_info_t) pciio_info);
-}
-
-devfs_handle_t
-pciio_info_dev_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_vertex);
-}
-
-/*ARGSUSED*/
-pciio_bus_t
-pciio_info_bus_get(pciio_info_t pciio_info)
-{
-    /* XXX for now O2 always gets back bus 0 */
-    return (pciio_bus_t)0;
-}
-
-pciio_slot_t
-pciio_info_slot_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_slot);
-}
-
-pciio_function_t
-pciio_info_function_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_func);
-}
-
-pciio_vendor_id_t
-pciio_info_vendor_id_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_vendor);
-}
-
-pciio_device_id_t
-pciio_info_device_id_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_device);
-}
-
-devfs_handle_t
-pciio_info_master_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_master);
-}
-
-arbitrary_info_t
-pciio_info_mfast_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_mfast);
-}
-
-pciio_provider_t       *
-pciio_info_pops_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_pops);
-}
-
-error_handler_f	       *
-pciio_info_efunc_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_efunc);
-}
-
-error_handler_arg_t    *
-pciio_info_einfo_get(pciio_info_t pciio_info)
-{
-    return (pciio_info->c_einfo);
-}
-
-pciio_space_t
-pciio_info_bar_space_get(pciio_info_t info, int win)
-{
-    return info->c_window[win].w_space;
-}
-
-iopaddr_t
-pciio_info_bar_base_get(pciio_info_t info, int win)
-{
-    return info->c_window[win].w_base;
-}
-
-size_t
-pciio_info_bar_size_get(pciio_info_t info, int win)
-{
-    return info->c_window[win].w_size;
-}
-
-iopaddr_t
-pciio_info_rom_base_get(pciio_info_t info)
-{
-    return info->c_rbase;
-}
-
-size_t
-pciio_info_rom_size_get(pciio_info_t info)
-{
-    return info->c_rsize;
-}
-
-
-/* =====================================================================
- *          GENERIC PCI INITIALIZATION FUNCTIONS
- */
-
-/*
- *    pciioinit: called once during device driver
- *      initializtion if this driver is configured into
- *      the system.
- */
-void
-pciio_init(void)
-{
-    cdl_p                   cp;
-
-#if DEBUG && ATTACH_DEBUG
-    printf("pciio_init\n");
-#endif
-    /* Allocate the registry.
-     * We might already have one.
-     * If we don't, go get one.
-     * MPness: someone might have
-     * set one up for us while we
-     * were not looking; use an atomic
-     * compare-and-swap to commit to
-     * using the new registry if and
-     * only if nobody else did first.
-     * If someone did get there first,
-     * toss the one we allocated back
-     * into the pool.
-     */
-    if (pciio_registry == NULL) {
-	cp = cdl_new(EDGE_LBL_PCI, "vendor", "device");
-	if (!compare_and_swap_ptr((void **) &pciio_registry, NULL, (void *) cp)) {
-	    cdl_del(cp);
-	}
-    }
-    ASSERT(pciio_registry != NULL);
-}
-
-/*
- *    pciioattach: called for each vertex in the graph
- *      that is a PCI provider.
- */
-/*ARGSUSED */
-int
-pciio_attach(devfs_handle_t pciio)
-{
-#if DEBUG && ATTACH_DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-    printk("%v: pciio_attach\n", pciio);
-#else
-    printk("0x%x: pciio_attach\n", pciio);
-#endif
-#endif
-    return 0;
-}
-
-/*
- * Associate a set of pciio_provider functions with a vertex.
- */
-void
-pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns)
-{
-    hwgraph_info_add_LBL(provider, INFO_LBL_PFUNCS, (arbitrary_info_t) pciio_fns);
-}
-
-/*
- * Disassociate a set of pciio_provider functions with a vertex.
- */
-void
-pciio_provider_unregister(devfs_handle_t provider)
-{
-    arbitrary_info_t        ainfo;
-
-    hwgraph_info_remove_LBL(provider, INFO_LBL_PFUNCS, (long *) &ainfo);
-}
-
-/*
- * Obtain a pointer to the pciio_provider functions for a specified Crosstalk
- * provider.
- */
-pciio_provider_t       *
-pciio_provider_fns_get(devfs_handle_t provider)
-{
-    arbitrary_info_t        ainfo = 0;
-
-    (void) hwgraph_info_get_LBL(provider, INFO_LBL_PFUNCS, &ainfo);
-    return (pciio_provider_t *) ainfo;
-}
-
-/*ARGSUSED4 */
-int
-pciio_driver_register(
-			 pciio_vendor_id_t vendor_id,
-			 pciio_device_id_t device_id,
-			 char *driver_prefix,
-			 unsigned flags)
-{
-    /* a driver's init routine might call
-     * pciio_driver_register before the
-     * system calls pciio_init; so we
-     * make the init call ourselves here.
-     */
-    if (pciio_registry == NULL)
-	pciio_init();
-
-    return cdl_add_driver(pciio_registry,
-			  vendor_id, device_id,
-			  driver_prefix, flags, NULL);
-}
-
-/*
- * Remove an initialization function.
- */
-void
-pciio_driver_unregister(
-			   char *driver_prefix)
-{
-    /* before a driver calls unregister,
-     * it must have called register; so
-     * we can assume we have a registry here.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    cdl_del_driver(pciio_registry, driver_prefix, NULL);
-}
-
-/* 
- * Set the slot status for a device supported by the 
- * driver being registered.
- */
-void
-pciio_driver_reg_callback(
-                           devfs_handle_t pconn_vhdl,
-			   int key1,
-			   int key2,
-                           int error)
-{
-}
-
-/* 
- * Set the slot status for a device supported by the 
- * driver being unregistered.
- */
-void
-pciio_driver_unreg_callback(
-                           devfs_handle_t pconn_vhdl,
-			   int key1,
-			   int key2,
-                           int error)
-{
-}
-
-/*
- * Call some function with each vertex that
- * might be one of this driver's attach points.
- */
-void
-pciio_iterate(char *driver_prefix,
-	      pciio_iter_f * func)
-{
-    /* a driver's init routine might call
-     * pciio_iterate before the
-     * system calls pciio_init; so we
-     * make the init call ourselves here.
-     */
-    if (pciio_registry == NULL)
-	pciio_init();
-
-    ASSERT(pciio_registry != NULL);
-
-    cdl_iterate(pciio_registry, driver_prefix, (cdl_iter_f *) func);
-}
-
-devfs_handle_t
-pciio_device_register(
-		devfs_handle_t connectpt,	/* vertex for /hw/.../pciio/%d */
-		devfs_handle_t master,	/* card's master ASIC (PCI provider) */
-		pciio_slot_t slot,	/* card's slot */
-		pciio_function_t func,	/* card's func */
-		pciio_vendor_id_t vendor_id,
-		pciio_device_id_t device_id)
-{
-    return pciio_device_info_register
-	(connectpt, pciio_device_info_new (NULL, master, slot, func,
-					   vendor_id, device_id));
-}
-
-void
-pciio_device_unregister(devfs_handle_t pconn)
-{
-    DEV_FUNC(pconn,device_unregister)(pconn);
-}
-
-pciio_info_t
-pciio_device_info_new(
-		pciio_info_t pciio_info,
-		devfs_handle_t master,
-		pciio_slot_t slot,
-		pciio_function_t func,
-		pciio_vendor_id_t vendor_id,
-		pciio_device_id_t device_id)
-{
-    if (!pciio_info)
-	GET_NEW(pciio_info);
-    ASSERT(pciio_info != NULL);
-
-    pciio_info->c_slot = slot;
-    pciio_info->c_func = func;
-    pciio_info->c_vendor = vendor_id;
-    pciio_info->c_device = device_id;
-    pciio_info->c_master = master;
-    pciio_info->c_mfast = hwgraph_fastinfo_get(master);
-    pciio_info->c_pops = pciio_provider_fns_get(master);
-    pciio_info->c_efunc = 0;
-    pciio_info->c_einfo = 0;
-
-    return pciio_info;
-}
-
-void
-pciio_device_info_free(pciio_info_t pciio_info)
-{
-    /* NOTE : pciio_info is a structure within the pcibr_info
-     *	      and not a pointer to memory allocated on the heap !!
-     */
-    BZERO((char *)pciio_info,sizeof(pciio_info));
-}
-
-devfs_handle_t
-pciio_device_info_register(
-		devfs_handle_t connectpt,		/* vertex at center of bus */
-		pciio_info_t pciio_info)	/* details about the connectpt */
-{
-    char		name[32];
-    devfs_handle_t	pconn;
-    int device_master_set(devfs_handle_t, devfs_handle_t);
-
-    pciio_slot_func_to_name(name,
-			    pciio_info->c_slot,
-			    pciio_info->c_func);
-
-    if (GRAPH_SUCCESS !=
-	hwgraph_path_add(connectpt, name, &pconn))
-	return pconn;
-
-    pciio_info->c_vertex = pconn;
-    pciio_info_set(pconn, pciio_info);
-#ifdef DEBUG_PCIIO
-    {
-	int pos;
-	char dname[256];
-	pos = devfs_generate_path(pconn, dname, 256);
-	printk("%s : pconn path= %s \n", __FUNCTION__, &dname[pos]);
-    }
-#endif /* DEBUG_PCIIO */
-
-    /*
-     * create link to our pci provider
-     */
-
-    device_master_set(pconn, pciio_info->c_master);
-
-#if USRPCI
-    /*
-     * Call into usrpci provider to let it initialize for
-     * the given slot.
-     */
-    if (pciio_info->c_slot != PCIIO_SLOT_NONE)
-	usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot);
-#endif
-
-    return pconn;
-}
-
-void
-pciio_device_info_unregister(devfs_handle_t connectpt,
-			     pciio_info_t pciio_info)
-{
-    char		name[32];
-    devfs_handle_t	pconn;
-
-    if (!pciio_info)
-	return;
-
-    pciio_slot_func_to_name(name,
-			    pciio_info->c_slot,
-			    pciio_info->c_func);
-
-    hwgraph_edge_remove(connectpt,name,&pconn);
-    pciio_info_set(pconn,0);
-
-    /* Remove the link to our pci provider */
-    hwgraph_edge_remove(pconn, EDGE_LBL_MASTER, NULL);
-
-
-    hwgraph_vertex_unref(pconn);
-    hwgraph_vertex_destroy(pconn);
-    
-}
-/* Add the pci card inventory information to the hwgraph
- */
-static void
-pciio_device_inventory_add(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
-
-    ASSERT(pciio_info);
-    ASSERT(pciio_info->c_vertex == pconn_vhdl);
-
-    /* Donot add inventory  for non-existent devices */
-    if ((pciio_info->c_vendor == PCIIO_VENDOR_ID_NONE)	||
-	(pciio_info->c_device == PCIIO_DEVICE_ID_NONE))
-	return;
-    device_inventory_add(pconn_vhdl,INV_IOBD,INV_PCIADAP,
-			 pciio_info->c_vendor,pciio_info->c_device,
-			 pciio_info->c_slot);
-}
-
-static void
-pciio_device_inventory_remove(devfs_handle_t pconn_vhdl)
-{
-#ifdef LATER
-    hwgraph_inventory_remove(pconn_vhdl,-1,-1,-1,-1,-1);
-#endif
-}
-
-/*ARGSUSED */
-int
-pciio_device_attach(devfs_handle_t pconn,
-		    int          drv_flags)
-{
-    pciio_info_t            pciio_info;
-    pciio_vendor_id_t       vendor_id;
-    pciio_device_id_t       device_id;
-
-
-    pciio_device_inventory_add(pconn);
-    pciio_info = pciio_info_get(pconn);
-
-    vendor_id = pciio_info->c_vendor;
-    device_id = pciio_info->c_device;
-
-    /* we don't start attaching things until
-     * all the driver init routines (including
-     * pciio_init) have been called; so we
-     * can assume here that we have a registry.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn, drv_flags));
-}
-
-int
-pciio_device_detach(devfs_handle_t pconn,
-		    int          drv_flags)
-{
-    pciio_info_t            pciio_info;
-    pciio_vendor_id_t       vendor_id;
-    pciio_device_id_t       device_id;
-
-    pciio_device_inventory_remove(pconn);
-    pciio_info = pciio_info_get(pconn);
-
-    vendor_id = pciio_info->c_vendor;
-    device_id = pciio_info->c_device;
-
-    /* we don't start attaching things until
-     * all the driver init routines (including
-     * pciio_init) have been called; so we
-     * can assume here that we have a registry.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    return(cdl_del_connpt(pciio_registry, vendor_id, device_id,
-		          pconn, drv_flags));
-
-}
-
-/*
- * pciio_error_register:
- * arrange for a function to be called with
- * a specified first parameter plus other
- * information when an error is encountered
- * and traced to the pci slot corresponding
- * to the connection point pconn.
- *
- * may also be called with a null function
- * pointer to "unregister" the error handler.
- *
- * NOTE: subsequent calls silently overwrite
- * previous data for this vertex. We assume that
- * cooperating drivers, well, cooperate ...
- */
-void
-pciio_error_register(devfs_handle_t pconn,
-		     error_handler_f *efunc,
-		     error_handler_arg_t einfo)
-{
-    pciio_info_t            pciio_info;
-
-    pciio_info = pciio_info_get(pconn);
-    ASSERT(pciio_info != NULL);
-    pciio_info->c_efunc = efunc;
-    pciio_info->c_einfo = einfo;
-}
-
-/*
- * Check if any device has been found in this slot, and return
- * true or false
- * vhdl is the vertex for the slot
- */
-int
-pciio_slot_inuse(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-
-    ASSERT(pciio_info);
-    ASSERT(pciio_info->c_vertex == pconn_vhdl);
-    if (pciio_info->c_vendor) {
-	/*
-	 * Non-zero value for vendor indicate
-	 * a board being found in this slot.
-	 */
-	return 1;
-    }
-    return 0;
-}
-
-int
-pciio_dma_enabled(devfs_handle_t pconn_vhdl)
-{
-	return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl);
-}
-
-/*
- * These are complementary Linux interfaces that takes in a pci_dev * as the 
- * first arguement instead of devfs_handle_t.
- */
-iopaddr_t               snia_pciio_dmatrans_addr(struct pci_dev *, device_desc_t, paddr_t, size_t, unsigned);
-pciio_dmamap_t          snia_pciio_dmamap_alloc(struct pci_dev *, device_desc_t, size_t, unsigned);
-void                    snia_pciio_dmamap_free(pciio_dmamap_t);
-iopaddr_t               snia_pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t);
-void                    snia_pciio_dmamap_done(pciio_dmamap_t);
-pciio_endian_t          snia_pciio_endian_set(struct pci_dev *pci_dev, pciio_endian_t device_end,
-					      pciio_endian_t desired_end);
-
-#include <linux/module.h>
-EXPORT_SYMBOL(snia_pciio_dmatrans_addr);
-EXPORT_SYMBOL(snia_pciio_dmamap_alloc);
-EXPORT_SYMBOL(snia_pciio_dmamap_free);
-EXPORT_SYMBOL(snia_pciio_dmamap_addr);
-EXPORT_SYMBOL(snia_pciio_dmamap_done);
-EXPORT_SYMBOL(snia_pciio_endian_set);
-
-pciio_endian_t
-snia_pciio_endian_set(struct pci_dev *pci_dev,
-	pciio_endian_t device_end,
-	pciio_endian_t desired_end)
-{
-	devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
-	
-	return DEV_FUNC(dev, endian_set)
-		(dev, device_end, desired_end);
-}
-
-iopaddr_t
-snia_pciio_dmatrans_addr(struct pci_dev *pci_dev, /* translate for this device */
-                    device_desc_t dev_desc,     /* device descriptor */
-                    paddr_t paddr,      /* system physical address */
-                    size_t byte_count,  /* length */
-                    unsigned flags)
-{                                       /* defined in dma.h */
-
-    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
-
-    return DEV_FUNC(dev, dmatrans_addr)
-        (dev, dev_desc, paddr, byte_count, flags);
-}
-
-pciio_dmamap_t
-snia_pciio_dmamap_alloc(struct pci_dev *pci_dev,  /* set up mappings for this device */
-                   device_desc_t dev_desc,      /* device descriptor */
-                   size_t byte_count_max,       /* max size of a mapping */
-                   unsigned flags)
-{                                       /* defined in dma.h */
-
-    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
-
-    return (pciio_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
-        (dev, dev_desc, byte_count_max, flags);
-}
-
-void
-snia_pciio_dmamap_free(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_free)
-        (CAST_DMAMAP(pciio_dmamap));
-}
-
-iopaddr_t
-snia_pciio_dmamap_addr(pciio_dmamap_t pciio_dmamap,  /* use these mapping resources */
-                  paddr_t paddr,        /* map for this address */
-                  size_t byte_count)
-{                                       /* map this many bytes */
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_addr)
-        (CAST_DMAMAP(pciio_dmamap), paddr, byte_count);
-}
-
-void
-snia_pciio_dmamap_done(pciio_dmamap_t pciio_dmamap)
-{
-    DMAMAP_FUNC(pciio_dmamap, dmamap_done)
-        (CAST_DMAMAP(pciio_dmamap));
-}
-
diff -Nru a/arch/ia64/sn/io/platform_init/Makefile b/arch/ia64/sn/io/platform_init/Makefile
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/platform_init/Makefile	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,12 @@
+#
+# 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) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
+#
+# Makefile for the sn2 io routines.
+
+EXTRA_CFLAGS    := -DLITTLE_ENDIAN
+
+obj-y				+=  sgi_io_init.o irix_io_init.o
diff -Nru a/arch/ia64/sn/io/platform_init/irix_io_init.c b/arch/ia64/sn/io/platform_init/irix_io_init.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/platform_init/irix_io_init.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,88 @@
+/* $Id$
+ *
+ * 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) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn_private.h>
+#include <linux/smp.h>
+#include <asm/sn/simulator.h>
+
+extern void init_all_devices(void);
+extern void klhwg_add_all_modules(vertex_hdl_t);
+extern void klhwg_add_all_nodes(vertex_hdl_t);
+
+extern vertex_hdl_t hwgraph_root;
+extern void io_module_init(void);
+extern int pci_bus_to_hcl_cvlink(void);
+extern void mlreset(void);
+
+/* #define DEBUG_IO_INIT 1 */
+#ifdef DEBUG_IO_INIT
+#define DBG(x...) printk(x)
+#else
+#define DBG(x...)
+#endif /* DEBUG_IO_INIT */
+
+/*
+ * This routine is responsible for the setup of all the IRIX hwgraph style
+ * stuff that's been pulled into linux.  It's called by sn_pci_find_bios which
+ * is called just before the generic Linux PCI layer does its probing (by 
+ * platform_pci_fixup aka sn_pci_fixup).
+ *
+ * It is very IMPORTANT that this call is only made by the Master CPU!
+ *
+ */
+
+void
+irix_io_init(void)
+{
+	cnodeid_t cnode;
+
+	/*
+	 * This is the Master CPU.  Emulate mlsetup and main.c in Irix.
+	 */
+	mlreset();
+
+        /*
+         * Initialize platform-dependent vertices in the hwgraph:
+         *      module
+         *      node
+         *      cpu
+         *      memory
+         *      slot
+         *      hub
+         *      router
+         *      xbow
+         */
+
+        io_module_init(); /* Use to be called module_init() .. */
+        klhwg_add_all_modules(hwgraph_root);
+        klhwg_add_all_nodes(hwgraph_root);
+
+	for (cnode = 0; cnode < numnodes; cnode++) {
+		extern void per_hub_init(cnodeid_t);
+		per_hub_init(cnode);
+	}
+
+	/* We can do headless hub cnodes here .. */
+
+	/*
+	 *
+	 * Our IO Infrastructure drivers are in place .. 
+	 * Initialize the whole IO Infrastructure .. xwidget/device probes.
+	 *
+	 */
+	init_all_devices();
+	pci_bus_to_hcl_cvlink();
+}
diff -Nru a/arch/ia64/sn/io/platform_init/sgi_io_init.c b/arch/ia64/sn/io/platform_init/sgi_io_init.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/platform_init/sgi_io_init.c	Wed Jun 18 23:42:05 2003
@@ -0,0 +1,109 @@
+/*
+ * 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) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+#include <linux/types.h>
+#include <linux/config.h>
+#include <linux/slab.h>
+#include <asm/sn/sgi.h>
+#include <asm/sn/io.h>
+#include <asm/sn/sn_cpuid.h>
+#include <asm/sn/klconfig.h>
+#include <asm/sn/sn_private.h>
+#include <asm/sn/pda.h>
+#include <linux/smp.h>
+
+extern int init_hcl(void);
+
+/*
+ * per_hub_init
+ *
+ * 	This code is executed once for each Hub chip.
+ */
+void
+per_hub_init(cnodeid_t cnode)
+{
+	nasid_t		nasid;
+	nodepda_t	*npdap;
+	ii_icmr_u_t	ii_icmr;
+	ii_ibcr_u_t	ii_ibcr;
+	ii_ilcsr_u_t	ii_ilcsr;
+
+	nasid = COMPACT_TO_NASID_NODEID(cnode);
+
+	ASSERT(nasid != INVALID_NASID);
+	ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode);
+
+	npdap = NODEPDA(cnode);
+
+	/* Disable the request and reply errors. */
+	REMOTE_HUB_S(nasid, IIO_IWEIM, 0xC000);
+
+	/*
+	 * Set the total number of CRBs that can be used.
+	 */
+	ii_icmr.ii_icmr_regval= 0x0;
+	ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xf;
+	if (enable_shub_wars_1_1() ) {
+		// Set bit one of ICMR to prevent II from sending interrupt for II bug.
+		ii_icmr.ii_icmr_regval |= 0x1; 
+	}
+	REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval);
+
+	/*
+	 * Set the number of CRBs that both of the BTEs combined
+	 * can use minus 1.
+	 */
+	ii_ibcr.ii_ibcr_regval= 0x0;
+	ii_ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
+	if (ii_ilcsr.ii_ilcsr_fld_s.i_llp_stat & LNK_STAT_WORKING) {
+	    ii_ibcr.ii_ibcr_fld_s.i_count = 0x8;
+	} else {
+	    /*
+	     * if the LLP is down, there is no attached I/O, so
+	    * give BTE all the CRBs.
+	    */
+	    ii_ibcr.ii_ibcr_fld_s.i_count = 0x14;
+	}
+	REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval);
+
+	/*
+	 * Set CRB timeout to be 10ms.
+	 */
+	REMOTE_HUB_S(nasid, IIO_ICTP, 0xffffff );
+	REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
+
+	/* Initialize error interrupts for this hub. */
+	hub_error_init(cnode);
+}
+
+/*
+ * This routine is responsible for the setup of all the IRIX hwgraph style
+ * stuff that's been pulled into linux.  It's called by sn_pci_find_bios which
+ * is called just before the generic Linux PCI layer does its probing (by 
+ * platform_pci_fixup aka sn_pci_fixup).
+ *
+ * It is very IMPORTANT that this call is only made by the Master CPU!
+ *
+ */
+
+void
+sgi_master_io_infr_init(void)
+{
+	extern void irix_io_init(void);
+
+	init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */
+	irix_io_init(); /* Do IRIX Compatibility IO Init */
+
+#ifdef	CONFIG_KDB
+	{
+		extern void kdba_io_init(void);
+		kdba_io_init();
+	}
+#endif
+
+}
diff -Nru a/arch/ia64/sn/io/sgi_if.c b/arch/ia64/sn/io/sgi_if.c
--- a/arch/ia64/sn/io/sgi_if.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/sn/io/sgi_if.c	Wed Jun 18 23:42:07 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -20,8 +20,6 @@
 #include <asm/sn/pci/pciio.h>
 #include <asm/sn/slotnum.h>
 
-unsigned char Is_pic_on_this_nasid[512];	/* non-0 when this is a pic shub */
-
 void *
 snia_kmem_zalloc(size_t size, int flag)
 {
@@ -37,13 +35,6 @@
         kfree(ptr);
 }
 
-int
-nic_vertex_info_match(devfs_handle_t v, char *s)
-{
-	/* we don't support this */
-	return(0);
-}
-
 /*
  * the alloc/free_node routines do a simple kmalloc for now ..
  */
@@ -102,34 +93,6 @@
                 }
         }
         return (neg ? n : -n);
-}
-
-char *
-strtok_r(char *string, const char *sepset, char **lasts)
-{
-        register char   *q, *r;
-
-        /*first or subsequent call*/
-        if (string == NULL)
-                string = *lasts;
-
-        if(string == 0)         /* return if no tokens remaining */
-                return(NULL);
-
-        q = string + strspn(string, sepset);    /* skip leading separators */
-
-        if(*q == '\0') {                /* return if no tokens remaining */
-                *lasts = 0;     /* indicate this is last token */
-                return(NULL);
-        }
-
-        if((r = strpbrk(q, sepset)) == NULL)    /* move past token */
-                *lasts = 0;     /* indicate this is last token */
-        else {
-                *r = '\0';
-                *lasts = r+1;
-        }
-        return(q);
 }
 
 /*
diff -Nru a/arch/ia64/sn/io/sgi_io_init.c b/arch/ia64/sn/io/sgi_io_init.c
--- a/arch/ia64/sn/io/sgi_io_init.c	Wed Jun 18 23:42:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,308 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/pci/pciba.h>
-#include <linux/smp.h>
-
-extern void mlreset(int );
-extern int init_hcl(void);
-extern void klgraph_hack_init(void);
-extern void hubspc_init(void);
-extern void pciio_init(void);
-extern void pcibr_init(void);
-extern void xtalk_init(void);
-extern void xbow_init(void);
-extern void xbmon_init(void);
-extern void pciiox_init(void);
-extern void usrpci_init(void);
-extern void ioc3_init(void);
-extern void initialize_io(void);
-#if defined(CONFIG_IA64_SGI_SN1)
-extern void intr_clear_all(nasid_t);
-#endif
-extern void klhwg_add_all_modules(devfs_handle_t);
-extern void klhwg_add_all_nodes(devfs_handle_t);
-
-void sn_mp_setup(void);
-extern devfs_handle_t hwgraph_root;
-extern void io_module_init(void);
-extern void pci_bus_cvlink_init(void);
-extern void temp_hack(void);
-
-extern int pci_bus_to_hcl_cvlink(void);
-
-/* #define DEBUG_IO_INIT */
-#ifdef DEBUG_IO_INIT
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* DEBUG_IO_INIT */
-
-/*
- * per_hub_init
- *
- * 	This code is executed once for each Hub chip.
- */
-static void
-per_hub_init(cnodeid_t cnode)
-{
-	nasid_t		nasid;
-	nodepda_t	*npdap;
-	ii_icmr_u_t	ii_icmr;
-	ii_ibcr_u_t	ii_ibcr;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-	ASSERT(nasid != INVALID_NASID);
-	ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode);
-
-	npdap = NODEPDA(cnode);
-
-#if defined(CONFIG_IA64_SGI_SN1)
-	/* initialize per-node synergy perf instrumentation */
-	npdap->synergy_perf_enabled = 0; /* off by default */
-	npdap->synergy_perf_lock = SPIN_LOCK_UNLOCKED;
-	npdap->synergy_perf_freq = SYNERGY_PERF_FREQ_DEFAULT;
-	npdap->synergy_inactive_intervals = 0;
-	npdap->synergy_active_intervals = 0;
-	npdap->synergy_perf_data = NULL;
-	npdap->synergy_perf_first = NULL;
-#endif /* CONFIG_IA64_SGI_SN1 */
-
-
-	/*
-	 * Set the total number of CRBs that can be used.
-	 */
-	ii_icmr.ii_icmr_regval= 0x0;
-	ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xF;
-	REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval);
-
-	/*
-	 * Set the number of CRBs that both of the BTEs combined
-	 * can use minus 1.
-	 */
-	ii_ibcr.ii_ibcr_regval= 0x0;
-	ii_ibcr.ii_ibcr_fld_s.i_count = 0x8;
-	REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval);
-
-	/*
-	 * Set CRB timeout to be 10ms.
-	 */
-	REMOTE_HUB_S(nasid, IIO_ICTP, 0x1000 );
-	REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
-
-
-#if defined(CONFIG_IA64_SGI_SN1)
-	/* Reserve all of the hardwired interrupt levels. */
-	intr_reserve_hardwired(cnode);
-#endif
-
-	/* Initialize error interrupts for this hub. */
-	hub_error_init(cnode);
-}
-
-/*
- * This routine is responsible for the setup of all the IRIX hwgraph style
- * stuff that's been pulled into linux.  It's called by sn1_pci_find_bios which
- * is called just before the generic Linux PCI layer does its probing (by 
- * platform_pci_fixup aka sn1_pci_fixup).
- *
- * It is very IMPORTANT that this call is only made by the Master CPU!
- *
- */
-
-void
-sgi_master_io_infr_init(void)
-{
-	int cnode;
-
-	/*
-	 * Do any early init stuff .. einit_tbl[] etc.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling init_hcl().\n");
-	init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */
-
-	/*
-	 * initialize the Linux PCI to xwidget vertexes ..
-	 */
-	DBG("--> sgi_master_io_infr_init: calling pci_bus_cvlink_init().\n");
-	pci_bus_cvlink_init();
-
-#ifdef BRINGUP
-#ifdef CONFIG_IA64_SGI_SN1
-	/*
-	 * Hack to provide statically initialzed klgraph entries.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling klgraph_hack_init()\n");
-	klgraph_hack_init();
-#endif /* CONFIG_IA64_SGI_SN1 */
-#endif /* BRINGUP */
-
-	/*
-	 * This is the Master CPU.  Emulate mlsetup and main.c in Irix.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling mlreset(0).\n");
-	mlreset(0); /* Master .. */
-
-	/*
-	 * allowboot() is called by kern/os/main.c in main()
-	 * Emulate allowboot() ...
-	 *   per_cpu_init() - only need per_hub_init()
-	 *   cpu_io_setup() - Nothing to do.
-	 * 
-	 */
-	DBG("--> sgi_master_io_infr_init: calling sn_mp_setup().\n");
-	sn_mp_setup();
-
-	DBG("--> sgi_master_io_infr_init: calling per_hub_init(0).\n");
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		per_hub_init(cnode);
-	}
-
-	/* We can do headless hub cnodes here .. */
-
-	/*
-	 * io_init[] stuff.
-	 *
-	 * Get SGI IO Infrastructure drivers to init and register with 
-	 * each other etc.
-	 */
-
-	DBG("--> sgi_master_io_infr_init: calling hubspc_init()\n");
-	hubspc_init();
-
-	DBG("--> sgi_master_io_infr_init: calling pciio_init()\n");
-	pciio_init();
-
-	DBG("--> sgi_master_io_infr_init: calling pcibr_init()\n");
-	pcibr_init();
-
-	DBG("--> sgi_master_io_infr_init: calling xtalk_init()\n");
-	xtalk_init();
-
-	DBG("--> sgi_master_io_infr_init: calling xbow_init()\n");
-	xbow_init();
-
-	DBG("--> sgi_master_io_infr_init: calling xbmon_init()\n");
-	xbmon_init();
-
-	DBG("--> sgi_master_io_infr_init: calling pciiox_init()\n");
-	pciiox_init();
-
-	DBG("--> sgi_master_io_infr_init: calling usrpci_init()\n");
-	usrpci_init();
-
-	DBG("--> sgi_master_io_infr_init: calling ioc3_init()\n");
-	ioc3_init();
-
-	/*
-	 *
-	 * Our IO Infrastructure drivers are in place .. 
-	 * Initialize the whole IO Infrastructure .. xwidget/device probes.
-	 *
-	 */
-	DBG("--> sgi_master_io_infr_init: Start Probe and IO Initialization\n");
-	initialize_io();
-
-	DBG("--> sgi_master_io_infr_init: Setting up SGI IO Links for Linux PCI\n");
-	pci_bus_to_hcl_cvlink();
-
-#ifdef CONFIG_PCIBA
-	DBG("--> sgi_master_io_infr_init: calling pciba_init()\n");
-	pciba_init();
-#endif
-
-	DBG("--> Leave sgi_master_io_infr_init: DONE setting up SGI Links for PCI\n");
-}
-
-/*
- * sgi_slave_io_infr_init - This routine must be called on all cpus except 
- * the Master CPU.
- */
-void
-sgi_slave_io_infr_init(void)
-{
-	/* Emulate cboot() .. */
-	mlreset(1); /* This is a slave cpu */
-
-	// per_hub_init(0); /* Need to get and send in actual cnode number */
-
-	/* Done */
-}
-
-/*
- * One-time setup for MP SN.
- * Allocate per-node data, slurp prom klconfig information and
- * convert it to hwgraph information.
- */
-void
-sn_mp_setup(void)
-{
-	cnodeid_t	cnode;
-	cpuid_t		cpu;
-
-	for (cpu = 0; cpu < NR_CPUS; cpu++) {
-		/* Skip holes in CPU space */
-		if (cpu_enabled(cpu)) {
-			init_platform_pda(cpu);
-		}
-	}
-
-	/*
-	 * Initialize platform-dependent vertices in the hwgraph:
-	 *	module
-	 *	node
-	 *	cpu
-	 *	memory
-	 *	slot
-	 *	hub
-	 *	router
-	 *	xbow
-	 */
-
-	DBG("sn_mp_io_setup: calling io_module_init()\n");
-	io_module_init(); /* Use to be called module_init() .. */
-
-	DBG("sn_mp_setup: calling klhwg_add_all_modules()\n");
-	klhwg_add_all_modules(hwgraph_root);
-	DBG("sn_mp_setup: calling klhwg_add_all_nodes()\n");
-	klhwg_add_all_nodes(hwgraph_root);
-
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-
-		/*
-		 * This routine clears the Hub's Interrupt registers.
-		 */
-		/*
-		 * We need to move this intr_clear_all() routine 
-		 * from SN/intr.c to a more appropriate file.
-		 * Talk to Al Mayer.
-		 */
-#if defined(CONFIG_IA64_SGI_SN1)
-                intr_clear_all(COMPACT_TO_NASID_NODEID(cnode));
-#endif
-		/* now init the hub */
-	//	per_hub_init(cnode);
-
-	}
-
-#if defined(CONFIG_IA64_SGI_SN1)
-	synergy_perf_init();
-#endif
-
-}
diff -Nru a/arch/ia64/sn/io/sgi_io_sim.c b/arch/ia64/sn/io/sgi_io_sim.c
--- a/arch/ia64/sn/io/sgi_io_sim.c	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/sn/io/sgi_io_sim.c	Wed Jun 18 23:42:06 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/config.h>
@@ -15,18 +15,11 @@
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/klconfig.h>
 #include <asm/sn/module.h>
-#include <asm/sn/nic.h>
 #include <asm/sn/sn_private.h>
 
-cpuid_t         master_procid = 0;
+cpuid_t         master_procid;
 char arg_maxnodes[4];
 
-extern void init_all_devices(void);
-
-#if defined(CONFIG_IA64_SGI_SN1)
-synergy_da_t	*Synergy_da_indr[MAX_COMPACT_NODES * 2];
-#endif
-
 /*
  * Return non-zero if the given variable was specified
  */
@@ -36,44 +29,12 @@
         return (strlen(s) != 0);
 }
 
-void xbmon_init(void)
-{
-	FIXME("xbmon_init : no-op\n");
-
-}
-
-void pciiox_init(void)
-{
-	FIXME("pciiox_init : no-op\n");
-
-}
-
-void usrpci_init(void)
-{
-	FIXME("usrpci_init : no-op\n");
-
-}
-
-void ioc3_init(void)
-{
-	FIXME("ioc3_init : no-op\n");
-
-}
-
-void initialize_io(void)
-{
-
-	init_all_devices();
-}
-
 /*
  * Routines provided by ml/SN/promif.c.
  */
-static __psunsigned_t master_bridge_base = (__psunsigned_t)NULL;
+static __psunsigned_t master_bridge_base;
 nasid_t console_nasid = (nasid_t)-1;
-#if !defined(CONFIG_IA64_SGI_SN1)
 char master_baseio_wid;
-#endif
 static char console_wid;
 static char console_pcislot;
 
@@ -95,27 +56,6 @@
                 return 0;
 }
 
-#if defined(CONFIG_IA64_SGI_SN1)
-int
-is_master_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid)
-{
-
-        /*
-         * If the widget numbers are different, we're not the master.
-         */
-        if (test_wid != (xwidgetnum_t)console_wid)
-                return 0;
-
-        /*
-         * If the NASIDs are the same or equivalent, we're the master.
-         */
-        if (check_nasid_equiv(test_nasid, console_nasid)) {
-                return 1;
-        } else {
-                return 0;
-        }
-}
-#else
 int
 is_master_baseio_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid)
 {
@@ -136,15 +76,4 @@
         } else {
                 return 0;
         }
-}
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-/*
- * Routines provided by ml/SN/nvram.c
- */
-void
-nvram_baseinit(void)
-{
-	FIXME("nvram_baseinit : no-op\n");
-
 }
diff -Nru a/arch/ia64/sn/io/sn1/hub_intr.c b/arch/ia64/sn/io/sn1/hub_intr.c
--- a/arch/ia64/sn/io/sn1/hub_intr.c	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,307 +0,0 @@
-/* $Id: hub_intr.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * 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) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/types.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/iograph.h>
-#include <asm/param.h>
-#include <asm/sn/pio.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/xtalk/xtalkaddrs.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_cpuid.h>
-
-extern xtalk_provider_t hub_provider;
-
-/* ARGSUSED */
-void
-hub_intr_init(devfs_handle_t hubv)
-{
-}
-
-/*
- * hub_device_desc_update
- *	Update the passed in device descriptor with the actual the
- * 	target cpu number and interrupt priority level.
- *	NOTE : These might be the same as the ones passed in thru
- *	the descriptor.
- */
-static void
-hub_device_desc_update(device_desc_t 	dev_desc, 
-		       ilvl_t 		intr_swlevel,
-		       cpuid_t		cpu)
-{
-}
-
-int allocate_my_bit = INTRCONNECT_ANYBIT;
-
-/*
- * Allocate resources required for an interrupt as specified in dev_desc.
- * Returns a hub interrupt handle on success, or 0 on failure.
- */
-static hub_intr_t
-do_hub_intr_alloc(devfs_handle_t dev,		/* which crosstalk device */
-		  device_desc_t dev_desc,	/* device descriptor */
-		  devfs_handle_t owner_dev,	/* owner of this interrupt, if known */
-		  int uncond_nothread)		/* unconditionally non-threaded */
-{
-	cpuid_t cpu = (cpuid_t)0;			/* cpu to receive interrupt */
-        int cpupicked = 0;
-	int bit;			/* interrupt vector */
-	/*REFERENCED*/
-	int intr_resflags = 0;
-	hub_intr_t intr_hdl;
-	cnodeid_t nodeid;		/* node to receive interrupt */
-	/*REFERENCED*/
-	nasid_t nasid;			/* nasid to receive interrupt */
-	struct xtalk_intr_s *xtalk_info;
-	iopaddr_t xtalk_addr;		/* xtalk addr on hub to set intr */
-	xwidget_info_t xwidget_info;	/* standard crosstalk widget info handle */
-	char *intr_name = NULL;
-	ilvl_t intr_swlevel = (ilvl_t)0;
-	extern int default_intr_pri;
-	extern void synergy_intr_alloc(int, int);
-
-
-	if (dev_desc) {
-		if (dev_desc->flags & D_INTR_ISERR) {
-			intr_resflags = II_ERRORINT;
-		} else if (!uncond_nothread && !(dev_desc->flags & D_INTR_NOTHREAD)) {
-			intr_resflags = II_THREADED;
-		} else {
-			/* Neither an error nor a thread. */
-			intr_resflags = 0;
-		}
-	} else {
-		intr_swlevel = default_intr_pri;
-		if (!uncond_nothread)
-			intr_resflags = II_THREADED;
-	}
-
-	/* XXX - Need to determine if the interrupt should be threaded. */
-
-	/* If the cpu has not been picked already then choose a candidate 
-	 * interrupt target and reserve the interrupt bit 
-	 */
-	if (!cpupicked) {
-		cpu = intr_heuristic(dev,dev_desc,allocate_my_bit,
-				     intr_resflags,owner_dev,
-				     intr_name,&bit);
-	}
-
-	/* At this point we SHOULD have a valid cpu */
-	if (cpu == CPU_NONE) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-		printk(KERN_WARNING  "%v hub_intr_alloc could not allocate interrupt\n",
-			owner_dev);
-#else
-		printk(KERN_WARNING  "%p hub_intr_alloc could not allocate interrupt\n",
-			(void *)owner_dev);
-#endif
-		return(0);
-
-	}
-
-	/* If the cpu has been picked already (due to the bridge data 
-	 * corruption bug) then try to reserve an interrupt bit .
-	 */
-	if (cpupicked) {
-		bit = intr_reserve_level(cpu, allocate_my_bit, 
-					 intr_resflags, 
-					 owner_dev, intr_name);
-		if (bit < 0) {
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-			printk(KERN_WARNING  "Could not reserve an interrupt bit for cpu "
-				" %d and dev %v\n",
-				cpu,owner_dev);
-#else
-			printk(KERN_WARNING  "Could not reserve an interrupt bit for cpu "
-				" %d and dev %p\n",
-				(int)cpu, (void *)owner_dev);
-#endif
-				
-			return(0);
-		}
-	}
-
-	nodeid = cpuid_to_cnodeid(cpu);
-	nasid = cpuid_to_nasid(cpu);
-	xtalk_addr = HUBREG_AS_XTALKADDR(nasid, PIREG(PI_INT_PEND_MOD, cpuid_to_subnode(cpu)));
-
-	/*
-	 * Allocate an interrupt handle, and fill it in.  There are two
-	 * pieces to an interrupt handle: the piece needed by generic
-	 * xtalk code which is used by crosstalk device drivers, and
-	 * the piece needed by low-level IP27 hardware code.
-	 */
-	intr_hdl = snia_kmem_alloc_node(sizeof(struct hub_intr_s), KM_NOSLEEP, nodeid);
-	ASSERT_ALWAYS(intr_hdl);
-
-	/* 
-	 * Fill in xtalk information for generic xtalk interfaces that
-	 * operate on xtalk_intr_hdl's.
-	 */
-	xtalk_info = &intr_hdl->i_xtalk_info;
-	xtalk_info->xi_dev = dev;
-	xtalk_info->xi_vector = bit;
-	xtalk_info->xi_addr = xtalk_addr;
-
-	/*
-	 * Regardless of which CPU we ultimately interrupt, a given crosstalk
-	 * widget always handles interrupts (and PIO and DMA) through its 
-	 * designated "master" crosstalk provider.
-	 */
-	xwidget_info = xwidget_info_get(dev);
-	if (xwidget_info)
-		xtalk_info->xi_target = xwidget_info_masterid_get(xwidget_info);
-
-	/* Fill in low level hub information for hub_* interrupt interface */
-	intr_hdl->i_swlevel = intr_swlevel;
-	intr_hdl->i_cpuid = cpu;
-	intr_hdl->i_bit = bit;
-	intr_hdl->i_flags = HUB_INTR_IS_ALLOCED;
-
-	/* Store the actual interrupt priority level & interrupt target
-	 * cpu back in the device descriptor.
-	 */
-	hub_device_desc_update(dev_desc, intr_swlevel, cpu);
-	synergy_intr_alloc((int)bit, (int)cpu);
-	return(intr_hdl);
-}
-
-/*
- * Allocate resources required for an interrupt as specified in dev_desc.
- * Returns a hub interrupt handle on success, or 0 on failure.
- */
-hub_intr_t
-hub_intr_alloc(	devfs_handle_t dev,		/* which crosstalk device */
-		device_desc_t dev_desc,		/* device descriptor */
-		devfs_handle_t owner_dev)		/* owner of this interrupt, if known */
-{
-	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 0));
-}
-
-/*
- * Allocate resources required for an interrupt as specified in dev_desc.
- * Uncondtionally request non-threaded, regardless of what the device
- * descriptor might say.
- * Returns a hub interrupt handle on success, or 0 on failure.
- */
-hub_intr_t
-hub_intr_alloc_nothd(devfs_handle_t dev,		/* which crosstalk device */
-		device_desc_t dev_desc,		/* device descriptor */
-		devfs_handle_t owner_dev)		/* owner of this interrupt, if known */
-{
-	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 1));
-}
-
-/*
- * Free resources consumed by intr_alloc.
- */
-void
-hub_intr_free(hub_intr_t intr_hdl)
-{
-	cpuid_t cpu = intr_hdl->i_cpuid;
-	int bit = intr_hdl->i_bit;
-	xtalk_intr_t xtalk_info;
-
-	if (intr_hdl->i_flags & HUB_INTR_IS_CONNECTED) {
-		/* Setting the following fields in the xtalk interrupt info
-	 	 * clears the interrupt target register in the xtalk user
-	 	 */
-		xtalk_info = &intr_hdl->i_xtalk_info;
-		xtalk_info->xi_dev = NODEV;
-		xtalk_info->xi_vector = 0;
-		xtalk_info->xi_addr = 0;
-		hub_intr_disconnect(intr_hdl);
-	}
-
-	if (intr_hdl->i_flags & HUB_INTR_IS_ALLOCED)
-		kfree(intr_hdl);
-
-	intr_unreserve_level(cpu, bit);
-}
-
-
-/*
- * Associate resources allocated with a previous hub_intr_alloc call with the
- * described handler, arg, name, etc.
- */
-/*ARGSUSED*/
-int
-hub_intr_connect(	hub_intr_t intr_hdl,		/* xtalk intr resource handle */
-			xtalk_intr_setfunc_t setfunc,	/* func to set intr hw */
-			void *setfunc_arg)		/* arg to setfunc */
-{
-	int rv;
-	cpuid_t cpu = intr_hdl->i_cpuid;
-	int bit = intr_hdl->i_bit;
-	extern int synergy_intr_connect(int, int);
-
-	ASSERT(intr_hdl->i_flags & HUB_INTR_IS_ALLOCED);
-
-	rv = intr_connect_level(cpu, bit, intr_hdl->i_swlevel, NULL);
-	if (rv < 0)
-		return(rv);
-
-	intr_hdl->i_xtalk_info.xi_setfunc = setfunc;
-	intr_hdl->i_xtalk_info.xi_sfarg = setfunc_arg;
-
-	if (setfunc) (*setfunc)((xtalk_intr_t)intr_hdl);
-
-	intr_hdl->i_flags |= HUB_INTR_IS_CONNECTED;
-	return(synergy_intr_connect((int)bit, (int)cpu));
-}
-
-
-/*
- * Disassociate handler with the specified interrupt.
- */
-void
-hub_intr_disconnect(hub_intr_t intr_hdl)
-{
-	/*REFERENCED*/
-	int rv;
-	cpuid_t cpu = intr_hdl->i_cpuid;
-	int bit = intr_hdl->i_bit;
-	xtalk_intr_setfunc_t setfunc;
-
-	setfunc = intr_hdl->i_xtalk_info.xi_setfunc;
-
-	/* TBD: send disconnected interrupts somewhere harmless */
-	if (setfunc) (*setfunc)((xtalk_intr_t)intr_hdl);
-
-	rv = intr_disconnect_level(cpu, bit);
-	ASSERT(rv == 0);
-	intr_hdl->i_flags &= ~HUB_INTR_IS_CONNECTED;
-}
-
-
-/*
- * Return a hwgraph vertex that represents the CPU currently
- * targeted by an interrupt.
- */
-devfs_handle_t
-hub_intr_cpu_get(hub_intr_t intr_hdl)
-{
-	cpuid_t cpuid = intr_hdl->i_cpuid;
-	ASSERT(cpuid != CPU_NONE);
-
-	return(cpuid_to_vertex(cpuid));
-}
diff -Nru a/arch/ia64/sn/io/sn1/hubcounters.c b/arch/ia64/sn/io/sn1/hubcounters.c
--- a/arch/ia64/sn/io/sn1/hubcounters.c	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,283 +0,0 @@
-/* $Id: hubcounters.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * 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) 1992-1997,2000-2002 Silicon Graphics, Inc.
- * All rights reserved.
- */
-#include <linux/kernel.h>
-#include <linux/slab.h>
-#include <asm/types.h>
-#include <asm/sn/io.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/router.h>
-#include <asm/sn/snconfig.h>
-#include <asm/sn/slotnum.h>
-#include <asm/sn/clksupport.h>
-#include <asm/sn/sndrv.h>
-
-extern void hubni_error_handler(char *, int); /* huberror.c */
-
-static int hubstats_ioctl(struct inode *, struct file *, unsigned int, unsigned long);
-struct file_operations hub_mon_fops = {
-        ioctl:          hubstats_ioctl,
-};
-
-#define HUB_CAPTURE_TICKS	(2 * HZ)
-
-#define HUB_ERR_THRESH		500
-#define USEC_PER_SEC		1000000
-#define NSEC_PER_SEC		USEC_PER_SEC*1000
-
-volatile int hub_print_usecs = 600 * USEC_PER_SEC;
-
-/* Return success if the hub's crosstalk link is working */
-int
-hub_xtalk_link_up(nasid_t nasid)
-{
-	hubreg_t	llp_csr_reg;
-
-	/* Read the IO LLP control status register */
-	llp_csr_reg = REMOTE_HUB_L(nasid, IIO_LLP_CSR);
-
-	/* Check if the xtalk link is working */
-	if (llp_csr_reg & IIO_LLP_CSR_IS_UP) 
-		return(1);
-
-	return(0);
-
-	
-}
-
-static char *error_flag_to_type(unsigned char error_flag)
-{
-    switch(error_flag) {
-    case 0x1: return ("NI retries");
-    case 0x2: return ("NI SN errors");
-    case 0x4: return ("NI CB errors");
-    case 0x8: return ("II CB errors");
-    case 0x10: return ("II SN errors");
-    default: return ("Errors");
-    }
-}
-
-int
-print_hub_error(hubstat_t *hsp, hubreg_t reg,
-		int64_t delta, unsigned char error_flag)
-{
-	int64_t rate;
-
-	reg *= hsp->hs_per_minute;	/* Convert to minutes */
-	rate = reg / delta;
-
-	if (rate > HUB_ERR_THRESH) {
-		
-		if(hsp->hs_maint & error_flag) 
-		{
-		printk( "Excessive %s (%ld/min) on %s",
-			error_flag_to_type(error_flag), rate, hsp->hs_name); 
-		}
-		else 
-		{
-		   hsp->hs_maint |= error_flag;
-		printk( "Excessive %s (%ld/min) on %s",
-			error_flag_to_type(error_flag), rate, hsp->hs_name); 
-		}
-		return 1;
-	} else {
-		return 0;
-	}
-}
-
-
-int
-check_hub_error_rates(hubstat_t *hsp)
-{
-	int64_t delta = hsp->hs_timestamp - hsp->hs_timebase;
-	int printed = 0;
-
-	printed += print_hub_error(hsp, hsp->hs_ni_retry_errors,
-				   delta, 0x1);
-
-#if 0
-	printed += print_hub_error(hsp, hsp->hs_ni_sn_errors,
-				   delta, 0x2);
-#endif
-
-	printed += print_hub_error(hsp, hsp->hs_ni_cb_errors,
-				   delta, 0x4);
-
-
-	/* If the hub's xtalk link is not working there is 
-	 * no need to print the "Excessive..." warning 
-	 * messages
-	 */
-	if (!hub_xtalk_link_up(hsp->hs_nasid))
-		return(printed);
-
-
-	printed += print_hub_error(hsp, hsp->hs_ii_cb_errors,
-				   delta, 0x8);
-
-	printed += print_hub_error(hsp, hsp->hs_ii_sn_errors,
-				   delta, 0x10);
-
-	return printed;
-}
-
-
-void
-capture_hub_stats(cnodeid_t cnodeid, struct nodepda_s *npda)
-{
-	nasid_t nasid;
-	hubstat_t *hsp = &(npda->hubstats);
-	hubreg_t port_error;
-	ii_illr_u_t illr;
-	int count;
-	int overflow = 0;
-
-	/*
-	 * If our link wasn't up at boot time, don't worry about error rates.
-	 */
-	if (!(hsp->hs_ni_port_status & NPS_LINKUP_MASK)) {
-		printk("capture_hub_stats: cnode=%d hs_ni_port_status=0x%016lx : link is not up\n",
-		cnodeid, hsp->hs_ni_port_status);
-		return;
-	}
-
-	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
-
-	hsp->hs_timestamp = GET_RTC_COUNTER();
-
-	port_error = REMOTE_HUB_L(nasid, NI_PORT_ERROR_CLEAR);
-	count = ((port_error & NPE_RETRYCOUNT_MASK) >> NPE_RETRYCOUNT_SHFT);
-	hsp->hs_ni_retry_errors += count;
-	if (count == NPE_COUNT_MAX)
-		overflow = 1;
-	count = ((port_error & NPE_SNERRCOUNT_MASK) >> NPE_SNERRCOUNT_SHFT);
-	hsp->hs_ni_sn_errors += count;
-	if (count == NPE_COUNT_MAX)
-		overflow = 1;
-	count = ((port_error & NPE_CBERRCOUNT_MASK) >> NPE_CBERRCOUNT_SHFT);
-	hsp->hs_ni_cb_errors += count;
-	if (overflow || count == NPE_COUNT_MAX)
-		hsp->hs_ni_overflows++;
-
-	if (port_error & NPE_FATAL_ERRORS) {
-#ifdef ajm
-		hubni_error_handler("capture_hub_stats", 1);
-#else
-		printk("Error: hubni_error_handler in capture_hub_stats");
-#endif
-	}
-
-	illr.ii_illr_regval = REMOTE_HUB_L(nasid, IIO_LLP_LOG);
-	REMOTE_HUB_S(nasid, IIO_LLP_LOG, 0);
-
-	hsp->hs_ii_sn_errors += illr.ii_illr_fld_s.i_sn_cnt;
-	hsp->hs_ii_cb_errors += illr.ii_illr_fld_s.i_cb_cnt;
-	if ((illr.ii_illr_fld_s.i_sn_cnt == IIO_LLP_SN_MAX) ||
-	    (illr.ii_illr_fld_s.i_cb_cnt == IIO_LLP_CB_MAX))
-		hsp->hs_ii_overflows++;
-
-	if (hsp->hs_print) {
-		if (check_hub_error_rates(hsp)) {
-			hsp->hs_last_print = GET_RTC_COUNTER();
-			hsp->hs_print = 0;
-		}
-	} else {
-		if ((GET_RTC_COUNTER() -
-		    hsp->hs_last_print) > hub_print_usecs)
-			hsp->hs_print = 1;
-	}
-		
-	npda->hubticks = HUB_CAPTURE_TICKS;
-}
-
-
-void
-init_hub_stats(cnodeid_t cnodeid, struct nodepda_s *npda)
-{
-	hubstat_t *hsp = &(npda->hubstats);
-	nasid_t nasid = cnodeid_to_nasid(cnodeid);
-	bzero(&(npda->hubstats), sizeof(hubstat_t));
-
-	hsp->hs_version = HUBSTAT_VERSION;
-	hsp->hs_cnode = cnodeid;
-	hsp->hs_nasid = nasid;
-	hsp->hs_timebase = GET_RTC_COUNTER();
-	hsp->hs_ni_port_status = REMOTE_HUB_L(nasid, NI_PORT_STATUS);
-
-	/* Clear the II error counts. */
-	REMOTE_HUB_S(nasid, IIO_LLP_LOG, 0);
-
-	/* Clear the NI counts. */
-	REMOTE_HUB_L(nasid, NI_PORT_ERROR_CLEAR);
-
-	hsp->hs_per_minute = (long long)RTC_CYCLES_PER_SEC * 60LL;
-
-	npda->hubticks = HUB_CAPTURE_TICKS;
-
-	/* XX should use kmem_alloc_node */
-	hsp->hs_name = (char *)kmalloc(MAX_HUB_PATH, GFP_KERNEL);
-	ASSERT_ALWAYS(hsp->hs_name);
-
-	sprintf(hsp->hs_name, "/dev/hw/" EDGE_LBL_MODULE "/%03d/"
-	        EDGE_LBL_NODE "/" EDGE_LBL_HUB,
-		npda->module_id);
-
-	hsp->hs_last_print = 0;
-	hsp->hs_print = 1;
-
-	hub_print_usecs = hub_print_usecs;
-
-#if 0
-	printk("init_hub_stats: cnode=%d nasid=%d hs_version=%d hs_ni_port_status=0x%016lx\n",
-		cnodeid, nasid, hsp->hs_version, hsp->hs_ni_port_status);
-#endif
-}
-
-static int
-hubstats_ioctl(struct inode *inode, struct file *file,
-        unsigned int cmd, unsigned long arg)
-{
-        cnodeid_t       cnode;
-        nodepda_t       *npdap;
-        uint64_t        longarg;
-        devfs_handle_t  d;
-
-        if ((d = devfs_get_handle_from_inode(inode)) == NULL)
-                return -ENODEV;
-        cnode = (cnodeid_t)hwgraph_fastinfo_get(d);
-        npdap = NODEPDA(cnode);
-
-	if (npdap->hubstats.hs_version != HUBSTAT_VERSION) {
-		init_hub_stats(cnode, npdap);
-	}
-
-        switch (cmd) {
-	case SNDRV_GET_INFOSIZE:
-		longarg = sizeof(hubstat_t);
-		if (copy_to_user((void *)arg, &longarg, sizeof(longarg))) {
-		    return -EFAULT;
-		}
-		break;
-
-	case SNDRV_GET_HUBINFO:
-		/* refresh npda->hubstats */
-		capture_hub_stats(cnode, npdap);
-		if (copy_to_user((void *)arg, &npdap->hubstats, sizeof(hubstat_t))) {
-		    return -EFAULT;
-		}
-		break;
-
-	default:
-		return -EINVAL;
-	}
-
-	return 0;
-}
diff -Nru a/arch/ia64/sn/io/sn1/huberror.c b/arch/ia64/sn/io/sn1/huberror.c
--- a/arch/ia64/sn/io/sn1/huberror.c	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,228 +0,0 @@
-/* $Id: huberror.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/smp.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/intr.h>
-
-extern void hubni_eint_init(cnodeid_t cnode);
-extern void hubii_eint_init(cnodeid_t cnode);
-extern void hubii_eint_handler (int irq, void *arg, struct pt_regs *ep);
-extern void snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs);
-
-extern int maxcpus;
-
-#define HUB_ERROR_PERIOD        (120 * HZ)      /* 2 minutes */
-
-
-void
-hub_error_clear(nasid_t nasid)
-{
-	int i;
-	hubreg_t idsr;
-	int sn;
-
-	for(sn=0; sn<NUM_SUBNODES; sn++) {
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_INT_PEND, -1);
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS0_A_CLR, -1);
-		REMOTE_HUB_PI_S(nasid, sn, PI_ERR_STATUS0_B_CLR, -1);
-		REMOTE_HUB_PI_S(nasid, sn, PI_SPURIOUS_HDR_0, 0);
-		REMOTE_HUB_PI_S(nasid, sn, PI_SPURIOUS_HDR_1, 0);
-	}
-
-	REMOTE_HUB_L(nasid, MD_DIR_ERROR_CLR);
-	REMOTE_HUB_L(nasid, MD_MEM_ERROR_CLR);
-	REMOTE_HUB_L(nasid, MD_MISC1_ERROR_CLR);
-	REMOTE_HUB_L(nasid, MD_PROTOCOL_ERR_CLR);
-
-    /*
-     * Make sure spurious write response errors are cleared
-     * (values are from hub_set_prb())
-     */
-    for (i = 0; i <= HUB_WIDGET_ID_MAX - HUB_WIDGET_ID_MIN + 1; i++) {
-        iprb_t prb;
-
-	prb.iprb_regval = REMOTE_HUB_L(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)));
-
-        /* Clear out some fields */
-        prb.iprb_ovflow = 1;
-        prb.iprb_bnakctr = 0;
-        prb.iprb_anakctr = 0;
-
-	/*
-	 * PIO reads in fire-and-forget mode on bedrock 1.0 don't
-	 * frob the credit count properly, making the responses appear
-	 * spurious.  So don't use fire-and-forget mode.  Bug 761802.
-	 */
-        prb.iprb_ff = 0;        /* disable fire-and-forget mode by default */
-
-        prb.iprb_xtalkctr = 3;  /* approx. PIO credits for the widget */
-
-        REMOTE_HUB_S(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)), prb.iprb_regval);
-    }
-
-    REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, -1);
-    idsr = REMOTE_HUB_L(nasid, IIO_IIDSR);
-    REMOTE_HUB_S(nasid, IIO_IIDSR, (idsr & ~(IIO_IIDSR_SENT_MASK)));
-
-    REMOTE_HUB_L(nasid, NI_PORT_ERROR_CLEAR);
-    /* No need to clear NI_PORT_HEADER regs; they are continually overwritten*/
-
-    REMOTE_HUB_S(nasid, LB_ERROR_MASK_CLR, -1);
-    REMOTE_HUB_S(nasid, LB_ERROR_HDR1, 0);
-
-    /* Clear XB error regs, in order */
-    for (i = 0;
-         i <= XB_FIRST_ERROR_CLEAR - XB_POQ0_ERROR_CLEAR;
-         i += sizeof(hubreg_t)) {
-        REMOTE_HUB_S(nasid, XB_POQ0_ERROR_CLEAR + i, 0);
-    }
-}
-
-
-/*
- * Function	: hub_error_init
- * Purpose	: initialize the error handling requirements for a given hub.
- * Parameters	: cnode, the compact nodeid.
- * Assumptions	: Called only once per hub, either by a local cpu. Or by a 
- *			remote cpu, when this hub is headless.(cpuless)
- * Returns	: None
- */
-
-void
-hub_error_init(cnodeid_t cnode)
-{
-	nasid_t nasid;
-
-    nasid = cnodeid_to_nasid(cnode);
-    hub_error_clear(nasid);
-
-    /*
-     * Now setup the hub ii and ni error interrupt handler.
-     */
-
-    hubii_eint_init(cnode);
-    hubni_eint_init(cnode);
-
-    return;
-}
-
-/*
- * Function	: hubii_eint_init
- * Parameters	: cnode
- * Purpose	: to initialize the hub iio error interrupt.
- * Assumptions	: Called once per hub, by the cpu which will ultimately
- *			handle this interrupt.
- * Returns	: None.
- */
-
-
-void
-hubii_eint_init(cnodeid_t cnode)
-{
-    int			bit, rv;
-    ii_iidsr_u_t    	hubio_eint;
-    hubinfo_t		hinfo; 
-    cpuid_t		intr_cpu;
-    devfs_handle_t 	hub_v;
-    ii_ilcsr_u_t	ilcsr;
-    int bit_pos_to_irq(int bit);
-    int synergy_intr_connect(int bit, int cpuid);
-
-
-    hub_v = (devfs_handle_t)cnodeid_to_vertex(cnode);
-    ASSERT_ALWAYS(hub_v);
-    hubinfo_get(hub_v, &hinfo);
-
-    ASSERT(hinfo);
-    ASSERT(hinfo->h_cnodeid == cnode);
-
-    ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR);
-
-    if ((ilcsr.ii_ilcsr_fld_s.i_llp_stat & 0x2) == 0) {
-	/* 
-	 * HUB II link is not up. 
-	 * Just disable LLP, and don't connect any interrupts.
-	 */
-	ilcsr.ii_ilcsr_fld_s.i_llp_en = 0;
-	REMOTE_HUB_S(hinfo->h_nasid, IIO_ILCSR, ilcsr.ii_ilcsr_regval);
-	return;
-    }
-    /* Select a possible interrupt target where there is a free interrupt
-     * bit and also reserve the interrupt bit for this IO error interrupt
-     */
-    intr_cpu = intr_heuristic(hub_v,0,INTRCONNECT_ANYBIT,II_ERRORINT,hub_v,
-			      "HUB IO error interrupt",&bit);
-    if (intr_cpu == CPU_NONE) {
-	printk("hubii_eint_init: intr_reserve_level failed, cnode %d", cnode);
-	return;
-    }
-	
-    rv = intr_connect_level(intr_cpu, bit, 0, NULL);
-    synergy_intr_connect(bit, intr_cpu);
-    request_irq(bit_pos_to_irq(bit) + (intr_cpu << 8), hubii_eint_handler, 0, "SN hub error", (void *)hub_v);
-    ASSERT_ALWAYS(rv >= 0);
-    hubio_eint.ii_iidsr_regval = 0;
-    hubio_eint.ii_iidsr_fld_s.i_enable = 1;
-    hubio_eint.ii_iidsr_fld_s.i_level = bit;/* Take the least significant bits*/
-    hubio_eint.ii_iidsr_fld_s.i_node = COMPACT_TO_NASID_NODEID(cnode);
-    hubio_eint.ii_iidsr_fld_s.i_pi_id = cpuid_to_subnode(intr_cpu);
-    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, hubio_eint.ii_iidsr_regval);
-
-}
-
-void
-hubni_eint_init(cnodeid_t cnode)
-{
-    int intr_bit;
-    cpuid_t targ;
-
-
-    if ((targ = cnodeid_to_cpuid(cnode)) == CPU_NONE)
-	return;
-
-	/* The prom chooses which cpu gets these interrupts, but we
-	*  don't know which one it chose.  We will register all of the 
-	*  cpus to be sure.  This only costs us an irqaction per cpu.
-	*/
-    for (; targ < CPUS_PER_NODE; targ++) {
-	if (!cpu_enabled(targ) ) continue;
-	/* connect the INTEND1 bits. */
-	for (intr_bit = XB_ERROR; intr_bit <= MSC_PANIC_INTR; intr_bit++) {
-		intr_connect_level(targ, intr_bit, II_ERRORINT, NULL);
-	}
-	request_irq(SGI_HUB_ERROR_IRQ + (targ << 8), snia_error_intr_handler, 0, "SN hub error", NULL);
-	/* synergy masks are initialized in the prom to enable all interrupts. */
-	/* We'll just leave them that way, here, for these interrupts. */
-    }
-}
-
-
-/*ARGSUSED*/
-void
-hubii_eint_handler (int irq, void *arg, struct pt_regs *ep)
-{
-
-	panic("Hubii interrupt\n");
-}
diff -Nru a/arch/ia64/sn/io/sn1/ip37.c b/arch/ia64/sn/io/sn1/ip37.c
--- a/arch/ia64/sn/io/sn1/ip37.c	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,47 +0,0 @@
-/* 
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * ip37.c
- *	Support for IP35/IP37 machines
- */
-
-#include <linux/types.h>
-
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/pci/bridge.h>     /* for bridge_t */
-
-
-xwidgetnum_t
-hub_widget_id(nasid_t nasid)
-{
-	hubii_wcr_t	ii_wcr;	/* the control status register */
-		
-	ii_wcr.wcr_reg_value = REMOTE_HUB_L(nasid,IIO_WCR);
-
-	return ii_wcr.wcr_fields_s.wcr_widget_id;
-}
-
-int
-is_fine_dirmode(void)
-{
-	return (((LOCAL_HUB_L(LB_REV_ID) & LRI_SYSTEM_SIZE_MASK)
-		>> LRI_SYSTEM_SIZE_SHFT) == SYSTEM_SIZE_SMALL);
-
-}
-
-
-void
-ni_reset_port(void)
-{
-	LOCAL_HUB_S(NI_RESET_ENABLE, NRE_RESETOK);
-	LOCAL_HUB_S(NI_PORT_RESET, NPR_PORTRESET | NPR_LOCALRESET);
-}
diff -Nru a/arch/ia64/sn/io/sn1/mem_refcnt.c b/arch/ia64/sn/io/sn1/mem_refcnt.c
--- a/arch/ia64/sn/io/sn1/mem_refcnt.c	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,220 +0,0 @@
-/* $Id: mem_refcnt.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/sn1/mem_refcnt.h>
-#include <asm/sn/sn1/hwcntrs.h>
-#include <asm/sn/sn1/hubspc.h>
-// From numa_hw.h
-
-#define MIGR_COUNTER_MAX_GET(nodeid) \
-        (NODEPDA_MCD((nodeid))->migr_system_kparms.migr_threshold_reference)
-/*
- * Get the Absolute Theshold
- */
-#define MIGR_THRESHOLD_ABS_GET(nodeid) ( \
-        MD_MIG_VALUE_THRESH_GET(COMPACT_TO_NASID_NODEID(nodeid)))
-/*
- * Get the current Differential Threshold
- */
-#define MIGR_THRESHOLD_DIFF_GET(nodeid) \
-        (NODEPDA_MCD(nodeid)->migr_as_kparms.migr_base_threshold)
-
-#define NUM_OF_HW_PAGES_PER_SW_PAGE()   (NBPP / MD_PAGE_SIZE)
-
-// #include "migr_control.h"
-
-int
-mem_refcnt_attach(devfs_handle_t hub)
-{
-#if 0
-        devfs_handle_t refcnt_dev;
-        
-        hwgraph_char_device_add(hub,
-                                "refcnt",
-                                "hubspc_", 
-				&refcnt_dev);
-        device_info_set(refcnt_dev, (void*)(ulong)HUBSPC_REFCOUNTERS);
-#endif
-
-        return (0);
-}
-
-
-/*ARGSUSED*/
-int
-mem_refcnt_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp)
-{
-        cnodeid_t node;
-
-        node = master_node_get(*devp);
-
-        ASSERT( (node >= 0) && (node < numnodes) );
-
-        if (NODEPDA(node)->migr_refcnt_counterbuffer == NULL) {
-                return (ENODEV);
-        }
-
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
-        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != (size_t)0 );
-
-        return (0);
-}
-
-/*ARGSUSED*/
-int
-mem_refcnt_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-        return 0;
-}
-
-/*ARGSUSED*/
-int
-mem_refcnt_mmap(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-        cnodeid_t node;
-        int errcode;
-        char* buffer;
-        size_t blen;
-        
-        node = master_node_get(dev);
-
-        ASSERT( (node >= 0) && (node < numnodes) );
-
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL);
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
-        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 );
-
-        /*
-         * XXXX deal with prot's somewhere around here....
-         */
-
-        buffer = NODEPDA(node)->migr_refcnt_counterbuffer;
-        blen = NODEPDA(node)->migr_refcnt_cbsize;
-
-        /*
-         * Force offset to be a multiple of sizeof(refcnt_t)
-         * We round up.
-         */
-
-        off = (((off - 1)/sizeof(refcnt_t)) + 1) * sizeof(refcnt_t);
-
-        if ( ((buffer + blen) - (buffer + off + len)) < 0 ) {
-                return (EPERM);
-        }
-
-        errcode = v_mapphys(vt,
-                            buffer + off,
-                            len);
-
-        return errcode;
-}
-
-/*ARGSUSED*/
-int
-mem_refcnt_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-        return 0;
-}
-
-/* ARGSUSED */
-int
-mem_refcnt_ioctl(devfs_handle_t dev,
-                 int cmd,
-                 void *arg,
-                 int mode,
-                 cred_t *cred_p,
-                 int *rvalp)
-{
-        cnodeid_t node;
-        int errcode;
-	extern int numnodes;
-        
-        node = master_node_get(dev);
-
-        ASSERT( (node >= 0) && (node < numnodes) );
-
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbuffer != NULL);
-        ASSERT( NODEPDA(node)->migr_refcnt_counterbase != NULL );
-        ASSERT( NODEPDA(node)->migr_refcnt_cbsize != 0 );
-
-        errcode = 0;
-        
-        switch (cmd) {
-        case RCB_INFO_GET:
-        {
-                rcb_info_t rcb;
-                
-                rcb.rcb_len = NODEPDA(node)->migr_refcnt_cbsize;
-                
-                rcb.rcb_sw_sets = NODEPDA(node)->migr_refcnt_numsets;
-                rcb.rcb_sw_counters_per_set = numnodes;
-                rcb.rcb_sw_counter_size = sizeof(refcnt_t);
-
-                rcb.rcb_base_pages = NODEPDA(node)->migr_refcnt_numsets /
-                                     NUM_OF_HW_PAGES_PER_SW_PAGE();  
-                rcb.rcb_base_page_size = NBPP;
-                rcb.rcb_base_paddr = ctob(slot_getbasepfn(node, 0));
-                
-                rcb.rcb_cnodeid = node;
-                rcb.rcb_granularity = MD_PAGE_SIZE;
-#ifdef LATER
-                rcb.rcb_hw_counter_max = MIGR_COUNTER_MAX_GET(node);
-                rcb.rcb_diff_threshold = MIGR_THRESHOLD_DIFF_GET(node);
-#endif
-                rcb.rcb_abs_threshold = MIGR_THRESHOLD_ABS_GET(node);
-                rcb.rcb_num_slots = MAX_MEM_SLOTS;
-
-                if (COPYOUT(&rcb, arg, sizeof(rcb_info_t))) {
-                        errcode = EFAULT;
-                }
-
-                break;
-        }
-        case RCB_SLOT_GET:
-        {
-                rcb_slot_t slot[MAX_MEM_SLOTS];
-                int s;
-                int nslots;
-
-                nslots = MAX_MEM_SLOTS;
-                ASSERT(nslots <= MAX_MEM_SLOTS);
-                for (s = 0; s < nslots; s++) {
-                        slot[s].base = (uint64_t)ctob(slot_getbasepfn(node, s));
-#ifdef LATER
-                        slot[s].size  = (uint64_t)ctob(slot_getsize(node, s));
-#else
-                        slot[s].size  = (uint64_t)1;
-#endif
-                }
-                if (COPYOUT(&slot[0], arg, nslots * sizeof(rcb_slot_t))) {
-                        errcode = EFAULT;
-                }
-                
-                *rvalp = nslots;
-                break;
-        }
-                
-        default:
-                errcode = EINVAL;
-                break;
-
-        }
-        
-        return errcode;
-}
diff -Nru a/arch/ia64/sn/io/sn1/ml_SN_intr.c b/arch/ia64/sn/io/sn1/ml_SN_intr.c
--- a/arch/ia64/sn/io/sn1/ml_SN_intr.c	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1154 +0,0 @@
-/* $Id: ml_SN_intr.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-/*
- * intr.c-
- *	This file contains all of the routines necessary to set up and
- *	handle interrupts on an IP27 board.
- */
-
-#ident  "$Revision: 1.1 $"
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/smp.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/intr.h>
-
-
-#if DEBUG_INTR_TSTAMP_DEBUG
-#include <sys/debug.h>
-#include <sys/idbg.h>
-#include <sys/inst.h>
-void do_splx_log(int, int);
-void spldebug_log_event(int);
-#endif
-
-#ifdef CONFIG_SMP
-extern unsigned long cpu_online_map;
-#endif
-#define cpu_allows_intr(cpu)	(1)
-// If I understand what's going on with this, 32 should work.
-// physmem_maxradius seems to be the maximum number of router
-// hops to get from one end of the system to the other.  With
-// a maximally configured machine, with the dumbest possible
-// topology, we would make 32 router hops.  For what we're using
-// it for, the dumbest possible should suffice.
-#define physmem_maxradius()	32
-
-#define SUBNODE_ANY (-1)
-
-extern int	nmied;
-extern int	hub_intr_wakeup_cnt;
-extern synergy_da_t	*Synergy_da_indr[];
-extern cpuid_t         master_procid;
-
-extern cnodeid_t master_node_get(devfs_handle_t vhdl);
-
-extern void snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs);
-
-
-#define INTR_LOCK(vecblk) \
-     (s = mutex_spinlock(&(vecblk)->vector_lock))
-#define INTR_UNLOCK(vecblk) \
-      mutex_spinunlock(&(vecblk)->vector_lock, s)
-
-/*
- * REACT/Pro
- */
-
-
-
-/* 
- * Find first bit set 
- * Used outside this file also 
- */
-int ms1bit(unsigned long x)
-{
-    int			b;
-
-    if (x >> 32)	b  = 32, x >>= 32;
-    else		b  =  0;
-    if (x >> 16)	b += 16, x >>= 16;
-    if (x >>  8)	b +=  8, x >>=  8;
-    if (x >>  4)	b +=  4, x >>=  4;
-    if (x >>  2)	b +=  2, x >>=  2;
-
-    return b + (int) (x >> 1);
-}
-
-/* ARGSUSED */
-void
-intr_stray(void *lvl)
-{
-    printk(KERN_WARNING  "Stray Interrupt - level %ld to cpu %d", (long)lvl, smp_processor_id());
-}
-
-#if defined(DEBUG)
-
-/* Infrastructure  to gather the device - target cpu mapping info */
-#define MAX_DEVICES	1000	/* Reasonable large number . Need not be 
-				 * the exact maximum # devices possible.
-				 */
-#define MAX_NAME	100	
-typedef struct {
-	dev_t		dev;	/* device */
-	cpuid_t		cpuid;	/* target cpu */
-	cnodeid_t	cnodeid;/* node on which the target cpu is present */
-	int		bit;	/* intr bit reserved */
-	char		intr_name[MAX_NAME]; /* name of the interrupt */
-} intr_dev_targ_map_t;
-
-intr_dev_targ_map_t 	intr_dev_targ_map[MAX_DEVICES];
-uint64_t		intr_dev_targ_map_size;
-spinlock_t		intr_dev_targ_map_lock;
-
-/* Print out the device - target cpu mapping.
- * This routine is used only in the idbg command
- * "intrmap" 
- */
-void
-intr_dev_targ_map_print(cnodeid_t cnodeid)
-{
-	int  i,j,size = 0;
-	int  print_flag = 0,verbose = 0;	
-	char node_name[10];
-	
-	if (cnodeid != CNODEID_NONE) {
-		nodepda_t 	*npda;
-
-		npda = NODEPDA(cnodeid);
-		for (j=0; j<NUM_SUBNODES; j++) {
-			qprintf("\n SUBNODE %d\n INT_PEND0: ", j);
-			for(i = 0 ; i < N_INTPEND_BITS ; i++)
-				qprintf("%d",SNPDA(npda,j)->intr_dispatch0.info[i].ii_flags);
-			qprintf("\n INT_PEND1: ");
-			for(i = 0 ; i < N_INTPEND_BITS ; i++)
-				qprintf("%d",SNPDA(npda,j)->intr_dispatch1.info[i].ii_flags);
-		}
-		verbose = 1;
-	}
-	qprintf("\n Device - Target Map [Interrupts: %s Node%s]\n\n",
-		(verbose ? "All" : "Non-hardwired"),
-		(cnodeid == CNODEID_NONE) ? "s: All" : node_name); 
-		
-	qprintf("Device\tCpu\tCnode\tIntr_bit\tIntr_name\n");
-	for (i = 0 ; i < intr_dev_targ_map_size ; i++) {
-
-		print_flag = 0;
-		if (verbose) {
-			if (cnodeid != CNODEID_NONE) {
-				if (cnodeid == intr_dev_targ_map[i].cnodeid)
-					print_flag = 1;
-			} else {
-				print_flag = 1;
-			}
-		} else {
-			if (intr_dev_targ_map[i].dev != 0) {
-				if (cnodeid != CNODEID_NONE) {
-					if (cnodeid == 
-					    intr_dev_targ_map[i].cnodeid)
-						print_flag = 1;
-				} else {
-					print_flag = 1;
-				}
-			}
-		}
-		if (print_flag) {
-			size++;
-			qprintf("%d\t%d\t%d\t%d\t%s\n",
-				intr_dev_targ_map[i].dev,
-				intr_dev_targ_map[i].cpuid,
-				intr_dev_targ_map[i].cnodeid,
-				intr_dev_targ_map[i].bit,
-				intr_dev_targ_map[i].intr_name);
-		}
-
-	}
-	qprintf("\nTotal : %d\n",size);
-}
-#endif /* DEBUG */
-
-/*
- * The spinlocks have already been initialized.  Now initialize the interrupt
- * vectors.  One processor on each hub does the work.
- */
-void
-intr_init_vecblk(nodepda_t *npda, cnodeid_t node, int sn)
-{
-    int			i, ip=0;
-    intr_vecblk_t	*vecblk;
-    subnode_pda_t	*snpda;
-
-
-    snpda = SNPDA(npda,sn);
-    do {
-	if (ip == 0) {
-	    vecblk = &snpda->intr_dispatch0;
-	} else {
-	    vecblk = &snpda->intr_dispatch1;
-	}
-
-	/* Initialize this vector. */
-	for (i = 0; i < N_INTPEND_BITS; i++) {
-		vecblk->vectors[i].iv_func = intr_stray;
-		vecblk->vectors[i].iv_prefunc = NULL;
-		vecblk->vectors[i].iv_arg = (void *)(__psint_t)(ip * N_INTPEND_BITS + i);
-
-		vecblk->info[i].ii_owner_dev = 0;
-		strcpy(vecblk->info[i].ii_name, "Unused");
-		vecblk->info[i].ii_flags = 0;	/* No flags */
-		vecblk->vectors[i].iv_mustruncpu = -1; /* No CPU yet. */
-
-	    }
-
-	mutex_spinlock_init(&vecblk->vector_lock);
-
-	vecblk->vector_count = 0;    
-	for (i = 0; i < CPUS_PER_SUBNODE; i++)
-		vecblk->cpu_count[i] = 0;
-
-	vecblk->vector_state = VECTOR_UNINITED;
-
-    } while (++ip < 2);
-
-}
-
-
-/*
- * do_intr_reserve_level(cpuid_t cpu, int bit, int resflags, int reserve, 
- *					devfs_handle_t owner_dev, char *name)
- *	Internal work routine to reserve or unreserve an interrupt level.
- *		cpu is the CPU to which the interrupt will be sent.
- *		bit is the level bit to reserve.  -1 means any level
- *		resflags should include II_ERRORINT if this is an
- *			error interrupt, II_THREADED if the interrupt handler
- *			will be threaded, or 0 otherwise.
- *		reserve should be set to II_RESERVE or II_UNRESERVE
- *			to get or clear a reservation.
- *		owner_dev is the device that "owns" this interrupt, if supplied
- *		name is a human-readable name for this interrupt, if supplied
- *	intr_reserve_level returns the bit reserved or -1 to indicate an error
- */
-static int
-do_intr_reserve_level(cpuid_t cpu, int bit, int resflags, int reserve, 
-					devfs_handle_t owner_dev, char *name)
-{
-    intr_vecblk_t	*vecblk;
-    hub_intmasks_t 	*hub_intmasks;
-    unsigned long s;
-    int rv = 0;
-    int ip;
-    synergy_da_t	*sda;
-    int		which_synergy;
-    cnodeid_t	cnode;
-
-    ASSERT(bit < N_INTPEND_BITS * 2);
-
-    cnode = cpuid_to_cnodeid(cpu);
-    which_synergy = cpuid_to_synergy(cpu);
-    sda = Synergy_da_indr[(cnode * 2) + which_synergy];
-    hub_intmasks = &sda->s_intmasks;
-    // hub_intmasks = &pdaindr[cpu].pda->p_intmasks;
-
-    // if (pdaindr[cpu].pda == NULL) return -1;
-    if ((bit < N_INTPEND_BITS) && !(resflags & II_ERRORINT)) {
-	vecblk = hub_intmasks->dispatch0;
-	ip = 0;
-    } else {
-	ASSERT((bit >= N_INTPEND_BITS) || (bit == -1));
-	bit -= N_INTPEND_BITS;	/* Get position relative to INT_PEND1 reg. */
-	vecblk = hub_intmasks->dispatch1;
-	ip = 1;
-    }
-
-    INTR_LOCK(vecblk);
-
-    if (bit <= -1) {
-	bit = 0;
-	ASSERT(reserve == II_RESERVE);
-	/* Choose any available level */
-	for (; bit < N_INTPEND_BITS; bit++) {
-	    if (!(vecblk->info[bit].ii_flags & II_RESERVE)) {
-		rv = bit;
-		break;
-	    }
-	}
-
-	/* Return -1 if all interrupt levels int this register are taken. */
-	if (bit == N_INTPEND_BITS)
-	    rv = -1;
-
-    } else {
-	/* Reserve a particular level if it's available. */
-	if ((vecblk->info[bit].ii_flags & II_RESERVE) == reserve) {
-	    /* Can't (un)reserve a level that's already (un)reserved. */
-	    rv = -1;
-	} else {
-	    rv = bit;
-	}
-    }
-
-    /* Reserve the level and bump the count. */
-    if (rv != -1) {
-	if (reserve) {
-	    vecblk->info[bit].ii_flags |= (II_RESERVE | resflags);
-	    vecblk->info[bit].ii_owner_dev = owner_dev;
-	    /* Copy in the name. */
-	    if (name)
-		strlcpy(vecblk->info[bit].ii_name, name,
-			sizeof(vecblk->info[bit].ii_name));
-	    else
-		vecblk->info[bit].ii_name[0] = '\0';
-	    vecblk->vector_count++;
-	} else {
-	    vecblk->info[bit].ii_flags = 0;	/* Clear all the flags */
-	    vecblk->info[bit].ii_owner_dev = 0;
-	    /* Clear the name. */
-	    vecblk->info[bit].ii_name[0] = '\0';
-	    vecblk->vector_count--;
-	}
-    }
-
-    INTR_UNLOCK(vecblk);
-
-#if defined(DEBUG)
-    if (rv >= 0) {
-	    /* Gather this device - target cpu mapping information
-	     * in a table which can be used later by the idbg "intrmap"
-	     * command
-	     */
-	    s = mutex_spinlock(&intr_dev_targ_map_lock);
-	    if (intr_dev_targ_map_size < MAX_DEVICES) {
-		    intr_dev_targ_map_t	*p;
-
-		    p 		= &intr_dev_targ_map[intr_dev_targ_map_size];
-		    p->dev  	= owner_dev;
-		    p->cpuid 	= cpu; 
-		    p->cnodeid 	= cpuid_to_cnodeid(cpu); 
-		    p->bit 	= ip * N_INTPEND_BITS + rv;
-		    if (name)
-			strlcpy(p->intr_name, name, sizeof(p->intr_name));
-		    else
-			p->intr_name[0] = '\0';
-		    intr_dev_targ_map_size++;
-	    }
-	    mutex_spinunlock(&intr_dev_targ_map_lock,s);
-    }
-#endif /* DEBUG */
-
-    return (((rv == -1) ? rv : (ip * N_INTPEND_BITS) + rv)) ;
-}
-
-
-/*
- * WARNING:  This routine should only be called from within ml/SN.
- *	Reserve an interrupt level.
- */
-int
-intr_reserve_level(cpuid_t cpu, int bit, int resflags, devfs_handle_t owner_dev, char *name)
-{
-	return(do_intr_reserve_level(cpu, bit, resflags, II_RESERVE, owner_dev, name));
-}
-
-
-/*
- * WARNING:  This routine should only be called from within ml/SN.
- *	Unreserve an interrupt level.
- */
-void
-intr_unreserve_level(cpuid_t cpu, int bit)
-{
-	(void)do_intr_reserve_level(cpu, bit, 0, II_UNRESERVE, 0, NULL);
-}
-
-/*
- * Get values that vary depending on which CPU and bit we're operating on
- */
-static hub_intmasks_t *
-intr_get_ptrs(cpuid_t cpu, int bit,
-	      int *new_bit,		/* Bit relative to the register */
-	      hubreg_t **intpend_masks, /* Masks for this register */
-	      intr_vecblk_t **vecblk,	/* Vecblock for this interrupt */
-	      int *ip)			/* Which intpend register */
-{
-	hub_intmasks_t *hub_intmasks;
-	synergy_da_t	*sda;
-	int		which_synergy;
-	cnodeid_t	cnode;
-
-	ASSERT(bit < N_INTPEND_BITS * 2);
-
-	cnode = cpuid_to_cnodeid(cpu);
-	which_synergy = cpuid_to_synergy(cpu);
-	sda = Synergy_da_indr[(cnode * 2) + which_synergy];
-	hub_intmasks = &sda->s_intmasks;
-
-	// hub_intmasks = &pdaindr[cpu].pda->p_intmasks;
-
-	if (bit < N_INTPEND_BITS) {
-		*intpend_masks = hub_intmasks->intpend0_masks;
-		*vecblk = hub_intmasks->dispatch0;
-		*ip = 0;
-		*new_bit = bit;
-	} else {
-		*intpend_masks = hub_intmasks->intpend1_masks;
-		*vecblk = hub_intmasks->dispatch1;
-		*ip = 1;
-		*new_bit = bit - N_INTPEND_BITS;
-	}
-
-	return hub_intmasks;
-}
-
-
-/*
- * intr_connect_level(cpuid_t cpu, int bit, ilvl_t intr_swlevel, 
- *		intr_func_t intr_func, void *intr_arg);
- *	This is the lowest-level interface to the interrupt code.  It shouldn't
- *	be called from outside the ml/SN directory.
- *	intr_connect_level hooks up an interrupt to a particular bit in
- *	the INT_PEND0/1 masks.  Returns 0 on success.
- *		cpu is the CPU to which the interrupt will be sent.
- *		bit is the level bit to connect to
- *		intr_swlevel tells which software level to use
- *		intr_func is the interrupt handler
- *		intr_arg is an arbitrary argument interpreted by the handler
- *		intr_prefunc is a prologue function, to be called
- *			with interrupts disabled, to disable
- *			the interrupt at source.  It is called
- *			with the same argument.  Should be NULL for
- *			typical interrupts, which can be masked
- *			by the infrastructure at the level bit.
- *	intr_connect_level returns 0 on success or nonzero on an error
- */
-/* ARGSUSED */
-int
-intr_connect_level(cpuid_t cpu, int bit, ilvl_t intr_swlevel, intr_func_t intr_prefunc)
-{
-    intr_vecblk_t	*vecblk;
-    hubreg_t		*intpend_masks;
-    int rv = 0;
-    int ip;
-    unsigned long s;
-
-    ASSERT(bit < N_INTPEND_BITS * 2);
-
-    (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks,
-				 &vecblk, &ip);
-
-    INTR_LOCK(vecblk);
-
-    if ((vecblk->info[bit].ii_flags & II_INUSE) ||
-	(!(vecblk->info[bit].ii_flags & II_RESERVE))) {
-	/* Can't assign to a level that's in use or isn't reserved. */
-	rv = -1;
-    } else {
-	/* Stuff parameters into vector and info */
-	vecblk->vectors[bit].iv_prefunc = intr_prefunc;
-	vecblk->info[bit].ii_flags |= II_INUSE;
-    }
-
-    /* Now stuff the masks if everything's okay. */
-    if (!rv) {
-	int lslice;
-	volatile hubreg_t *mask_reg;
-	// nasid_t nasid = COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu));
-	nasid_t nasid = cpuid_to_nasid(cpu);
-	int	subnode = cpuid_to_subnode(cpu);
-
-	/* Make sure it's not already pending when we connect it. */
-	REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit + ip * N_INTPEND_BITS);
-
-	if (bit >= GFX_INTR_A && bit <= CC_PEND_B) {
-		intpend_masks[0] |= (1ULL << (uint64_t)bit);
-	}
-
-	lslice = cpuid_to_localslice(cpu);
-	vecblk->cpu_count[lslice]++;
-#if SN1
-	/*
-	 * On SN1, there are 8 interrupt mask registers per node:
-	 * 	PI_0 MASK_0 A
-	 * 	PI_0 MASK_1 A
-	 * 	PI_0 MASK_0 B
-	 * 	PI_0 MASK_1 B
-	 * 	PI_1 MASK_0 A
-	 * 	PI_1 MASK_1 A
-	 * 	PI_1 MASK_0 B
-	 * 	PI_1 MASK_1 B
-	 */
-#endif
-	if (ip == 0) {
-		mask_reg = REMOTE_HUB_PI_ADDR(nasid, subnode, 
-		        PI_INT_MASK0_A + PI_INT_MASK_OFFSET * lslice);
-	} else {
-		mask_reg = REMOTE_HUB_PI_ADDR(nasid, subnode,
-			PI_INT_MASK1_A + PI_INT_MASK_OFFSET * lslice);
-	}
-
-	HUB_S(mask_reg, intpend_masks[0]);
-    }
-
-    INTR_UNLOCK(vecblk);
-
-    return rv;
-}
-
-
-/*
- * intr_disconnect_level(cpuid_t cpu, int bit)
- *
- *	This is the lowest-level interface to the interrupt code.  It should
- *	not be called from outside the ml/SN directory.
- *	intr_disconnect_level removes a particular bit from an interrupt in
- * 	the INT_PEND0/1 masks.  Returns 0 on success or nonzero on failure.
- */
-int
-intr_disconnect_level(cpuid_t cpu, int bit)
-{
-    intr_vecblk_t	*vecblk;
-    hubreg_t		*intpend_masks;
-    unsigned long s;
-    int rv = 0;
-    int ip;
-
-    (void)intr_get_ptrs(cpu, bit, &bit, &intpend_masks,
-				 &vecblk, &ip);
-
-    INTR_LOCK(vecblk);
-
-    if ((vecblk->info[bit].ii_flags & (II_RESERVE | II_INUSE)) !=
-	((II_RESERVE | II_INUSE))) {
-	/* Can't remove a level that's not in use or isn't reserved. */
-	rv = -1;
-    } else {
-	/* Stuff parameters into vector and info */
-	vecblk->vectors[bit].iv_func = (intr_func_t)NULL;
-	vecblk->vectors[bit].iv_prefunc = (intr_func_t)NULL;
-	vecblk->vectors[bit].iv_arg = 0;
-	vecblk->info[bit].ii_flags &= ~II_INUSE;
-#ifdef BASE_ITHRTEAD
-	vecblk->vectors[bit].iv_mustruncpu = -1; /* No mustrun CPU any more. */
-#endif
-    }
-
-    /* Now clear the masks if everything's okay. */
-    if (!rv) {
-	int lslice;
-	volatile hubreg_t *mask_reg;
-
-	intpend_masks[0] &= ~(1ULL << (uint64_t)bit);
-	lslice = cpuid_to_localslice(cpu);
-	vecblk->cpu_count[lslice]--;
-	mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu)), 
-				   cpuid_to_subnode(cpu),
-				   ip == 0 ? PI_INT_MASK0_A : PI_INT_MASK1_A);
-	mask_reg = (volatile hubreg_t *)((__psunsigned_t)mask_reg +
-					(PI_INT_MASK_OFFSET * lslice));
-	*mask_reg = intpend_masks[0];
-    }
-
-    INTR_UNLOCK(vecblk);
-
-    return rv;
-}
-
-/*
- * Actually block or unblock an interrupt
- */
-void
-do_intr_block_bit(cpuid_t cpu, int bit, int block)
-{
-	intr_vecblk_t *vecblk;
-	int ip;
-	unsigned long s;
-	hubreg_t *intpend_masks;
-	volatile hubreg_t mask_value;
-	volatile hubreg_t *mask_reg;
-
-	intr_get_ptrs(cpu, bit, &bit, &intpend_masks, &vecblk, &ip);
-
-	INTR_LOCK(vecblk);
-
-	if (block)
-		/* Block */
-		intpend_masks[0] &= ~(1ULL << (uint64_t)bit);
-	else
-		/* Unblock */
-		intpend_masks[0] |= (1ULL << (uint64_t)bit);
-
-	if (ip == 0) {
-		mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu)), 
-		        cpuid_to_subnode(cpu), PI_INT_MASK0_A);
-	} else {
-		mask_reg = REMOTE_HUB_PI_ADDR(COMPACT_TO_NASID_NODEID(cpuid_to_cnodeid(cpu)), 
-			cpuid_to_subnode(cpu), PI_INT_MASK1_A);
-	}
-
-	HUB_S(mask_reg, intpend_masks[0]);
-
-	/*
-	 * Wait for it to take effect.  (One read should suffice.)
-	 * This is only necessary when blocking an interrupt
-	 */
-	if (block)
-		while ((mask_value = HUB_L(mask_reg)) != intpend_masks[0])
-			;
-
-	INTR_UNLOCK(vecblk);
-}
-
-
-/*
- * Block a particular interrupt (cpu/bit pair).
- */
-/* ARGSUSED */
-void
-intr_block_bit(cpuid_t cpu, int bit)
-{
-	do_intr_block_bit(cpu, bit, 1);
-}
-
-
-/*
- * Unblock a particular interrupt (cpu/bit pair).
- */
-/* ARGSUSED */
-void
-intr_unblock_bit(cpuid_t cpu, int bit)
-{
-	do_intr_block_bit(cpu, bit, 0);
-}
-
-
-/* verifies that the specified CPUID is on the specified SUBNODE (if any) */
-#define cpu_on_subnode(cpuid, which_subnode) \
-	   (((which_subnode) == SUBNODE_ANY) || (cpuid_to_subnode(cpuid) == (which_subnode)))
-
-
-/*
- * Choose one of the CPUs on a specified node or subnode to receive
- * interrupts. Don't pick a cpu which has been specified as a NOINTR cpu.
- *
- * Among all acceptable CPUs, the CPU that has the fewest total number
- * of interrupts targetted towards it is chosen.  Note that we never
- * consider how frequent each of these interrupts might occur, so a rare
- * hardware error interrupt is weighted equally with a disk interrupt.
- */
-static cpuid_t
-do_intr_cpu_choose(cnodeid_t cnode, int which_subnode)
-{
-	cpuid_t 	cpu, best_cpu = CPU_NONE;
-	int		slice, min_count=1000;
-
-	min_count = 1000;
-	for (slice=0; slice < CPUS_PER_NODE; slice++) {
-		intr_vecblk_t 	*vecblk0, *vecblk1;
-		int total_intrs_to_slice;
-		subnode_pda_t *snpda;
-		int local_cpu_num;
-
-		cpu = cnode_slice_to_cpuid(cnode, slice);
-		if (cpu == CPU_NONE)
-			continue;
-
-		/* If this cpu isn't enabled for interrupts, skip it */
-		if (!cpu_enabled(cpu) || !cpu_allows_intr(cpu))
-			continue;
-
-		/* If this isn't the right subnode, skip it */
-		if (!cpu_on_subnode(cpu, which_subnode))
-			continue;
-
-		/* OK, this one's a potential CPU for interrupts */
-		snpda = SUBNODEPDA(cnode,SUBNODE(slice));
-		vecblk0 = &snpda->intr_dispatch0;
-		vecblk1 = &snpda->intr_dispatch1;
-		local_cpu_num = LOCALCPU(slice);
-		total_intrs_to_slice = vecblk0->cpu_count[local_cpu_num] +
-		              vecblk1->cpu_count[local_cpu_num];
-
-		if (min_count > total_intrs_to_slice) {
-			min_count = total_intrs_to_slice;
-			best_cpu = cpu;
-		}
-	}
-	return best_cpu;
-}
-
-/*
- * Choose an appropriate interrupt target CPU on a specified node.
- * If which_subnode is SUBNODE_ANY, then subnode is not considered.
- * Otherwise, the chosen CPU must be on the specified subnode.
- */
-static cpuid_t
-intr_cpu_choose_from_node(cnodeid_t cnode, int which_subnode)
-{
-	return(do_intr_cpu_choose(cnode, which_subnode));
-}
-
-
-/* Make it easy to identify subnode vertices in the hwgraph */
-void
-mark_subnodevertex_as_subnode(devfs_handle_t vhdl, int which_subnode)
-{
-	graph_error_t rv;
-
-	ASSERT(0 <= which_subnode);
-	ASSERT(which_subnode < NUM_SUBNODES);
-
-	rv = hwgraph_info_add_LBL(vhdl, INFO_LBL_CPUBUS, (arbitrary_info_t)which_subnode);
-	ASSERT_ALWAYS(rv == GRAPH_SUCCESS);
-
-	rv = hwgraph_info_export_LBL(vhdl, INFO_LBL_CPUBUS, sizeof(arbitrary_info_t));
-	ASSERT_ALWAYS(rv == GRAPH_SUCCESS);
-}
-
-
-/*
- * Given a device descriptor, extract interrupt target information and
- * choose an appropriate CPU.  Return CPU_NONE if we can't make sense
- * out of the target information.
- * TBD: Should this be considered platform-independent code?
- */
-
-
-/*
- * intr_bit_reserve_test(cpuid,which_subnode,cnode,req_bit,intr_resflags,
- *		owner_dev,intr_name,*resp_bit)
- *	Either cpuid is not CPU_NONE or cnodeid not CNODE_NONE but
- * 	not both.
- * 1. 	If cpuid is specified, this routine tests if this cpu can be a valid
- * 	interrupt target candidate.
- * 2. 	If cnodeid is specified, this routine tests if there is a cpu on 
- *	this node which can be a valid interrupt target candidate.
- * 3.	If a valid interrupt target cpu candidate is found then an attempt at 
- * 	reserving an interrupt bit on the corresponding cnode is made.
- *
- * If steps 1 & 2 both fail or step 3 fails then we are not able to get a valid
- * interrupt target cpu then routine returns CPU_NONE (failure)
- * Otherwise routine returns cpuid of interrupt target (success)
- */
-static cpuid_t
-intr_bit_reserve_test(cpuid_t 		cpuid,
-		      int		favor_subnode,
-		      cnodeid_t 	cnodeid,
-		      int		req_bit,
-		      int 		intr_resflags,
-		      devfs_handle_t 	owner_dev,
-		      char		*intr_name,
-		      int		*resp_bit)
-{
-
-	ASSERT((cpuid==CPU_NONE) || (cnodeid==CNODEID_NONE));
-
-	if (cnodeid != CNODEID_NONE) {
-		/* Try to choose a interrupt cpu candidate */
-		cpuid = intr_cpu_choose_from_node(cnodeid, favor_subnode);
-	}
-
-	if (cpuid != CPU_NONE) {
-		/* Try to reserve an interrupt bit on the hub 
-		 * corresponding to the canidate cnode. If we
-		 * are successful then we got a cpu which can
-		 * act as an interrupt target for the io device.
-		 * Otherwise we need to continue the search
-		 * further.
-		 */
-		*resp_bit = do_intr_reserve_level(cpuid, 
-						  req_bit,
-						  intr_resflags,
-						  II_RESERVE,
-						  owner_dev, 
-						  intr_name);
-
-		if (*resp_bit >= 0)
-			/* The interrupt target  specified was fine */
-			return(cpuid);
-	}
-	return(CPU_NONE);
-}
-/*
- * intr_heuristic(dev_t dev,device_desc_t dev_desc,
- *		  int req_bit,int intr_resflags,dev_t owner_dev,
- *		  char *intr_name,int *resp_bit)
- *
- * Choose an interrupt destination for an interrupt.
- *	dev is the device for which the interrupt is being set up
- *	dev_desc is a description of hardware and policy that could
- *		help determine where this interrupt should go
- *	req_bit is the interrupt bit requested 
- *		(can be INTRCONNECT_ANY_BIT in which the first available
- * 		 interrupt bit is used)
- *	intr_resflags indicates whether we want to (un)reserve bit
- *	owner_dev is the owner device
- *	intr_name is the readable interrupt name	
- * 	resp_bit indicates whether we succeeded in getting the required
- *		 action  { (un)reservation} done	
- *		 negative value indicates failure
- *
- */
-/* ARGSUSED */
-cpuid_t
-intr_heuristic(devfs_handle_t 		dev,
-	       device_desc_t 	dev_desc,
-	       int		req_bit,
-	       int 		intr_resflags,
-	       devfs_handle_t 		owner_dev,
-	       char		*intr_name,
-	       int		*resp_bit)
-{
-	cpuid_t		cpuid;				/* possible intr targ*/
-	cnodeid_t 	candidate;			/* possible canidate */
-	int		which_subnode = SUBNODE_ANY;
-
-/* SN1 + pcibr Addressing Limitation */
-	{
-	devfs_handle_t pconn_vhdl;
-	pcibr_soft_t pcibr_soft;
-
-	/*
-	 * This combination of SN1 and Bridge hardware has an odd "limitation".
-	 * Due to the choice of addresses for PI0 and PI1 registers on SN1
-	 * and historical limitations in Bridge, Bridge is unable to
-	 * send interrupts to both PI0 CPUs and PI1 CPUs -- we have
-	 * to choose one set or the other.  That choice is implicitly
-	 * made when Bridge first attaches its error interrupt.  After
-	 * that point, all subsequent interrupts are restricted to the
-	 * same PI number (though it's possible to send interrupts to
-	 * the same PI number on a different node).
-	 *
-	 * Since neither SN1 nor Bridge designers are willing to admit a
-	 * bug, we can't really call this a "workaround".  It's a permanent
-	 * solution for an SN1-specific and Bridge-specific hardware
-	 * limitation that won't ever be lifted.
-	 */
-        if ((hwgraph_edge_get(dev, EDGE_LBL_PCI, &pconn_vhdl) == GRAPH_SUCCESS) &&
-	   ((pcibr_soft = pcibr_soft_get(pconn_vhdl)) != NULL)) {
-		/*
-		 * We "know" that the error interrupt is the first
-		 * interrupt set up by pcibr_attach.  Send all interrupts
-		 * on this bridge to the same subnode number.
-		 */
-		if (pcibr_soft->bsi_err_intr) {
-			which_subnode = cpuid_to_subnode(((hub_intr_t) pcibr_soft->bsi_err_intr)->i_cpuid);
-		}
-	}
-	}
-
-	/* Check if we can find a valid interrupt target candidate on
-	 * the master node for the device.
-	 */
-	cpuid = intr_bit_reserve_test(CPU_NONE,
-				      which_subnode,	
-				      master_node_get(dev),
-				      req_bit,
-				      intr_resflags,
-				      owner_dev,
-				      intr_name,
-				      resp_bit);
-
-	if (cpuid != CPU_NONE) {
-		if (cpu_on_subnode(cpuid, which_subnode))
-			return(cpuid);	/* got a valid interrupt target */
-		else
-			intr_unreserve_level(cpuid, *resp_bit);
-	}
-
-	printk(KERN_WARNING  "Cannot target interrupts to closest node(%d): (0x%lx)\n",
-		master_node_get(dev),(unsigned long)owner_dev);
-
-	/* Fall through into the default algorithm
-	 * (exhaustive-search-for-the-nearest-possible-interrupt-target)
-	 * for finding the interrupt target
-	 */
-
-	{
-	/*
-	 * Do a stupid round-robin assignment of the node.
-	 *  (Should do a "nearest neighbor" but not for SN1.
-	 */
-		static cnodeid_t last_node = -1;
-
-		if (last_node >= numnodes) last_node = 0;
-		for (candidate = last_node + 1; candidate != last_node; candidate++) {
-			if (candidate == numnodes) candidate = 0;
-			cpuid = intr_bit_reserve_test(CPU_NONE,
-					      which_subnode,
-					      candidate,
-					      req_bit,
-					      intr_resflags,
-					      owner_dev,
-					      intr_name,
-					      resp_bit);
-
-			if (cpuid != CPU_NONE) {
-				if (cpu_on_subnode(cpuid, which_subnode)) {
-					last_node = candidate;
-					return(cpuid);	/* got a valid interrupt target */
-				}
-				else
-					intr_unreserve_level(cpuid, *resp_bit);
-			}
-		}
-		last_node = candidate;
-	}
-
-	printk(KERN_WARNING  "Cannot target interrupts to any close node: %ld (0x%lx)\n",
-		(long)owner_dev, (unsigned long)owner_dev);
-
-	/* In the worst case try to allocate interrupt bits on the
-	 * master processor's node. We may get here during error interrupt
-	 * allocation phase when the topology matrix is not yet setup
-	 * and hence cannot do an exhaustive search.
-	 */
-	ASSERT(cpu_allows_intr(master_procid));
-	cpuid = intr_bit_reserve_test(master_procid,
-				      which_subnode,
-				      CNODEID_NONE,
-				      req_bit,
-				      intr_resflags,
-				      owner_dev,
-				      intr_name,
-				      resp_bit);
-
-	if (cpuid != CPU_NONE) {
-		if (cpu_on_subnode(cpuid, which_subnode))
-			return(cpuid);
-		else
-			intr_unreserve_level(cpuid, *resp_bit);
-	}
-
-	printk(KERN_WARNING  "Cannot target interrupts: (0x%lx)\n",
-		(unsigned long)owner_dev);
-
-	return(CPU_NONE);	/* Should never get here */
-}
-
-struct hardwired_intr_s {
-	signed char level;
-	int flags;
-	char *name;
-} const hardwired_intr[] = {
-	{ INT_PEND0_BASELVL + RESERVED_INTR,	0,	"Reserved" },
-	{ INT_PEND0_BASELVL + GFX_INTR_A,	0, 	"Gfx A" },
-	{ INT_PEND0_BASELVL + GFX_INTR_B,	0, 	"Gfx B" },
-	{ INT_PEND0_BASELVL + PG_MIG_INTR,	II_THREADED, "Migration" },
-	{ INT_PEND0_BASELVL + UART_INTR,	II_THREADED, "Bedrock/L1" },
-	{ INT_PEND0_BASELVL + CC_PEND_A,	0,	"Crosscall A" },
-	{ INT_PEND0_BASELVL + CC_PEND_B,	0,	"Crosscall B" },
-	{ INT_PEND1_BASELVL + CLK_ERR_INTR,	II_ERRORINT, "Clock Error" },
-	{ INT_PEND1_BASELVL + COR_ERR_INTR_A,	II_ERRORINT, "Correctable Error A" },
-	{ INT_PEND1_BASELVL + COR_ERR_INTR_B,	II_ERRORINT, "Correctable Error B" },
-	{ INT_PEND1_BASELVL + MD_COR_ERR_INTR,	II_ERRORINT, "MD Correct. Error" },
-	{ INT_PEND1_BASELVL + NI_ERROR_INTR,	II_ERRORINT, "NI Error" },
-	{ INT_PEND1_BASELVL + NI_BRDCAST_ERR_A,	II_ERRORINT, "Remote NI Error"},
-	{ INT_PEND1_BASELVL + NI_BRDCAST_ERR_B,	II_ERRORINT, "Remote NI Error"},
-	{ INT_PEND1_BASELVL + MSC_PANIC_INTR,	II_ERRORINT, "MSC Panic" },
-	{ INT_PEND1_BASELVL + LLP_PFAIL_INTR_A,	II_ERRORINT, "LLP Pfail WAR" },
-	{ INT_PEND1_BASELVL + LLP_PFAIL_INTR_B,	II_ERRORINT, "LLP Pfail WAR" },
-	{ INT_PEND1_BASELVL + NACK_INT_A,	0, "CPU A Nack count == NACK_CMP" },
-	{ INT_PEND1_BASELVL + NACK_INT_B,	0, "CPU B Nack count == NACK_CMP" },
-	{ INT_PEND1_BASELVL + LB_ERROR,		0, "Local Block Error" },
-	{ INT_PEND1_BASELVL + XB_ERROR,		0, "Local XBar Error" },
-	{ -1, 0, (char *)NULL},
-};
-
-/*
- * Reserve all of the hardwired interrupt levels so they're not used as
- * general purpose bits later.
- */
-void
-intr_reserve_hardwired(cnodeid_t cnode)
-{
-	cpuid_t cpu;
-	int level;
-	int i;
-	char subnode_done[NUM_SUBNODES];
-
-	// cpu = cnodetocpu(cnode);
-	for (cpu = 0; cpu < smp_num_cpus; cpu++) {
-		if (cpuid_to_cnodeid(cpu) == cnode) {
-			break;
-		}
-	}
-	if (cpu == smp_num_cpus) cpu = CPU_NONE;
-	if (cpu == CPU_NONE) {
-		printk("Node %d has no CPUs", cnode);
-		return;
-	}
-
-	for (i=0; i<NUM_SUBNODES; i++)
-		subnode_done[i] = 0;
-
-	for (; cpu<smp_num_cpus && cpu_enabled(cpu) && cpuid_to_cnodeid(cpu) == cnode; cpu++) {
-		int which_subnode = cpuid_to_subnode(cpu);
-		if (subnode_done[which_subnode])
-			continue;
-		subnode_done[which_subnode] = 1;
-
-		for (i = 0; hardwired_intr[i].level != -1; i++) {
-			level = hardwired_intr[i].level;
-
-			if (level != intr_reserve_level(cpu, level,
-						hardwired_intr[i].flags,
-						(devfs_handle_t) NULL,
-						hardwired_intr[i].name))
-				panic("intr_reserve_hardwired: Can't reserve level %d, cpu %ld.", level, cpu);
-		}
-	}
-}
-
-
-/*
- * Check and clear interrupts.
- */
-/*ARGSUSED*/
-static void
-intr_clear_bits(nasid_t nasid, volatile hubreg_t *pend, int base_level,
-		char *name)
-{
-	volatile hubreg_t bits;
-	int i;
-
-	/* Check pending interrupts */
-	if ((bits = HUB_L(pend)) != 0) {
-		for (i = 0; i < N_INTPEND_BITS; i++) {
-			if (bits & (1 << i)) {
-#ifdef INTRDEBUG
-				printk(KERN_WARNING  "Nasid %d interrupt bit %d set in %s",
-					nasid, i, name);
-#endif
-				LOCAL_HUB_CLR_INTR(base_level + i);
-			}
-		}
-	}
-}
-
-/*
- * Clear out our interrupt registers.
- */
-void
-intr_clear_all(nasid_t nasid)
-{
-	int	sn;
-
-	for(sn=0; sn<NUM_SUBNODES; sn++) {
-		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK0_A, 0);
-		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK0_B, 0);
-		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK1_A, 0);
-		REMOTE_HUB_PI_S(nasid, sn, PI_INT_MASK1_B, 0);
-	
-		intr_clear_bits(nasid, REMOTE_HUB_PI_ADDR(nasid, sn, PI_INT_PEND0),
-				INT_PEND0_BASELVL, "INT_PEND0");
-		intr_clear_bits(nasid, REMOTE_HUB_PI_ADDR(nasid, sn, PI_INT_PEND1),
-				INT_PEND1_BASELVL, "INT_PEND1");
-	}
-}
-
-/* 
- * Dump information about a particular interrupt vector.
- */
-static void
-dump_vector(intr_info_t *info, intr_vector_t *vector, int bit, hubreg_t ip,
-		hubreg_t ima, hubreg_t imb, void (*pf)(char *, ...))
-{
-	hubreg_t value = 1LL << bit;
-
-	pf("  Bit %02d: %s: func 0x%x arg 0x%x prefunc 0x%x\n",
-		bit, info->ii_name,
-		vector->iv_func, vector->iv_arg, vector->iv_prefunc);
-	pf("   vertex 0x%x %s%s",
-		info->ii_owner_dev,
-		((info->ii_flags) & II_RESERVE) ? "R" : "U",
-		((info->ii_flags) & II_INUSE) ? "C" : "-");
-	pf("%s%s%s%s",
-		ip & value ? "P" : "-",
-		ima & value ? "A" : "-",
-		imb & value ? "B" : "-",
-		((info->ii_flags) & II_ERRORINT) ? "E" : "-");
-	pf("\n");
-}
-
-
-/*
- * Dump information about interrupt vector assignment.
- */
-void
-intr_dumpvec(cnodeid_t cnode, void (*pf)(char *, ...))
-{
-	nodepda_t *npda;
-	int ip, sn, bit;
-	intr_vecblk_t *dispatch;
-	hubreg_t ipr, ima, imb;
-	nasid_t nasid;
-
-	if ((cnode < 0) || (cnode >= numnodes)) {
-		pf("intr_dumpvec: cnodeid out of range: %d\n", cnode);
-		return ;
-	}
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-	if (nasid == INVALID_NASID) {
-		pf("intr_dumpvec: Bad cnodeid: %d\n", cnode);
-		return ;
-	}
-		
-
-	npda = NODEPDA(cnode);
-
-	for (sn = 0; sn < NUM_SUBNODES; sn++) {
-		for (ip = 0; ip < 2; ip++) {
-			dispatch = ip ? &(SNPDA(npda,sn)->intr_dispatch1) : &(SNPDA(npda,sn)->intr_dispatch0);
-			ipr = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_PEND1 : PI_INT_PEND0);
-			ima = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_MASK1_A : PI_INT_MASK0_A);
-			imb = REMOTE_HUB_PI_L(nasid, sn, ip ? PI_INT_MASK1_B : PI_INT_MASK0_B);
-	
-			pf("Node %d INT_PEND%d:\n", cnode, ip);
-	
-			if (dispatch->ithreads_enabled)
-				pf(" Ithreads enabled\n");
-			else
-				pf(" Ithreads disabled\n");
-			pf(" vector_count = %d, vector_state = %d\n",
-				dispatch->vector_count,
-				dispatch->vector_state);
-			pf(" CPU A count %d, CPU B count %d\n",
- 		   	dispatch->cpu_count[0],
- 		   	dispatch->cpu_count[1]);
-			pf(" &vector_lock = 0x%x\n",
-				&(dispatch->vector_lock));
-			for (bit = 0; bit < N_INTPEND_BITS; bit++) {
-				if ((dispatch->info[bit].ii_flags & II_RESERVE) ||
-			    	(ipr & (1L << bit))) {
-					dump_vector(&(dispatch->info[bit]),
-					    	&(dispatch->vectors[bit]),
-					    	bit, ipr, ima, imb, pf);
-				}
-			}
-			pf("\n");
-		}
-	}
-}
-
diff -Nru a/arch/ia64/sn/io/sn1/pcibr.c b/arch/ia64/sn/io/sn1/pcibr.c
--- a/arch/ia64/sn/io/sn1/pcibr.c	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,7704 +0,0 @@
-/*
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-int NeedXbridgeSwap = 0;
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_defs.h>
-#include <asm/sn/prio.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_private.h>
-
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
-extern boolean_t                is_sys_critical_vertex(devfs_handle_t);
-
-#undef PCIBR_ATE_DEBUG
-
-#if 0
-#define DEBUG 1	 /* To avoid lots of bad printk() formats leave off */
-#endif
-#define PCI_DEBUG 1
-#define ATTACH_DEBUG 1
-#define PCIBR_SOFT_LIST 1
-
-#ifndef	LOCAL
-#define	LOCAL		static
-#endif
-
-/*
- * Macros related to the Lucent USS 302/312 usb timeout workaround.  It
- * appears that if the lucent part can get into a retry loop if it sees a
- * DAC on the bus during a pio read retry.  The loop is broken after about
- * 1ms, so we need to set up bridges holding this part to allow at least
- * 1ms for pio.
- */
-
-#define USS302_TIMEOUT_WAR
-
-#ifdef USS302_TIMEOUT_WAR
-#define LUCENT_USBHC_VENDOR_ID_NUM	0x11c1
-#define LUCENT_USBHC302_DEVICE_ID_NUM	0x5801
-#define LUCENT_USBHC312_DEVICE_ID_NUM	0x5802
-#define USS302_BRIDGE_TIMEOUT_HLD	4
-#endif
-
-#define PCIBR_LLP_CONTROL_WAR
-#if defined (PCIBR_LLP_CONTROL_WAR)
-int                     pcibr_llp_control_war_cnt;
-#endif				/* PCIBR_LLP_CONTROL_WAR */
-
-int                     pcibr_devflag = D_MP;
-
-#ifdef LATER
-#define F(s,n)		{ 1l<<(s),-(s), n }
-
-struct reg_desc         bridge_int_status_desc[] =
-{
-    F(31, "MULTI_ERR"),
-    F(30, "PMU_ESIZE_EFAULT"),
-    F(29, "UNEXPECTED_RESP"),
-    F(28, "BAD_XRESP_PACKET"),
-    F(27, "BAD_XREQ_PACKET"),
-    F(26, "RESP_XTALK_ERROR"),
-    F(25, "REQ_XTALK_ERROR"),
-    F(24, "INVALID_ADDRESS"),
-    F(23, "UNSUPPORTED_XOP"),
-    F(22, "XREQ_FIFO_OFLOW"),
-    F(21, "LLP_REC_SNERROR"),
-    F(20, "LLP_REC_CBERROR"),
-    F(19, "LLP_RCTY"),
-    F(18, "LLP_TX_RETRY"),
-    F(17, "LLP_TCTY"),
-    F(16, "SSRAM_PERR"),
-    F(15, "PCI_ABORT"),
-    F(14, "PCI_PARITY"),
-    F(13, "PCI_SERR"),
-    F(12, "PCI_PERR"),
-    F(11, "PCI_MASTER_TOUT"),
-    F(10, "PCI_RETRY_CNT"),
-    F(9, "XREAD_REQ_TOUT"),
-    F(8, "GIO_BENABLE_ERR"),
-    F(7, "INT7"),
-    F(6, "INT6"),
-    F(5, "INT5"),
-    F(4, "INT4"),
-    F(3, "INT3"),
-    F(2, "INT2"),
-    F(1, "INT1"),
-    F(0, "INT0"),
-    {0}
-};
-
-struct reg_values       space_v[] =
-{
-    {PCIIO_SPACE_NONE, "none"},
-    {PCIIO_SPACE_ROM, "ROM"},
-    {PCIIO_SPACE_IO, "I/O"},
-    {PCIIO_SPACE_MEM, "MEM"},
-    {PCIIO_SPACE_MEM32, "MEM(32)"},
-    {PCIIO_SPACE_MEM64, "MEM(64)"},
-    {PCIIO_SPACE_CFG, "CFG"},
-    {PCIIO_SPACE_WIN(0), "WIN(0)"},
-    {PCIIO_SPACE_WIN(1), "WIN(1)"},
-    {PCIIO_SPACE_WIN(2), "WIN(2)"},
-    {PCIIO_SPACE_WIN(3), "WIN(3)"},
-    {PCIIO_SPACE_WIN(4), "WIN(4)"},
-    {PCIIO_SPACE_WIN(5), "WIN(5)"},
-    {PCIIO_SPACE_BAD, "BAD"},
-    {0}
-};
-
-struct reg_desc         space_desc[] =
-{
-    {0xFF, 0, "space", 0, space_v},
-    {0}
-};
-
-#if DEBUG
-#define	device_desc	device_bits
-LOCAL struct reg_desc   device_bits[] =
-{
-    {BRIDGE_DEV_ERR_LOCK_EN, 0, "ERR_LOCK_EN"},
-    {BRIDGE_DEV_PAGE_CHK_DIS, 0, "PAGE_CHK_DIS"},
-    {BRIDGE_DEV_FORCE_PCI_PAR, 0, "FORCE_PCI_PAR"},
-    {BRIDGE_DEV_VIRTUAL_EN, 0, "VIRTUAL_EN"},
-    {BRIDGE_DEV_PMU_WRGA_EN, 0, "PMU_WRGA_EN"},
-    {BRIDGE_DEV_DIR_WRGA_EN, 0, "DIR_WRGA_EN"},
-    {BRIDGE_DEV_DEV_SIZE, 0, "DEV_SIZE"},
-    {BRIDGE_DEV_RT, 0, "RT"},
-    {BRIDGE_DEV_SWAP_PMU, 0, "SWAP_PMU"},
-    {BRIDGE_DEV_SWAP_DIR, 0, "SWAP_DIR"},
-    {BRIDGE_DEV_PREF, 0, "PREF"},
-    {BRIDGE_DEV_PRECISE, 0, "PRECISE"},
-    {BRIDGE_DEV_COH, 0, "COH"},
-    {BRIDGE_DEV_BARRIER, 0, "BARRIER"},
-    {BRIDGE_DEV_GBR, 0, "GBR"},
-    {BRIDGE_DEV_DEV_SWAP, 0, "DEV_SWAP"},
-    {BRIDGE_DEV_DEV_IO_MEM, 0, "DEV_IO_MEM"},
-    {BRIDGE_DEV_OFF_MASK, BRIDGE_DEV_OFF_ADDR_SHFT, "DEV_OFF", "%x"},
-    {0}
-};
-#endif	/* DEBUG */
-
-#ifdef SUPPORT_PRINTING_R_FORMAT
-LOCAL struct reg_values xio_cmd_pactyp[] =
-{
-    {0x0, "RdReq"},
-    {0x1, "RdResp"},
-    {0x2, "WrReqWithResp"},
-    {0x3, "WrResp"},
-    {0x4, "WrReqNoResp"},
-    {0x5, "Reserved(5)"},
-    {0x6, "FetchAndOp"},
-    {0x7, "Reserved(7)"},
-    {0x8, "StoreAndOp"},
-    {0x9, "Reserved(9)"},
-    {0xa, "Reserved(a)"},
-    {0xb, "Reserved(b)"},
-    {0xc, "Reserved(c)"},
-    {0xd, "Reserved(d)"},
-    {0xe, "SpecialReq"},
-    {0xf, "SpecialResp"},
-    {0}
-};
-
-LOCAL struct reg_desc   xio_cmd_bits[] =
-{
-    {WIDGET_DIDN, -28, "DIDN", "%x"},
-    {WIDGET_SIDN, -24, "SIDN", "%x"},
-    {WIDGET_PACTYP, -20, "PACTYP", 0, xio_cmd_pactyp},
-    {WIDGET_TNUM, -15, "TNUM", "%x"},
-    {WIDGET_COHERENT, 0, "COHERENT"},
-    {WIDGET_DS, 0, "DS"},
-    {WIDGET_GBR, 0, "GBR"},
-    {WIDGET_VBPM, 0, "VBPM"},
-    {WIDGET_ERROR, 0, "ERROR"},
-    {WIDGET_BARRIER, 0, "BARRIER"},
-    {0}
-};
-#endif	/* SUPPORT_PRINTING_R_FORMAT */
-
-#if PCIBR_FREEZE_TIME || PCIBR_ATE_DEBUG
-LOCAL struct reg_desc   ate_bits[] =
-{
-    {0xFFFF000000000000ull, -48, "RMF", "%x"},
-    {~(IOPGSIZE - 1) &			/* may trim off some low bits */
-     0x0000FFFFFFFFF000ull, 0, "XIO", "%x"},
-    {0x0000000000000F00ull, -8, "port", "%x"},
-    {0x0000000000000010ull, 0, "Barrier"},
-    {0x0000000000000008ull, 0, "Prefetch"},
-    {0x0000000000000004ull, 0, "Precise"},
-    {0x0000000000000002ull, 0, "Coherent"},
-    {0x0000000000000001ull, 0, "Valid"},
-    {0}
-};
-#endif
-
-#if PCIBR_ATE_DEBUG
-LOCAL struct reg_values ssram_sizes[] =
-{
-    {BRIDGE_CTRL_SSRAM_512K, "512k"},
-    {BRIDGE_CTRL_SSRAM_128K, "128k"},
-    {BRIDGE_CTRL_SSRAM_64K, "64k"},
-    {BRIDGE_CTRL_SSRAM_1K, "1k"},
-    {0}
-};
-
-LOCAL struct reg_desc   control_bits[] =
-{
-    {BRIDGE_CTRL_FLASH_WR_EN, 0, "FLASH_WR_EN"},
-    {BRIDGE_CTRL_EN_CLK50, 0, "EN_CLK50"},
-    {BRIDGE_CTRL_EN_CLK40, 0, "EN_CLK40"},
-    {BRIDGE_CTRL_EN_CLK33, 0, "EN_CLK33"},
-    {BRIDGE_CTRL_RST_MASK, -24, "RST", "%x"},
-    {BRIDGE_CTRL_IO_SWAP, 0, "IO_SWAP"},
-    {BRIDGE_CTRL_MEM_SWAP, 0, "MEM_SWAP"},
-    {BRIDGE_CTRL_PAGE_SIZE, 0, "PAGE_SIZE"},
-    {BRIDGE_CTRL_SS_PAR_BAD, 0, "SS_PAR_BAD"},
-    {BRIDGE_CTRL_SS_PAR_EN, 0, "SS_PAR_EN"},
-    {BRIDGE_CTRL_SSRAM_SIZE_MASK, 0, "SSRAM_SIZE", 0, ssram_sizes},
-    {BRIDGE_CTRL_F_BAD_PKT, 0, "F_BAD_PKT"},
-    {BRIDGE_CTRL_LLP_XBAR_CRD_MASK, -12, "LLP_XBAR_CRD", "%d"},
-    {BRIDGE_CTRL_CLR_RLLP_CNT, 0, "CLR_RLLP_CNT"},
-    {BRIDGE_CTRL_CLR_TLLP_CNT, 0, "CLR_TLLP_CNT"},
-    {BRIDGE_CTRL_SYS_END, 0, "SYS_END"},
-    {BRIDGE_CTRL_MAX_TRANS_MASK, -4, "MAX_TRANS", "%d"},
-    {BRIDGE_CTRL_WIDGET_ID_MASK, 0, "WIDGET_ID", "%x"},
-    {0}
-};
-#endif
-#endif	/* LATER */
-
-/* kbrick widgetnum-to-bus layout */
-int p_busnum[MAX_PORT_NUM] = {                  /* widget#      */
-        0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7    */
-        2,                                      /* 0x8          */
-        1,                                      /* 0x9          */
-        0, 0,                                   /* 0xa - 0xb    */
-        5,                                      /* 0xc          */
-        6,                                      /* 0xd          */
-        4,                                      /* 0xe          */
-        3,                                      /* 0xf          */
-};
-
-/*
- * Additional PIO spaces per slot are
- * recorded in this structure.
- */
-struct pciio_piospace_s {
-    pciio_piospace_t        next;	/* another space for this device */
-    char                    free;	/* 1 if free, 0 if in use               */
-    pciio_space_t           space;	/* Which space is in use                */
-    iopaddr_t               start;	/* Starting address of the PIO space    */
-    size_t                  count;	/* size of PIO space                    */
-};
-
-#if PCIBR_SOFT_LIST
-pcibr_list_p            pcibr_list = 0;
-#endif
-
-#define	INFO_LBL_PCIBR_ASIC_REV	"_pcibr_asic_rev"
-
-#define	PCIBR_D64_BASE_UNSET	(0xFFFFFFFFFFFFFFFF)
-#define	PCIBR_D32_BASE_UNSET	(0xFFFFFFFF)
-
-#define PCIBR_VALID_SLOT(s)	(s < 8)
-
-#ifdef SN_XXX
-extern int      hub_device_flags_set(devfs_handle_t       widget_dev,
-                                     hub_widget_flags_t flags);
-#endif
-extern pciio_dmamap_t get_free_pciio_dmamap(devfs_handle_t);
-extern void free_pciio_dmamap(pcibr_dmamap_t);
-
-/*
- * This is the file operation table for the pcibr driver.
- * As each of the functions are implemented, put the 
- * appropriate function name below.
- */
-struct file_operations pcibr_fops = {
-        owner:  THIS_MODULE,
-        llseek: NULL,
-        read: NULL,
-        write: NULL,
-        readdir: NULL,
-        poll: NULL,
-        ioctl: NULL,
-        mmap: NULL,
-        open: NULL,
-        flush: NULL,
-        release: NULL,
-        fsync: NULL,
-        fasync: NULL,
-        lock: NULL,
-        readv: NULL,
-        writev: NULL
-};
-
-extern devfs_handle_t hwgraph_root;
-extern graph_error_t hwgraph_vertex_unref(devfs_handle_t vhdl);
-extern int cap_able(uint64_t x);
-extern uint64_t rmalloc(struct map *mp, size_t size);
-extern void rmfree(struct map *mp, size_t size, uint64_t a);
-extern int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen);
-extern long atoi(register char *p);
-extern char *dev_to_name(devfs_handle_t dev, char *buf, uint buflen);
-extern cnodeid_t nodevertex_to_cnodeid(devfs_handle_t vhdl);
-extern graph_error_t hwgraph_edge_remove(devfs_handle_t from, char *name, devfs_handle_t *toptr);
-extern struct map *rmallocmap(uint64_t mapsiz);
-extern void rmfreemap(struct map *mp);
-extern int compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr);
-extern int io_path_map_widget(devfs_handle_t vertex);
-
-
-
-/* =====================================================================
- *    Function Table of Contents
- *
- *      The order of functions in this file has stopped
- *      making much sense. We might want to take a look
- *      at it some time and bring back some sanity, or
- *      perhaps bust this file into smaller chunks.
- */
-
-LOCAL void              do_pcibr_rrb_clear(bridge_t *, int);
-LOCAL void              do_pcibr_rrb_flush(bridge_t *, int);
-LOCAL int               do_pcibr_rrb_count_valid(bridge_t *, pciio_slot_t);
-LOCAL int               do_pcibr_rrb_count_avail(bridge_t *, pciio_slot_t);
-LOCAL int               do_pcibr_rrb_alloc(bridge_t *, pciio_slot_t, int);
-LOCAL int               do_pcibr_rrb_free(bridge_t *, pciio_slot_t, int);
-
-LOCAL void              do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int);
-
-int			pcibr_wrb_flush(devfs_handle_t);
-int                     pcibr_rrb_alloc(devfs_handle_t, int *, int *);
-int                     pcibr_rrb_check(devfs_handle_t, int *, int *, int *, int *);
-int                     pcibr_alloc_all_rrbs(devfs_handle_t, int, int, int, int, int, int, int, int, int);
-void                    pcibr_rrb_flush(devfs_handle_t);
-
-LOCAL int               pcibr_try_set_device(pcibr_soft_t, pciio_slot_t, unsigned, bridgereg_t);
-void                    pcibr_release_device(pcibr_soft_t, pciio_slot_t, bridgereg_t);
-
-LOCAL void              pcibr_clearwidint(bridge_t *);
-LOCAL void              pcibr_setwidint(xtalk_intr_t);
-LOCAL int               pcibr_probe_slot(bridge_t *, cfg_p, unsigned *);
-
-void                    pcibr_init(void);
-int                     pcibr_attach(devfs_handle_t);
-int			pcibr_detach(devfs_handle_t);
-int                     pcibr_open(devfs_handle_t *, int, int, cred_t *);
-int                     pcibr_close(devfs_handle_t, int, int, cred_t *);
-int                     pcibr_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint);
-int                     pcibr_unmap(devfs_handle_t, vhandl_t *);
-int                     pcibr_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *);
-
-void                    pcibr_freeblock_sub(iopaddr_t *, iopaddr_t *, iopaddr_t, size_t);
-
-LOCAL int               pcibr_init_ext_ate_ram(bridge_t *);
-LOCAL int               pcibr_ate_alloc(pcibr_soft_t, int);
-LOCAL void              pcibr_ate_free(pcibr_soft_t, int, int);
-
-LOCAL pcibr_info_t      pcibr_info_get(devfs_handle_t);
-LOCAL pcibr_info_t      pcibr_device_info_new(pcibr_soft_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
-LOCAL void		pcibr_device_info_free(devfs_handle_t, pciio_slot_t);
-LOCAL iopaddr_t         pcibr_addr_pci_to_xio(devfs_handle_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-
-pcibr_piomap_t          pcibr_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
-void                    pcibr_piomap_free(pcibr_piomap_t);
-caddr_t                 pcibr_piomap_addr(pcibr_piomap_t, iopaddr_t, size_t);
-void                    pcibr_piomap_done(pcibr_piomap_t);
-caddr_t                 pcibr_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-iopaddr_t               pcibr_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
-void                    pcibr_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
-
-LOCAL iopaddr_t         pcibr_flags_to_d64(unsigned, pcibr_soft_t);
-LOCAL bridge_ate_t      pcibr_flags_to_ate(unsigned);
-
-pcibr_dmamap_t          pcibr_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
-void                    pcibr_dmamap_free(pcibr_dmamap_t);
-LOCAL bridge_ate_p      pcibr_ate_addr(pcibr_soft_t, int);
-LOCAL iopaddr_t         pcibr_addr_xio_to_pci(pcibr_soft_t, iopaddr_t, size_t);
-iopaddr_t               pcibr_dmamap_addr(pcibr_dmamap_t, paddr_t, size_t);
-alenlist_t              pcibr_dmamap_list(pcibr_dmamap_t, alenlist_t, unsigned);
-void                    pcibr_dmamap_done(pcibr_dmamap_t);
-cnodeid_t		pcibr_get_dmatrans_node(devfs_handle_t);
-iopaddr_t               pcibr_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              pcibr_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
-void                    pcibr_dmamap_drain(pcibr_dmamap_t);
-void                    pcibr_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
-void                    pcibr_dmalist_drain(devfs_handle_t, alenlist_t);
-iopaddr_t               pcibr_dmamap_pciaddr_get(pcibr_dmamap_t);
-
-static unsigned		pcibr_intr_bits(pciio_info_t info, pciio_intr_line_t lines);
-pcibr_intr_t            pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
-void                    pcibr_intr_free(pcibr_intr_t);
-LOCAL void              pcibr_setpciint(xtalk_intr_t);
-int                     pcibr_intr_connect(pcibr_intr_t);
-void                    pcibr_intr_disconnect(pcibr_intr_t);
-
-devfs_handle_t            pcibr_intr_cpu_get(pcibr_intr_t);
-void                    pcibr_xintr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
-void                    pcibr_intr_func(intr_arg_t);
-
-void                    pcibr_provider_startup(devfs_handle_t);
-void                    pcibr_provider_shutdown(devfs_handle_t);
-
-int                     pcibr_reset(devfs_handle_t);
-pciio_endian_t          pcibr_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
-int                     pcibr_priority_bits_set(pcibr_soft_t, pciio_slot_t, pciio_priority_t);
-pciio_priority_t        pcibr_priority_set(devfs_handle_t, pciio_priority_t);
-int                     pcibr_device_flags_set(devfs_handle_t, pcibr_device_flags_t);
-
-LOCAL cfg_p             pcibr_config_addr(devfs_handle_t, unsigned);
-uint64_t                pcibr_config_get(devfs_handle_t, unsigned, unsigned);
-LOCAL uint64_t          do_pcibr_config_get(cfg_p, unsigned, unsigned);
-void                    pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t);
-LOCAL void              do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t);
-
-LOCAL pcibr_hints_t     pcibr_hints_get(devfs_handle_t, int);
-void                    pcibr_hints_fix_rrbs(devfs_handle_t);
-void                    pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t);
-void			pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *);
-void                    pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t);
-void                    pcibr_hints_handsoff(devfs_handle_t);
-void                    pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, ulong);
-
-LOCAL int		pcibr_slot_info_init(devfs_handle_t,pciio_slot_t);
-LOCAL int		pcibr_slot_info_free(devfs_handle_t,pciio_slot_t);
-
-#ifdef LATER
-LOCAL int	        pcibr_slot_info_return(pcibr_soft_t, pciio_slot_t,
-                                               pcibr_slot_info_resp_t);
-LOCAL void       	pcibr_slot_func_info_return(pcibr_info_h, int,
-                                                    pcibr_slot_func_info_resp_t);
-#endif	/* LATER */
-
-LOCAL int		pcibr_slot_addr_space_init(devfs_handle_t,pciio_slot_t);
-LOCAL int		pcibr_slot_device_init(devfs_handle_t, pciio_slot_t);
-LOCAL int		pcibr_slot_guest_info_init(devfs_handle_t,pciio_slot_t);
-LOCAL int		pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t);
-LOCAL int		pcibr_slot_call_device_attach(devfs_handle_t,
-						      pciio_slot_t, int);
-LOCAL int		pcibr_slot_call_device_detach(devfs_handle_t,
-						      pciio_slot_t, int);
-
-LOCAL int               pcibr_slot_detach(devfs_handle_t, pciio_slot_t, int);
-LOCAL int 		pcibr_is_slot_sys_critical(devfs_handle_t, pciio_slot_t);
-#ifdef LATER
-LOCAL int		pcibr_slot_query(devfs_handle_t, pcibr_slot_info_req_t);
-#endif
-
-/* =====================================================================
- *    RRB management
- */
-
-#define LSBIT(word)		((word) &~ ((word)-1))
-
-#define PCIBR_RRB_SLOT_VIRTUAL	8
-
-LOCAL void
-do_pcibr_rrb_clear(bridge_t *bridge, int rrb)
-{
-    bridgereg_t             status;
-
-    /* bridge_lock must be held;
-     * this RRB must be disabled.
-     */
-
-    /* wait until RRB has no outstanduing XIO packets. */
-    while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) {
-	;				/* XXX- beats on bridge. bad idea? */
-    }
-
-    /* if the RRB has data, drain it. */
-    if (status & BRIDGE_RRB_VALID(rrb)) {
-	bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb);
-
-	/* wait until RRB is no longer valid. */
-	while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) {
-	    ;				/* XXX- beats on bridge. bad idea? */
-	}
-    }
-}
-
-LOCAL void
-do_pcibr_rrb_flush(bridge_t *bridge, int rrbn)
-{
-    reg_p                   rrbp = &bridge->b_rrb_map[rrbn & 1].reg;
-    bridgereg_t             rrbv;
-    int                     shft = 4 * (rrbn >> 1);
-    unsigned                ebit = BRIDGE_RRB_EN << shft;
-
-    rrbv = *rrbp;
-    if (rrbv & ebit)
-	*rrbp = rrbv & ~ebit;
-
-    do_pcibr_rrb_clear(bridge, rrbn);
-
-    if (rrbv & ebit)
-	*rrbp = rrbv;
-}
-
-/*
- *    pcibr_rrb_count_valid: count how many RRBs are
- *      marked valid for the specified PCI slot on this
- *      bridge.
- *
- *      NOTE: The "slot" parameter for all pcibr_rrb
- *      management routines must include the "virtual"
- *      bit; when manageing both the normal and the
- *      virtual channel, separate calls to these
- *      routines must be made. To denote the virtual
- *      channel, add PCIBR_RRB_SLOT_VIRTUAL to the slot
- *      number.
- *
- *      IMPL NOTE: The obvious algorithm is to iterate
- *      through the RRB fields, incrementing a count if
- *      the RRB is valid and matches the slot. However,
- *      it is much simpler to use an algorithm derived
- *      from the "partitioned add" idea. First, XOR in a
- *      pattern such that the fields that match this
- *      slot come up "all ones" and all other fields
- *      have zeros in the mismatching bits. Then AND
- *      together the bits in the field, so we end up
- *      with one bit turned on for each field that
- *      matched. Now we need to count these bits. This
- *      can be done either with a series of shift/add
- *      instructions or by using "tmp % 15"; I expect
- *      that the cascaded shift/add will be faster.
- */
-
-LOCAL int
-do_pcibr_rrb_count_valid(bridge_t *bridge,
-			 pciio_slot_t slot)
-{
-    bridgereg_t             tmp;
-
-    tmp = bridge->b_rrb_map[slot & 1].reg;
-    tmp ^= 0x11111111 * (7 - slot / 2);
-    tmp &= (0xCCCCCCCC & tmp) >> 2;
-    tmp &= (0x22222222 & tmp) >> 1;
-    tmp += tmp >> 4;
-    tmp += tmp >> 8;
-    tmp += tmp >> 16;
-    return tmp & 15;
-}
-
-/*
- *    do_pcibr_rrb_count_avail: count how many RRBs are
- *      available to be allocated for the specified slot.
- *
- *      IMPL NOTE: similar to the above, except we are
- *      just counting how many fields have the valid bit
- *      turned off.
- */
-LOCAL int
-do_pcibr_rrb_count_avail(bridge_t *bridge,
-			 pciio_slot_t slot)
-{
-    bridgereg_t             tmp;
-
-    tmp = bridge->b_rrb_map[slot & 1].reg;
-    tmp = (0x88888888 & ~tmp) >> 3;
-    tmp += tmp >> 4;
-    tmp += tmp >> 8;
-    tmp += tmp >> 16;
-    return tmp & 15;
-}
-
-/*
- *    do_pcibr_rrb_alloc: allocate some additional RRBs
- *      for the specified slot. Returns -1 if there were
- *      insufficient free RRBs to satisfy the request,
- *      or 0 if the request was fulfilled.
- *
- *      Note that if a request can be partially filled,
- *      it will be, even if we return failure.
- *
- *      IMPL NOTE: again we avoid iterating across all
- *      the RRBs; instead, we form up a word containing
- *      one bit for each free RRB, then peel the bits
- *      off from the low end.
- */
-LOCAL int
-do_pcibr_rrb_alloc(bridge_t *bridge,
-		   pciio_slot_t slot,
-		   int more)
-{
-    int                     rv = 0;
-    bridgereg_t             reg, tmp, bit;
-
-    reg = bridge->b_rrb_map[slot & 1].reg;
-    tmp = (0x88888888 & ~reg) >> 3;
-    while (more-- > 0) {
-	bit = LSBIT(tmp);
-	if (!bit) {
-	    rv = -1;
-	    break;
-	}
-	tmp &= ~bit;
-	reg = ((reg & ~(bit * 15)) | (bit * (8 + slot / 2)));
-    }
-    bridge->b_rrb_map[slot & 1].reg = reg;
-    return rv;
-}
-
-/*
- *    do_pcibr_rrb_free: release some of the RRBs that
- *      have been allocated for the specified
- *      slot. Returns zero for success, or negative if
- *      it was unable to free that many RRBs.
- *
- *      IMPL NOTE: We form up a bit for each RRB
- *      allocated to the slot, aligned with the VALID
- *      bitfield this time; then we peel bits off one at
- *      a time, releasing the corresponding RRB.
- */
-LOCAL int
-do_pcibr_rrb_free(bridge_t *bridge,
-		  pciio_slot_t slot,
-		  int less)
-{
-    int                     rv = 0;
-    bridgereg_t             reg, tmp, clr, bit;
-    int                     i;
-
-    clr = 0;
-    reg = bridge->b_rrb_map[slot & 1].reg;
-
-    /* This needs to be done otherwise the rrb's on the virtual channel
-     * for this slot won't be freed !!
-     */
-    tmp = reg & 0xbbbbbbbb;
-
-    tmp ^= (0x11111111 * (7 - slot / 2));
-    tmp &= (0x33333333 & tmp) << 2;
-    tmp &= (0x44444444 & tmp) << 1;
-    while (less-- > 0) {
-	bit = LSBIT(tmp);
-	if (!bit) {
-	    rv = -1;
-	    break;
-	}
-	tmp &= ~bit;
-	reg &= ~bit;
-	clr |= bit;
-    }
-    bridge->b_rrb_map[slot & 1].reg = reg;
-
-    for (i = 0; i < 8; i++)
-	if (clr & (8 << (4 * i)))
-	    do_pcibr_rrb_clear(bridge, (2 * i) + (slot & 1));
-
-    return rv;
-}
-
-LOCAL void
-do_pcibr_rrb_autoalloc(pcibr_soft_t pcibr_soft,
-		       int slot,
-		       int more_rrbs)
-{
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    int                     got;
-
-    for (got = 0; got < more_rrbs; ++got) {
-	if (pcibr_soft->bs_rrb_res[slot & 7] > 0)
-	    pcibr_soft->bs_rrb_res[slot & 7]--;
-	else if (pcibr_soft->bs_rrb_avail[slot & 1] > 0)
-	    pcibr_soft->bs_rrb_avail[slot & 1]--;
-	else
-	    break;
-	if (do_pcibr_rrb_alloc(bridge, slot, 1) < 0)
-	    break;
-#if PCIBR_RRB_DEBUG
-	printk( "do_pcibr_rrb_autoalloc: add one to slot %d%s\n",
-		slot & 7, slot & 8 ? "v" : "");
-#endif
-	pcibr_soft->bs_rrb_valid[slot]++;
-    }
-#if PCIBR_RRB_DEBUG
-    printk("%s: %d+%d free RRBs. Allocation list:\n", pcibr_soft->bs_name,
-	    pcibr_soft->bs_rrb_avail[0],
-	    pcibr_soft->bs_rrb_avail[1]);
-    for (slot = 0; slot < 8; ++slot)
-	printk("\t%d+%d+%d",
-		0xFFF & pcibr_soft->bs_rrb_valid[slot],
-		0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-		pcibr_soft->bs_rrb_res[slot]);
-	printk("\n");
-#endif
-}
-
-/*
- * Device driver interface to flush the write buffers for a specified
- * device hanging off the bridge.
- */
-int
-pcibr_wrb_flush(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    volatile bridgereg_t   *wrb_flush;
-
-    wrb_flush = &(bridge->b_wr_req_buf[pciio_slot].reg);
-    while (*wrb_flush);
-
-    return(0);
-}
-/*
- * Device driver interface to request RRBs for a specified device
- * hanging off a Bridge.  The driver requests the total number of
- * RRBs it would like for the normal channel (vchan0) and for the
- * "virtual channel" (vchan1).  The actual number allocated to each
- * channel is returned.
- *
- * If we cannot allocate at least one RRB to a channel that needs
- * at least one, return -1 (failure).  Otherwise, satisfy the request
- * as best we can and return 0.
- */
-int
-pcibr_rrb_alloc(devfs_handle_t pconn_vhdl,
-		int *count_vchan0,
-		int *count_vchan1)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    int                     desired_vchan0;
-    int                     desired_vchan1;
-    int                     orig_vchan0;
-    int                     orig_vchan1;
-    int                     delta_vchan0;
-    int                     delta_vchan1;
-    int                     final_vchan0;
-    int                     final_vchan1;
-    int                     avail_rrbs;
-    unsigned long           s;
-    int                     error;
-
-    /*
-     * TBD: temper request with admin info about RRB allocation,
-     * and according to demand from other devices on this Bridge.
-     *
-     * One way of doing this would be to allocate two RRBs
-     * for each device on the bus, before any drivers start
-     * asking for extras. This has the weakness that one
-     * driver might not give back an "extra" RRB until after
-     * another driver has already failed to get one that
-     * it wanted.
-     */
-
-    s = pcibr_lock(pcibr_soft);
-
-    /* How many RRBs do we own? */
-    orig_vchan0 = pcibr_soft->bs_rrb_valid[pciio_slot];
-    orig_vchan1 = pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL];
-
-    /* How many RRBs do we want? */
-    desired_vchan0 = count_vchan0 ? *count_vchan0 : orig_vchan0;
-    desired_vchan1 = count_vchan1 ? *count_vchan1 : orig_vchan1;
-
-    /* How many RRBs are free? */
-    avail_rrbs = pcibr_soft->bs_rrb_avail[pciio_slot & 1]
-	+ pcibr_soft->bs_rrb_res[pciio_slot];
-
-    /* Figure desired deltas */
-    delta_vchan0 = desired_vchan0 - orig_vchan0;
-    delta_vchan1 = desired_vchan1 - orig_vchan1;
-
-    /* Trim back deltas to something
-     * that we can actually meet, by
-     * decreasing the ending allocation
-     * for whichever channel wants
-     * more RRBs. If both want the same
-     * number, cut the second channel.
-     * NOTE: do not change the allocation for
-     * a channel that was passed as NULL.
-     */
-    while ((delta_vchan0 + delta_vchan1) > avail_rrbs) {
-	if (count_vchan0 &&
-	    (!count_vchan1 ||
-	     ((orig_vchan0 + delta_vchan0) >
-	      (orig_vchan1 + delta_vchan1))))
-	    delta_vchan0--;
-	else
-	    delta_vchan1--;
-    }
-
-    /* Figure final RRB allocations
-     */
-    final_vchan0 = orig_vchan0 + delta_vchan0;
-    final_vchan1 = orig_vchan1 + delta_vchan1;
-
-    /* If either channel wants RRBs but our actions
-     * would leave it with none, declare an error,
-     * but DO NOT change any RRB allocations.
-     */
-    if ((desired_vchan0 && !final_vchan0) ||
-	(desired_vchan1 && !final_vchan1)) {
-
-	error = -1;
-
-    } else {
-
-	/* Commit the allocations: free, then alloc.
-	 */
-	if (delta_vchan0 < 0)
-	    (void) do_pcibr_rrb_free(bridge, pciio_slot, -delta_vchan0);
-	if (delta_vchan1 < 0)
-	    (void) do_pcibr_rrb_free(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, -delta_vchan1);
-
-	if (delta_vchan0 > 0)
-	    (void) do_pcibr_rrb_alloc(bridge, pciio_slot, delta_vchan0);
-	if (delta_vchan1 > 0)
-	    (void) do_pcibr_rrb_alloc(bridge, PCIBR_RRB_SLOT_VIRTUAL + pciio_slot, delta_vchan1);
-
-	/* Return final values to caller.
-	 */
-	if (count_vchan0)
-	    *count_vchan0 = final_vchan0;
-	if (count_vchan1)
-	    *count_vchan1 = final_vchan1;
-
-	/* prevent automatic changes to this slot's RRBs
-	 */
-	pcibr_soft->bs_rrb_fixed |= 1 << pciio_slot;
-
-	/* Track the actual allocations, release
-	 * any further reservations, and update the
-	 * number of available RRBs.
-	 */
-
-	pcibr_soft->bs_rrb_valid[pciio_slot] = final_vchan0;
-	pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL] = final_vchan1;
-	pcibr_soft->bs_rrb_avail[pciio_slot & 1] =
-	    pcibr_soft->bs_rrb_avail[pciio_slot & 1]
-	    + pcibr_soft->bs_rrb_res[pciio_slot]
-	    - delta_vchan0
-	    - delta_vchan1;
-	pcibr_soft->bs_rrb_res[pciio_slot] = 0;
-
-#if PCIBR_RRB_DEBUG
-	printk("pcibr_rrb_alloc: slot %d set to %d+%d; %d+%d free\n",
-		pciio_slot, final_vchan0, final_vchan1,
-		pcibr_soft->bs_rrb_avail[0],
-		pcibr_soft->bs_rrb_avail[1]);
-	for (pciio_slot = 0; pciio_slot < 8; ++pciio_slot)
-	    printk("\t%d+%d+%d",
-		    0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot],
-		    0xFFF & pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL],
-		    pcibr_soft->bs_rrb_res[pciio_slot]);
-	printk("\n");
-#endif
-
-	error = 0;
-    }
-
-    pcibr_unlock(pcibr_soft, s);
-    return error;
-}
-
-/*
- * Device driver interface to check the current state
- * of the RRB allocations.
- *
- *   pconn_vhdl is your PCI connection point (specifies which
- *      PCI bus and which slot).
- *
- *   count_vchan0 points to where to return the number of RRBs
- *      assigned to the primary DMA channel, used by all DMA
- *      that does not explicitly ask for the alternate virtual
- *      channel.
- *
- *   count_vchan1 points to where to return the number of RRBs
- *      assigned to the secondary DMA channel, used when
- *      PCIBR_VCHAN1 and PCIIO_DMA_A64 are specified.
- *
- *   count_reserved points to where to return the number of RRBs
- *      that have been automatically reserved for your device at
- *      startup, but which have not been assigned to a
- *      channel. RRBs must be assigned to a channel to be used;
- *      this can be done either with an explicit pcibr_rrb_alloc
- *      call, or automatically by the infrastructure when a DMA
- *      translation is constructed. Any call to pcibr_rrb_alloc
- *      will release any unassigned reserved RRBs back to the
- *      free pool.
- *
- *   count_pool points to where to return the number of RRBs
- *      that are currently unassigned and unreserved. This
- *      number can (and will) change as other drivers make calls
- *      to pcibr_rrb_alloc, or automatically allocate RRBs for
- *      DMA beyond their initial reservation.
- *
- * NULL may be passed for any of the return value pointers
- * the caller is not interested in.
- *
- * The return value is "0" if all went well, or "-1" if
- * there is a problem. Additionally, if the wrong vertex
- * is passed in, one of the subsidiary support functions
- * could panic with a "bad pciio fingerprint."
- */
-
-int
-pcibr_rrb_check(devfs_handle_t pconn_vhdl,
-		int *count_vchan0,
-		int *count_vchan1,
-		int *count_reserved,
-		int *count_pool)
-{
-    pciio_info_t            pciio_info;
-    pciio_slot_t            pciio_slot;
-    pcibr_soft_t            pcibr_soft;
-    unsigned long           s;
-    int                     error = -1;
-
-    if ((pciio_info = pciio_info_get(pconn_vhdl)) &&
-	(pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info)) &&
-	((pciio_slot = pciio_info_slot_get(pciio_info)) < 8)) {
-
-	s = pcibr_lock(pcibr_soft);
-
-	if (count_vchan0)
-	    *count_vchan0 =
-		pcibr_soft->bs_rrb_valid[pciio_slot];
-
-	if (count_vchan1)
-	    *count_vchan1 =
-		pcibr_soft->bs_rrb_valid[pciio_slot + PCIBR_RRB_SLOT_VIRTUAL];
-
-	if (count_reserved)
-	    *count_reserved =
-		pcibr_soft->bs_rrb_res[pciio_slot];
-
-	if (count_pool)
-	    *count_pool =
-		pcibr_soft->bs_rrb_avail[pciio_slot & 1];
-
-	error = 0;
-
-	pcibr_unlock(pcibr_soft, s);
-    }
-    return error;
-}
-
-/* pcibr_alloc_all_rrbs allocates all the rrbs available in the quantities
- * requested for each of the devies.  The evn_odd argument indicates whether
- * allcoation for the odd or even rrbs is requested and next group of four pairse
- * are the amount to assign to each device (they should sum to <= 8) and
- * whether to set the viritual bit for that device (1 indictaes yes, 0 indicates no)
- * the devices in order are either 0, 2, 4, 6 or 1, 3, 5, 7
- * if even_odd is even we alloc even rrbs else we allocate odd rrbs
- * returns 0 if no errors else returns -1
- */
-
-int
-pcibr_alloc_all_rrbs(devfs_handle_t vhdl, int even_odd,
-		     int dev_1_rrbs, int virt1, int dev_2_rrbs, int virt2,
-		     int dev_3_rrbs, int virt3, int dev_4_rrbs, int virt4)
-{
-    devfs_handle_t            pcibr_vhdl;
-    pcibr_soft_t            pcibr_soft = NULL;
-    bridge_t               *bridge = NULL;
-
-    uint32_t              rrb_setting = 0;
-    int                     rrb_shift = 7;
-    uint32_t              cur_rrb;
-    int                     dev_rrbs[4];
-    int                     virt[4];
-    int                     i, j;
-    unsigned long           s;
-
-    if (GRAPH_SUCCESS ==
-	hwgraph_traverse(vhdl, EDGE_LBL_PCI, &pcibr_vhdl)) {
-	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-	if (pcibr_soft)
-	    bridge = pcibr_soft->bs_base;
-	hwgraph_vertex_unref(pcibr_vhdl);
-    }
-    if (bridge == NULL)
-	bridge = (bridge_t *) xtalk_piotrans_addr
-	    (vhdl, NULL, 0, sizeof(bridge_t), 0);
-
-    even_odd &= 1;
-
-    dev_rrbs[0] = dev_1_rrbs;
-    dev_rrbs[1] = dev_2_rrbs;
-    dev_rrbs[2] = dev_3_rrbs;
-    dev_rrbs[3] = dev_4_rrbs;
-
-    virt[0] = virt1;
-    virt[1] = virt2;
-    virt[2] = virt3;
-    virt[3] = virt4;
-
-    if ((dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs) > 8) {
-	return -1;
-    }
-    if ((dev_1_rrbs < 0) || (dev_2_rrbs < 0) || (dev_3_rrbs < 0) || (dev_4_rrbs < 0)) {
-	return -1;
-    }
-    /* walk through rrbs */
-    for (i = 0; i < 4; i++) {
-	if (virt[i]) {
-	    cur_rrb = i | 0xc;
-	    cur_rrb = cur_rrb << (rrb_shift * 4);
-	    rrb_shift--;
-	    rrb_setting = rrb_setting | cur_rrb;
-	    dev_rrbs[i] = dev_rrbs[i] - 1;
-	}
-	for (j = 0; j < dev_rrbs[i]; j++) {
-	    cur_rrb = i | 0x8;
-	    cur_rrb = cur_rrb << (rrb_shift * 4);
-	    rrb_shift--;
-	    rrb_setting = rrb_setting | cur_rrb;
-	}
-    }
-
-    if (pcibr_soft)
-	s = pcibr_lock(pcibr_soft);
-
-    bridge->b_rrb_map[even_odd].reg = rrb_setting;
-
-    if (pcibr_soft) {
-
-	pcibr_soft->bs_rrb_fixed |= 0x55 << even_odd;
-
-	/* since we've "FIXED" the allocations
-	 * for these slots, we probably can dispense
-	 * with tracking avail/res/valid data, but
-	 * keeping it up to date helps debugging.
-	 */
-
-	pcibr_soft->bs_rrb_avail[even_odd] =
-	    8 - (dev_1_rrbs + dev_2_rrbs + dev_3_rrbs + dev_4_rrbs);
-
-	pcibr_soft->bs_rrb_res[even_odd + 0] = 0;
-	pcibr_soft->bs_rrb_res[even_odd + 2] = 0;
-	pcibr_soft->bs_rrb_res[even_odd + 4] = 0;
-	pcibr_soft->bs_rrb_res[even_odd + 6] = 0;
-
-	pcibr_soft->bs_rrb_valid[even_odd + 0] = dev_1_rrbs - virt1;
-	pcibr_soft->bs_rrb_valid[even_odd + 2] = dev_2_rrbs - virt2;
-	pcibr_soft->bs_rrb_valid[even_odd + 4] = dev_3_rrbs - virt3;
-	pcibr_soft->bs_rrb_valid[even_odd + 6] = dev_4_rrbs - virt4;
-
-	pcibr_soft->bs_rrb_valid[even_odd + 0 + PCIBR_RRB_SLOT_VIRTUAL] = virt1;
-	pcibr_soft->bs_rrb_valid[even_odd + 2 + PCIBR_RRB_SLOT_VIRTUAL] = virt2;
-	pcibr_soft->bs_rrb_valid[even_odd + 4 + PCIBR_RRB_SLOT_VIRTUAL] = virt3;
-	pcibr_soft->bs_rrb_valid[even_odd + 6 + PCIBR_RRB_SLOT_VIRTUAL] = virt4;
-
-	pcibr_unlock(pcibr_soft, s);
-    }
-    return 0;
-}
-
-/*
- *    pcibr_rrb_flush: chase down all the RRBs assigned
- *      to the specified connection point, and flush
- *      them.
- */
-void
-pcibr_rrb_flush(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    unsigned long           s;
-    reg_p                   rrbp;
-    unsigned                rrbm;
-    int                     i;
-    int                     rrbn;
-    unsigned                sval;
-    unsigned                mask;
-
-    sval = BRIDGE_RRB_EN | (pciio_slot >> 1);
-    mask = BRIDGE_RRB_EN | BRIDGE_RRB_PDEV;
-    rrbn = pciio_slot & 1;
-    rrbp = &bridge->b_rrb_map[rrbn].reg;
-
-    s = pcibr_lock(pcibr_soft);
-    rrbm = *rrbp;
-    for (i = 0; i < 8; ++i) {
-	if ((rrbm & mask) == sval)
-	    do_pcibr_rrb_flush(bridge, rrbn);
-	rrbm >>= 4;
-	rrbn += 2;
-    }
-    pcibr_unlock(pcibr_soft, s);
-}
-
-/* =====================================================================
- *    Device(x) register management
- */
-
-/* pcibr_try_set_device: attempt to modify Device(x)
- * for the specified slot on the specified bridge
- * as requested in flags, limited to the specified
- * bits. Returns which BRIDGE bits were in conflict,
- * or ZERO if everything went OK.
- *
- * Caller MUST hold pcibr_lock when calling this function.
- */
-LOCAL int
-pcibr_try_set_device(pcibr_soft_t pcibr_soft,
-		     pciio_slot_t slot,
-		     unsigned flags,
-		     bridgereg_t mask)
-{
-    bridge_t               *bridge;
-    pcibr_soft_slot_t       slotp;
-    bridgereg_t             old;
-    bridgereg_t             new;
-    bridgereg_t             chg;
-    bridgereg_t             bad;
-    bridgereg_t             badpmu;
-    bridgereg_t             badd32;
-    bridgereg_t             badd64;
-    bridgereg_t             fix;
-    unsigned long           s;
-    bridgereg_t             xmask;
-
-    xmask = mask;
-    if (pcibr_soft->bs_xbridge) {
-    	if (mask == BRIDGE_DEV_PMU_BITS)
-		xmask = XBRIDGE_DEV_PMU_BITS;
-	if (mask == BRIDGE_DEV_D64_BITS)
-		xmask = XBRIDGE_DEV_D64_BITS;
-    }
-
-    slotp = &pcibr_soft->bs_slot[slot];
-
-    s = pcibr_lock(pcibr_soft);
-
-    bridge = pcibr_soft->bs_base;
-
-    old = slotp->bss_device;
-
-    /* figure out what the desired
-     * Device(x) bits are based on
-     * the flags specified.
-     */
-
-    new = old;
-
-    /* Currently, we inherit anything that
-     * the new caller has not specified in
-     * one way or another, unless we take
-     * action here to not inherit.
-     *
-     * This is needed for the "swap" stuff,
-     * since it could have been set via
-     * pcibr_endian_set -- altho note that
-     * any explicit PCIBR_BYTE_STREAM or
-     * PCIBR_WORD_VALUES will freely override
-     * the effect of that call (and vice
-     * versa, no protection either way).
-     *
-     * I want to get rid of pcibr_endian_set
-     * in favor of tracking DMA endianness
-     * using the flags specified when DMA
-     * channels are created.
-     */
-
-#define	BRIDGE_DEV_WRGA_BITS	(BRIDGE_DEV_PMU_WRGA_EN | BRIDGE_DEV_DIR_WRGA_EN)
-#define	BRIDGE_DEV_SWAP_BITS	(BRIDGE_DEV_SWAP_PMU | BRIDGE_DEV_SWAP_DIR)
-
-    /* Do not use Barrier, Write Gather,
-     * or Prefetch unless asked.
-     * Leave everything else as it
-     * was from the last time.
-     */
-    new = new
-	& ~BRIDGE_DEV_BARRIER
-	& ~BRIDGE_DEV_WRGA_BITS
-	& ~BRIDGE_DEV_PREF
-	;
-
-    /* Generic macro flags
-     */
-    if (flags & PCIIO_DMA_DATA) {
-	new = (new
-            & ~BRIDGE_DEV_BARRIER)      /* barrier off */
-            | BRIDGE_DEV_PREF;          /* prefetch on */
-
-    }
-    if (flags & PCIIO_DMA_CMD) {
-        new = ((new
-            & ~BRIDGE_DEV_PREF)         /* prefetch off */
-            & ~BRIDGE_DEV_WRGA_BITS)    /* write gather off */
-            | BRIDGE_DEV_BARRIER;       /* barrier on */
-    }
-    /* Generic detail flags
-     */
-    if (flags & PCIIO_WRITE_GATHER)
-	new |= BRIDGE_DEV_WRGA_BITS;
-    if (flags & PCIIO_NOWRITE_GATHER)
-	new &= ~BRIDGE_DEV_WRGA_BITS;
-
-    if (flags & PCIIO_PREFETCH)
-	new |= BRIDGE_DEV_PREF;
-    if (flags & PCIIO_NOPREFETCH)
-	new &= ~BRIDGE_DEV_PREF;
-
-    if (flags & PCIBR_WRITE_GATHER)
-	new |= BRIDGE_DEV_WRGA_BITS;
-    if (flags & PCIBR_NOWRITE_GATHER)
-	new &= ~BRIDGE_DEV_WRGA_BITS;
-
-    if (flags & PCIIO_BYTE_STREAM)
-	new |= (pcibr_soft->bs_xbridge) ? 
-			BRIDGE_DEV_SWAP_DIR : BRIDGE_DEV_SWAP_BITS;
-    if (flags & PCIIO_WORD_VALUES)
-	new &= (pcibr_soft->bs_xbridge) ? 
-			~BRIDGE_DEV_SWAP_DIR : ~BRIDGE_DEV_SWAP_BITS;
-
-    /* Provider-specific flags
-     */
-    if (flags & PCIBR_PREFETCH)
-	new |= BRIDGE_DEV_PREF;
-    if (flags & PCIBR_NOPREFETCH)
-	new &= ~BRIDGE_DEV_PREF;
-
-    if (flags & PCIBR_PRECISE)
-	new |= BRIDGE_DEV_PRECISE;
-    if (flags & PCIBR_NOPRECISE)
-	new &= ~BRIDGE_DEV_PRECISE;
-
-    if (flags & PCIBR_BARRIER)
-	new |= BRIDGE_DEV_BARRIER;
-    if (flags & PCIBR_NOBARRIER)
-	new &= ~BRIDGE_DEV_BARRIER;
-
-    if (flags & PCIBR_64BIT)
-	new |= BRIDGE_DEV_DEV_SIZE;
-    if (flags & PCIBR_NO64BIT)
-	new &= ~BRIDGE_DEV_DEV_SIZE;
-
-    chg = old ^ new;				/* what are we changing, */
-    chg &= xmask;				/* of the interesting bits */
-
-    if (chg) {
-
-	badd32 = slotp->bss_d32_uctr ? (BRIDGE_DEV_D32_BITS & chg) : 0;
-	if (pcibr_soft->bs_xbridge) {
-		badpmu = slotp->bss_pmu_uctr ? (XBRIDGE_DEV_PMU_BITS & chg) : 0;
-		badd64 = slotp->bss_d64_uctr ? (XBRIDGE_DEV_D64_BITS & chg) : 0;
-	} else {
-		badpmu = slotp->bss_pmu_uctr ? (BRIDGE_DEV_PMU_BITS & chg) : 0;
-		badd64 = slotp->bss_d64_uctr ? (BRIDGE_DEV_D64_BITS & chg) : 0;
-	}
-	bad = badpmu | badd32 | badd64;
-
-	if (bad) {
-
-	    /* some conflicts can be resolved by
-	     * forcing the bit on. this may cause
-	     * some performance degredation in
-	     * the stream(s) that want the bit off,
-	     * but the alternative is not allowing
-	     * the new stream at all.
-	     */
-            if ( (fix = bad & (BRIDGE_DEV_PRECISE |
-                             BRIDGE_DEV_BARRIER)) ){
-		bad &= ~fix;
-		/* don't change these bits if
-		 * they are already set in "old"
-		 */
-		chg &= ~(fix & old);
-	    }
-	    /* some conflicts can be resolved by
-	     * forcing the bit off. this may cause
-	     * some performance degredation in
-	     * the stream(s) that want the bit on,
-	     * but the alternative is not allowing
-	     * the new stream at all.
-	     */
-	    if ( (fix = bad & (BRIDGE_DEV_WRGA_BITS |
-			     BRIDGE_DEV_PREF)) ) {
-		bad &= ~fix;
-		/* don't change these bits if
-		 * we wanted to turn them on.
-		 */
-		chg &= ~(fix & new);
-	    }
-	    /* conflicts in other bits mean
-	     * we can not establish this DMA
-	     * channel while the other(s) are
-	     * still present.
-	     */
-	    if (bad) {
-		pcibr_unlock(pcibr_soft, s);
-#if (DEBUG && PCIBR_DEV_DEBUG)
-		printk("pcibr_try_set_device: mod blocked by %R\n", bad, device_bits);
-#endif
-		return bad;
-	    }
-	}
-    }
-    if (mask == BRIDGE_DEV_PMU_BITS)
-	slotp->bss_pmu_uctr++;
-    if (mask == BRIDGE_DEV_D32_BITS)
-	slotp->bss_d32_uctr++;
-    if (mask == BRIDGE_DEV_D64_BITS)
-	slotp->bss_d64_uctr++;
-
-    /* the value we want to write is the
-     * original value, with the bits for
-     * our selected changes flipped, and
-     * with any disabled features turned off.
-     */
-    new = old ^ chg;			/* only change what we want to change */
-
-    if (slotp->bss_device == new) {
-	pcibr_unlock(pcibr_soft, s);
-	return 0;
-    }
-    bridge->b_device[slot].reg = new;
-    slotp->bss_device = new;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    pcibr_unlock(pcibr_soft, s);
-#if DEBUG && PCIBR_DEV_DEBUG
-    printk("pcibr Device(%d): 0x%p\n", slot, bridge->b_device[slot].reg);
-#endif
-
-    return 0;
-}
-
-void
-pcibr_release_device(pcibr_soft_t pcibr_soft,
-		     pciio_slot_t slot,
-		     bridgereg_t mask)
-{
-    pcibr_soft_slot_t       slotp;
-    unsigned long           s;
-
-    slotp = &pcibr_soft->bs_slot[slot];
-
-    s = pcibr_lock(pcibr_soft);
-
-    if (mask == BRIDGE_DEV_PMU_BITS)
-	slotp->bss_pmu_uctr--;
-    if (mask == BRIDGE_DEV_D32_BITS)
-	slotp->bss_d32_uctr--;
-    if (mask == BRIDGE_DEV_D64_BITS)
-	slotp->bss_d64_uctr--;
-
-    pcibr_unlock(pcibr_soft, s);
-}
-
-/*
- * flush write gather buffer for slot
- */
-LOCAL void
-pcibr_device_write_gather_flush(pcibr_soft_t pcibr_soft,
-              pciio_slot_t slot)
-{
-    bridge_t               *bridge;
-    unsigned long          s;
-    volatile uint32_t     wrf;
-    s = pcibr_lock(pcibr_soft);
-    bridge = pcibr_soft->bs_base;
-    wrf = bridge->b_wr_req_buf[slot].reg;
-    pcibr_unlock(pcibr_soft, s);
-}
-
-/* =====================================================================
- *    Bridge (pcibr) "Device Driver" entry points
- */
-
-/*
- * pcibr_probe_slot: read a config space word
- * while trapping any errors; reutrn zero if
- * all went OK, or nonzero if there was an error.
- * The value read, if any, is passed back
- * through the valp parameter.
- */
-LOCAL int
-pcibr_probe_slot(bridge_t *bridge,
-		 cfg_p cfg,
-		 unsigned *valp)
-{
-    int                     rv;
-    bridgereg_t             old_enable, new_enable;
-    int badaddr_val(volatile void *, int, volatile void *);
-
-
-    old_enable = bridge->b_int_enable;
-    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-
-    bridge->b_int_enable = new_enable;
-
-	/*
-	 * The xbridge doesn't clear b_err_int_view unless
-	 * multi-err is cleared...
-	 */
-	if (is_xbridge(bridge))
-	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
-		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
-	    }
-
-    if (bridge->b_int_status & BRIDGE_IRR_PCI_GRP) {
-	bridge->b_int_rst_stat = BRIDGE_IRR_PCI_GRP_CLR;
-	(void) bridge->b_wid_tflush;	/* flushbus */
-    }
-    rv = badaddr_val((void *) cfg, 4, valp);
-
-	/*
-	 * The xbridge doesn't set master timeout in b_int_status
-	 * here.  Fortunately it's in error_interrupt_view.
-	 */
-	if (is_xbridge(bridge))
-	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
-		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
-		rv = 1;		/* unoccupied slot */
-	    }
-
-    bridge->b_int_enable = old_enable;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-
-    return rv;
-}
-
-/*
- *    pcibr_init: called once during system startup or
- *      when a loadable driver is loaded.
- *
- *      The driver_register function should normally
- *      be in _reg, not _init.  But the pcibr driver is
- *      required by devinit before the _reg routines
- *      are called, so this is an exception.
- */
-void
-pcibr_init(void)
-{
-#if DEBUG && ATTACH_DEBUG
-    printk("pcibr_init\n");
-#endif
-
-    xwidget_driver_register(XBRIDGE_WIDGET_PART_NUM,
-			    XBRIDGE_WIDGET_MFGR_NUM,
-			    "pcibr_",
-			    0);
-    xwidget_driver_register(BRIDGE_WIDGET_PART_NUM,
-			    BRIDGE_WIDGET_MFGR_NUM,
-			    "pcibr_",
-			    0);
-}
-
-/*
- * open/close mmap/munmap interface would be used by processes
- * that plan to map the PCI bridge, and muck around with the
- * registers. This is dangerous to do, and will be allowed
- * to a select brand of programs. Typically these are
- * diagnostics programs, or some user level commands we may
- * write to do some weird things.
- * To start with expect them to have root priveleges.
- * We will ask for more later.
- */
-/* ARGSUSED */
-int
-pcibr_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-pcibr_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-pcibr_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-    int                     error;
-    devfs_handle_t            vhdl = dev_to_vhdl(dev);
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get(vhdl);
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    ASSERT(pcibr_soft);
-    len = ctob(btoc(len));		/* Make len page aligned */
-    error = v_mapphys(vt, (void *) ((__psunsigned_t) bridge + off), len);
-
-    /*
-     * If the offset being mapped corresponds to the flash prom
-     * base, and if the mapping succeeds, and if the user
-     * has requested the protections to be WRITE, enable the
-     * flash prom to be written.
-     *
-     * XXX- deprecate this in favor of using the
-     * real flash driver ...
-     */
-    if (!error &&
-	((off == BRIDGE_EXTERNAL_FLASH) ||
-	 (len > BRIDGE_EXTERNAL_FLASH))) {
-	int                     s;
-
-	/*
-	 * ensure that we write and read without any interruption.
-	 * The read following the write is required for the Bridge war
-	 */
-	s = splhi();
-	bridge->b_wid_control |= BRIDGE_CTRL_FLASH_WR_EN;
-	bridge->b_wid_control;		/* inval addr bug war */
-	splx(s);
-    }
-    return error;
-}
-
-/*ARGSUSED */
-int
-pcibr_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t) dev);
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    /*
-     * If flashprom write was enabled, disable it, as
-     * this is the last unmap.
-     */
-    if (bridge->b_wid_control & BRIDGE_CTRL_FLASH_WR_EN) {
-	int                     s;
-
-	/*
-	 * ensure that we write and read without any interruption.
-	 * The read following the write is required for the Bridge war
-	 */
-	s = splhi();
-	bridge->b_wid_control &= ~BRIDGE_CTRL_FLASH_WR_EN;
-	bridge->b_wid_control;		/* inval addr bug war */
-	splx(s);
-    }
-    return 0;
-}
-
-/* This is special case code used by grio. There are plans to make
- * this a bit more general in the future, but till then this should
- * be sufficient.
- */
-pciio_slot_t
-pcibr_device_slot_get(devfs_handle_t dev_vhdl)
-{
-    char                    devname[MAXDEVNAME];
-    devfs_handle_t            tdev;
-    pciio_info_t            pciio_info;
-    pciio_slot_t            slot = PCIIO_SLOT_NONE;
-
-    vertex_to_name(dev_vhdl, devname, MAXDEVNAME);
-
-    /* run back along the canonical path
-     * until we find a PCI connection point.
-     */
-    tdev = hwgraph_connectpt_get(dev_vhdl);
-    while (tdev != GRAPH_VERTEX_NONE) {
-	pciio_info = pciio_info_chk(tdev);
-	if (pciio_info) {
-	    slot = pciio_info_slot_get(pciio_info);
-	    break;
-	}
-	hwgraph_vertex_unref(tdev);
-	tdev = hwgraph_connectpt_get(tdev);
-    }
-    hwgraph_vertex_unref(tdev);
-
-    return slot;
-}
-
-/*==========================================================================
- *	BRIDGE PCI SLOT RELATED IOCTLs
- */
-char *pci_space_name[] = {"NONE", 
-			  "ROM",
-			  "IO",
-			  "",
-			  "MEM",
-			  "MEM32",
-			  "MEM64",
-			  "CFG",
-			  "WIN0",
-			  "WIN1",
-			  "WIN2",
-			  "WIN3",
-			  "WIN4",
-			  "WIN5",
-			  "",
-			  "BAD"};
-
-
-/*ARGSUSED */
-int
-pcibr_ioctl(devfs_handle_t dev,
-	    int cmd,
-	    void *arg,
-	    int flag,
-	    struct cred *cr,
-	    int *rvalp)
-{
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t)dev);
-#ifdef LATER
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-#endif
-    int                     error = 0;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    switch (cmd) {
-#ifdef LATER
-    case GIOCSETBW:
-	{
-	    grio_ioctl_info_t       info;
-	    pciio_slot_t            slot = 0;
-
-	    if (!cap_able((uint64_t)CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
-		error = EFAULT;
-		break;
-	    }
-#ifdef GRIO_DEBUG
-	    printk("pcibr:: prev_vhdl: %d reqbw: %lld\n",
-		    info.prev_vhdl, info.reqbw);
-#endif				/* GRIO_DEBUG */
-
-	    if ((slot = pcibr_device_slot_get(info.prev_vhdl)) ==
-		PCIIO_SLOT_NONE) {
-		error = EIO;
-		break;
-	    }
-	    if (info.reqbw)
-		pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_HIGH);
-	    break;
-	}
-
-    case GIOCRELEASEBW:
-	{
-	    grio_ioctl_info_t       info;
-	    pciio_slot_t            slot = 0;
-
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
-		error = EFAULT;
-		break;
-	    }
-#ifdef GRIO_DEBUG
-	    printk("pcibr:: prev_vhdl: %d reqbw: %lld\n",
-		    info.prev_vhdl, info.reqbw);
-#endif				/* GRIO_DEBUG */
-
-	    if ((slot = pcibr_device_slot_get(info.prev_vhdl)) ==
-		PCIIO_SLOT_NONE) {
-		error = EIO;
-		break;
-	    }
-	    if (info.reqbw)
-		pcibr_priority_bits_set(pcibr_soft, slot, PCI_PRIO_LOW);
-	    break;
-	}
-
-    case PCIBR_SLOT_POWERUP:
-	{
-	    pciio_slot_t	slot;
-
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-
-	    slot = (pciio_slot_t)(uint64_t)arg;
-	    error = pcibr_slot_powerup(pcibr_vhdl,slot);
-	    break;
-	}
-    case PCIBR_SLOT_SHUTDOWN:
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-
-	    slot = (pciio_slot_t)(uint64_t)arg;
-	    error = pcibr_slot_powerup(pcibr_vhdl,slot);
-	    break;
-	}
-    case PCIBR_SLOT_QUERY:
-	{
-	    struct pcibr_slot_info_req_s        req;
-
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-
-            if (COPYIN(arg, &req, sizeof(req))) {
-                error = EFAULT;
-                break;
-            }
-
-            error = pcibr_slot_query(pcibr_vhdl, &req);
-	    break;
-	}
-#endif	/* LATER */
-    default:
-	break;
-
-    }
-
-    return error;
-}
-
-void
-pcibr_freeblock_sub(iopaddr_t *free_basep,
-		    iopaddr_t *free_lastp,
-		    iopaddr_t base,
-		    size_t size)
-{
-    iopaddr_t               free_base = *free_basep;
-    iopaddr_t               free_last = *free_lastp;
-    iopaddr_t               last = base + size - 1;
-
-    if ((last < free_base) || (base > free_last));	/* free block outside arena */
-
-    else if ((base <= free_base) && (last >= free_last))
-	/* free block contains entire arena */
-	*free_basep = *free_lastp = 0;
-
-    else if (base <= free_base)
-	/* free block is head of arena */
-	*free_basep = last + 1;
-
-    else if (last >= free_last)
-	/* free block is tail of arena */
-	*free_lastp = base - 1;
-
-    /*
-     * We are left with two regions: the free area
-     * in the arena "below" the block, and the free
-     * area in the arena "above" the block. Keep
-     * the one that is bigger.
-     */
-
-    else if ((base - free_base) > (free_last - last))
-	*free_lastp = base - 1;		/* keep lower chunk */
-    else
-	*free_basep = last + 1;		/* keep upper chunk */
-}
-
-/* Convert from ssram_bits in control register to number of SSRAM entries */
-#define ATE_NUM_ENTRIES(n) _ate_info[n]
-
-/* Possible choices for number of ATE entries in Bridge's SSRAM */
-LOCAL int               _ate_info[] =
-{
-    0,					/* 0 entries */
-    8 * 1024,				/* 8K entries */
-    16 * 1024,				/* 16K entries */
-    64 * 1024				/* 64K entries */
-};
-
-#define ATE_NUM_SIZES (sizeof(_ate_info) / sizeof(int))
-#define ATE_PROBE_VALUE 0x0123456789abcdefULL
-
-/*
- * Determine the size of this bridge's external mapping SSRAM, and set
- * the control register appropriately to reflect this size, and initialize
- * the external SSRAM.
- */
-LOCAL int
-pcibr_init_ext_ate_ram(bridge_t *bridge)
-{
-    int                     largest_working_size = 0;
-    int                     num_entries, entry;
-    int                     i, j;
-    bridgereg_t             old_enable, new_enable;
-    int                     s;
-
-    /* Probe SSRAM to determine its size. */
-    old_enable = bridge->b_int_enable;
-    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-    bridge->b_int_enable = new_enable;
-
-    for (i = 1; i < ATE_NUM_SIZES; i++) {
-	/* Try writing a value */
-	bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
-
-	/* Guard against wrap */
-	for (j = 1; j < i; j++)
-	    bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0;
-
-	/* See if value was written */
-	if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
-	    largest_working_size = i;
-    }
-    bridge->b_int_enable = old_enable;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-
-    /*
-     * ensure that we write and read without any interruption.
-     * The read following the write is required for the Bridge war
-     */
-
-    s = splhi();
-    bridge->b_wid_control = (bridge->b_wid_control
-	& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
-	| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
-    bridge->b_wid_control;		/* inval addr bug war */
-    splx(s);
-
-    num_entries = ATE_NUM_ENTRIES(largest_working_size);
-
-#if PCIBR_ATE_DEBUG
-    if (num_entries)
-	printk("bridge at 0x%x: clearing %d external ATEs\n", bridge, num_entries);
-    else
-	printk("bridge at 0x%x: no externa9422l ATE RAM found\n", bridge);
-#endif
-
-    /* Initialize external mapping entries */
-    for (entry = 0; entry < num_entries; entry++)
-	bridge->b_ext_ate_ram[entry] = 0;
-
-    return (num_entries);
-}
-
-/*
- * Allocate "count" contiguous Bridge Address Translation Entries
- * on the specified bridge to be used for PCI to XTALK mappings.
- * Indices in rm map range from 1..num_entries.  Indicies returned
- * to caller range from 0..num_entries-1.
- *
- * Return the start index on success, -1 on failure.
- */
-LOCAL int
-pcibr_ate_alloc(pcibr_soft_t pcibr_soft, int count)
-{
-    int                     index = 0;
-
-    index = (int) rmalloc(pcibr_soft->bs_int_ate_map, (size_t) count);
-/* printk("Colin: pcibr_ate_alloc - index %d count %d \n", index, count); */
-
-    if (!index && pcibr_soft->bs_ext_ate_map)
-	index = (int) rmalloc(pcibr_soft->bs_ext_ate_map, (size_t) count);
-
-    /* rmalloc manages resources in the 1..n
-     * range, with 0 being failure.
-     * pcibr_ate_alloc manages resources
-     * in the 0..n-1 range, with -1 being failure.
-     */
-    return index - 1;
-}
-
-LOCAL void
-pcibr_ate_free(pcibr_soft_t pcibr_soft, int index, int count)
-/* Who says there's no such thing as a free meal? :-) */
-{
-    /* note the "+1" since rmalloc handles 1..n but
-     * we start counting ATEs at zero.
-     */
-/* printk("Colin: pcibr_ate_free - index %d count %d\n", index, count); */
-
-    rmfree((index < pcibr_soft->bs_int_ate_size)
-	   ? pcibr_soft->bs_int_ate_map
-	   : pcibr_soft->bs_ext_ate_map,
-	   count, index + 1);
-}
-
-LOCAL pcibr_info_t
-pcibr_info_get(devfs_handle_t vhdl)
-{
-    return (pcibr_info_t) pciio_info_get(vhdl);
-}
-
-pcibr_info_t
-pcibr_device_info_new(
-			 pcibr_soft_t pcibr_soft,
-			 pciio_slot_t slot,
-			 pciio_function_t rfunc,
-			 pciio_vendor_id_t vendor,
-			 pciio_device_id_t device)
-{
-    pcibr_info_t            pcibr_info;
-    pciio_function_t        func;
-    int                     ibit;
-
-    func = (rfunc == PCIIO_FUNC_NONE) ? 0 : rfunc;
-
-    NEW(pcibr_info);
-    pciio_device_info_new(&pcibr_info->f_c,
-			  pcibr_soft->bs_vhdl,
-			  slot, rfunc,
-			  vendor, device);
-
-    if (slot != PCIIO_SLOT_NONE) {
-
-	/*
-	 * Currently favored mapping from PCI
-	 * slot number and INTA/B/C/D to Bridge
-	 * PCI Interrupt Bit Number:
-	 *
-	 *     SLOT     A B C D
-	 *      0       0 4 0 4
-	 *      1       1 5 1 5
-	 *      2       2 6 2 6
-	 *      3       3 7 3 7
-	 *      4       4 0 4 0
-	 *      5       5 1 5 1
-	 *      6       6 2 6 2
-	 *      7       7 3 7 3
-	 *
-	 * XXX- allow pcibr_hints to override default
-	 * XXX- allow ADMIN to override pcibr_hints
-	 */
-	for (ibit = 0; ibit < 4; ++ibit)
-	    pcibr_info->f_ibit[ibit] =
-		(slot + 4 * ibit) & 7;
-
-	/*
-	 * Record the info in the sparse func info space.
-	 */
-	if (func < pcibr_soft->bs_slot[slot].bss_ninfo)
-	    pcibr_soft->bs_slot[slot].bss_infos[func] = pcibr_info;
-    }
-    return pcibr_info;
-}
-
-void
-pcibr_device_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot)
-{
-    pcibr_soft_t	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    pcibr_info_t	pcibr_info;
-    pciio_function_t	func;
-    pcibr_soft_slot_t	slotp = &pcibr_soft->bs_slot[slot];
-    int			nfunc = slotp->bss_ninfo;
-
-
-    for (func = 0; func < nfunc; func++) {
-	pcibr_info = slotp->bss_infos[func];
-
-	if (!pcibr_info) 
-	    continue;
-
-	slotp->bss_infos[func] = 0;
-	pciio_device_info_unregister(pcibr_vhdl, &pcibr_info->f_c);
-	pciio_device_info_free(&pcibr_info->f_c);
-	DEL(pcibr_info);
-    }
-
-    /* Clear the DEVIO(x) for this slot */
-    slotp->bss_devio.bssd_space = PCIIO_SPACE_NONE;
-    slotp->bss_devio.bssd_base = PCIBR_D32_BASE_UNSET;
-    slotp->bss_device  = 0;
-
-    
-    /* Reset the mapping usage counters */
-    slotp->bss_pmu_uctr = 0;
-    slotp->bss_d32_uctr = 0;
-    slotp->bss_d64_uctr = 0;
-
-    /* Clear the Direct translation info */
-    slotp->bss_d64_base = PCIBR_D64_BASE_UNSET;
-    slotp->bss_d64_flags = 0;
-    slotp->bss_d32_base = PCIBR_D32_BASE_UNSET;
-    slotp->bss_d32_flags = 0;
-
-    /* Clear out shadow info necessary for the external SSRAM workaround */
-    slotp->bss_ext_ates_active = ATOMIC_INIT(0);
-    slotp->bss_cmd_pointer = 0;
-    slotp->bss_cmd_shadow = 0;
-
-}
-
-/* 
- * PCI_ADDR_SPACE_LIMITS_LOAD
- *	Gets the current values of 
- *		pci io base, 
- *		pci io last,
- *		pci low memory base,
- *		pci low memory last,
- *		pci high memory base,
- * 		pci high memory last
- */
-#define PCI_ADDR_SPACE_LIMITS_LOAD()			\
-    pci_io_fb = pcibr_soft->bs_spinfo.pci_io_base;	\
-    pci_io_fl = pcibr_soft->bs_spinfo.pci_io_last;	\
-    pci_lo_fb = pcibr_soft->bs_spinfo.pci_swin_base;	\
-    pci_lo_fl = pcibr_soft->bs_spinfo.pci_swin_last;	\
-    pci_hi_fb = pcibr_soft->bs_spinfo.pci_mem_base;	\
-    pci_hi_fl = pcibr_soft->bs_spinfo.pci_mem_last;
-/*
- * PCI_ADDR_SPACE_LIMITS_STORE
- *	Sets the current values of
- *		pci io base, 
- *		pci io last,
- *		pci low memory base,
- *		pci low memory last,
- *		pci high memory base,
- * 		pci high memory last
- */
-#define PCI_ADDR_SPACE_LIMITS_STORE()			\
-    pcibr_soft->bs_spinfo.pci_io_base = pci_io_fb;	\
-    pcibr_soft->bs_spinfo.pci_io_last = pci_io_fl;	\
-    pcibr_soft->bs_spinfo.pci_swin_base = pci_lo_fb;	\
-    pcibr_soft->bs_spinfo.pci_swin_last = pci_lo_fl;	\
-    pcibr_soft->bs_spinfo.pci_mem_base = pci_hi_fb;	\
-    pcibr_soft->bs_spinfo.pci_mem_last = pci_hi_fl;
-
-#define PCI_ADDR_SPACE_LIMITS_PRINT()			\
-    printf("+++++++++++++++++++++++\n"			\
-	   "IO base 0x%x last 0x%x\n"			\
-	   "SWIN base 0x%x last 0x%x\n"			\
-	   "MEM base 0x%x last 0x%x\n"			\
-	   "+++++++++++++++++++++++\n",			\
-	   pcibr_soft->bs_spinfo.pci_io_base,		\
-	   pcibr_soft->bs_spinfo.pci_io_last,		\
-	   pcibr_soft->bs_spinfo.pci_swin_base,		\
-	   pcibr_soft->bs_spinfo.pci_swin_last,		\
-	   pcibr_soft->bs_spinfo.pci_mem_base,		\
-	   pcibr_soft->bs_spinfo.pci_mem_last);
-
-/*
- * pcibr_slot_info_init
- *	Probe for this slot and see if it is populated.
- *	If it is populated initialize the generic PCI infrastructural
- * 	information associated with this particular PCI device.
- */
-int
-pcibr_slot_info_init(devfs_handle_t 	pcibr_vhdl,
-		     pciio_slot_t 	slot)
-{
-    pcibr_soft_t	    pcibr_soft;
-    pcibr_info_h	    pcibr_infoh;
-    pcibr_info_t	    pcibr_info;
-    bridge_t		   *bridge;
-    cfg_p                   cfgw;
-    unsigned                idword;
-    unsigned                pfail;
-    unsigned                idwords[8];
-    pciio_vendor_id_t       vendor;
-    pciio_device_id_t       device;
-    unsigned                htype;
-    cfg_p                   wptr;
-    int                     win;
-    pciio_space_t           space;
-    iopaddr_t		    pci_io_fb,	pci_io_fl;
-    iopaddr_t		    pci_lo_fb,  pci_lo_fl;
-    iopaddr_t		    pci_hi_fb,  pci_hi_fl;
-    int			    nfunc;
-    pciio_function_t	    rfunc;
-    int			    func;
-    devfs_handle_t	    conn_vhdl;
-    pcibr_soft_slot_t	    slotp;
-    
-    /* Get the basic software information required to proceed */
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    if (!pcibr_soft)
-	return(EINVAL);
-
-    bridge = pcibr_soft->bs_base;
-    if (!PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    /* If we have a host slot (eg:- IOC3 has 2 PCI slots and the initialization
-     * is done by the host slot then we are done.
-     */
-    if (pcibr_soft->bs_slot[slot].has_host) {
-	return(0);    
-    }
-
-    /* Check for a slot with any system critical functions */
-    if (pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
-        return(EPERM);
-
-    /* Load the current values of allocated PCI address spaces */
-    PCI_ADDR_SPACE_LIMITS_LOAD();
-    
-    /* Try to read the device-id/vendor-id from the config space */
-    cfgw = bridge->b_type0_cfg_dev[slot].l;
-
-    if (pcibr_probe_slot(bridge, cfgw, &idword)) 
-	return(ENODEV);
-
-    slotp = &pcibr_soft->bs_slot[slot];
-    slotp->slot_status |= SLOT_POWER_UP;
-
-    vendor = 0xFFFF & idword;
-    /* If the vendor id is not valid then the slot is not populated
-     * and we are done.
-     */
-    if (vendor == 0xFFFF) 
-	return(ENODEV);			
-    
-    device = 0xFFFF & (idword >> 16);
-    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
-
-    nfunc = 1;
-    rfunc = PCIIO_FUNC_NONE;
-    pfail = 0;
-
-    /* NOTE: if a card claims to be multifunction
-     * but only responds to config space 0, treat
-     * it as a unifunction card.
-     */
-
-    if (htype & 0x80) {		/* MULTIFUNCTION */
-	for (func = 1; func < 8; ++func) {
-	    cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
-	    if (pcibr_probe_slot(bridge, cfgw, &idwords[func])) {
-		pfail |= 1 << func;
-		continue;
-	    }
-	    vendor = 0xFFFF & idwords[func];
-	    if (vendor == 0xFFFF) {
-		pfail |= 1 << func;
-		continue;
-	    }
-	    nfunc = func + 1;
-	    rfunc = 0;
-	}
-	cfgw = bridge->b_type0_cfg_dev[slot].l;
-    }
-    NEWA(pcibr_infoh, nfunc);
-    
-    pcibr_soft->bs_slot[slot].bss_ninfo = nfunc;
-    pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh;
-
-    for (func = 0; func < nfunc; ++func) {
-	unsigned                cmd_reg;
-	
-	if (func) {
-	    if (pfail & (1 << func))
-		continue;
-	    
-	    idword = idwords[func];
-	    cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
-	    
-	    device = 0xFFFF & (idword >> 16);
-	    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
-	    rfunc = func;
-	}
-	htype &= 0x7f;
-	if (htype != 0x00) {
-	    printk(KERN_WARNING  "%s pcibr: pci slot %d func %d has strange header type 0x%x\n",
-		    pcibr_soft->bs_name, slot, func, htype);
-	    continue;
-	}
-#if DEBUG && ATTACH_DEBUG
-	printk(KERN_NOTICE   
-		"%s pcibr: pci slot %d func %d: vendor 0x%x device 0x%x",
-		pcibr_soft->bs_name, slot, func, vendor, device);
-#endif	
-
-	pcibr_info = pcibr_device_info_new
-	    (pcibr_soft, slot, rfunc, vendor, device);
-	conn_vhdl = pciio_device_info_register(pcibr_vhdl, &pcibr_info->f_c);
-	if (func == 0)
-	    slotp->slot_conn = conn_vhdl;
-
-#ifdef LITTLE_ENDIAN
-	cmd_reg = cfgw[(PCI_CFG_COMMAND ^ 4) / 4];
-#else
-	cmd_reg = cfgw[PCI_CFG_COMMAND / 4];
-#endif
-	
-	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
-
-	for (win = 0; win < PCI_CFG_BASE_ADDRS; ++win) {
-	    iopaddr_t               base, mask, code;
-	    size_t                  size;
-
-	    /*
-	     * GET THE BASE & SIZE OF THIS WINDOW:
-	     *
-	     * The low two or four bits of the BASE register
-	     * determines which address space we are in; the
-	     * rest is a base address. BASE registers
-	     * determine windows that are power-of-two sized
-	     * and naturally aligned, so we can get the size
-	     * of a window by writing all-ones to the
-	     * register, reading it back, and seeing which
-	     * bits are used for decode; the least
-	     * significant nonzero bit is also the size of
-	     * the window.
-	     *
-	     * WARNING: someone may already have allocated
-	     * some PCI space to this window, and in fact
-	     * PIO may be in process at this very moment
-	     * from another processor (or even from this
-	     * one, if we get interrupted)! So, if the BASE
-	     * already has a nonzero address, be generous
-	     * and use the LSBit of that address as the
-	     * size; this could overstate the window size.
-	     * Usually, when one card is set up, all are set
-	     * up; so, since we don't bitch about
-	     * overlapping windows, we are ok.
-	     *
-	     * UNFORTUNATELY, some cards do not clear their
-	     * BASE registers on reset. I have two heuristics
-	     * that can detect such cards: first, if the
-	     * decode enable is turned off for the space
-	     * that the window uses, we can disregard the
-	     * initial value. second, if the address is
-	     * outside the range that we use, we can disregard
-	     * it as well.
-	     *
-	     * This is looking very PCI generic. Except for
-	     * knowing how many slots and where their config
-	     * spaces are, this window loop and the next one
-	     * could probably be shared with other PCI host
-	     * adapters. It would be interesting to see if
-	     * this could be pushed up into pciio, when we
-	     * start supporting more PCI providers.
-	     */
-#ifdef LITTLE_ENDIAN
-	    base = wptr[((win*4)^4)/4];
-#else
-	    base = wptr[win];
-#endif
-
-	    if (base & PCI_BA_IO_SPACE) {
-		/* BASE is in I/O space. */
-		space = PCIIO_SPACE_IO;
-		mask = -4;
-		code = base & 3;
-		base = base & mask;
-		if (base == 0) {
-		    ;		/* not assigned */
-		} else if (!(cmd_reg & PCI_CMD_IO_SPACE)) {
-		    base = 0;	/* decode not enabled */
-		}
-	    } else {
-		/* BASE is in MEM space. */
-		space = PCIIO_SPACE_MEM;
-		mask = -16;
-		code = base & PCI_BA_MEM_LOCATION;	/* extract BAR type */
-		base = base & mask;
-		if (base == 0) {
-		    ;		/* not assigned */
-		} else if (!(cmd_reg & PCI_CMD_MEM_SPACE)) {
-		    base = 0;	/* decode not enabled */
-		} else if (base & 0xC0000000) {
-		    base = 0;	/* outside permissable range */
-		} else if ((code == PCI_BA_MEM_64BIT) &&
-#ifdef LITTLE_ENDIAN
-			   (wptr[(((win + 1)*4)^4)/4] != 0)) {
-#else 
-			   (wptr[win + 1] != 0)) {
-#endif /* LITTLE_ENDIAN */
-		    base = 0;	/* outside permissable range */
-		}
-	    }
-
-	    if (base != 0) {	/* estimate size */
-		size = base & -base;
-	    } else {		/* calculate size */
-#ifdef LITTLE_ENDIAN
-		wptr[((win*4)^4)/4] = ~0;	/* turn on all bits */
-		size = wptr[((win*4)^4)/4];	/* get stored bits */
-#else 
-		wptr[win] = ~0;	/* turn on all bits */
-		size = wptr[win];	/* get stored bits */
-#endif /* LITTLE_ENDIAN */
-		size &= mask;	/* keep addr */
-		size &= -size;	/* keep lsbit */
-		if (size == 0)
-		    continue;
-	    }	
-
-	    pcibr_info->f_window[win].w_space = space;
-	    pcibr_info->f_window[win].w_base = base;
-	    pcibr_info->f_window[win].w_size = size;
-
-	    /*
-	     * If this window already has PCI space
-	     * allocated for it, "subtract" that space from
-	     * our running freeblocks. Don't worry about
-	     * overlaps in existing allocated windows; we
-	     * may be overstating their sizes anyway.
-	     */
-
-	    if (base && size) {
-		if (space == PCIIO_SPACE_IO) {
-		    pcibr_freeblock_sub(&pci_io_fb,
-					&pci_io_fl,
-					base, size);
-		} else {
-		    pcibr_freeblock_sub(&pci_lo_fb,
-					&pci_lo_fl,
-					base, size);
-		    pcibr_freeblock_sub(&pci_hi_fb,
-					&pci_hi_fl,
-					base, size);
-		}	
-	    }
-#if defined(IOC3_VENDOR_ID_NUM) && defined(IOC3_DEVICE_ID_NUM)
-	    /*
-	     * IOC3 BASE_ADDR* BUG WORKAROUND
-	     *
-	     
-	     * If we write to BASE1 on the IOC3, the
-	     * data in BASE0 is replaced. The
-	     * original workaround was to remember
-	     * the value of BASE0 and restore it
-	     * when we ran off the end of the BASE
-	     * registers; however, a later
-	     * workaround was added (I think it was
-	     * rev 1.44) to avoid setting up
-	     * anything but BASE0, with the comment
-	     * that writing all ones to BASE1 set
-	     * the enable-parity-error test feature
-	     * in IOC3's SCR bit 14.
-	     *
-	     * So, unless we defer doing any PCI
-	     * space allocation until drivers
-	     * attach, and set up a way for drivers
-	     * (the IOC3 in paricular) to tell us
-	     * generically to keep our hands off
-	     * BASE registers, we gotta "know" about
-	     * the IOC3 here.
-	     *
-	     * Too bad the PCI folks didn't reserve the
-	     * all-zero value for 'no BASE here' (it is a
-	     * valid code for an uninitialized BASE in
-	     * 32-bit PCI memory space).
-	     */
-	    
-	    if ((vendor == IOC3_VENDOR_ID_NUM) &&
-		(device == IOC3_DEVICE_ID_NUM))
-		break;
-#endif
-	    if (code == PCI_BA_MEM_64BIT) {
-		win++;		/* skip upper half */
-#ifdef LITTLE_ENDIAN
-		wptr[((win*4)^4)/4] = 0;	/* which must be zero */
-#else 
-		wptr[win] = 0;	/* which must be zero */
-#endif /* LITTLE_ENDIAN */
-	    }
-	}				/* next win */
-    }				/* next func */
-
-    /* Store back the values for allocated PCI address spaces */
-    PCI_ADDR_SPACE_LIMITS_STORE();
-    return(0);
-}					
-
-/*
- * pcibr_slot_info_free
- *	Remove all the PCI infrastructural information associated
- * 	with a particular PCI device.
- */
-int
-pcibr_slot_info_free(devfs_handle_t pcibr_vhdl,
-                     pciio_slot_t slot)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    int			nfunc;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-
-    pcibr_device_info_free(pcibr_vhdl, slot);
-
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-    DELA(pcibr_infoh,nfunc);
-    pcibr_soft->bs_slot[slot].bss_ninfo = 0;
-
-    return(0);
-}
-
-int as_debug = 0;
-/*
- * pcibr_slot_addr_space_init
- *	Reserve chunks of PCI address space as required by 
- * 	the base registers in the card.
- */
-int
-pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl,
-			   pciio_slot_t	slot)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    bridge_t		*bridge;
-    iopaddr_t		pci_io_fb, pci_io_fl;
-    iopaddr_t		pci_lo_fb, pci_lo_fl;
-    iopaddr_t		pci_hi_fb, pci_hi_fl;
-    size_t              align;
-    iopaddr_t           mask;
-    int		    	nbars;
-    int		       	nfunc;
-    int			func;
-    int			win;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    bridge = pcibr_soft->bs_base;
-
-    /* Get the current values for the allocated PCI address spaces */
-    PCI_ADDR_SPACE_LIMITS_LOAD();
-
-    if (as_debug)
-#ifdef LATER
-    PCI_ADDR_SPACE_LIMITS_PRINT();
-#endif
-    /* allocate address space,
-     * for windows that have not been
-     * previously assigned.
-     */
-    if (pcibr_soft->bs_slot[slot].has_host) {
-	return(0);
-    }
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    if (nfunc < 1)
-	return(EINVAL);
-
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-    if (!pcibr_infoh)
-	return(EINVAL);
-
-    /*
-     * Try to make the DevIO windows not
-     * overlap by pushing the "io" and "hi"
-     * allocation areas up to the next one
-     * or two megabyte bound. This also
-     * keeps them from being zero.
-     *
-     * DO NOT do this with "pci_lo" since
-     * the entire "lo" area is only a
-     * megabyte, total ...
-     */
-    align = (slot < 2) ? 0x200000 : 0x100000;
-    mask = -align;
-    pci_io_fb = (pci_io_fb + align - 1) & mask;
-    pci_hi_fb = (pci_hi_fb + align - 1) & mask;
-
-    for (func = 0; func < nfunc; ++func) {
-	cfg_p                   cfgw;
-	cfg_p                   wptr;
-	pciio_space_t           space;
-	iopaddr_t               base;
-	size_t                  size;
-	cfg_p                   pci_cfg_cmd_reg_p;
-	unsigned                pci_cfg_cmd_reg;
-	unsigned                pci_cfg_cmd_reg_add = 0;
-
-	pcibr_info = pcibr_infoh[func];
-
-	if (!pcibr_info)
-	    continue;
-
-	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-	    continue;
-	
-	cfgw = bridge->b_type0_cfg_dev[slot].f[func].l;
-	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
-
-	nbars = PCI_CFG_BASE_ADDRS;
-
-	for (win = 0; win < nbars; ++win) {
-
-	    space = pcibr_info->f_window[win].w_space;
-	    base = pcibr_info->f_window[win].w_base;
-	    size = pcibr_info->f_window[win].w_size;
-	    
-	    if (size < 1)
-		continue;
-
-	    if (base >= size) {
-#if DEBUG && PCI_DEBUG
-		printk("pcibr: slot %d func %d window %d is in %d[0x%x..0x%x], alloc by prom\n",
-			slot, func, win, space, base, base + size - 1);
-#endif
-		continue;		/* already allocated */
-	    }
-	    align = size;		/* ie. 0x00001000 */
-	    if (align < _PAGESZ)
-		align = _PAGESZ;	/* ie. 0x00004000 */
-	    mask = -align;		/* ie. 0xFFFFC000 */
-
-	    switch (space) {
-	    case PCIIO_SPACE_IO:
-		base = (pci_io_fb + align - 1) & mask;
-		if ((base + size) > pci_io_fl) {
-		    base = 0;
-		    break;
-		}
-		pci_io_fb = base + size;
-		break;
-		
-	    case PCIIO_SPACE_MEM:
-#ifdef LITTLE_ENDIAN
-		if ((wptr[((win*4)^4)/4] & PCI_BA_MEM_LOCATION) ==
-#else
-		if ((wptr[win] & PCI_BA_MEM_LOCATION) ==
-#endif  /* LITTLE_ENDIAN */
-		    PCI_BA_MEM_1MEG) {
-		    /* allocate from 20-bit PCI space */
-		    base = (pci_lo_fb + align - 1) & mask;
-		    if ((base + size) > pci_lo_fl) {
-			base = 0;
-			break;
-		    }
-		    pci_lo_fb = base + size;
-		} else {
-		    /* allocate from 32-bit or 64-bit PCI space */
-		    base = (pci_hi_fb + align - 1) & mask;
-		    if ((base + size) > pci_hi_fl) {
-			base = 0;
-			break;
-		    }
-		    pci_hi_fb = base + size;
-		}
-		break;
-		
-	    default:
-		base = 0;
-#if DEBUG && PCI_DEBUG
-		printk("pcibr: slot %d window %d had bad space code %d\n",
-			slot, win, space);
-#endif
-	    }
-	    pcibr_info->f_window[win].w_base = base;
-#ifdef LITTLE_ENDIAN
-	    wptr[((win*4)^4)/4] = base;
-#if DEBUG && PCI_DEBUG
-		printk("Setting base address 0x%p base 0x%x\n", &(wptr[((win*4)^4)/4]), base);
-#endif
-#else
-	    wptr[win] = base;
-#endif  /* LITTLE_ENDIAN */
-
-#if DEBUG && PCI_DEBUG
-	    if (base >= size)
-		printk("pcibr: slot %d func %d window %d is in %d [0x%x..0x%x], alloc by pcibr\n",
-			slot, func, win, space, base, base + size - 1);
-	    else
-		printk("pcibr: slot %d func %d window %d, unable to alloc 0x%x in 0x%p\n",
-			slot, func, win, size, space);
-#endif
-	}				/* next base */
-
-	/*
-	 * Allocate space for the EXPANSION ROM
-	 * NOTE: DO NOT DO THIS ON AN IOC3,
-	 * as it blows the system away.
-	 */
-	base = size = 0;
-	if ((pcibr_soft->bs_slot[slot].bss_vendor_id != IOC3_VENDOR_ID_NUM) ||
-	    (pcibr_soft->bs_slot[slot].bss_device_id != IOC3_DEVICE_ID_NUM)) {
-
-	    wptr = cfgw + PCI_EXPANSION_ROM / 4;
-#ifdef LITTLE_ENDIAN
-	    wptr[1] = 0xFFFFF000;
-	    mask = wptr[1];
-#else
-	    *wptr = 0xFFFFF000;
-	    mask = *wptr;
-#endif  /* LITTLE_ENDIAN */
-	    if (mask & 0xFFFFF000) {
-		size = mask & -mask;
-		align = size;
-		if (align < _PAGESZ)
-		    align = _PAGESZ;
-		mask = -align;
-		base = (pci_hi_fb + align - 1) & mask;
-		if ((base + size) > pci_hi_fl)
-		    base = size = 0;
-		else {
-		    pci_hi_fb = base + size;
-#ifdef LITTLE_ENDIAN
-		    wptr[1] = base;
-#else
-		    *wptr = base;
-#endif  /* LITTLE_ENDIAN */
-#if DEBUG && PCI_DEBUG
-		    printk("%s/%d ROM in 0x%lx..0x%lx (alloc by pcibr)\n",
-			    pcibr_soft->bs_name, slot,
-			    base, base + size - 1);
-#endif
-		}
-	    }
-	}
-	pcibr_info->f_rbase = base;
-	pcibr_info->f_rsize = size;
-	
-	/*
-	 * if necessary, update the board's
-	 * command register to enable decoding
-	 * in the windows we added.
-	 *
-	 * There are some bits we always want to
-	 * be sure are set.
-	 */
-	pci_cfg_cmd_reg_add |= PCI_CMD_IO_SPACE;
-
-	/*
-	 * The Adaptec 1160 FC Controller WAR #767995:
-	 * The part incorrectly ignores the upper 32 bits of a 64 bit
-	 * address when decoding references to its registers so to
-	 * keep it from responding to a bus cycle that it shouldn't
-	 * we only use I/O space to get at it's registers.  Don't
-	 * enable memory space accesses on that PCI device.
-	 */
-	#define FCADP_VENDID 0x9004 /* Adaptec Vendor ID from fcadp.h */
-	#define FCADP_DEVID 0x1160  /* Adaptec 1160 Device ID from fcadp.h */
-
-	if ((pcibr_info->f_vendor != FCADP_VENDID) ||
-	    (pcibr_info->f_device != FCADP_DEVID))
-	    pci_cfg_cmd_reg_add |= PCI_CMD_MEM_SPACE;
-
-	pci_cfg_cmd_reg_add |= PCI_CMD_BUS_MASTER;
-
-	pci_cfg_cmd_reg_p = cfgw + PCI_CFG_COMMAND / 4;
-	pci_cfg_cmd_reg = *pci_cfg_cmd_reg_p;
-#if PCI_FBBE	/* XXX- check here to see if dev can do fast-back-to-back */
-	if (!((pci_cfg_cmd_reg >> 16) & PCI_STAT_F_BK_BK_CAP))
-	    fast_back_to_back_enable = 0;
-#endif
-	pci_cfg_cmd_reg &= 0xFFFF;
-	if (pci_cfg_cmd_reg_add & ~pci_cfg_cmd_reg)
-	    *pci_cfg_cmd_reg_p = pci_cfg_cmd_reg | pci_cfg_cmd_reg_add;
-	
-    }				/* next func */
-
-    /* Now that we have allocated new chunks of PCI address spaces to this
-     * card we need to update the bookkeeping values which indicate
-     * the current PCI address space allocations.
-     */
-    PCI_ADDR_SPACE_LIMITS_STORE();
-    return(0);
-}
-
-/*
- * pcibr_slot_device_init
- * 	Setup the device register in the bridge for this PCI slot.
- */
-int
-pcibr_slot_device_init(devfs_handle_t pcibr_vhdl,
-		       pciio_slot_t slot)
-{
-    pcibr_soft_t	 pcibr_soft;
-    bridge_t		*bridge;
-    bridgereg_t		 devreg;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    bridge = pcibr_soft->bs_base;
-
-    /*
-     * Adjustments to Device(x)
-     * and init of bss_device shadow
-     */
-    devreg = bridge->b_device[slot].reg;
-    devreg &= ~BRIDGE_DEV_PAGE_CHK_DIS;
-    devreg |= BRIDGE_DEV_COH | BRIDGE_DEV_VIRTUAL_EN;
-#ifdef LITTLE_ENDIAN
-    devreg |= BRIDGE_DEV_DEV_SWAP;
-#endif
-    pcibr_soft->bs_slot[slot].bss_device = devreg;
-    bridge->b_device[slot].reg = devreg;
-
-#if DEBUG && PCI_DEBUG
-	printk("pcibr Device(%d): 0x%lx\n", slot, bridge->b_device[slot].reg);
-#endif
-
-#if DEBUG && PCI_DEBUG
-    printk("pcibr: PCI space allocation done.\n");
-#endif
-
-    return(0);
-}
-
-/*
- * pcibr_slot_guest_info_init
- *	Setup the host/guest relations for a PCI slot.
- */
-int
-pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl,
-			   pciio_slot_t	slot)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    pcibr_soft_slot_t	slotp;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    slotp = &pcibr_soft->bs_slot[slot];
-
-    /* create info and verticies for guest slots;
-     * for compatibilitiy macros, create info
-     * for even unpopulated slots (but do not
-     * build verticies for them).
-     */
-    if (pcibr_soft->bs_slot[slot].bss_ninfo < 1) {
-	NEWA(pcibr_infoh, 1);
-	pcibr_soft->bs_slot[slot].bss_ninfo = 1;
-	pcibr_soft->bs_slot[slot].bss_infos = pcibr_infoh;
-
-	pcibr_info = pcibr_device_info_new
-	    (pcibr_soft, slot, PCIIO_FUNC_NONE,
-	     PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE);
-
-	if (pcibr_soft->bs_slot[slot].has_host) {
-	    slotp->slot_conn = pciio_device_info_register
-		(pcibr_vhdl, &pcibr_info->f_c);
-	}
-    }
-
-    /* generate host/guest relations
-     */
-    if (pcibr_soft->bs_slot[slot].has_host) {
-	int  host = pcibr_soft->bs_slot[slot].host_slot;
-	pcibr_soft_slot_t host_slotp = &pcibr_soft->bs_slot[host];
-
-	hwgraph_edge_add(slotp->slot_conn,
-			 host_slotp->slot_conn,
-			 EDGE_LBL_HOST);
-
-	/* XXX- only gives us one guest edge per
-	 * host. If/when we have a host with more than
-	 * one guest, we will need to figure out how
-	 * the host finds all its guests, and sorts
-	 * out which one is which.
-	 */
-	hwgraph_edge_add(host_slotp->slot_conn,
-			 slotp->slot_conn,
-			 EDGE_LBL_GUEST);
-    }
-
-    return(0);
-}
-
-/*
- * pcibr_slot_initial_rrb_alloc
- *	Allocate a default number of rrbs for this slot on 
- * 	the two channels.  This is dictated by the rrb allocation
- * 	strategy routine defined per platform.
- */
-
-int
-pcibr_slot_initial_rrb_alloc(devfs_handle_t pcibr_vhdl,
-			     pciio_slot_t slot)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    bridge_t		*bridge;
-    int                 c0, c1;
-    int			r;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    bridge = pcibr_soft->bs_base;
-
-    /* How may RRBs are on this slot?
-     */
-    c0 = do_pcibr_rrb_count_valid(bridge, slot);
-    c1 = do_pcibr_rrb_count_valid(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL);
-
-#if PCIBR_RRB_DEBUG
-    printk("pcibr_attach: slot %d started with %d+%d\n", slot, c0, c1);
-#endif
-
-    /* Do we really need any?
-     */
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-    pcibr_info = pcibr_infoh[0];
-    if ((pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE) &&
-	!pcibr_soft->bs_slot[slot].has_host) {
-	if (c0 > 0)
-	    do_pcibr_rrb_free(bridge, slot, c0);
-	if (c1 > 0)
-	    do_pcibr_rrb_free(bridge, slot + PCIBR_RRB_SLOT_VIRTUAL, c1);
-	pcibr_soft->bs_rrb_valid[slot] = 0x1000;
-	pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = 0x1000;
-	return(ENODEV);
-    }
-
-    pcibr_soft->bs_rrb_avail[slot & 1] -= c0 + c1;
-    pcibr_soft->bs_rrb_valid[slot] = c0;
-    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = c1;
-
-    pcibr_soft->bs_rrb_avail[0] = do_pcibr_rrb_count_avail(bridge, 0);
-    pcibr_soft->bs_rrb_avail[1] = do_pcibr_rrb_count_avail(bridge, 1);
-
-    r = 3 - (c0 + c1);
-
-    if (r > 0) {
-	pcibr_soft->bs_rrb_res[slot] = r;
-	pcibr_soft->bs_rrb_avail[slot & 1] -= r;
-    }
-
-#if PCIBR_RRB_DEBUG
-    printk("\t%d+%d+%d",
-	    0xFFF & pcibr_soft->bs_rrb_valid[slot],
-	    0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-	    pcibr_soft->bs_rrb_res[slot]);
-    printk("\n");
-#endif
-
-    return(0);
-}
-
-/*
- * pcibr_slot_call_device_attach
- *	This calls the associated driver attach routine for the PCI
- * 	card in this slot.
- */
-int
-pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl,
-			      pciio_slot_t slot,
-			      int          drv_flags)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    async_attach_t	aa = NULL;
-    int			func;
-    devfs_handle_t	xconn_vhdl,conn_vhdl;
-    int			nfunc;
-    int                 error_func;
-    int                 error_slot = 0;
-    int                 error = ENODEV;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-
-    if (pcibr_soft->bs_slot[slot].has_host) {
-        return(EPERM);
-    }
-    
-    xconn_vhdl = pcibr_soft->bs_conn;
-    aa = async_attach_get_info(xconn_vhdl);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-
-    for (func = 0; func < nfunc; ++func) {
-
-	pcibr_info = pcibr_infoh[func];
-	
-	if (!pcibr_info)
-	    continue;
-
-	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-	    continue;
-
-	conn_vhdl = pcibr_info->f_vertex;
-
-#ifdef LATER
-	/*
-	 * Activate if and when we support cdl.
-	 */
-	if (aa)
-	    async_attach_add_info(conn_vhdl, aa);
-#endif	/* LATER */
-
-	error_func = pciio_device_attach(conn_vhdl, drv_flags);
-
-        pcibr_info->f_att_det_error = error_func;
-
-	if (error_func)
-	    error_slot = error_func;
-
-        error = error_slot;
-
-    }				/* next func */
-
-    if (error) {
-	if ((error != ENODEV) && (error != EUNATCH))
-	    pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_INCMPLT;
-    } else {
-        pcibr_soft->bs_slot[slot].slot_status |= SLOT_STARTUP_CMPLT;
-    }
-        
-    return(error);
-}
-
-/*
- * pcibr_slot_call_device_detach
- *	This calls the associated driver detach routine for the PCI
- * 	card in this slot.
- */
-int
-pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl,
-			      pciio_slot_t slot,
-			      int          drv_flags)
-{
-    pcibr_soft_t	pcibr_soft;
-    pcibr_info_h	pcibr_infoh;
-    pcibr_info_t	pcibr_info;
-    int			func;
-    devfs_handle_t	conn_vhdl = GRAPH_VERTEX_NONE;
-    int			nfunc;
-    int                 error_func;
-    int                 error_slot = 0;
-    int                 error = ENODEV;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-	return(EINVAL);
-
-    if (pcibr_soft->bs_slot[slot].has_host)
-        return(EPERM);
-
-    /* Make sure that we do not detach a system critical function vertex */
-    if(pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
-        return(EPERM);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-
-    for (func = 0; func < nfunc; ++func) {
-
-	pcibr_info = pcibr_infoh[func];
-	
-	if (!pcibr_info)
-	    continue;
-
-	if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-	    continue;
-
-	conn_vhdl = pcibr_info->f_vertex;
-
-	error_func = pciio_device_detach(conn_vhdl, drv_flags);
-
-        pcibr_info->f_att_det_error = error_func;
-
-	if (error_func)
-	    error_slot = error_func;
-
-	error = error_slot;
-
-    }				/* next func */
-
-    pcibr_soft->bs_slot[slot].slot_status &= ~SLOT_STATUS_MASK;
-
-    if (error) {
-	if ((error != ENODEV) && (error != EUNATCH))
-            pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_INCMPLT;
-    } else {
-        if (conn_vhdl != GRAPH_VERTEX_NONE) 
-            pcibr_device_unregister(conn_vhdl);
-        pcibr_soft->bs_slot[slot].slot_status |= SLOT_SHUTDOWN_CMPLT;
-    }
-        
-    return(error);
-}
-
-/*
- * pcibr_slot_detach
- *	This is a place holder routine to keep track of all the
- *	slot-specific freeing that needs to be done.
- */
-int
-pcibr_slot_detach(devfs_handle_t pcibr_vhdl,
-		  pciio_slot_t slot,
-		  int          drv_flags)
-{
-    int		  error;
-    
-    /* Call the device detach function */
-    error = (pcibr_slot_call_device_detach(pcibr_vhdl, slot, drv_flags));
-    return (error);
-
-}
-
-/*
- * pcibr_is_slot_sys_critical
- *      Check slot for any functions that are system critical.
- *      Return 1 if any are system critical or 0 otherwise.
- *
- *      This function will always return 0 when called by 
- *      pcibr_attach() because the system critical vertices 
- *      have not yet been set in the hwgraph.
- */
-int
-pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl,
-                      pciio_slot_t slot)
-{
-    pcibr_soft_t        pcibr_soft;
-    pcibr_info_h        pcibr_infoh;
-    pcibr_info_t        pcibr_info;
-    devfs_handle_t        conn_vhdl = GRAPH_VERTEX_NONE;
-    int                 nfunc;
-    int                 func;
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    if (!pcibr_soft || !PCIBR_VALID_SLOT(slot))
-        return(0);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-
-    for (func = 0; func < nfunc; ++func) {
-
-        pcibr_info = pcibr_infoh[func];
-        if (!pcibr_info)
-            continue;
-
-        if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-            continue;
-
-        conn_vhdl = pcibr_info->f_vertex;
-        if (is_sys_critical_vertex(conn_vhdl)) { 
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-            printk(KERN_WARNING  "%v is a system critical device vertex\n", conn_vhdl);
-#else
-            printk(KERN_WARNING  "%p is a system critical device vertex\n", (void *)conn_vhdl);
-#endif
-            return(1); 
-        }
-
-    }
-
-    return(0);
-}
-
-/*
- * pcibr_device_unregister
- *	This frees up any hardware resources reserved for this PCI device
- * 	and removes any PCI infrastructural information setup for it.
- *	This is usually used at the time of shutting down of the PCI card.
- */
-int
-pcibr_device_unregister(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t	 pciio_info;
-    devfs_handle_t	 pcibr_vhdl;
-    pciio_slot_t	 slot;
-    pcibr_soft_t	 pcibr_soft;
-    bridge_t		*bridge;
-    int			 error_call;
-    int			 error = 0;
-
-    pciio_info = pciio_info_get(pconn_vhdl);
-
-    pcibr_vhdl = pciio_info_master_get(pciio_info);
-    slot = pciio_info_slot_get(pciio_info);
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge = pcibr_soft->bs_base;
-
-    /* Clear all the hardware xtalk resources for this device */
-    xtalk_widgetdev_shutdown(pcibr_soft->bs_conn, slot);
-
-    /* Flush all the rrbs */
-    pcibr_rrb_flush(pconn_vhdl);
-
-    /* Free the rrbs allocated to this slot */
-    error_call = do_pcibr_rrb_free(bridge, slot, 
-		                   pcibr_soft->bs_rrb_valid[slot] +
-		                   pcibr_soft->bs_rrb_valid[slot + 
-                                   PCIBR_RRB_SLOT_VIRTUAL]);
-
-    if (error_call)
-        error = ERANGE;
-
-    pcibr_soft->bs_rrb_valid[slot] = 0;
-    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL] = 0;
-    pcibr_soft->bs_rrb_res[slot] = 0;
-
-    /* Flush the write buffers !! */
-    error_call = pcibr_wrb_flush(pconn_vhdl);
-
-    if (error_call)
-        error = error_call;
-
-    /* Clear the information specific to the slot */
-    error_call = pcibr_slot_info_free(pcibr_vhdl, slot);
-
-    if (error_call)
-        error = error_call;
-
-    return(error);
-    
-}
-
-/* 
- * build a convenience link path in the
- * form of ".../<iobrick>/bus/<busnum>"
- * 
- * returns 1 on success, 0 otherwise
- *
- * depends on hwgraph separator == '/'
- */
-int
-pcibr_bus_cnvlink(devfs_handle_t f_c, int slot)
-{
-        char dst[MAXDEVNAME];
-	char *dp = dst;
-        char *cp, *xp;
-        int widgetnum;
-        char pcibus[8];
-	devfs_handle_t nvtx, svtx;
-	int rv;
-
-#if DEBUG
-	printk("pcibr_bus_cnvlink: slot= %d f_c= %p\n", 
-		slot, f_c);
-	{
-		int pos;
-		char dname[256];
-		pos = devfs_generate_path(f_c, dname, 256);
-		printk("%s : path= %s\n", __FUNCTION__, &dname[pos]);
-	}
-#endif
-
-	if (GRAPH_SUCCESS != hwgraph_vertex_name_get(f_c, dst, MAXDEVNAME))
-		return 0;
-
-	/* dst example == /hw/module/001c02/Pbrick/xtalk/8/pci/direct */
-
-	/* find the widget number */
-	xp = strstr(dst, "/"EDGE_LBL_XTALK"/");
-	if (xp == NULL)
-		return 0;
-	widgetnum = atoi(xp+7);
-	if (widgetnum < XBOW_PORT_8 || widgetnum > XBOW_PORT_F)
-		return 0;
-
-	/* remove "/pci/direct" from path */
-	cp = strstr(dst, "/" EDGE_LBL_PCI "/" "direct");
-	if (cp == NULL)
-		return 0;
-	*cp = (char)NULL;
-
-	/* get the vertex for the widget */
-	if (GRAPH_SUCCESS != hwgraph_traverse(NULL, dp, &svtx))	
-		return 0;
-
-	*xp = (char)NULL;		/* remove "/xtalk/..." from path */
-
-	/* dst example now == /hw/module/001c02/Pbrick */
-
-	/* get the bus number */
-        strcat(dst, "/bus");
-        sprintf(pcibus, "%d", p_busnum[widgetnum]);
-
-	/* link to bus to widget */
-	rv = hwgraph_path_add(NULL, dp, &nvtx);
-	if (GRAPH_SUCCESS == rv)
-		rv = hwgraph_edge_add(nvtx, svtx, pcibus);
-
-	return (rv == GRAPH_SUCCESS);
-}
-
-
-/*
- *    pcibr_attach: called every time the crosstalk
- *      infrastructure is asked to initialize a widget
- *      that matches the part number we handed to the
- *      registration routine above.
- */
-/*ARGSUSED */
-int
-pcibr_attach(devfs_handle_t xconn_vhdl)
-{
-    /* REFERENCED */
-    graph_error_t           rc;
-    devfs_handle_t            pcibr_vhdl;
-    devfs_handle_t            ctlr_vhdl;
-    bridge_t               *bridge = NULL;
-    bridgereg_t             id;
-    int                     rev;
-    pcibr_soft_t            pcibr_soft;
-    pcibr_info_t            pcibr_info;
-    xwidget_info_t          info;
-    xtalk_intr_t            xtalk_intr;
-    device_desc_t           dev_desc = (device_desc_t)0;
-    int                     slot;
-    int                     ibit;
-    devfs_handle_t            noslot_conn;
-    char                    devnm[MAXDEVNAME], *s;
-    pcibr_hints_t           pcibr_hints;
-    bridgereg_t             b_int_enable;
-    unsigned                rrb_fixed = 0;
-
-    iopaddr_t               pci_io_fb, pci_io_fl;
-    iopaddr_t               pci_lo_fb, pci_lo_fl;
-    iopaddr_t               pci_hi_fb, pci_hi_fl;
-
-    int                     spl_level;
-#ifdef LATER
-    char		    *nicinfo = (char *)0;
-#endif
-
-#if PCI_FBBE
-    int                     fast_back_to_back_enable;
-#endif
-    l1sc_t		    *scp;
-    nasid_t		    nasid;
-
-    async_attach_t          aa = NULL;
-
-    aa = async_attach_get_info(xconn_vhdl);
-
-#if DEBUG && ATTACH_DEBUG
-    printk("pcibr_attach: xconn_vhdl=  %p\n", xconn_vhdl);
-    {
-	int pos;
-	char dname[256];
-	pos = devfs_generate_path(xconn_vhdl, dname, 256);
-	printk("%s : path= %s \n", __FUNCTION__, &dname[pos]);
-    }
-#endif
-
-    /* Setup the PRB for the bridge in CONVEYOR BELT
-     * mode. PRBs are setup in default FIRE-AND-FORGET
-     * mode during the initialization.
-     */
-    hub_device_flags_set(xconn_vhdl, HUB_PIO_CONVEYOR);
-
-    bridge = (bridge_t *)
-	xtalk_piotrans_addr(xconn_vhdl, NULL,
-			    0, sizeof(bridge_t), 0);
-
-#ifndef MEDUSA_HACK
-    if ((bridge->b_wid_stat & BRIDGE_STAT_PCI_GIO_N) == 0)
-	return -1;			/* someone else handles GIO bridges. */
-#endif
-
-    if (XWIDGET_PART_REV_NUM(bridge->b_wid_id) == XBRIDGE_PART_REV_A)
-	NeedXbridgeSwap = 1;
-
-    /*
-     * Create the vertex for the PCI bus, which we
-     * will also use to hold the pcibr_soft and
-     * which will be the "master" vertex for all the
-     * pciio connection points we will hang off it.
-     * This needs to happen before we call nic_bridge_vertex_info
-     * as we are some of the *_vmc functions need access to the edges.
-     *
-     * Opening this vertex will provide access to
-     * the Bridge registers themselves.
-     */
-    rc = hwgraph_path_add(xconn_vhdl, EDGE_LBL_PCI, &pcibr_vhdl);
-    ASSERT(rc == GRAPH_SUCCESS);
-
-    ctlr_vhdl = NULL;
-    ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER,
-                0, DEVFS_FL_AUTO_DEVNUM,
-                0, 0,
-                S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-                &pcibr_fops, NULL);
-
-    ASSERT(ctlr_vhdl != NULL);
-
-    /*
-     * decode the nic, and hang its stuff off our
-     * connection point where other drivers can get
-     * at it.
-     */
-#ifdef LATER
-    nicinfo = BRIDGE_VERTEX_MFG_INFO(xconn_vhdl, (nic_data_t) & bridge->b_nic);
-#endif
-
-    /*
-     * Get the hint structure; if some NIC callback
-     * marked this vertex as "hands-off" then we
-     * just return here, before doing anything else.
-     */
-    pcibr_hints = pcibr_hints_get(xconn_vhdl, 0);
-
-    if (pcibr_hints && pcibr_hints->ph_hands_off)
-	return -1;			/* generic operations disabled */
-
-    id = bridge->b_wid_id;
-    rev = XWIDGET_PART_REV_NUM(id);
-
-    hwgraph_info_add_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, (arbitrary_info_t) rev);
-
-    /*
-     * allocate soft state structure, fill in some
-     * fields, and hook it up to our vertex.
-     */
-    NEW(pcibr_soft);
-    BZERO(pcibr_soft, sizeof *pcibr_soft);
-    pcibr_soft_set(pcibr_vhdl, pcibr_soft);
-
-    pcibr_soft->bs_conn = xconn_vhdl;
-    pcibr_soft->bs_vhdl = pcibr_vhdl;
-    pcibr_soft->bs_base = bridge;
-    pcibr_soft->bs_rev_num = rev;
-    pcibr_soft->bs_intr_bits = pcibr_intr_bits;
-    if (is_xbridge(bridge)) {
-	pcibr_soft->bs_int_ate_size = XBRIDGE_INTERNAL_ATES;
-	pcibr_soft->bs_xbridge = 1;
-    } else {
-	pcibr_soft->bs_int_ate_size = BRIDGE_INTERNAL_ATES;
-	pcibr_soft->bs_xbridge = 0;
-    }
-
-    nasid = NASID_GET(bridge);
-    scp = &NODEPDA( NASID_TO_COMPACT_NODEID(nasid) )->module->elsc;
-    pcibr_soft->bs_l1sc = scp;
-    pcibr_soft->bs_moduleid = iobrick_module_get(scp);
-    pcibr_soft->bsi_err_intr = 0;
-
-    /* Bridges up through REV C
-     * are unable to set the direct
-     * byteswappers to BYTE_STREAM.
-     */
-    if (pcibr_soft->bs_rev_num <= BRIDGE_PART_REV_C) {
-	pcibr_soft->bs_pio_end_io = PCIIO_WORD_VALUES;
-	pcibr_soft->bs_pio_end_mem = PCIIO_WORD_VALUES;
-    }
-#if PCIBR_SOFT_LIST
-    {
-	pcibr_list_p            self;
-
-	NEW(self);
-	self->bl_soft = pcibr_soft;
-	self->bl_vhdl = pcibr_vhdl;
-	self->bl_next = pcibr_list;
-        pcibr_list = self; 
-    }
-#endif
-
-    /*
-     * get the name of this bridge vertex and keep the info. Use this
-     * only where it is really needed now: like error interrupts.
-     */
-    s = dev_to_name(pcibr_vhdl, devnm, MAXDEVNAME);
-    pcibr_soft->bs_name = kmalloc(strlen(s) + 1, GFP_KERNEL);
-    strcpy(pcibr_soft->bs_name, s);
-
-#if SHOW_REVS || DEBUG
-#if !DEBUG
-    if (kdebug)
-#endif
-	printk("%sBridge ASIC: rev %s (code=0x%x) at %s\n",
-		is_xbridge(bridge) ? "X" : "",
-		(rev == BRIDGE_PART_REV_A) ? "A" :
-		(rev == BRIDGE_PART_REV_B) ? "B" :
-		(rev == BRIDGE_PART_REV_C) ? "C" :
-		(rev == BRIDGE_PART_REV_D) ? "D" :
-		(rev == XBRIDGE_PART_REV_A) ? "A" :
-		(rev == XBRIDGE_PART_REV_B) ? "B" :
-		"unknown",
-		rev, pcibr_soft->bs_name);
-#endif
-
-    info = xwidget_info_get(xconn_vhdl);
-    pcibr_soft->bs_xid = xwidget_info_id_get(info);
-    pcibr_soft->bs_master = xwidget_info_master_get(info);
-    pcibr_soft->bs_mxid = xwidget_info_masterid_get(info);
-
-    /*
-     * Init bridge lock.
-     */
-    spin_lock_init(&pcibr_soft->bs_lock);
-
-    /*
-     * If we have one, process the hints structure.
-     */
-    if (pcibr_hints) {
-	rrb_fixed = pcibr_hints->ph_rrb_fixed;
-
-	pcibr_soft->bs_rrb_fixed = rrb_fixed;
-
-	if (pcibr_hints->ph_intr_bits)
-	    pcibr_soft->bs_intr_bits = pcibr_hints->ph_intr_bits;
-
-	for (slot = 0; slot < 8; ++slot) {
-	    int                     hslot = pcibr_hints->ph_host_slot[slot] - 1;
-
-	    if (hslot < 0) {
-		pcibr_soft->bs_slot[slot].host_slot = slot;
-	    } else {
-		pcibr_soft->bs_slot[slot].has_host = 1;
-		pcibr_soft->bs_slot[slot].host_slot = hslot;
-	    }
-	}
-    }
-    /*
-     * set up initial values for state fields
-     */
-    for (slot = 0; slot < 8; ++slot) {
-	pcibr_soft->bs_slot[slot].bss_devio.bssd_space = PCIIO_SPACE_NONE;
-	pcibr_soft->bs_slot[slot].bss_d64_base = PCIBR_D64_BASE_UNSET;
-	pcibr_soft->bs_slot[slot].bss_d32_base = PCIBR_D32_BASE_UNSET;
-	pcibr_soft->bs_slot[slot].bss_ext_ates_active = ATOMIC_INIT(0);
-    }
-
-    for (ibit = 0; ibit < 8; ++ibit) {
-	pcibr_soft->bs_intr[ibit].bsi_xtalk_intr = 0;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_soft = pcibr_soft;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_list = NULL;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_stat = 
-							&(bridge->b_int_status);
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_hdlrcnt = 0;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_shared = 0;
-	pcibr_soft->bs_intr[ibit].bsi_pcibr_intr_wrap.iw_connected = 0;
-    }
-
-    /*
-     * Initialize various Bridge registers.
-     */
-
-    /*
-     * On pre-Rev.D bridges, set the PCI_RETRY_CNT
-     * to zero to avoid dropping stores. (#475347)
-     */
-    if (rev < BRIDGE_PART_REV_D)
-	bridge->b_bus_timeout &= ~BRIDGE_BUS_PCI_RETRY_MASK;
-
-    /*
-     * Clear all pending interrupts.
-     */
-    bridge->b_int_rst_stat = (BRIDGE_IRR_ALL_CLR);
-
-    /*
-     * Until otherwise set up,
-     * assume all interrupts are
-     * from slot 7.
-     */
-    bridge->b_int_device = (uint32_t) 0xffffffff;
-
-    {
-	bridgereg_t             dirmap;
-	paddr_t                 paddr;
-	iopaddr_t               xbase;
-	xwidgetnum_t            xport;
-	iopaddr_t               offset;
-	int                     num_entries = 0;
-	int                     entry;
-	cnodeid_t		cnodeid;
-	nasid_t			nasid;
-
-	/* Set the Bridge's 32-bit PCI to XTalk
-	 * Direct Map register to the most useful
-	 * value we can determine.  Note that we
-	 * must use a single xid for all of:
-	 *      direct-mapped 32-bit DMA accesses
-	 *      direct-mapped 64-bit DMA accesses
-	 *      DMA accesses through the PMU
-	 *      interrupts
-	 * This is the only way to guarantee that
-	 * completion interrupts will reach a CPU
-	 * after all DMA data has reached memory.
-	 * (Of course, there may be a few special
-	 * drivers/controlers that explicitly manage
-	 * this ordering problem.)
-	 */
-
-	cnodeid = 0;  /* default node id */
-	/*
-	 * Determine the base address node id to be used for all 32-bit
-	 * Direct Mapping I/O. The default is node 0, but this can be changed
-	 * via a DEVICE_ADMIN directive and the PCIBUS_DMATRANS_NODE
-	 * attribute in the irix.sm config file. A device driver can obtain
-	 * this node value via a call to pcibr_get_dmatrans_node().
-	 */
-	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
-	paddr = NODE_OFFSET(nasid) + 0;
-
-	/* currently, we just assume that if we ask
-	 * for a DMA mapping to "zero" the XIO
-	 * host will transmute this into a request
-	 * for the lowest hunk of memory.
-	 */
-	xbase = xtalk_dmatrans_addr(xconn_vhdl, 0,
-				    paddr, _PAGESZ, 0);
-
-	if (xbase != XIO_NOWHERE) {
-	    if (XIO_PACKED(xbase)) {
-		xport = XIO_PORT(xbase);
-		xbase = XIO_ADDR(xbase);
-	    } else
-		xport = pcibr_soft->bs_mxid;
-
-	    offset = xbase & ((1ull << BRIDGE_DIRMAP_OFF_ADDRSHFT) - 1ull);
-	    xbase >>= BRIDGE_DIRMAP_OFF_ADDRSHFT;
-
-	    dirmap = xport << BRIDGE_DIRMAP_W_ID_SHFT;
-
-	    if (xbase)
-		dirmap |= BRIDGE_DIRMAP_OFF & xbase;
-	    else if (offset >= (512 << 20))
-		dirmap |= BRIDGE_DIRMAP_ADD512;
-
-	    bridge->b_dir_map = dirmap;
-	}
-	/*
-	 * Set bridge's idea of page size according to the system's
-	 * idea of "IO page size".  TBD: The idea of IO page size
-	 * should really go away.
-	 */
-	/*
-	 * ensure that we write and read without any interruption.
-	 * The read following the write is required for the Bridge war
-	 */
-	spl_level = splhi();
-#if IOPGSIZE == 4096
-	bridge->b_wid_control &= ~BRIDGE_CTRL_PAGE_SIZE;
-#elif IOPGSIZE == 16384
-	bridge->b_wid_control |= BRIDGE_CTRL_PAGE_SIZE;
-#else
-	<<<Unable to deal with IOPGSIZE >>>;
-#endif
-	bridge->b_wid_control;		/* inval addr bug war */
-	splx(spl_level);
-
-	/* Initialize internal mapping entries */
-	for (entry = 0; entry < pcibr_soft->bs_int_ate_size; entry++)
-	    bridge->b_int_ate_ram[entry].wr = 0;
-
-	/*
-	 * Determine if there's external mapping SSRAM on this
-	 * bridge.  Set up Bridge control register appropriately,
-	 * inititlize SSRAM, and set software up to manage RAM
-	 * entries as an allocatable resource.
-	 *
-	 * Currently, we just use the rm* routines to manage ATE
-	 * allocation.  We should probably replace this with a
-	 * Best Fit allocator.
-	 *
-	 * For now, if we have external SSRAM, avoid using
-	 * the internal ssram: we can't turn PREFETCH on
-	 * when we use the internal SSRAM; and besides,
-	 * this also guarantees that no allocation will
-	 * straddle the internal/external line, so we
-	 * can increment ATE write addresses rather than
-	 * recomparing against BRIDGE_INTERNAL_ATES every
-	 * time.
-	 */
-	if (is_xbridge(bridge))
-		num_entries = 0;
-	else
-		num_entries = pcibr_init_ext_ate_ram(bridge);
-
-	/* we always have 128 ATEs (512 for Xbridge) inside the chip
-	 * even if disabled for debugging.
-	 */
-	pcibr_soft->bs_int_ate_map = rmallocmap(pcibr_soft->bs_int_ate_size);
-	pcibr_ate_free(pcibr_soft, 0, pcibr_soft->bs_int_ate_size);
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_attach: %d INTERNAL ATEs\n", pcibr_soft->bs_int_ate_size);
-#endif
-
-	if (num_entries > pcibr_soft->bs_int_ate_size) {
-#if PCIBR_ATE_NOTBOTH			/* for debug -- forces us to use external ates */
-	    printk("pcibr_attach: disabling internal ATEs.\n");
-	    pcibr_ate_alloc(pcibr_soft, pcibr_soft->bs_int_ate_size);
-#endif
-	    pcibr_soft->bs_ext_ate_map = rmallocmap(num_entries);
-	    pcibr_ate_free(pcibr_soft, pcibr_soft->bs_int_ate_size,
-			   num_entries - pcibr_soft->bs_int_ate_size);
-#if PCIBR_ATE_DEBUG
-	    printk("pcibr_attach: %d EXTERNAL ATEs\n",
-		    num_entries - pcibr_soft->bs_int_ate_size);
-#endif
-	}
-    }
-
-    {
-	bridgereg_t             dirmap;
-	iopaddr_t               xbase;
-
-	/*
-	 * now figure the *real* xtalk base address
-	 * that dirmap sends us to.
-	 */
-	dirmap = bridge->b_dir_map;
-	if (dirmap & BRIDGE_DIRMAP_OFF)
-	    xbase = (iopaddr_t)(dirmap & BRIDGE_DIRMAP_OFF)
-			<< BRIDGE_DIRMAP_OFF_ADDRSHFT;
-	else if (dirmap & BRIDGE_DIRMAP_ADD512)
-	    xbase = 512 << 20;
-	else
-	    xbase = 0;
-
-	pcibr_soft->bs_dir_xbase = xbase;
-
-	/* it is entirely possible that we may, at this
-	 * point, have our dirmap pointing somewhere
-	 * other than our "master" port.
-	 */
-	pcibr_soft->bs_dir_xport =
-	    (dirmap & BRIDGE_DIRMAP_W_ID) >> BRIDGE_DIRMAP_W_ID_SHFT;
-    }
-
-    /* pcibr sources an error interrupt;
-     * figure out where to send it.
-     *
-     * If any interrupts are enabled in bridge,
-     * then the prom set us up and our interrupt
-     * has already been reconnected in mlreset
-     * above.
-     *
-     * Need to set the D_INTR_ISERR flag
-     * in the dev_desc used for allocating the
-     * error interrupt, so our interrupt will
-     * be properly routed and prioritized.
-     *
-     * If our crosstalk provider wants to
-     * fix widget error interrupts to specific
-     * destinations, D_INTR_ISERR is how it
-     * knows to do this.
-     */
-
-    xtalk_intr = xtalk_intr_alloc(xconn_vhdl, dev_desc, pcibr_vhdl);
-    ASSERT(xtalk_intr != NULL);
-
-    pcibr_soft->bsi_err_intr = xtalk_intr;
-
-    /*
-     * On IP35 with XBridge, we do some extra checks in pcibr_setwidint
-     * in order to work around some addressing limitations.  In order
-     * for that fire wall to work properly, we need to make sure we
-     * start from a known clean state.
-     */
-    pcibr_clearwidint(bridge);
-
-    xtalk_intr_connect(xtalk_intr, (xtalk_intr_setfunc_t)pcibr_setwidint, (void *)bridge);
-
-    /*
-     * now we can start handling error interrupts;
-     * enable all of them.
-     * NOTE: some PCI ints may already be enabled.
-     */
-    b_int_enable = bridge->b_int_enable | BRIDGE_ISR_ERRORS;
-
-
-    bridge->b_int_enable = b_int_enable;
-    bridge->b_int_mode = 0;		/* do not send "clear interrupt" packets */
-
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-
-    /*
-     * Depending on the rev of bridge, disable certain features.
-     * Easiest way seems to be to force the PCIBR_NOwhatever
-     * flag to be on for all DMA calls, which overrides any
-     * PCIBR_whatever flag or even the setting of whatever
-     * from the PCIIO_DMA_class flags (or even from the other
-     * PCIBR flags, since NO overrides YES).
-     */
-    pcibr_soft->bs_dma_flags = 0;
-
-    /* PREFETCH:
-     * Always completely disabled for REV.A;
-     * at "pcibr_prefetch_enable_rev", anyone
-     * asking for PCIIO_PREFETCH gets it.
-     * Between these two points, you have to ask
-     * for PCIBR_PREFETCH, which promises that
-     * your driver knows about known Bridge WARs.
-     */
-    if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_B)
-	pcibr_soft->bs_dma_flags |= PCIBR_NOPREFETCH;
-    else if (pcibr_soft->bs_rev_num < 
-		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_prefetch_enable_rev))
-	pcibr_soft->bs_dma_flags |= PCIIO_NOPREFETCH;
-
-    /* WRITE_GATHER:
-     * Disabled up to but not including the
-     * rev number in pcibr_wg_enable_rev. There
-     * is no "WAR range" as with prefetch.
-     */
-    if (pcibr_soft->bs_rev_num < 
-		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_wg_enable_rev))
-	pcibr_soft->bs_dma_flags |= PCIBR_NOWRITE_GATHER;
-
-    pciio_provider_register(pcibr_vhdl, &pcibr_provider);
-    pciio_provider_startup(pcibr_vhdl);
-
-    pci_io_fb = 0x00000004;		/* I/O FreeBlock Base */
-    pci_io_fl = 0xFFFFFFFF;		/* I/O FreeBlock Last */
-
-    pci_lo_fb = 0x00000010;		/* Low Memory FreeBlock Base */
-    pci_lo_fl = 0x001FFFFF;		/* Low Memory FreeBlock Last */
-
-    pci_hi_fb = 0x00200000;		/* High Memory FreeBlock Base */
-    pci_hi_fl = 0x3FFFFFFF;		/* High Memory FreeBlock Last */
-
-
-    PCI_ADDR_SPACE_LIMITS_STORE();
-
-    /* build "no-slot" connection point
-     */
-    pcibr_info = pcibr_device_info_new
-	(pcibr_soft, PCIIO_SLOT_NONE, PCIIO_FUNC_NONE,
-	 PCIIO_VENDOR_ID_NONE, PCIIO_DEVICE_ID_NONE);
-    noslot_conn = pciio_device_info_register
-	(pcibr_vhdl, &pcibr_info->f_c);
-
-    /* Remember the no slot connection point info for tearing it
-     * down during detach.
-     */
-    pcibr_soft->bs_noslot_conn = noslot_conn;
-    pcibr_soft->bs_noslot_info = pcibr_info;
-#if PCI_FBBE
-    fast_back_to_back_enable = 1;
-#endif
-
-#if PCI_FBBE
-    if (fast_back_to_back_enable) {
-	/*
-	 * All devices on the bus are capable of fast back to back, so
-	 * we need to set the fast back to back bit in all devices on
-	 * the bus that are capable of doing such accesses.
-	 */
-    }
-#endif
-
-#ifdef LATER
-    /* If the bridge has been reset then there is no need to reset
-     * the individual PCI slots.
-     */
-    for (slot = 0; slot < 8; ++slot)  
-	/* Reset all the slots */
-	(void)pcibr_slot_reset(pcibr_vhdl, slot);
-#endif
-
-    for (slot = 0; slot < 8; ++slot)
-	/* Find out what is out there */
-	(void)pcibr_slot_info_init(pcibr_vhdl,slot);
-
-    for (slot = 0; slot < 8; ++slot)  
-	/* Set up the address space for this slot in the pci land */
-	(void)pcibr_slot_addr_space_init(pcibr_vhdl,slot);
-
-    for (slot = 0; slot < 8; ++slot)  
-	/* Setup the device register */
-	(void)pcibr_slot_device_init(pcibr_vhdl, slot);
-
-#ifndef __ia64
-    for (slot = 0; slot < 8; ++slot)  
-	/* Set up convenience links */
-	if (is_xbridge(bridge))
-		if (pcibr_soft->bs_slot[slot].bss_ninfo > 0) /* if occupied */
-			pcibr_bus_cnvlink(pcibr_info->f_vertex, slot);
-#endif
-
-    for (slot = 0; slot < 8; ++slot)  
-	/* Setup host/guest relations */
-	(void)pcibr_slot_guest_info_init(pcibr_vhdl,slot);
-
-    for (slot = 0; slot < 8; ++slot)  
-	/* Initial RRB management */
-	(void)pcibr_slot_initial_rrb_alloc(pcibr_vhdl,slot);
-
-    /* driver attach routines should be called out from generic linux code */
-    for (slot = 0; slot < 8; ++slot)  
-	/* Call the device attach */
-	(void)pcibr_slot_call_device_attach(pcibr_vhdl, slot, 0);
-
-    /*
-     * Each Pbrick PCI bus only has slots 1 and 2.   Similarly for
-     * widget 0xe on Ibricks.  Allocate RRB's accordingly.
-     */
-    if (pcibr_soft->bs_moduleid > 0) {
-	switch (MODULE_GET_BTCHAR(pcibr_soft->bs_moduleid)) {
-	case 'p':		/* Pbrick */
-		do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
-		do_pcibr_rrb_autoalloc(pcibr_soft, 2, 8);
-		break;
-	case 'i':		/* Ibrick */
-	  	/* port 0xe on the Ibrick only has slots 1 and 2 */
-		if (pcibr_soft->bs_xid == 0xe) {
-			do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
-			do_pcibr_rrb_autoalloc(pcibr_soft, 2, 8);
-		}
-		else {
-		    	/* allocate one RRB for the serial port */
-			do_pcibr_rrb_autoalloc(pcibr_soft, 0, 1);
-		}
-		break;
-	} /* switch */
-    }
-
-#ifdef LATER
-    if (strstr(nicinfo, XTALK_PCI_PART_NUM)) {
-	do_pcibr_rrb_autoalloc(pcibr_soft, 1, 8);
-#if PCIBR_RRB_DEBUG
-	printf("\n\nFound XTALK_PCI (030-1275) at %v\n", xconn_vhdl);
-
-	printf("pcibr_attach: %v Shoebox RRB MANAGEMENT: %d+%d free\n",
-		pcibr_vhdl,
-		pcibr_soft->bs_rrb_avail[0],
-		pcibr_soft->bs_rrb_avail[1]);
-
-	for (slot = 0; slot < 8; ++slot)
-	    printf("\t%d+%d+%d",
-	    0xFFF & pcibr_soft->bs_rrb_valid[slot],
-	    0xFFF & pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-	    pcibr_soft->bs_rrb_res[slot]);
-
-	printf("\n");
-#endif
-    }
-#else
-	FIXME("pcibr_attach: Call do_pcibr_rrb_autoalloc nicinfo\n");
-#endif
-
-    if (aa)
-	    async_attach_add_info(noslot_conn, aa);
-
-    pciio_device_attach(noslot_conn, 0);
-
-
-    /* 
-     * Tear down pointer to async attach info -- async threads for
-     * bridge's descendants may be running but the bridge's work is done.
-     */
-    if (aa)
-	    async_attach_del_info(xconn_vhdl);
-
-    return 0;
-}
-/*
- * pcibr_detach:
- *	Detach the bridge device from the hwgraph after cleaning out all the 
- *	underlying vertices.
- */
-int
-pcibr_detach(devfs_handle_t xconn)
-{
-    pciio_slot_t	slot;
-    devfs_handle_t	pcibr_vhdl;
-    pcibr_soft_t	pcibr_soft;
-    bridge_t		*bridge;
-
-    /* Get the bridge vertex from its xtalk connection point */
-    if (hwgraph_traverse(xconn, EDGE_LBL_PCI, &pcibr_vhdl) != GRAPH_SUCCESS)
-	return(1);
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge = pcibr_soft->bs_base;
-
-    /* Disable the interrupts from the bridge */
-    bridge->b_int_enable = 0;
-
-    /* Detach all the PCI devices talking to this bridge */
-    for(slot = 0; slot < 8; slot++) {
-#ifdef DEBUG
-	printk("pcibr_device_detach called for %p/%d\n",
-		pcibr_vhdl,slot);
-#endif
-	pcibr_slot_detach(pcibr_vhdl, slot, 0);
-    }
-
-    /* Unregister the no-slot connection point */
-    pciio_device_info_unregister(pcibr_vhdl,
-				 &(pcibr_soft->bs_noslot_info->f_c));
-
-    spin_lock_destroy(&pcibr_soft->bs_lock);
-    kfree(pcibr_soft->bs_name);
-    
-    /* Error handler gets unregistered when the widget info is 
-     * cleaned 
-     */
-    /* Free the soft ATE maps */
-    if (pcibr_soft->bs_int_ate_map)
-	rmfreemap(pcibr_soft->bs_int_ate_map);
-    if (pcibr_soft->bs_ext_ate_map)
-	rmfreemap(pcibr_soft->bs_ext_ate_map);
-
-    /* Disconnect the error interrupt and free the xtalk resources 
-     * associated with it.
-     */
-    xtalk_intr_disconnect(pcibr_soft->bsi_err_intr);
-    xtalk_intr_free(pcibr_soft->bsi_err_intr);
-
-    /* Clear the software state maintained by the bridge driver for this
-     * bridge.
-     */
-    DEL(pcibr_soft);
-    /* Remove the Bridge revision labelled info */
-    (void)hwgraph_info_remove_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, NULL);
-    /* Remove the character device associated with this bridge */
-    (void)hwgraph_edge_remove(pcibr_vhdl, EDGE_LBL_CONTROLLER, NULL);
-    /* Remove the PCI bridge vertex */
-    (void)hwgraph_edge_remove(xconn, EDGE_LBL_PCI, NULL);
-
-    return(0);
-}
-
-int
-pcibr_asic_rev(devfs_handle_t pconn_vhdl)
-{
-    devfs_handle_t            pcibr_vhdl;
-    arbitrary_info_t        ainfo;
-
-    if (GRAPH_SUCCESS !=
-	hwgraph_traverse(pconn_vhdl, EDGE_LBL_MASTER, &pcibr_vhdl))
-	return -1;
-
-    if (GRAPH_SUCCESS !=
-	hwgraph_info_get_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, &ainfo))
-	return -1;
-
-    return (int) ainfo;
-}
-
-int
-pcibr_write_gather_flush(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t  pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t  pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    pciio_slot_t  slot;
-    slot = pciio_info_slot_get(pciio_info);
-    pcibr_device_write_gather_flush(pcibr_soft, slot);
-    return 0;
-}
-
-/* =====================================================================
- *    PIO MANAGEMENT
- */
-
-LOCAL iopaddr_t
-pcibr_addr_pci_to_xio(devfs_handle_t pconn_vhdl,
-		      pciio_slot_t slot,
-		      pciio_space_t space,
-		      iopaddr_t pci_addr,
-		      size_t req_size,
-		      unsigned flags)
-{
-    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
-    pciio_info_t            pciio_info = &pcibr_info->f_c;
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    unsigned                bar;	/* which BASE reg on device is decoding */
-    iopaddr_t               xio_addr = XIO_NOWHERE;
-
-    pciio_space_t           wspace;	/* which space device is decoding */
-    iopaddr_t               wbase;	/* base of device decode on PCI */
-    size_t                  wsize;	/* size of device decode on PCI */
-
-    int                     try;	/* DevIO(x) window scanning order control */
-    int                     win;	/* which DevIO(x) window is being used */
-    pciio_space_t           mspace;	/* target space for devio(x) register */
-    iopaddr_t               mbase;	/* base of devio(x) mapped area on PCI */
-    size_t                  msize;	/* size of devio(x) mapped area on PCI */
-    size_t                  mmask;	/* addr bits stored in Device(x) */
-
-    unsigned long           s;
-
-    s = pcibr_lock(pcibr_soft);
-
-    if (pcibr_soft->bs_slot[slot].has_host) {
-	slot = pcibr_soft->bs_slot[slot].host_slot;
-	pcibr_info = pcibr_soft->bs_slot[slot].bss_infos[0];
-    }
-    if (space == PCIIO_SPACE_NONE)
-	goto done;
-
-    if (space == PCIIO_SPACE_CFG) {
-	/*
-	 * Usually, the first mapping
-	 * established to a PCI device
-	 * is to its config space.
-	 *
-	 * In any case, we definitely
-	 * do NOT need to worry about
-	 * PCI BASE registers, and
-	 * MUST NOT attempt to point
-	 * the DevIO(x) window at
-	 * this access ...
-	 */
-	if (((flags & PCIIO_BYTE_STREAM) == 0) &&
-	    ((pci_addr + req_size) <= BRIDGE_TYPE0_CFG_FUNC_OFF))
-	    xio_addr = pci_addr + BRIDGE_TYPE0_CFG_DEV(slot);
-
-	goto done;
-    }
-    if (space == PCIIO_SPACE_ROM) {
-	/* PIO to the Expansion Rom.
-	 * Driver is responsible for
-	 * enabling and disabling
-	 * decodes properly.
-	 */
-	wbase = pcibr_info->f_rbase;
-	wsize = pcibr_info->f_rsize;
-
-	/*
-	 * While the driver should know better
-	 * than to attempt to map more space
-	 * than the device is decoding, he might
-	 * do it; better to bail out here.
-	 */
-	if ((pci_addr + req_size) > wsize)
-	    goto done;
-
-	pci_addr += wbase;
-	space = PCIIO_SPACE_MEM;
-    }
-    /*
-     * reduce window mappings to raw
-     * space mappings (maybe allocating
-     * windows), and try for DevIO(x)
-     * usage (setting it if it is available).
-     */
-    bar = space - PCIIO_SPACE_WIN0;
-    if (bar < 6) {
-	wspace = pcibr_info->f_window[bar].w_space;
-	if (wspace == PCIIO_SPACE_NONE)
-	    goto done;
-
-	/* get PCI base and size */
-	wbase = pcibr_info->f_window[bar].w_base;
-	wsize = pcibr_info->f_window[bar].w_size;
-
-	/*
-	 * While the driver should know better
-	 * than to attempt to map more space
-	 * than the device is decoding, he might
-	 * do it; better to bail out here.
-	 */
-	if ((pci_addr + req_size) > wsize)
-	    goto done;
-
-	/* shift from window relative to
-	 * decoded space relative.
-	 */
-	pci_addr += wbase;
-	space = wspace;
-    } else
-	bar = -1;
-
-    /* Scan all the DevIO(x) windows twice looking for one
-     * that can satisfy our request. The first time through,
-     * only look at assigned windows; the second time, also
-     * look at PCIIO_SPACE_NONE windows. Arrange the order
-     * so we always look at our own window first.
-     *
-     * We will not attempt to satisfy a single request
-     * by concatinating multiple windows.
-     */
-    for (try = 0; try < 16; ++try) {
-	bridgereg_t             devreg;
-	unsigned                offset;
-
-	win = (try + slot) % 8;
-
-	/* If this DevIO(x) mapping area can provide
-	 * a mapping to this address, use it.
-	 */
-	msize = (win < 2) ? 0x200000 : 0x100000;
-	mmask = -msize;
-	if (space != PCIIO_SPACE_IO)
-	    mmask &= 0x3FFFFFFF;
-
-	offset = pci_addr & (msize - 1);
-
-	/* If this window can't possibly handle that request,
-	 * go on to the next window.
-	 */
-	if (((pci_addr & (msize - 1)) + req_size) > msize)
-	    continue;
-
-	devreg = pcibr_soft->bs_slot[win].bss_device;
-
-	/* Is this window "nailed down"?
-	 * If not, maybe we can use it.
-	 * (only check this the second time through)
-	 */
-	mspace = pcibr_soft->bs_slot[win].bss_devio.bssd_space;
-	if ((try > 7) && (mspace == PCIIO_SPACE_NONE)) {
-
-	    /* If this is the primary DevIO(x) window
-	     * for some other device, skip it.
-	     */
-	    if ((win != slot) &&
-		(PCIIO_VENDOR_ID_NONE !=
-		 pcibr_soft->bs_slot[win].bss_vendor_id))
-		continue;
-
-	    /* It's a free window, and we fit in it.
-	     * Set up Device(win) to our taste.
-	     */
-	    mbase = pci_addr & mmask;
-
-	    /* check that we would really get from
-	     * here to there.
-	     */
-	    if ((mbase | offset) != pci_addr)
-		continue;
-
-	    devreg &= ~BRIDGE_DEV_OFF_MASK;
-	    if (space != PCIIO_SPACE_IO)
-		devreg |= BRIDGE_DEV_DEV_IO_MEM;
-	    else
-		devreg &= ~BRIDGE_DEV_DEV_IO_MEM;
-	    devreg |= (mbase >> 20) & BRIDGE_DEV_OFF_MASK;
-
-	    /* default is WORD_VALUES.
-	     * if you specify both,
-	     * operation is undefined.
-	     */
-	    if (flags & PCIIO_BYTE_STREAM)
-		devreg |= BRIDGE_DEV_DEV_SWAP;
-	    else
-		devreg &= ~BRIDGE_DEV_DEV_SWAP;
-
-	    if (pcibr_soft->bs_slot[win].bss_device != devreg) {
-		bridge->b_device[win].reg = devreg;
-		pcibr_soft->bs_slot[win].bss_device = devreg;
-		bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
-
-#if DEBUG && PCI_DEBUG
-		printk("pcibr Device(%d): 0x%lx\n", win, bridge->b_device[win].reg);
-#endif
-	    }
-	    pcibr_soft->bs_slot[win].bss_devio.bssd_space = space;
-	    pcibr_soft->bs_slot[win].bss_devio.bssd_base = mbase;
-	    xio_addr = BRIDGE_DEVIO(win) + (pci_addr - mbase);
-
-#if DEBUG && PCI_DEBUG
-	    printk("%s LINE %d map to space %d space desc 0x%x[%lx..%lx] for slot %d allocates DevIO(%d) devreg 0x%x\n", 
-		    __FUNCTION__, __LINE__, space, space_desc,
-		    pci_addr, pci_addr + req_size - 1,
-		    slot, win, devreg);
-#endif
-
-	    goto done;
-	}				/* endif DevIO(x) not pointed */
-	mbase = pcibr_soft->bs_slot[win].bss_devio.bssd_base;
-
-	/* Now check for request incompat with DevIO(x)
-	 */
-	if ((mspace != space) ||
-	    (pci_addr < mbase) ||
-	    ((pci_addr + req_size) > (mbase + msize)) ||
-	    ((flags & PCIIO_BYTE_STREAM) && !(devreg & BRIDGE_DEV_DEV_SWAP)) ||
-	    (!(flags & PCIIO_BYTE_STREAM) && (devreg & BRIDGE_DEV_DEV_SWAP)))
-	    continue;
-
-	/* DevIO(x) window is pointed at PCI space
-	 * that includes our target. Calculate the
-	 * final XIO address, release the lock and
-	 * return.
-	 */
-	xio_addr = BRIDGE_DEVIO(win) + (pci_addr - mbase);
-
-#if DEBUG && PCI_DEBUG
-	printk("%s LINE %d map to space %d [0x%p..0x%p] for slot %d uses DevIO(%d)\n",
-		__FUNCTION__, __LINE__, space,  pci_addr, pci_addr + req_size - 1, slot, win);
-#endif
-	goto done;
-    }
-
-    switch (space) {
-	/*
-	 * Accesses to device decode
-	 * areas that do a not fit
-	 * within the DevIO(x) space are
-	 * modified to be accesses via
-	 * the direct mapping areas.
-	 *
-	 * If necessary, drivers can
-	 * explicitly ask for mappings
-	 * into these address spaces,
-	 * but this should never be needed.
-	 */
-    case PCIIO_SPACE_MEM:		/* "mem space" */
-    case PCIIO_SPACE_MEM32:		/* "mem, use 32-bit-wide bus" */
-	if ((pci_addr + BRIDGE_PCI_MEM32_BASE + req_size - 1) <=
-	    BRIDGE_PCI_MEM32_LIMIT)
-	    xio_addr = pci_addr + BRIDGE_PCI_MEM32_BASE;
-	break;
-
-    case PCIIO_SPACE_MEM64:		/* "mem, use 64-bit-wide bus" */
-	if ((pci_addr + BRIDGE_PCI_MEM64_BASE + req_size - 1) <=
-	    BRIDGE_PCI_MEM64_LIMIT)
-	    xio_addr = pci_addr + BRIDGE_PCI_MEM64_BASE;
-	break;
-
-    case PCIIO_SPACE_IO:		/* "i/o space" */
-	/* Bridge Hardware Bug WAR #482741:
-	 * The 4G area that maps directly from
-	 * XIO space to PCI I/O space is busted
-	 * until Bridge Rev D.
-	 */
-	if ((pcibr_soft->bs_rev_num > BRIDGE_PART_REV_C) &&
-	    ((pci_addr + BRIDGE_PCI_IO_BASE + req_size - 1) <=
-	     BRIDGE_PCI_IO_LIMIT))
-	    xio_addr = pci_addr + BRIDGE_PCI_IO_BASE;
-	break;
-    }
-
-    /* Check that "Direct PIO" byteswapping matches,
-     * try to change it if it does not.
-     */
-    if (xio_addr != XIO_NOWHERE) {
-	unsigned                bst;	/* nonzero to set bytestream */
-	unsigned               *bfp;	/* addr of record of how swapper is set */
-	unsigned                swb;	/* which control bit to mung */
-	unsigned                bfo;	/* current swapper setting */
-	unsigned                bfn;	/* desired swapper setting */
-
-	bfp = ((space == PCIIO_SPACE_IO)
-	       ? (&pcibr_soft->bs_pio_end_io)
-	       : (&pcibr_soft->bs_pio_end_mem));
-
-	bfo = *bfp;
-
-	bst = flags & PCIIO_BYTE_STREAM;
-
-	bfn = bst ? PCIIO_BYTE_STREAM : PCIIO_WORD_VALUES;
-
-	if (bfn == bfo) {		/* we already match. */
-	    ;
-	} else if (bfo != 0) {		/* we have a conflict. */
-#if DEBUG && PCI_DEBUG
-	    printk("pcibr_addr_pci_to_xio: swap conflict in space %d , was%s%s, want%s%s\n",
-		    space, 
-		    bfo & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
-		    bfo & PCIIO_WORD_VALUES ? " WORD_VALUES" : "",
-		    bfn & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
-		    bfn & PCIIO_WORD_VALUES ? " WORD_VALUES" : "");
-#endif
-	    xio_addr = XIO_NOWHERE;
-	} else {			/* OK to make the change. */
-	    bridgereg_t             octl, nctl;
-
-	    swb = (space == PCIIO_SPACE_IO) ? BRIDGE_CTRL_IO_SWAP : BRIDGE_CTRL_MEM_SWAP;
-	    octl = bridge->b_wid_control;
-	    nctl = bst ? octl | swb : octl & ~swb;
-
-	    if (octl != nctl)		/* make the change if any */
-		bridge->b_wid_control = nctl;
-
-	    *bfp = bfn;			/* record the assignment */
-
-#if DEBUG && PCI_DEBUG
-	    printk("pcibr_addr_pci_to_xio: swap for space %d  set to%s%s\n",
-		    space, 
-		    bfn & PCIIO_BYTE_STREAM ? " BYTE_STREAM" : "",
-		    bfn & PCIIO_WORD_VALUES ? " WORD_VALUES" : "");
-#endif
-	}
-    }
-  done:
-    pcibr_unlock(pcibr_soft, s);
-    return xio_addr;
-}
-
-/*ARGSUSED6 */
-pcibr_piomap_t
-pcibr_piomap_alloc(devfs_handle_t pconn_vhdl,
-		   device_desc_t dev_desc,
-		   pciio_space_t space,
-		   iopaddr_t pci_addr,
-		   size_t req_size,
-		   size_t req_size_max,
-		   unsigned flags)
-{
-    pcibr_info_t	    pcibr_info = pcibr_info_get(pconn_vhdl);
-    pciio_info_t            pciio_info = &pcibr_info->f_c;
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-
-    pcibr_piomap_t         *mapptr;
-    pcibr_piomap_t          maplist;
-    pcibr_piomap_t          pcibr_piomap;
-    iopaddr_t               xio_addr;
-    xtalk_piomap_t          xtalk_piomap;
-    unsigned long           s;
-
-    /* Make sure that the req sizes are non-zero */
-    if ((req_size < 1) || (req_size_max < 1))
-	return NULL;
-
-    /*
-     * Code to translate slot/space/addr
-     * into xio_addr is common between
-     * this routine and pcibr_piotrans_addr.
-     */
-    xio_addr = pcibr_addr_pci_to_xio(pconn_vhdl, pciio_slot, space, pci_addr, req_size, flags);
-
-    if (xio_addr == XIO_NOWHERE)
-	return NULL;
-
-    /* Check the piomap list to see if there is already an allocated
-     * piomap entry but not in use. If so use that one. Otherwise
-     * allocate a new piomap entry and add it to the piomap list
-     */
-    mapptr = &(pcibr_info->f_piomap);
-
-    s = pcibr_lock(pcibr_soft);
-    for (pcibr_piomap = *mapptr;
-	 pcibr_piomap != NULL;
-	 pcibr_piomap = pcibr_piomap->bp_next) {
-	if (pcibr_piomap->bp_mapsz == 0)
-	    break;
-    }
-
-    if (pcibr_piomap)
-	mapptr = NULL;
-    else {
-	pcibr_unlock(pcibr_soft, s);
-	NEW(pcibr_piomap);
-    }
-
-    pcibr_piomap->bp_dev = pconn_vhdl;
-    pcibr_piomap->bp_slot = pciio_slot;
-    pcibr_piomap->bp_flags = flags;
-    pcibr_piomap->bp_space = space;
-    pcibr_piomap->bp_pciaddr = pci_addr;
-    pcibr_piomap->bp_mapsz = req_size;
-    pcibr_piomap->bp_soft = pcibr_soft;
-    pcibr_piomap->bp_toc[0] = ATOMIC_INIT(0);
-
-    if (mapptr) {
-	s = pcibr_lock(pcibr_soft);
-	maplist = *mapptr;
-	pcibr_piomap->bp_next = maplist;
-	*mapptr = pcibr_piomap;
-    }
-    pcibr_unlock(pcibr_soft, s);
-
-
-    if (pcibr_piomap) {
-	xtalk_piomap =
-	    xtalk_piomap_alloc(xconn_vhdl, 0,
-			       xio_addr,
-			       req_size, req_size_max,
-			       flags & PIOMAP_FLAGS);
-	if (xtalk_piomap) {
-	    pcibr_piomap->bp_xtalk_addr = xio_addr;
-	    pcibr_piomap->bp_xtalk_pio = xtalk_piomap;
-	} else {
-	    pcibr_piomap->bp_mapsz = 0;
-	    pcibr_piomap = 0;
-	}
-    }
-    return pcibr_piomap;
-}
-
-/*ARGSUSED */
-void
-pcibr_piomap_free(pcibr_piomap_t pcibr_piomap)
-{
-    xtalk_piomap_free(pcibr_piomap->bp_xtalk_pio);
-    pcibr_piomap->bp_xtalk_pio = 0;
-    pcibr_piomap->bp_mapsz = 0;
-}
-
-/*ARGSUSED */
-caddr_t
-pcibr_piomap_addr(pcibr_piomap_t pcibr_piomap,
-		  iopaddr_t pci_addr,
-		  size_t req_size)
-{
-    return xtalk_piomap_addr(pcibr_piomap->bp_xtalk_pio,
-			     pcibr_piomap->bp_xtalk_addr +
-			     pci_addr - pcibr_piomap->bp_pciaddr,
-			     req_size);
-}
-
-/*ARGSUSED */
-void
-pcibr_piomap_done(pcibr_piomap_t pcibr_piomap)
-{
-    xtalk_piomap_done(pcibr_piomap->bp_xtalk_pio);
-}
-
-/*ARGSUSED */
-caddr_t
-pcibr_piotrans_addr(devfs_handle_t pconn_vhdl,
-		    device_desc_t dev_desc,
-		    pciio_space_t space,
-		    iopaddr_t pci_addr,
-		    size_t req_size,
-		    unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-
-    iopaddr_t               xio_addr;
-
-    xio_addr = pcibr_addr_pci_to_xio(pconn_vhdl, pciio_slot, space, pci_addr, req_size, flags);
-
-    if (xio_addr == XIO_NOWHERE)
-	return NULL;
-
-    return xtalk_piotrans_addr(xconn_vhdl, 0, xio_addr, req_size, flags & PIOMAP_FLAGS);
-}
-
-/*
- * PIO Space allocation and management.
- *      Allocate and Manage the PCI PIO space (mem and io space)
- *      This routine is pretty simplistic at this time, and
- *      does pretty trivial management of allocation and freeing..
- *      The current scheme is prone for fragmentation..
- *      Change the scheme to use bitmaps.
- */
-
-/*ARGSUSED */
-iopaddr_t
-pcibr_piospace_alloc(devfs_handle_t pconn_vhdl,
-		     device_desc_t dev_desc,
-		     pciio_space_t space,
-		     size_t req_size,
-		     size_t alignment)
-{
-    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
-    pciio_info_t            pciio_info = &pcibr_info->f_c;
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-    pciio_piospace_t        piosp;
-    unsigned long           s;
-
-    iopaddr_t              *pciaddr, *pcilast;
-    iopaddr_t               start_addr;
-    size_t                  align_mask;
-
-    /*
-     * Check for proper alignment
-     */
-    ASSERT(alignment >= NBPP);
-    ASSERT((alignment & (alignment - 1)) == 0);
-
-    align_mask = alignment - 1;
-    s = pcibr_lock(pcibr_soft);
-
-    /*
-     * First look if a previously allocated chunk exists.
-     */
-    if ((piosp = pcibr_info->f_piospace)) {
-	/*
-	 * Look through the list for a right sized free chunk.
-	 */
-	do {
-	    if (piosp->free &&
-		(piosp->space == space) &&
-		(piosp->count >= req_size) &&
-		!(piosp->start & align_mask)) {
-		piosp->free = 0;
-		pcibr_unlock(pcibr_soft, s);
-		return piosp->start;
-	    }
-	    piosp = piosp->next;
-	} while (piosp);
-    }
-    ASSERT(!piosp);
-
-    switch (space) {
-    case PCIIO_SPACE_IO:
-	pciaddr = &pcibr_soft->bs_spinfo.pci_io_base;
-	pcilast = &pcibr_soft->bs_spinfo.pci_io_last;
-	break;
-    case PCIIO_SPACE_MEM:
-    case PCIIO_SPACE_MEM32:
-	pciaddr = &pcibr_soft->bs_spinfo.pci_mem_base;
-	pcilast = &pcibr_soft->bs_spinfo.pci_mem_last;
-	break;
-    default:
-	ASSERT(0);
-	pcibr_unlock(pcibr_soft, s);
-	return 0;
-    }
-
-    start_addr = *pciaddr;
-
-    /*
-     * Align start_addr.
-     */
-    if (start_addr & align_mask)
-	start_addr = (start_addr + align_mask) & ~align_mask;
-
-    if ((start_addr + req_size) > *pcilast) {
-	/*
-	 * If too big a request, reject it.
-	 */
-	pcibr_unlock(pcibr_soft, s);
-	return 0;
-    }
-    *pciaddr = (start_addr + req_size);
-
-    NEW(piosp);
-    piosp->free = 0;
-    piosp->space = space;
-    piosp->start = start_addr;
-    piosp->count = req_size;
-    piosp->next = pcibr_info->f_piospace;
-    pcibr_info->f_piospace = piosp;
-
-    pcibr_unlock(pcibr_soft, s);
-    return start_addr;
-}
-
-/*ARGSUSED */
-void
-pcibr_piospace_free(devfs_handle_t pconn_vhdl,
-		    pciio_space_t space,
-		    iopaddr_t pciaddr,
-		    size_t req_size)
-{
-    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
-
-    pciio_piospace_t        piosp;
-    unsigned long           s;
-    char                    name[1024];
-
-    /*
-     * Look through the bridge data structures for the pciio_piospace_t
-     * structure corresponding to  'pciaddr'
-     */
-    s = pcibr_lock(pcibr_soft);
-    piosp = pcibr_info->f_piospace;
-    while (piosp) {
-	/*
-	 * Piospace free can only be for the complete
-	 * chunk and not parts of it..
-	 */
-	if (piosp->start == pciaddr) {
-	    if (piosp->count == req_size)
-		break;
-	    /*
-	     * Improper size passed for freeing..
-	     * Print a message and break;
-	     */
-	    hwgraph_vertex_name_get(pconn_vhdl, name, 1024);
-	    printk(KERN_WARNING  "pcibr_piospace_free: error");
-	    printk(KERN_WARNING  "Device %s freeing size (0x%lx) different than allocated (0x%lx)",
-					name, req_size, piosp->count);
-	    printk(KERN_WARNING  "Freeing 0x%lx instead", piosp->count);
-	    break;
-	}
-	piosp = piosp->next;
-    }
-
-    if (!piosp) {
-	printk(KERN_WARNING  
-		"pcibr_piospace_free: Address 0x%lx size 0x%lx - No match\n",
-		pciaddr, req_size);
-	pcibr_unlock(pcibr_soft, s);
-	return;
-    }
-    piosp->free = 1;
-    pcibr_unlock(pcibr_soft, s);
-    return;
-}
-
-/* =====================================================================
- *    DMA MANAGEMENT
- *
- *      The Bridge ASIC provides three methods of doing
- *      DMA: via a "direct map" register available in
- *      32-bit PCI space (which selects a contiguous 2G
- *      address space on some other widget), via
- *      "direct" addressing via 64-bit PCI space (all
- *      destination information comes from the PCI
- *      address, including transfer attributes), and via
- *      a "mapped" region that allows a bunch of
- *      different small mappings to be established with
- *      the PMU.
- *
- *      For efficiency, we most prefer to use the 32-bit
- *      direct mapping facility, since it requires no
- *      resource allocations. The advantage of using the
- *      PMU over the 64-bit direct is that single-cycle
- *      PCI addressing can be used; the advantage of
- *      using 64-bit direct over PMU addressing is that
- *      we do not have to allocate entries in the PMU.
- */
-
-/*
- * Convert PCI-generic software flags and Bridge-specific software flags
- * into Bridge-specific Direct Map attribute bits.
- */
-LOCAL iopaddr_t
-pcibr_flags_to_d64(unsigned flags, pcibr_soft_t pcibr_soft)
-{
-    iopaddr_t               attributes = 0;
-
-    /* Sanity check: Bridge only allows use of VCHAN1 via 64-bit addrs */
-#ifdef LATER
-    ASSERT_ALWAYS(!(flags & PCIBR_VCHAN1) || (flags & PCIIO_DMA_A64));
-#endif
-
-    /* Generic macro flags
-     */
-    if (flags & PCIIO_DMA_DATA) {	/* standard data channel */
-	attributes &= ~PCI64_ATTR_BAR;	/* no barrier bit */
-	attributes |= PCI64_ATTR_PREF;	/* prefetch on */
-    }
-    if (flags & PCIIO_DMA_CMD) {	/* standard command channel */
-	attributes |= PCI64_ATTR_BAR;	/* barrier bit on */
-	attributes &= ~PCI64_ATTR_PREF;	/* disable prefetch */
-    }
-    /* Generic detail flags
-     */
-    if (flags & PCIIO_PREFETCH)
-	attributes |= PCI64_ATTR_PREF;
-    if (flags & PCIIO_NOPREFETCH)
-	attributes &= ~PCI64_ATTR_PREF;
-
-    /* the swap bit is in the address attributes for xbridge */
-    if (pcibr_soft->bs_xbridge) {
-    	if (flags & PCIIO_BYTE_STREAM)
-        	attributes |= PCI64_ATTR_SWAP;
-    	if (flags & PCIIO_WORD_VALUES)
-        	attributes &= ~PCI64_ATTR_SWAP;
-    }
-
-    /* Provider-specific flags
-     */
-    if (flags & PCIBR_BARRIER)
-	attributes |= PCI64_ATTR_BAR;
-    if (flags & PCIBR_NOBARRIER)
-	attributes &= ~PCI64_ATTR_BAR;
-
-    if (flags & PCIBR_PREFETCH)
-	attributes |= PCI64_ATTR_PREF;
-    if (flags & PCIBR_NOPREFETCH)
-	attributes &= ~PCI64_ATTR_PREF;
-
-    if (flags & PCIBR_PRECISE)
-	attributes |= PCI64_ATTR_PREC;
-    if (flags & PCIBR_NOPRECISE)
-	attributes &= ~PCI64_ATTR_PREC;
-
-    if (flags & PCIBR_VCHAN1)
-	attributes |= PCI64_ATTR_VIRTUAL;
-    if (flags & PCIBR_VCHAN0)
-	attributes &= ~PCI64_ATTR_VIRTUAL;
-
-    return (attributes);
-}
-
-/*
- * Convert PCI-generic software flags and Bridge-specific software flags
- * into Bridge-specific Address Translation Entry attribute bits.
- */
-LOCAL bridge_ate_t
-pcibr_flags_to_ate(unsigned flags)
-{
-    bridge_ate_t            attributes;
-
-    /* default if nothing specified:
-     * NOBARRIER
-     * NOPREFETCH
-     * NOPRECISE
-     * COHERENT
-     * Plus the valid bit
-     */
-    attributes = ATE_CO | ATE_V;
-
-    /* Generic macro flags
-     */
-    if (flags & PCIIO_DMA_DATA) {	/* standard data channel */
-	attributes &= ~ATE_BAR;		/* no barrier */
-	attributes |= ATE_PREF;		/* prefetch on */
-    }
-    if (flags & PCIIO_DMA_CMD) {	/* standard command channel */
-	attributes |= ATE_BAR;		/* barrier bit on */
-	attributes &= ~ATE_PREF;	/* disable prefetch */
-    }
-    /* Generic detail flags
-     */
-    if (flags & PCIIO_PREFETCH)
-	attributes |= ATE_PREF;
-    if (flags & PCIIO_NOPREFETCH)
-	attributes &= ~ATE_PREF;
-
-    /* Provider-specific flags
-     */
-    if (flags & PCIBR_BARRIER)
-	attributes |= ATE_BAR;
-    if (flags & PCIBR_NOBARRIER)
-	attributes &= ~ATE_BAR;
-
-    if (flags & PCIBR_PREFETCH)
-	attributes |= ATE_PREF;
-    if (flags & PCIBR_NOPREFETCH)
-	attributes &= ~ATE_PREF;
-
-    if (flags & PCIBR_PRECISE)
-	attributes |= ATE_PREC;
-    if (flags & PCIBR_NOPRECISE)
-	attributes &= ~ATE_PREC;
-
-    return (attributes);
-}
-
-/*ARGSUSED */
-pcibr_dmamap_t
-pcibr_dmamap_alloc(devfs_handle_t pconn_vhdl,
-		   device_desc_t dev_desc,
-		   size_t req_size_max,
-		   unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    pciio_slot_t            slot;
-    xwidgetnum_t            xio_port;
-
-    xtalk_dmamap_t          xtalk_dmamap;
-    pcibr_dmamap_t          pcibr_dmamap;
-    int                     ate_count;
-    int                     ate_index;
-
-    /* merge in forced flags */
-    flags |= pcibr_soft->bs_dma_flags;
-
-#ifdef IRIX
-    NEWf(pcibr_dmamap, flags);
-#else
-    /*
-     * On SNIA64, these maps are pre-allocated because pcibr_dmamap_alloc()
-     * can be called within an interrupt thread.
-     */
-    pcibr_dmamap = (pcibr_dmamap_t)get_free_pciio_dmamap(pcibr_soft->bs_vhdl);
-#endif
-
-    if (!pcibr_dmamap)
-	return 0;
-
-    xtalk_dmamap = xtalk_dmamap_alloc(xconn_vhdl, dev_desc, req_size_max,
-				      flags & DMAMAP_FLAGS);
-    if (!xtalk_dmamap) {
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_attach: xtalk_dmamap_alloc failed\n");
-#endif
-#ifdef IRIX
-	DEL(pcibr_dmamap);
-#else
-	free_pciio_dmamap(pcibr_dmamap);
-#endif
-	return 0;
-    }
-    xio_port = pcibr_soft->bs_mxid;
-    slot = pciio_info_slot_get(pciio_info);
-
-    pcibr_dmamap->bd_dev = pconn_vhdl;
-    pcibr_dmamap->bd_slot = slot;
-    pcibr_dmamap->bd_soft = pcibr_soft;
-    pcibr_dmamap->bd_xtalk = xtalk_dmamap;
-    pcibr_dmamap->bd_max_size = req_size_max;
-    pcibr_dmamap->bd_xio_port = xio_port;
-
-    if (flags & PCIIO_DMA_A64) {
-	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D64_BITS)) {
-	    iopaddr_t               pci_addr;
-	    int                     have_rrbs;
-	    int                     min_rrbs;
-
-	    /* Device is capable of A64 operations,
-	     * and the attributes of the DMA are
-	     * consistent with any previous DMA
-	     * mappings using shared resources.
-	     */
-
-	    pci_addr = pcibr_flags_to_d64(flags, pcibr_soft);
-
-	    pcibr_dmamap->bd_flags = flags;
-	    pcibr_dmamap->bd_xio_addr = 0;
-	    pcibr_dmamap->bd_pci_addr = pci_addr;
-
-	    /* Make sure we have an RRB (or two).
-	     */
-	    if (!(pcibr_soft->bs_rrb_fixed & (1 << slot))) {
-		if (flags & PCIBR_VCHAN1)
-		    slot += PCIBR_RRB_SLOT_VIRTUAL;
-		have_rrbs = pcibr_soft->bs_rrb_valid[slot];
-		if (have_rrbs < 2) {
-		    if (pci_addr & PCI64_ATTR_PREF)
-			min_rrbs = 2;
-		    else
-			min_rrbs = 1;
-		    if (have_rrbs < min_rrbs)
-			do_pcibr_rrb_autoalloc(pcibr_soft, slot, min_rrbs - have_rrbs);
-		}
-	    }
-#if PCIBR_ATE_DEBUG
-	    printk("pcibr_dmamap_alloc: using direct64\n");
-#endif
-	    return pcibr_dmamap;
-	}
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_dmamap_alloc: unable to use direct64\n");
-#endif
-	flags &= ~PCIIO_DMA_A64;
-    }
-    if (flags & PCIIO_FIXED) {
-	/* warning: mappings may fail later,
-	 * if direct32 can't get to the address.
-	 */
-	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_D32_BITS)) {
-	    /* User desires DIRECT A32 operations,
-	     * and the attributes of the DMA are
-	     * consistent with any previous DMA
-	     * mappings using shared resources.
-	     * Mapping calls may fail if target
-	     * is outside the direct32 range.
-	     */
-#if PCIBR_ATE_DEBUG
-	    printk("pcibr_dmamap_alloc: using direct32\n");
-#endif
-	    pcibr_dmamap->bd_flags = flags;
-	    pcibr_dmamap->bd_xio_addr = pcibr_soft->bs_dir_xbase;
-	    pcibr_dmamap->bd_pci_addr = PCI32_DIRECT_BASE;
-	    return pcibr_dmamap;
-	}
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_dmamap_alloc: unable to use direct32\n");
-#endif
-	/* If the user demands FIXED and we can't
-	 * give it to him, fail.
-	 */
-	xtalk_dmamap_free(xtalk_dmamap);
-#ifdef IRIX
-	DEL(pcibr_dmamap);
-#else
-	free_pciio_dmamap(pcibr_dmamap);
-#endif
-	return 0;
-    }
-    /*
-     * Allocate Address Translation Entries from the mapping RAM.
-     * Unless the PCIBR_NO_ATE_ROUNDUP flag is specified,
-     * the maximum number of ATEs is based on the worst-case
-     * scenario, where the requested target is in the
-     * last byte of an ATE; thus, mapping IOPGSIZE+2
-     * does end up requiring three ATEs.
-     */
-    if (!(flags & PCIBR_NO_ATE_ROUNDUP)) {
-	ate_count = IOPG((IOPGSIZE - 1)	/* worst case start offset */
-		     +req_size_max	/* max mapping bytes */
-		     - 1) + 1;		/* round UP */
-    } else {	/* assume requested target is page aligned */
-	ate_count = IOPG(req_size_max   /* max mapping bytes */
-		     - 1) + 1;		/* round UP */
-    }
-
-    ate_index = pcibr_ate_alloc(pcibr_soft, ate_count);
-
-    if (ate_index != -1) {
-	if (!pcibr_try_set_device(pcibr_soft, slot, flags, BRIDGE_DEV_PMU_BITS)) {
-	    bridge_ate_t            ate_proto;
-	    int                     have_rrbs;
-	    int                     min_rrbs;
-
-#if PCIBR_ATE_DEBUG
-	    printk("pcibr_dmamap_alloc: using PMU\n");
-#endif
-
-	    ate_proto = pcibr_flags_to_ate(flags);
-
-	    pcibr_dmamap->bd_flags = flags;
-	    pcibr_dmamap->bd_pci_addr =
-		PCI32_MAPPED_BASE + IOPGSIZE * ate_index;
-	    /*
-	     * for xbridge the byte-swap bit == bit 29 of PCI address
-	     */
-	    if (pcibr_soft->bs_xbridge) {
-		    if (flags & PCIIO_BYTE_STREAM)
-			    ATE_SWAP_ON(pcibr_dmamap->bd_pci_addr);
-		    /*
-		     * If swap was set in bss_device in pcibr_endian_set()
-		     * we need to change the address bit.
-		     */
-		    if (pcibr_soft->bs_slot[slot].bss_device & 
-							BRIDGE_DEV_SWAP_PMU)
-			    ATE_SWAP_ON(pcibr_dmamap->bd_pci_addr);
-		    if (flags & PCIIO_WORD_VALUES)
-			    ATE_SWAP_OFF(pcibr_dmamap->bd_pci_addr);
-	    }
-	    pcibr_dmamap->bd_xio_addr = 0;
-	    pcibr_dmamap->bd_ate_ptr = pcibr_ate_addr(pcibr_soft, ate_index);
-	    pcibr_dmamap->bd_ate_index = ate_index;
-	    pcibr_dmamap->bd_ate_count = ate_count;
-	    pcibr_dmamap->bd_ate_proto = ate_proto;
-
-	    /* Make sure we have an RRB (or two).
-	     */
-	    if (!(pcibr_soft->bs_rrb_fixed & (1 << slot))) {
-		have_rrbs = pcibr_soft->bs_rrb_valid[slot];
-		if (have_rrbs < 2) {
-		    if (ate_proto & ATE_PREF)
-			min_rrbs = 2;
-		    else
-			min_rrbs = 1;
-		    if (have_rrbs < min_rrbs)
-			do_pcibr_rrb_autoalloc(pcibr_soft, slot, min_rrbs - have_rrbs);
-		}
-	    }
-	    if (ate_index >= pcibr_soft->bs_int_ate_size && 
-				!pcibr_soft->bs_xbridge) {
-		bridge_t               *bridge = pcibr_soft->bs_base;
-		volatile unsigned      *cmd_regp;
-		unsigned                cmd_reg;
-		unsigned long           s;
-
-		pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_SSRAM;
-
-		s = pcibr_lock(pcibr_soft);
-		cmd_regp = &(bridge->
-			     b_type0_cfg_dev[slot].
-			     l[PCI_CFG_COMMAND / 4]);
-		cmd_reg = *cmd_regp;
-		pcibr_soft->bs_slot[slot].bss_cmd_pointer = cmd_regp;
-		pcibr_soft->bs_slot[slot].bss_cmd_shadow = cmd_reg;
-		pcibr_unlock(pcibr_soft, s);
-	    }
-	    return pcibr_dmamap;
-	}
-#if PCIBR_ATE_DEBUG
-	printk("pcibr_dmamap_alloc: unable to use PMU\n");
-#endif
-	pcibr_ate_free(pcibr_soft, ate_index, ate_count);
-    }
-    /* total failure: sorry, you just can't
-     * get from here to there that way.
-     */
-#if PCIBR_ATE_DEBUG
-    printk("pcibr_dmamap_alloc: complete failure.\n");
-#endif
-    xtalk_dmamap_free(xtalk_dmamap);
-#ifdef IRIX
-    DEL(pcibr_dmamap);
-#else
-    free_pciio_dmamap(pcibr_dmamap);
-#endif
-    return 0;
-}
-
-/*ARGSUSED */
-void
-pcibr_dmamap_free(pcibr_dmamap_t pcibr_dmamap)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
-    pciio_slot_t            slot = pcibr_dmamap->bd_slot;
-
-    unsigned                flags = pcibr_dmamap->bd_flags;
-
-    /* Make sure that bss_ext_ates_active
-     * is properly kept up to date.
-     */
-
-    if (PCIBR_DMAMAP_BUSY & flags)
-	if (PCIBR_DMAMAP_SSRAM & flags)
-	    atomic_dec(&(pcibr_soft->bs_slot[slot]. bss_ext_ates_active));
-
-    xtalk_dmamap_free(pcibr_dmamap->bd_xtalk);
-
-    if (pcibr_dmamap->bd_flags & PCIIO_DMA_A64) {
-	pcibr_release_device(pcibr_soft, slot, BRIDGE_DEV_D64_BITS);
-    }
-    if (pcibr_dmamap->bd_ate_count) {
-	pcibr_ate_free(pcibr_dmamap->bd_soft,
-		       pcibr_dmamap->bd_ate_index,
-		       pcibr_dmamap->bd_ate_count);
-	pcibr_release_device(pcibr_soft, slot, BRIDGE_DEV_PMU_BITS);
-    }
-#ifdef IRIX
-    DEL(pcibr_dmamap);
-#else
-    free_pciio_dmamap(pcibr_dmamap);
-#endif
-}
-
-/*
- * Setup an Address Translation Entry as specified.  Use either the Bridge
- * internal maps or the external map RAM, as appropriate.
- */
-LOCAL bridge_ate_p
-pcibr_ate_addr(pcibr_soft_t pcibr_soft,
-	       int ate_index)
-{
-    bridge_t *bridge = pcibr_soft->bs_base;
-
-    return (ate_index < pcibr_soft->bs_int_ate_size)
-	? &(bridge->b_int_ate_ram[ate_index].wr)
-	: &(bridge->b_ext_ate_ram[ate_index]);
-}
-
-/*
- *    pcibr_addr_xio_to_pci: given a PIO range, hand
- *      back the corresponding base PCI MEM address;
- *      this is used to short-circuit DMA requests that
- *      loop back onto this PCI bus.
- */
-LOCAL iopaddr_t
-pcibr_addr_xio_to_pci(pcibr_soft_t soft,
-		      iopaddr_t xio_addr,
-		      size_t req_size)
-{
-    iopaddr_t               xio_lim = xio_addr + req_size - 1;
-    iopaddr_t               pci_addr;
-    pciio_slot_t            slot;
-
-    if ((xio_addr >= BRIDGE_PCI_MEM32_BASE) &&
-	(xio_lim <= BRIDGE_PCI_MEM32_LIMIT)) {
-	pci_addr = xio_addr - BRIDGE_PCI_MEM32_BASE;
-	return pci_addr;
-    }
-    if ((xio_addr >= BRIDGE_PCI_MEM64_BASE) &&
-	(xio_lim <= BRIDGE_PCI_MEM64_LIMIT)) {
-	pci_addr = xio_addr - BRIDGE_PCI_MEM64_BASE;
-	return pci_addr;
-    }
-    for (slot = 0; slot < 8; ++slot)
-	if ((xio_addr >= BRIDGE_DEVIO(slot)) &&
-	    (xio_lim < BRIDGE_DEVIO(slot + 1))) {
-	    bridgereg_t             dev;
-
-	    dev = soft->bs_slot[slot].bss_device;
-	    pci_addr = dev & BRIDGE_DEV_OFF_MASK;
-	    pci_addr <<= BRIDGE_DEV_OFF_ADDR_SHFT;
-	    pci_addr += xio_addr - BRIDGE_DEVIO(slot);
-	    return (dev & BRIDGE_DEV_DEV_IO_MEM) ? pci_addr : PCI_NOWHERE;
-	}
-    return 0;
-}
-
-/* We are starting to get more complexity
- * surrounding writing ATEs, so pull
- * the writing code into this new function.
- */
-
-#if PCIBR_FREEZE_TIME
-#define	ATE_FREEZE()	s = ate_freeze(pcibr_dmamap, &freeze_time, cmd_regs)
-#else
-#define	ATE_FREEZE()	s = ate_freeze(pcibr_dmamap, cmd_regs)
-#endif
-
-LOCAL unsigned
-ate_freeze(pcibr_dmamap_t pcibr_dmamap,
-#if PCIBR_FREEZE_TIME
-	   unsigned *freeze_time_ptr,
-#endif
-	   unsigned *cmd_regs)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
-#ifdef LATER
-    int                     dma_slot = pcibr_dmamap->bd_slot;
-#endif
-    int                     ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM;
-    int                     slot;
-
-    unsigned long           s;
-    unsigned                cmd_reg;
-    volatile unsigned      *cmd_lwa;
-    unsigned                cmd_lwd;
-
-    if (!ext_ates)
-	return 0;
-
-    /* Bridge Hardware Bug WAR #484930:
-     * Bridge can't handle updating External ATEs
-     * while DMA is occurring that uses External ATEs,
-     * even if the particular ATEs involved are disjoint.
-     */
-
-    /* need to prevent anyone else from
-     * unfreezing the grant while we
-     * are working; also need to prevent
-     * this thread from being interrupted
-     * to keep PCI grant freeze time
-     * at an absolute minimum.
-     */
-    s = pcibr_lock(pcibr_soft);
-
-#ifdef LATER
-    /* just in case pcibr_dmamap_done was not called */
-    if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_BUSY) {
-	pcibr_dmamap->bd_flags &= ~PCIBR_DMAMAP_BUSY;
-	if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM)
-	    atomic_dec(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active));
-	xtalk_dmamap_done(pcibr_dmamap->bd_xtalk);
-    }
-#endif	/* LATER */
-#if PCIBR_FREEZE_TIME
-    *freeze_time_ptr = get_timestamp();
-#endif
-
-    cmd_lwa = 0;
-    for (slot = 0; slot < 8; ++slot)
-	if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) {
-	    cmd_reg = pcibr_soft->
-		bs_slot[slot].
-		bss_cmd_shadow;
-	    if (cmd_reg & PCI_CMD_BUS_MASTER) {
-		cmd_lwa = pcibr_soft->
-		    bs_slot[slot].
-		    bss_cmd_pointer;
-		cmd_lwd = cmd_reg ^ PCI_CMD_BUS_MASTER;
-		cmd_lwa[0] = cmd_lwd;
-	    }
-	    cmd_regs[slot] = cmd_reg;
-	} else
-	    cmd_regs[slot] = 0;
-
-    if (cmd_lwa) {
-	    bridge_t	*bridge = pcibr_soft->bs_base;
-
-	    /* Read the last master bit that has been cleared. This PIO read
-	     * on the PCI bus is to ensure the completion of any DMAs that
-	     * are due to bus requests issued by PCI devices before the
-	     * clearing of master bits.
-	     */
-	    cmd_lwa[0];
-
-	    /* Flush all the write buffers in the bridge */
-	    for (slot = 0; slot < 8; ++slot)
-		    if (atomic_read(&pcibr_soft->bs_slot[slot].bss_ext_ates_active)) {
-			    /* Flush the write buffer associated with this
-			     * PCI device which might be using dma map RAM.
-			     */
-			    bridge->b_wr_req_buf[slot].reg;
-		    }
-    }
-    return s;
-}
-
-#define	ATE_WRITE()    ate_write(ate_ptr, ate_count, ate)
-
-LOCAL void
-ate_write(bridge_ate_p ate_ptr,
-	  int ate_count,
-	  bridge_ate_t ate)
-{
-    while (ate_count-- > 0) {
-	*ate_ptr++ = ate;
-	ate += IOPGSIZE;
-    }
-}
-
-
-#if PCIBR_FREEZE_TIME
-#define	ATE_THAW()	ate_thaw(pcibr_dmamap, ate_index, ate, ate_total, freeze_time, cmd_regs, s)
-#else
-#define	ATE_THAW()	ate_thaw(pcibr_dmamap, ate_index, cmd_regs, s)
-#endif
-
-LOCAL void
-ate_thaw(pcibr_dmamap_t pcibr_dmamap,
-	 int ate_index,
-#if PCIBR_FREEZE_TIME
-	 bridge_ate_t ate,
-	 int ate_total,
-	 unsigned freeze_time_start,
-#endif
-	 unsigned *cmd_regs,
-	 unsigned s)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_dmamap->bd_soft;
-    int                     dma_slot = pcibr_dmamap->bd_slot;
-    int                     slot;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    int                     ext_ates = pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM;
-
-    unsigned                cmd_reg;
-
-#if PCIBR_FREEZE_TIME
-    unsigned                freeze_time;
-    static unsigned         max_freeze_time = 0;
-    static unsigned         max_ate_total;
-#endif
-
-    if (!ext_ates)
-	return;
-
-    /* restore cmd regs */
-    for (slot = 0; slot < 8; ++slot)
-	if ((cmd_reg = cmd_regs[slot]) & PCI_CMD_BUS_MASTER)
-	    bridge->b_type0_cfg_dev[slot].l[PCI_CFG_COMMAND / 4] = cmd_reg;
-
-    pcibr_dmamap->bd_flags |= PCIBR_DMAMAP_BUSY;
-    atomic_inc(&(pcibr_soft->bs_slot[dma_slot]. bss_ext_ates_active));
-
-#if PCIBR_FREEZE_TIME
-    freeze_time = get_timestamp() - freeze_time_start;
-
-    if ((max_freeze_time < freeze_time) ||
-	(max_ate_total < ate_total)) {
-	if (max_freeze_time < freeze_time)
-	    max_freeze_time = freeze_time;
-	if (max_ate_total < ate_total)
-	    max_ate_total = ate_total;
-	pcibr_unlock(pcibr_soft, s);
-	printk("%s: pci freeze time %d usec for %d ATEs\n"
-		"\tfirst ate: %R\n",
-		pcibr_soft->bs_name,
-		freeze_time * 1000 / 1250,
-		ate_total,
-		ate, ate_bits);
-    } else
-#endif
-	pcibr_unlock(pcibr_soft, s);
-}
-
-/*ARGSUSED */
-iopaddr_t
-pcibr_dmamap_addr(pcibr_dmamap_t pcibr_dmamap,
-		  paddr_t paddr,
-		  size_t req_size)
-{
-    pcibr_soft_t            pcibr_soft;
-    iopaddr_t               xio_addr;
-    xwidgetnum_t            xio_port;
-    iopaddr_t               pci_addr;
-    unsigned                flags;
-
-    ASSERT(pcibr_dmamap != NULL);
-    ASSERT(req_size > 0);
-    ASSERT(req_size <= pcibr_dmamap->bd_max_size);
-
-    pcibr_soft = pcibr_dmamap->bd_soft;
-
-    flags = pcibr_dmamap->bd_flags;
-
-    xio_addr = xtalk_dmamap_addr(pcibr_dmamap->bd_xtalk, paddr, req_size);
-    if (XIO_PACKED(xio_addr)) {
-	xio_port = XIO_PORT(xio_addr);
-	xio_addr = XIO_ADDR(xio_addr);
-    } else
-	xio_port = pcibr_dmamap->bd_xio_port;
-
-    /* If this DMA is to an address that
-     * refers back to this Bridge chip,
-     * reduce it back to the correct
-     * PCI MEM address.
-     */
-    if (xio_port == pcibr_soft->bs_xid) {
-	pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, req_size);
-    } else if (flags & PCIIO_DMA_A64) {
-	/* A64 DMA:
-	 * always use 64-bit direct mapping,
-	 * which always works.
-	 * Device(x) was set up during
-	 * dmamap allocation.
-	 */
-
-	/* attributes are already bundled up into bd_pci_addr.
-	 */
-	pci_addr = pcibr_dmamap->bd_pci_addr
-	    | ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT)
-	    | xio_addr;
-
-	/* Bridge Hardware WAR #482836:
-	 * If the transfer is not cache aligned
-	 * and the Bridge Rev is <= B, force
-	 * prefetch to be off.
-	 */
-	if (flags & PCIBR_NOPREFETCH)
-	    pci_addr &= ~PCI64_ATTR_PREF;
-
-#if DEBUG && PCIBR_DMA_DEBUG
-	printk("pcibr_dmamap_addr (direct64):\n"
-		"\twanted paddr [0x%x..0x%x]\n"
-		"\tXIO port 0x%x offset 0x%x\n"
-		"\treturning PCI 0x%x\n",
-		paddr, paddr + req_size - 1,
-		xio_port, xio_addr, pci_addr);
-#endif
-    } else if (flags & PCIIO_FIXED) {
-	/* A32 direct DMA:
-	 * always use 32-bit direct mapping,
-	 * which may fail.
-	 * Device(x) was set up during
-	 * dmamap allocation.
-	 */
-
-	if (xio_port != pcibr_soft->bs_dir_xport)
-	    pci_addr = 0;		/* wrong DIDN */
-	else if (xio_addr < pcibr_dmamap->bd_xio_addr)
-	    pci_addr = 0;		/* out of range */
-	else if ((xio_addr + req_size) >
-		 (pcibr_dmamap->bd_xio_addr + BRIDGE_DMA_DIRECT_SIZE))
-	    pci_addr = 0;		/* out of range */
-	else
-	    pci_addr = pcibr_dmamap->bd_pci_addr +
-		xio_addr - pcibr_dmamap->bd_xio_addr;
-
-#if DEBUG && PCIBR_DMA_DEBUG
-	printk("pcibr_dmamap_addr (direct32):\n"
-		"\twanted paddr [0x%x..0x%x]\n"
-		"\tXIO port 0x%x offset 0x%x\n"
-		"\treturning PCI 0x%x\n",
-		paddr, paddr + req_size - 1,
-		xio_port, xio_addr, pci_addr);
-#endif
-    } else {
-	bridge_t               *bridge = pcibr_soft->bs_base;
-	iopaddr_t               offset = IOPGOFF(xio_addr);
-	bridge_ate_t            ate_proto = pcibr_dmamap->bd_ate_proto;
-	int                     ate_count = IOPG(offset + req_size - 1) + 1;
-
-	int                     ate_index = pcibr_dmamap->bd_ate_index;
-	unsigned                cmd_regs[8];
-	unsigned                s;
-
-#if PCIBR_FREEZE_TIME
-	int                     ate_total = ate_count;
-	unsigned                freeze_time;
-#endif
-
-#if PCIBR_ATE_DEBUG
-	bridge_ate_t            ate_cmp;
-	bridge_ate_p            ate_cptr;
-	unsigned                ate_lo, ate_hi;
-	int                     ate_bad = 0;
-	int                     ate_rbc = 0;
-#endif
-	bridge_ate_p            ate_ptr = pcibr_dmamap->bd_ate_ptr;
-	bridge_ate_t            ate;
-
-	/* Bridge Hardware WAR #482836:
-	 * If the transfer is not cache aligned
-	 * and the Bridge Rev is <= B, force
-	 * prefetch to be off.
-	 */
-	if (flags & PCIBR_NOPREFETCH)
-	    ate_proto &= ~ATE_PREF;
-
-	ate = ate_proto
-	    | (xio_port << ATE_TIDSHIFT)
-	    | (xio_addr - offset);
-
-	pci_addr = pcibr_dmamap->bd_pci_addr + offset;
-
-	/* Fill in our mapping registers
-	 * with the appropriate xtalk data,
-	 * and hand back the PCI address.
-	 */
-
-	ASSERT(ate_count > 0);
-	if (ate_count <= pcibr_dmamap->bd_ate_count) {
-		ATE_FREEZE();
-		ATE_WRITE();
-		ATE_THAW();
-		bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
-	} else {
-		/* The number of ATE's required is greater than the number
-		 * allocated for this map. One way this can happen is if
-		 * pcibr_dmamap_alloc() was called with the PCIBR_NO_ATE_ROUNDUP
-		 * flag, and then when that map is used (right now), the
-		 * target address tells us we really did need to roundup.
-		 * The other possibility is that the map is just plain too
-		 * small to handle the requested target area.
-		 */
-#if PCIBR_ATE_DEBUG
-		printk(KERN_WARNING   "pcibr_dmamap_addr :\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\tate_count 0x%x bd_ate_count 0x%x\n"
-			"\tATE's required > number allocated\n",
-			paddr, paddr + req_size - 1,
-			ate_count, pcibr_dmamap->bd_ate_count);
-#endif
-		pci_addr = 0;
-	}
-
-    }
-    return pci_addr;
-}
-
-/*ARGSUSED */
-alenlist_t
-pcibr_dmamap_list(pcibr_dmamap_t pcibr_dmamap,
-		  alenlist_t palenlist,
-		  unsigned flags)
-{
-    pcibr_soft_t            pcibr_soft;
-    bridge_t               *bridge=NULL;
-
-    unsigned                al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
-    int                     inplace = flags & PCIIO_INPLACE;
-
-    alenlist_t              pciio_alenlist = 0;
-    alenlist_t              xtalk_alenlist;
-    size_t                  length;
-    iopaddr_t               offset;
-    unsigned                direct64;
-    int                     ate_index = 0;
-    int                     ate_count = 0;
-    int                     ate_total = 0;
-    bridge_ate_p            ate_ptr = (bridge_ate_p)0;
-    bridge_ate_t            ate_proto = (bridge_ate_t)0;
-    bridge_ate_t            ate_prev;
-    bridge_ate_t            ate;
-    alenaddr_t              xio_addr;
-    xwidgetnum_t            xio_port;
-    iopaddr_t               pci_addr;
-    alenaddr_t              new_addr;
-
-    unsigned                cmd_regs[8];
-    unsigned                s = 0;
-
-#if PCIBR_FREEZE_TIME
-    unsigned                freeze_time;
-#endif
-    int			    ate_freeze_done = 0;	/* To pair ATE_THAW
-							 * with an ATE_FREEZE
-							 */
-
-    pcibr_soft = pcibr_dmamap->bd_soft;
-
-    xtalk_alenlist = xtalk_dmamap_list(pcibr_dmamap->bd_xtalk, palenlist,
-				       flags & DMAMAP_FLAGS);
-    if (!xtalk_alenlist)
-	goto fail;
-
-    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
-
-    if (inplace) {
-	pciio_alenlist = xtalk_alenlist;
-    } else {
-	pciio_alenlist = alenlist_create(al_flags);
-	if (!pciio_alenlist)
-	    goto fail;
-    }
-
-    direct64 = pcibr_dmamap->bd_flags & PCIIO_DMA_A64;
-    if (!direct64) {
-	bridge = pcibr_soft->bs_base;
-	ate_ptr = pcibr_dmamap->bd_ate_ptr;
-	ate_index = pcibr_dmamap->bd_ate_index;
-	ate_proto = pcibr_dmamap->bd_ate_proto;
-	ATE_FREEZE();
-	ate_freeze_done = 1;	/* Remember that we need to do an ATE_THAW */
-    }
-    pci_addr = pcibr_dmamap->bd_pci_addr;
-
-    ate_prev = 0;			/* matches no valid ATEs */
-    while (ALENLIST_SUCCESS ==
-	   alenlist_get(xtalk_alenlist, NULL, 0,
-			&xio_addr, &length, al_flags)) {
-	if (XIO_PACKED(xio_addr)) {
-	    xio_port = XIO_PORT(xio_addr);
-	    xio_addr = XIO_ADDR(xio_addr);
-	} else
-	    xio_port = pcibr_dmamap->bd_xio_port;
-
-	if (xio_port == pcibr_soft->bs_xid) {
-	    new_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, length);
-	    if (new_addr == PCI_NOWHERE)
-		goto fail;
-	} else if (direct64) {
-	    new_addr = pci_addr | xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-
-	    /* Bridge Hardware WAR #482836:
-	     * If the transfer is not cache aligned
-	     * and the Bridge Rev is <= B, force
-	     * prefetch to be off.
-	     */
-	    if (flags & PCIBR_NOPREFETCH)
-		new_addr &= ~PCI64_ATTR_PREF;
-
-	} else {
-	    /* calculate the ate value for
-	     * the first address. If it
-	     * matches the previous
-	     * ATE written (ie. we had
-	     * multiple blocks in the
-	     * same IOPG), then back up
-	     * and reuse that ATE.
-	     *
-	     * We are NOT going to
-	     * aggressively try to
-	     * reuse any other ATEs.
-	     */
-	    offset = IOPGOFF(xio_addr);
-	    ate = ate_proto
-		| (xio_port << ATE_TIDSHIFT)
-		| (xio_addr - offset);
-	    if (ate == ate_prev) {
-#if PCIBR_ATE_DEBUG
-		printk("pcibr_dmamap_list: ATE share\n");
-#endif
-		ate_ptr--;
-		ate_index--;
-		pci_addr -= IOPGSIZE;
-	    }
-	    new_addr = pci_addr + offset;
-
-	    /* Fill in the hardware ATEs
-	     * that contain this block.
-	     */
-	    ate_count = IOPG(offset + length - 1) + 1;
-	    ate_total += ate_count;
-
-	    /* Ensure that this map contains enough ATE's */
-	    if (ate_total > pcibr_dmamap->bd_ate_count) {
-#if PCIBR_ATE_DEBUG
-		printk(KERN_WARNING   "pcibr_dmamap_list :\n"
-			"\twanted xio_addr [0x%x..0x%x]\n"
-			"\tate_total 0x%x bd_ate_count 0x%x\n"
-			"\tATE's required > number allocated\n",
-			xio_addr, xio_addr + length - 1,
-			ate_total, pcibr_dmamap->bd_ate_count);
-#endif
-		goto fail;
-	    }
-
-	    ATE_WRITE();
-
-	    ate_index += ate_count;
-	    ate_ptr += ate_count;
-
-	    ate_count <<= IOPFNSHIFT;
-	    ate += ate_count;
-	    pci_addr += ate_count;
-	}
-
-	/* write the PCI DMA address
-	 * out to the scatter-gather list.
-	 */
-	if (inplace) {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_replace(pciio_alenlist, NULL,
-				 &new_addr, &length, al_flags))
-		goto fail;
-	} else {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_append(pciio_alenlist,
-				new_addr, length, al_flags))
-		goto fail;
-	}
-    }
-    if (!inplace)
-	alenlist_done(xtalk_alenlist);
-
-    /* Reset the internal cursor of the alenlist to be returned back
-     * to the caller.
-     */
-    alenlist_cursor_init(pciio_alenlist, 0, NULL);
-
-
-    /* In case an ATE_FREEZE was done do the ATE_THAW to unroll all the
-     * changes that ATE_FREEZE has done to implement the external SSRAM
-     * bug workaround.
-     */
-    if (ate_freeze_done) {
-	ATE_THAW();
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    }
-    return pciio_alenlist;
-
-  fail:
-    /* There are various points of failure after doing an ATE_FREEZE
-     * We need to do an ATE_THAW. Otherwise the ATEs are locked forever.
-     * The decision to do an ATE_THAW needs to be based on whether a
-     * an ATE_FREEZE was done before.
-     */
-    if (ate_freeze_done) {
-	ATE_THAW();
-	bridge->b_wid_tflush;
-    }
-    if (pciio_alenlist && !inplace)
-	alenlist_destroy(pciio_alenlist);
-    return 0;
-}
-
-/*ARGSUSED */
-void
-pcibr_dmamap_done(pcibr_dmamap_t pcibr_dmamap)
-{
-    /*
-     * We could go through and invalidate ATEs here;
-     * for performance reasons, we don't.
-     * We also don't enforce the strict alternation
-     * between _addr/_list and _done, but Hub does.
-     */
-
-    if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_BUSY) {
-	pcibr_dmamap->bd_flags &= ~PCIBR_DMAMAP_BUSY;
-
-	if (pcibr_dmamap->bd_flags & PCIBR_DMAMAP_SSRAM)
-	    atomic_dec(&(pcibr_dmamap->bd_soft->bs_slot[pcibr_dmamap->bd_slot]. bss_ext_ates_active));
-    }
-
-    xtalk_dmamap_done(pcibr_dmamap->bd_xtalk);
-}
-
-
-/*
- * For each bridge, the DIR_OFF value in the Direct Mapping Register
- * determines the PCI to Crosstalk memory mapping to be used for all
- * 32-bit Direct Mapping memory accesses. This mapping can be to any
- * node in the system. This function will return that compact node id.
- */
-
-/*ARGSUSED */
-cnodeid_t
-pcibr_get_dmatrans_node(devfs_handle_t pconn_vhdl)
-{
-
-	pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
-	pcibr_soft_t	pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-	return(NASID_TO_COMPACT_NODEID(NASID_GET(pcibr_soft->bs_dir_xbase)));
-}
-
-/*ARGSUSED */
-iopaddr_t
-pcibr_dmatrans_addr(devfs_handle_t pconn_vhdl,
-		    device_desc_t dev_desc,
-		    paddr_t paddr,
-		    size_t req_size,
-		    unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
-
-    xwidgetnum_t            xio_port;
-    iopaddr_t               xio_addr;
-    iopaddr_t               pci_addr;
-
-    int                     have_rrbs;
-    int                     min_rrbs;
-
-    /* merge in forced flags */
-    flags |= pcibr_soft->bs_dma_flags;
-
-    xio_addr = xtalk_dmatrans_addr(xconn_vhdl, 0, paddr, req_size,
-				   flags & DMAMAP_FLAGS);
-
-    if (!xio_addr) {
-#if PCIBR_DMA_DEBUG
-	printk("pcibr_dmatrans_addr:\n"
-		"\tpciio connection point %v\n"
-		"\txtalk connection point %v\n"
-		"\twanted paddr [0x%x..0x%x]\n"
-		"\txtalk_dmatrans_addr returned 0x%x\n",
-		pconn_vhdl, xconn_vhdl,
-		paddr, paddr + req_size - 1,
-		xio_addr);
-#endif
-	return 0;
-    }
-    /*
-     * find which XIO port this goes to.
-     */
-    if (XIO_PACKED(xio_addr)) {
-	if (xio_addr == XIO_NOWHERE) {
-#if PCIBR_DMA_DEBUG
-	    printk("pcibr_dmatrans_addr:\n"
-		    "\tpciio connection point %v\n"
-		    "\txtalk connection point %v\n"
-		    "\twanted paddr [0x%x..0x%x]\n"
-		    "\txtalk_dmatrans_addr returned 0x%x\n",
-		    pconn_vhdl, xconn_vhdl,
-		    paddr, paddr + req_size - 1,
-		    xio_addr);
-#endif
-	    return 0;
-	}
-	xio_port = XIO_PORT(xio_addr);
-	xio_addr = XIO_ADDR(xio_addr);
-
-    } else
-	xio_port = pcibr_soft->bs_mxid;
-
-    /*
-     * If this DMA comes back to us,
-     * return the PCI MEM address on
-     * which it would land, or NULL
-     * if the target is something
-     * on bridge other than PCI MEM.
-     */
-    if (xio_port == pcibr_soft->bs_xid) {
-	pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, req_size);
-	return pci_addr;
-    }
-    /* If the caller can use A64, try to
-     * satisfy the request with the 64-bit
-     * direct map. This can fail if the
-     * configuration bits in Device(x)
-     * conflict with our flags.
-     */
-
-    if (flags & PCIIO_DMA_A64) {
-	pci_addr = slotp->bss_d64_base;
-	if (!(flags & PCIBR_VCHAN1))
-	    flags |= PCIBR_VCHAN0;
-	if ((pci_addr != PCIBR_D64_BASE_UNSET) &&
-	    (flags == slotp->bss_d64_flags)) {
-
-	    pci_addr |= xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-
-#if DEBUG && PCIBR_DMA_DEBUG
-#if HWG_PERF_CHECK
-	    if (xio_addr != 0x20000000)
-#endif
-		printk("pcibr_dmatrans_addr: [reuse]\n"
-			"\tpciio connection point %v\n"
-			"\txtalk connection point %v\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\txtalk_dmatrans_addr returned 0x%x\n"
-			"\tdirect 64bit address is 0x%x\n",
-			pconn_vhdl, xconn_vhdl,
-			paddr, paddr + req_size - 1,
-			xio_addr, pci_addr);
-#endif
-	    return (pci_addr);
-	}
-	if (!pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS)) {
-	    pci_addr = pcibr_flags_to_d64(flags, pcibr_soft);
-	    slotp->bss_d64_flags = flags;
-	    slotp->bss_d64_base = pci_addr;
-	    pci_addr |= xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-
-	    /* Make sure we have an RRB (or two).
-	     */
-	    if (!(pcibr_soft->bs_rrb_fixed & (1 << pciio_slot))) {
-		if (flags & PCIBR_VCHAN1)
-		    pciio_slot += PCIBR_RRB_SLOT_VIRTUAL;
-		have_rrbs = pcibr_soft->bs_rrb_valid[pciio_slot];
-		if (have_rrbs < 2) {
-		    if (pci_addr & PCI64_ATTR_PREF)
-			min_rrbs = 2;
-		    else
-			min_rrbs = 1;
-		    if (have_rrbs < min_rrbs)
-			do_pcibr_rrb_autoalloc(pcibr_soft, pciio_slot, min_rrbs - have_rrbs);
-		}
-	    }
-#if PCIBR_DMA_DEBUG
-#if HWG_PERF_CHECK
-	    if (xio_addr != 0x20000000)
-#endif
-		printk("pcibr_dmatrans_addr:\n"
-			"\tpciio connection point %v\n"
-			"\txtalk connection point %v\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\txtalk_dmatrans_addr returned 0x%x\n"
-			"\tdirect 64bit address is 0x%x\n"
-			"\tnew flags: 0x%x\n",
-			pconn_vhdl, xconn_vhdl,
-			paddr, paddr + req_size - 1,
-			xio_addr, pci_addr, (uint64_t) flags);
-#endif
-	    return (pci_addr);
-	}
-	/* our flags conflict with Device(x).
-	 */
-	flags = flags
-	    & ~PCIIO_DMA_A64
-	    & ~PCIBR_VCHAN0
-	    ;
-
-#if PCIBR_DMA_DEBUG
-	printk("pcibr_dmatrans_addr:\n"
-		"\tpciio connection point %v\n"
-		"\txtalk connection point %v\n"
-		"\twanted paddr [0x%x..0x%x]\n"
-		"\txtalk_dmatrans_addr returned 0x%x\n"
-		"\tUnable to set Device(x) bits for Direct-64\n",
-		pconn_vhdl, xconn_vhdl,
-		paddr, paddr + req_size - 1,
-		xio_addr);
-#endif
-    }
-    /* Try to satisfy the request with the 32-bit direct
-     * map. This can fail if the configuration bits in
-     * Device(x) conflict with our flags, or if the
-     * target address is outside where DIR_OFF points.
-     */
-    {
-	size_t                  map_size = 1ULL << 31;
-	iopaddr_t               xio_base = pcibr_soft->bs_dir_xbase;
-	iopaddr_t               offset = xio_addr - xio_base;
-	iopaddr_t               endoff = req_size + offset;
-
-	if ((req_size > map_size) ||
-	    (xio_addr < xio_base) ||
-	    (xio_port != pcibr_soft->bs_dir_xport) ||
-	    (endoff > map_size)) {
-#if PCIBR_DMA_DEBUG
-	    printk("pcibr_dmatrans_addr:\n"
-		    "\tpciio connection point %v\n"
-		    "\txtalk connection point %v\n"
-		    "\twanted paddr [0x%x..0x%x]\n"
-		    "\txtalk_dmatrans_addr returned 0x%x\n"
-		    "\txio region outside direct32 target\n",
-		    pconn_vhdl, xconn_vhdl,
-		    paddr, paddr + req_size - 1,
-		    xio_addr);
-#endif
-	} else {
-	    pci_addr = slotp->bss_d32_base;
-	    if ((pci_addr != PCIBR_D32_BASE_UNSET) &&
-		(flags == slotp->bss_d32_flags)) {
-
-		pci_addr |= offset;
-
-#if DEBUG && PCIBR_DMA_DEBUG
-		printk("pcibr_dmatrans_addr: [reuse]\n"
-			"\tpciio connection point %v\n"
-			"\txtalk connection point %v\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\txtalk_dmatrans_addr returned 0x%x\n"
-			"\tmapped via direct32 offset 0x%x\n"
-			"\twill DMA via pci addr 0x%x\n",
-			pconn_vhdl, xconn_vhdl,
-			paddr, paddr + req_size - 1,
-			xio_addr, offset, pci_addr);
-#endif
-		return (pci_addr);
-	    }
-	    if (!pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS)) {
-
-		pci_addr = PCI32_DIRECT_BASE;
-		slotp->bss_d32_flags = flags;
-		slotp->bss_d32_base = pci_addr;
-		pci_addr |= offset;
-
-		/* Make sure we have an RRB (or two).
-		 */
-		if (!(pcibr_soft->bs_rrb_fixed & (1 << pciio_slot))) {
-		    have_rrbs = pcibr_soft->bs_rrb_valid[pciio_slot];
-		    if (have_rrbs < 2) {
-			if (slotp->bss_device & BRIDGE_DEV_PREF)
-			    min_rrbs = 2;
-			else
-			    min_rrbs = 1;
-			if (have_rrbs < min_rrbs)
-			    do_pcibr_rrb_autoalloc(pcibr_soft, pciio_slot, min_rrbs - have_rrbs);
-		    }
-		}
-#if PCIBR_DMA_DEBUG
-#if HWG_PERF_CHECK
-		if (xio_addr != 0x20000000)
-#endif
-		    printk("pcibr_dmatrans_addr:\n"
-			    "\tpciio connection point %v\n"
-			    "\txtalk connection point %v\n"
-			    "\twanted paddr [0x%x..0x%x]\n"
-			    "\txtalk_dmatrans_addr returned 0x%x\n"
-			    "\tmapped via direct32 offset 0x%x\n"
-			    "\twill DMA via pci addr 0x%x\n"
-			    "\tnew flags: 0x%x\n",
-			    pconn_vhdl, xconn_vhdl,
-			    paddr, paddr + req_size - 1,
-			    xio_addr, offset, pci_addr, (uint64_t) flags);
-#endif
-		return (pci_addr);
-	    }
-	    /* our flags conflict with Device(x).
-	     */
-#if PCIBR_DMA_DEBUG
-	    printk("pcibr_dmatrans_addr:\n"
-		    "\tpciio connection point %v\n"
-		    "\txtalk connection point %v\n"
-		    "\twanted paddr [0x%x..0x%x]\n"
-		    "\txtalk_dmatrans_addr returned 0x%x\n"
-		    "\tUnable to set Device(x) bits for Direct-32\n",
-		    pconn_vhdl, xconn_vhdl,
-		    paddr, paddr + req_size - 1,
-		    xio_addr);
-#endif
-	}
-    }
-
-#if PCIBR_DMA_DEBUG
-    printk("pcibr_dmatrans_addr:\n"
-	    "\tpciio connection point %v\n"
-	    "\txtalk connection point %v\n"
-	    "\twanted paddr [0x%x..0x%x]\n"
-	    "\txtalk_dmatrans_addr returned 0x%x\n"
-	    "\tno acceptable PCI address found or constructable\n",
-	    pconn_vhdl, xconn_vhdl,
-	    paddr, paddr + req_size - 1,
-	    xio_addr);
-#endif
-
-    return 0;
-}
-
-/*ARGSUSED */
-alenlist_t
-pcibr_dmatrans_list(devfs_handle_t pconn_vhdl,
-		    device_desc_t dev_desc,
-		    alenlist_t palenlist,
-		    unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
-    xwidgetnum_t            xio_port;
-
-    alenlist_t              pciio_alenlist = 0;
-    alenlist_t              xtalk_alenlist = 0;
-
-    int                     inplace;
-    unsigned                direct64;
-    unsigned                al_flags;
-
-    iopaddr_t               xio_base;
-    alenaddr_t              xio_addr;
-    size_t                  xio_size;
-
-    size_t                  map_size;
-    iopaddr_t               pci_base;
-    alenaddr_t              pci_addr;
-
-    unsigned                relbits = 0;
-
-    /* merge in forced flags */
-    flags |= pcibr_soft->bs_dma_flags;
-
-    inplace = flags & PCIIO_INPLACE;
-    direct64 = flags & PCIIO_DMA_A64;
-    al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
-
-    if (direct64) {
-	map_size = 1ull << 48;
-	xio_base = 0;
-	pci_base = slotp->bss_d64_base;
-	if ((pci_base != PCIBR_D64_BASE_UNSET) &&
-	    (flags == slotp->bss_d64_flags)) {
-	    /* reuse previous base info */
-	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS) < 0) {
-	    /* DMA configuration conflict */
-	    goto fail;
-	} else {
-	    relbits = BRIDGE_DEV_D64_BITS;
-	    pci_base =
-		pcibr_flags_to_d64(flags, pcibr_soft);
-	}
-    } else {
-	xio_base = pcibr_soft->bs_dir_xbase;
-	map_size = 1ull << 31;
-	pci_base = slotp->bss_d32_base;
-	if ((pci_base != PCIBR_D32_BASE_UNSET) &&
-	    (flags == slotp->bss_d32_flags)) {
-	    /* reuse previous base info */
-	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS) < 0) {
-	    /* DMA configuration conflict */
-	    goto fail;
-	} else {
-	    relbits = BRIDGE_DEV_D32_BITS;
-	    pci_base = PCI32_DIRECT_BASE;
-	}
-    }
-
-    xtalk_alenlist = xtalk_dmatrans_list(xconn_vhdl, 0, palenlist,
-					 flags & DMAMAP_FLAGS);
-    if (!xtalk_alenlist)
-	goto fail;
-
-    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
-
-    if (inplace) {
-	pciio_alenlist = xtalk_alenlist;
-    } else {
-	pciio_alenlist = alenlist_create(al_flags);
-	if (!pciio_alenlist)
-	    goto fail;
-    }
-
-    while (ALENLIST_SUCCESS ==
-	   alenlist_get(xtalk_alenlist, NULL, 0,
-			&xio_addr, &xio_size, al_flags)) {
-
-	/*
-	 * find which XIO port this goes to.
-	 */
-	if (XIO_PACKED(xio_addr)) {
-	    if (xio_addr == XIO_NOWHERE) {
-#if PCIBR_DMA_DEBUG
-		printk("pcibr_dmatrans_addr:\n"
-			"\tpciio connection point %v\n"
-			"\txtalk connection point %v\n"
-			"\twanted paddr [0x%x..0x%x]\n"
-			"\txtalk_dmatrans_addr returned 0x%x\n",
-			pconn_vhdl, xconn_vhdl,
-			paddr, paddr + req_size - 1,
-			xio_addr);
-#endif
-		return 0;
-	    }
-	    xio_port = XIO_PORT(xio_addr);
-	    xio_addr = XIO_ADDR(xio_addr);
-	} else
-	    xio_port = pcibr_soft->bs_mxid;
-
-	/*
-	 * If this DMA comes back to us,
-	 * return the PCI MEM address on
-	 * which it would land, or NULL
-	 * if the target is something
-	 * on bridge other than PCI MEM.
-	 */
-	if (xio_port == pcibr_soft->bs_xid) {
-	    pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, xio_size);
-	    if ( (pci_addr == (alenaddr_t)NULL) )
-		goto fail;
-	} else if (direct64) {
-	    ASSERT(xio_port != 0);
-	    pci_addr = pci_base | xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-	} else {
-	    iopaddr_t               offset = xio_addr - xio_base;
-	    iopaddr_t               endoff = xio_size + offset;
-
-	    if ((xio_size > map_size) ||
-		(xio_addr < xio_base) ||
-		(xio_port != pcibr_soft->bs_dir_xport) ||
-		(endoff > map_size))
-		goto fail;
-
-	    pci_addr = pci_base + (xio_addr - xio_base);
-	}
-
-	/* write the PCI DMA address
-	 * out to the scatter-gather list.
-	 */
-	if (inplace) {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_replace(pciio_alenlist, NULL,
-				 &pci_addr, &xio_size, al_flags))
-		goto fail;
-	} else {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_append(pciio_alenlist,
-				pci_addr, xio_size, al_flags))
-		goto fail;
-	}
-    }
-
-    if (relbits) {
-	if (direct64) {
-	    slotp->bss_d64_flags = flags;
-	    slotp->bss_d64_base = pci_base;
-	} else {
-	    slotp->bss_d32_flags = flags;
-	    slotp->bss_d32_base = pci_base;
-	}
-    }
-    if (!inplace)
-	alenlist_done(xtalk_alenlist);
-
-    /* Reset the internal cursor of the alenlist to be returned back
-     * to the caller.
-     */
-    alenlist_cursor_init(pciio_alenlist, 0, NULL);
-    return pciio_alenlist;
-
-  fail:
-    if (relbits)
-	pcibr_release_device(pcibr_soft, pciio_slot, relbits);
-    if (pciio_alenlist && !inplace)
-	alenlist_destroy(pciio_alenlist);
-    return 0;
-}
-
-void
-pcibr_dmamap_drain(pcibr_dmamap_t map)
-{
-    xtalk_dmamap_drain(map->bd_xtalk);
-}
-
-void
-pcibr_dmaaddr_drain(devfs_handle_t pconn_vhdl,
-		    paddr_t paddr,
-		    size_t bytes)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-
-    xtalk_dmaaddr_drain(xconn_vhdl, paddr, bytes);
-}
-
-void
-pcibr_dmalist_drain(devfs_handle_t pconn_vhdl,
-		    alenlist_t list)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-
-    xtalk_dmalist_drain(xconn_vhdl, list);
-}
-
-/*
- * Get the starting PCIbus address out of the given DMA map.
- * This function is supposed to be used by a close friend of PCI bridge
- * since it relies on the fact that the starting address of the map is fixed at
- * the allocation time in the current implementation of PCI bridge.
- */
-iopaddr_t
-pcibr_dmamap_pciaddr_get(pcibr_dmamap_t pcibr_dmamap)
-{
-    return (pcibr_dmamap->bd_pci_addr);
-}
-
-/*
- *	There are end cases where a deadlock can occur if interrupt 
- *	processing completes and the Bridge b_int_status bit is still set.
- *
- *	One scenerio is if a second PCI interrupt occurs within 60ns of
- *	the previous interrupt being cleared. In this case the Bridge
- *	does not detect the transition, the Bridge b_int_status bit
- *	remains set, and because no transition was detected no interrupt
- *	packet is sent to the Hub/Heart.
- *
- *	A second scenerio is possible when a b_int_status bit is being
- *	shared by multiple devices:
- *						Device #1 generates interrupt
- *						Bridge b_int_status bit set
- *						Device #2 generates interrupt
- *		interrupt processing begins
- *		  ISR for device #1 runs and
- *			clears interrupt
- *						Device #1 generates interrupt
- *		  ISR for device #2 runs and
- *			clears interrupt
- *						(b_int_status bit still set)
- *		interrupt processing completes
- *		  
- *	Interrupt processing is now complete, but an interrupt is still
- *	outstanding for Device #1. But because there was no transition of
- *	the b_int_status bit, no interrupt packet will be generated and
- *	a deadlock will occur.
- *
- *	To avoid these deadlock situations, this function is used
- *	to check if a specific Bridge b_int_status bit is set, and if so,
- *	cause the setting of the corresponding interrupt bit.
- *
- *	On a XBridge (IP35), we do this by writing the appropriate Bridge Force 
- *	Interrupt register.
- */
-void
-pcibr_force_interrupt(pcibr_intr_wrap_t wrap)
-{
-	unsigned	bit;
-	pcibr_soft_t    pcibr_soft = wrap->iw_soft;
-	bridge_t       *bridge = pcibr_soft->bs_base;
-	cpuid_t cpuvertex_to_cpuid(devfs_handle_t vhdl);
-
-	bit = wrap->iw_intr;
-
-	if (pcibr_soft->bs_xbridge) {
-	    bridge->b_force_pin[bit].intr = 1;
-	} else if ((1 << bit) & *wrap->iw_stat) {
-	    cpuid_t	    cpu;
-	    unsigned        intr_bit;
-	    xtalk_intr_t    xtalk_intr =
-				pcibr_soft->bs_intr[bit].bsi_xtalk_intr;
-
-	    intr_bit = (short) xtalk_intr_vector_get(xtalk_intr);
-	    cpu = cpuvertex_to_cpuid(xtalk_intr_cpu_get(xtalk_intr));
-	    REMOTE_CPU_SEND_INTR(cpu, intr_bit);
-	}
-}
-
-/* =====================================================================
- *    INTERRUPT MANAGEMENT
- */
-
-static unsigned
-pcibr_intr_bits(pciio_info_t info,
-		pciio_intr_line_t lines)
-{
-    pciio_slot_t            slot = pciio_info_slot_get(info);
-    unsigned		    bbits = 0;
-
-    /*
-     * Currently favored mapping from PCI
-     * slot number and INTA/B/C/D to Bridge
-     * PCI Interrupt Bit Number:
-     *
-     *     SLOT     A B C D
-     *      0       0 4 0 4
-     *      1       1 5 1 5
-     *      2       2 6 2 6
-     *      3       3 7 3 7
-     *      4       4 0 4 0
-     *      5       5 1 5 1
-     *      6       6 2 6 2
-     *      7       7 3 7 3
-     */
-
-    if (slot < 8) {
-	if (lines & (PCIIO_INTR_LINE_A| PCIIO_INTR_LINE_C))
-	    bbits |= 1 << slot;
-	if (lines & (PCIIO_INTR_LINE_B| PCIIO_INTR_LINE_D))
-	    bbits |= 1 << (slot ^ 4);
-    }
-    return bbits;
-}
-
-
-/*ARGSUSED */
-pcibr_intr_t
-pcibr_intr_alloc(devfs_handle_t pconn_vhdl,
-		 device_desc_t dev_desc,
-		 pciio_intr_line_t lines,
-		 devfs_handle_t owner_dev)
-{
-    pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pcibr_info->f_slot;
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    int                     is_threaded = 0;
-    int                     thread_swlevel;
-
-    xtalk_intr_t           *xtalk_intr_p;
-    pcibr_intr_t           *pcibr_intr_p;
-    pcibr_intr_list_t      *intr_list_p;
-
-    unsigned                pcibr_int_bits;
-    unsigned                pcibr_int_bit;
-    xtalk_intr_t            xtalk_intr = (xtalk_intr_t)0;
-    hub_intr_t		    hub_intr;
-    pcibr_intr_t            pcibr_intr;
-    pcibr_intr_list_t       intr_entry;
-    pcibr_intr_list_t       intr_list;
-    bridgereg_t             int_dev;
-
-#if DEBUG && INTR_DEBUG
-    printk("%v: pcibr_intr_alloc\n"
-	    "%v:%s%s%s%s%s\n",
-	    owner_dev, pconn_vhdl,
-	    !(lines & 15) ? " No INTs?" : "",
-	    lines & 1 ? " INTA" : "",
-	    lines & 2 ? " INTB" : "",
-	    lines & 4 ? " INTC" : "",
-	    lines & 8 ? " INTD" : "");
-#endif
-
-    NEW(pcibr_intr);
-    if (!pcibr_intr)
-	return NULL;
-
-    if (dev_desc) {
-	cpuid_t intr_target_from_desc(device_desc_t, int);
-    } else {
-	extern int default_intr_pri;
-
-	is_threaded = 1; /* PCI interrupts are threaded, by default */
-	thread_swlevel = default_intr_pri;
-    }
-
-    pcibr_intr->bi_dev = pconn_vhdl;
-    pcibr_intr->bi_lines = lines;
-    pcibr_intr->bi_soft = pcibr_soft;
-    pcibr_intr->bi_ibits = 0;		/* bits will be added below */
-    pcibr_intr->bi_flags = is_threaded ? 0 : PCIIO_INTR_NOTHREAD;
-    pcibr_intr->bi_mustruncpu = CPU_NONE;
-    mutex_spinlock_init(&pcibr_intr->bi_ibuf.ib_lock);
-
-    pcibr_int_bits = pcibr_soft->bs_intr_bits((pciio_info_t)pcibr_info, lines);
-
-
-    /*
-     * For each PCI interrupt line requested, figure
-     * out which Bridge PCI Interrupt Line it maps
-     * to, and make sure there are xtalk resources
-     * allocated for it.
-     */
-#if DEBUG && INTR_DEBUG
-    printk("pcibr_int_bits: 0x%X\n", pcibr_int_bits);
-#endif 
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit ++) {
-	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
-	    xtalk_intr_p = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
-
-	    xtalk_intr = *xtalk_intr_p;
-
-	    if (xtalk_intr == NULL) {
-		/*
-		 * This xtalk_intr_alloc is constrained for two reasons:
-		 * 1) Normal interrupts and error interrupts need to be delivered
-		 *    through a single xtalk target widget so that there aren't any
-		 *    ordering problems with DMA, completion interrupts, and error
-		 *    interrupts. (Use of xconn_vhdl forces this.)
-		 *
-		 * 2) On IP35, addressing constraints on IP35 and Bridge force
-		 *    us to use a single PI number for all interrupts from a
-		 *    single Bridge. (IP35-specific code forces this, and we
-		 *    verify in pcibr_setwidint.)
-		 */
-
-		/*
-		 * All code dealing with threaded PCI interrupt handlers
-		 * is located at the pcibr level. Because of this,
-		 * we always want the lower layers (hub/heart_intr_alloc, 
-		 * intr_level_connect) to treat us as non-threaded so we
-		 * don't set up a duplicate threaded environment. We make
-		 * this happen by calling a special xtalk interface.
-		 */
-		xtalk_intr = xtalk_intr_alloc_nothd(xconn_vhdl, dev_desc, 
-			owner_dev);
-#if DEBUG && INTR_DEBUG
-		printk("%v: xtalk_intr=0x%X\n", xconn_vhdl, xtalk_intr);
-#endif
-
-		/* both an assert and a runtime check on this:
-		 * we need to check in non-DEBUG kernels, and
-		 * the ASSERT gets us more information when
-		 * we use DEBUG kernels.
-		 */
-		ASSERT(xtalk_intr != NULL);
-		if (xtalk_intr == NULL) {
-		    /* it is quite possible that our
-		     * xtalk_intr_alloc failed because
-		     * someone else got there first,
-		     * and we can find their results
-		     * in xtalk_intr_p.
-		     */
-		    if (!*xtalk_intr_p) {
-#ifdef SUPPORT_PRINTING_V_FORMAT
-			printk(KERN_ALERT  
-				"pcibr_intr_alloc %v: unable to get xtalk interrupt resources",
-				xconn_vhdl);
-#else
-			printk(KERN_ALERT  
-				"pcibr_intr_alloc 0x%p: unable to get xtalk interrupt resources",
-				(void *)xconn_vhdl);
-#endif
-			/* yes, we leak resources here. */
-			return 0;
-		    }
-		} else if (compare_and_swap_ptr((void **) xtalk_intr_p, NULL, xtalk_intr)) {
-		    /*
-		     * now tell the bridge which slot is
-		     * using this interrupt line.
-		     */
-		    int_dev = bridge->b_int_device;
-		    int_dev &= ~BRIDGE_INT_DEV_MASK(pcibr_int_bit);
-		    int_dev |= pciio_slot << BRIDGE_INT_DEV_SHFT(pcibr_int_bit);
-		    bridge->b_int_device = int_dev;	/* XXXMP */
-
-#if DEBUG && INTR_DEBUG
-		    printk("%v: bridge intr bit %d clears my wrb\n",
-			    pconn_vhdl, pcibr_int_bit);
-#endif
-		} else {
-		    /* someone else got one allocated first;
-		     * free the one we just created, and
-		     * retrieve the one they allocated.
-		     */
-		    xtalk_intr_free(xtalk_intr);
-		    xtalk_intr = *xtalk_intr_p;
-#if PARANOID
-		    /* once xtalk_intr is set, we never clear it,
-		     * so if the CAS fails above, this condition
-		     * can "never happen" ...
-		     */
-		    if (!xtalk_intr) {
-			printk(KERN_ALERT  
-				"pcibr_intr_alloc %v: unable to set xtalk interrupt resources",
-				xconn_vhdl);
-			/* yes, we leak resources here. */
-			return 0;
-		    }
-#endif
-		}
-	    }
-
-	    pcibr_intr->bi_ibits |= 1 << pcibr_int_bit;
-
-	    NEW(intr_entry);
-	    intr_entry->il_next = NULL;
-	    intr_entry->il_intr = pcibr_intr;
-	    intr_entry->il_wrbf = &(bridge->b_wr_req_buf[pciio_slot].reg);
-	    intr_list_p = 
-		&pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_list;
-#if DEBUG && INTR_DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-	    printk("0x%x: Bridge bit %d wrap=0x%x\n",
-		pconn_vhdl, pcibr_int_bit,
-		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap);
-#else
-	    printk("%v: Bridge bit %d wrap=0x%x\n",
-		pconn_vhdl, pcibr_int_bit,
-		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap);
-#endif
-#endif
-
-	    if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
-		/* we are the first interrupt on this bridge bit.
-		 */
-#if DEBUG && INTR_DEBUG
-		printk("%v INT 0x%x (bridge bit %d) allocated [FIRST]\n",
-			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		continue;
-	    }
-	    intr_list = *intr_list_p;
-	    pcibr_intr_p = &intr_list->il_intr;
-	    if (compare_and_swap_ptr((void **) pcibr_intr_p, NULL, pcibr_intr)) {
-		/* first entry on list was erased,
-		 * and we replaced it, so we
-		 * don't need our intr_entry.
-		 */
-		DEL(intr_entry);
-#if DEBUG && INTR_DEBUG
-		printk("%v INT 0x%x (bridge bit %d) replaces erased first\n",
-			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		continue;
-	    }
-	    intr_list_p = &intr_list->il_next;
-	    if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
-		/* we are the new second interrupt on this bit.
-		 */
-		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared = 1;
-#if DEBUG && INTR_DEBUG
-		printk("%v INT 0x%x (bridge bit %d) is new SECOND\n",
-			pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		continue;
-	    }
-	    while (1) {
-		pcibr_intr_p = &intr_list->il_intr;
-		if (compare_and_swap_ptr((void **) pcibr_intr_p, NULL, pcibr_intr)) {
-		    /* an entry on list was erased,
-		     * and we replaced it, so we
-		     * don't need our intr_entry.
-		     */
-		    DEL(intr_entry);
-#if DEBUG && INTR_DEBUG
-		    printk("%v INT 0x%x (bridge bit %d) replaces erased Nth\n",
-			    pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		    break;
-		}
-		intr_list_p = &intr_list->il_next;
-		if (compare_and_swap_ptr((void **) intr_list_p, NULL, intr_entry)) {
-		    /* entry appended to share list
-		     */
-#if DEBUG && INTR_DEBUG
-		    printk("%v INT 0x%x (bridge bit %d) is new Nth\n",
-			    pconn_vhdl, pcibr_int_bits, pcibr_int_bit);
-#endif
-		    break;
-		}
-		/* step to next record in chain
-		 */
-		intr_list = *intr_list_p;
-	    }
-	}
-    }
-
-#if DEBUG && INTR_DEBUG
-    printk("%v pcibr_intr_alloc complete\n", pconn_vhdl);
-#endif
-    hub_intr = (hub_intr_t)xtalk_intr;
-    pcibr_intr->bi_irq = hub_intr->i_bit;
-    pcibr_intr->bi_cpu = hub_intr->i_cpuid;
-    return pcibr_intr;
-}
-
-/*ARGSUSED */
-void
-pcibr_intr_free(pcibr_intr_t pcibr_intr)
-{
-    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
-    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
-    unsigned                pcibr_int_bit;
-    pcibr_intr_list_t       intr_list;
-    int			    intr_shared;
-    xtalk_intr_t	    *xtalk_intrp;
-
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++) {
-	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
-	    for (intr_list = 
-		     pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_list;
-		 intr_list != NULL;
-		 intr_list = intr_list->il_next)
-		if (compare_and_swap_ptr((void **) &intr_list->il_intr, 
-					 pcibr_intr, 
-					 NULL)) {
-#if DEBUG && INTR_DEBUG
-		    printk("%s: cleared a handler from bit %d\n",
-			    pcibr_soft->bs_name, pcibr_int_bit);
-#endif
-		}
-	    /* If this interrupt line is not being shared between multiple
-	     * devices release the xtalk interrupt resources.
-	     */
-	    intr_shared = 
-		pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared;
-	    xtalk_intrp = &pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
-
-	    if ((!intr_shared) && (*xtalk_intrp)) {
-
-		bridge_t 	*bridge = pcibr_soft->bs_base;
-		bridgereg_t	int_dev;
-
-		xtalk_intr_free(*xtalk_intrp);
-		*xtalk_intrp = 0;
-
-		/* Clear the PCI device interrupt to bridge interrupt pin
-		 * mapping.
-		 */
-		int_dev = bridge->b_int_device;
-		int_dev &= ~BRIDGE_INT_DEV_MASK(pcibr_int_bit);
-		bridge->b_int_device = int_dev;
-
-	    }
-	}
-    }
-    DEL(pcibr_intr);
-}
-
-LOCAL void
-pcibr_setpciint(xtalk_intr_t xtalk_intr)
-{
-    iopaddr_t               addr = xtalk_intr_addr_get(xtalk_intr);
-    xtalk_intr_vector_t     vect = xtalk_intr_vector_get(xtalk_intr);
-    bridgereg_t            *int_addr = (bridgereg_t *)
-    xtalk_intr_sfarg_get(xtalk_intr);
-
-    *int_addr = ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) |
-		 (BRIDGE_INT_ADDR_FLD & vect));
-}
-
-/*ARGSUSED */
-int
-pcibr_intr_connect(pcibr_intr_t pcibr_intr)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
-    unsigned                pcibr_int_bit;
-    bridgereg_t             b_int_enable;
-    unsigned long           s;
-
-    if (pcibr_intr == NULL)
-	return -1;
-
-#if DEBUG && INTR_DEBUG
-    printk("%v: pcibr_intr_connect\n",
-	    pcibr_intr->bi_dev);
-#endif
-
-    *((volatile unsigned *)&pcibr_intr->bi_flags) |= PCIIO_INTR_CONNECTED;
-
-    /*
-     * For each PCI interrupt line requested, figure
-     * out which Bridge PCI Interrupt Line it maps
-     * to, and make sure there are xtalk resources
-     * allocated for it.
-     */
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
-	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
-	    xtalk_intr_t            xtalk_intr;
-
-	    xtalk_intr = pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr;
-
-	    /*
-	     * If this interrupt line is being shared and the connect has
-	     * already been done, no need to do it again.
-	     */
-	    if (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected)
-		continue;
-
-
-	    /*
-	     * Use the pcibr wrapper function to handle all Bridge interrupts
-	     * regardless of whether the interrupt line is shared or not.
-	     */
-	    xtalk_intr_connect(xtalk_intr, (xtalk_intr_setfunc_t) pcibr_setpciint,
-			       (void *)&(bridge->b_int_addr[pcibr_int_bit].addr));
-	    pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected = 1;
-
-#if DEBUG && INTR_DEBUG
-	    printk("%v bridge bit %d wrapper connected\n",
-		    pcibr_intr->bi_dev, pcibr_int_bit);
-#endif
-	}
-    s = pcibr_lock(pcibr_soft);
-    b_int_enable = bridge->b_int_enable;
-    b_int_enable |= pcibr_int_bits;
-    bridge->b_int_enable = b_int_enable;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    pcibr_unlock(pcibr_soft, s);
-
-    return 0;
-}
-
-/*ARGSUSED */
-void
-pcibr_intr_disconnect(pcibr_intr_t pcibr_intr)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
-    unsigned                pcibr_int_bit;
-    bridgereg_t             b_int_enable;
-    unsigned long           s;
-
-    /* Stop calling the function. Now.
-     */
-    *((volatile unsigned *)&pcibr_intr->bi_flags) &= ~PCIIO_INTR_CONNECTED;
-    /*
-     * For each PCI interrupt line requested, figure
-     * out which Bridge PCI Interrupt Line it maps
-     * to, and disconnect the interrupt.
-     */
-
-    /* don't disable interrupts for lines that
-     * are shared between devices.
-     */
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
-	if ((pcibr_int_bits & (1 << pcibr_int_bit)) &&
-	    (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared))
-	    pcibr_int_bits &= ~(1 << pcibr_int_bit);
-    if (!pcibr_int_bits)
-	return;
-
-    s = pcibr_lock(pcibr_soft);
-    b_int_enable = bridge->b_int_enable;
-    b_int_enable &= ~pcibr_int_bits;
-    bridge->b_int_enable = b_int_enable;
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    pcibr_unlock(pcibr_soft, s);
-
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
-	if (pcibr_int_bits & (1 << pcibr_int_bit)) {
-	    /* if the interrupt line is now shared,
-	     * do not disconnect it.
-	     */
-	    if (pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared)
-		continue;
-
-	    xtalk_intr_disconnect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr);
-	    pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_connected = 0;
-
-#if DEBUG && INTR_DEBUG
-	    printk("%s: xtalk disconnect done for Bridge bit %d\n",
-		pcibr_soft->bs_name, pcibr_int_bit);
-#endif
-
-	    /* if we are sharing the interrupt line,
-	     * connect us up; this closes the hole
-	     * where the another pcibr_intr_alloc()
-	     * was in progress as we disconnected.
-	     */
-	    if (!pcibr_soft->bs_intr[pcibr_int_bit].bsi_pcibr_intr_wrap.iw_shared)
-		continue;
-
-	    xtalk_intr_connect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr,
-			       (xtalk_intr_setfunc_t)pcibr_setpciint,
-			       (void *) &(bridge->b_int_addr[pcibr_int_bit].addr));
-	}
-}
-
-/*ARGSUSED */
-devfs_handle_t
-pcibr_intr_cpu_get(pcibr_intr_t pcibr_intr)
-{
-    pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
-    unsigned                pcibr_int_bits = pcibr_intr->bi_ibits;
-    unsigned                pcibr_int_bit;
-
-    for (pcibr_int_bit = 0; pcibr_int_bit < 8; pcibr_int_bit++)
-	if (pcibr_int_bits & (1 << pcibr_int_bit))
-	    return xtalk_intr_cpu_get(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr);
-    return 0;
-}
-
-/* =====================================================================
- *    INTERRUPT HANDLING
- */
-LOCAL void
-pcibr_clearwidint(bridge_t *bridge)
-{
-    bridge->b_wid_int_upper = 0;
-    bridge->b_wid_int_lower = 0;
-}
-
-LOCAL void
-pcibr_setwidint(xtalk_intr_t intr)
-{
-    xwidgetnum_t            targ = xtalk_intr_target_get(intr);
-    iopaddr_t               addr = xtalk_intr_addr_get(intr);
-    xtalk_intr_vector_t     vect = xtalk_intr_vector_get(intr);
-    widgetreg_t		    NEW_b_wid_int_upper, NEW_b_wid_int_lower;
-    widgetreg_t		    OLD_b_wid_int_upper, OLD_b_wid_int_lower;
-
-    bridge_t               *bridge = (bridge_t *)xtalk_intr_sfarg_get(intr);
-
-    NEW_b_wid_int_upper = ( (0x000F0000 & (targ << 16)) |
-			       XTALK_ADDR_TO_UPPER(addr));
-    NEW_b_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
-
-    OLD_b_wid_int_upper = bridge->b_wid_int_upper;
-    OLD_b_wid_int_lower = bridge->b_wid_int_lower;
-
-    /* Verify that all interrupts from this Bridge are using a single PI */
-    if ((OLD_b_wid_int_upper != 0) && (OLD_b_wid_int_lower != 0)) {
-	/*
-	 * Once set, these registers shouldn't change; they should
-	 * be set multiple times with the same values.
-	 *
-	 * If we're attempting to change these registers, it means
-	 * that our heuristics for allocating interrupts in a way
-	 * appropriate for IP35 have failed, and the admin needs to
-	 * explicitly direct some interrupts (or we need to make the
-	 * heuristics more clever).
-	 *
-	 * In practice, we hope this doesn't happen very often, if
-	 * at all.
-	 */
-	if ((OLD_b_wid_int_upper != NEW_b_wid_int_upper) ||
-	    (OLD_b_wid_int_lower != NEW_b_wid_int_lower)) {
-		printk(KERN_WARNING  "Interrupt allocation is too complex.\n");
-		printk(KERN_WARNING  "Use explicit administrative interrupt targetting.\n");
-		printk(KERN_WARNING  "bridge=0x%lx targ=0x%x\n", (unsigned long)bridge, targ);
-		printk(KERN_WARNING  "NEW=0x%x/0x%x  OLD=0x%x/0x%x\n",
-			NEW_b_wid_int_upper, NEW_b_wid_int_lower,
-			OLD_b_wid_int_upper, OLD_b_wid_int_lower);
-		PRINT_PANIC("PCI Bridge interrupt targetting error\n");
-	}
-    }
-
-    bridge->b_wid_int_upper = NEW_b_wid_int_upper;
-    bridge->b_wid_int_lower = NEW_b_wid_int_lower;
-    bridge->b_int_host_err = vect;
-}
-
-/*
- * pcibr_intr_preset: called during mlreset time
- * if the platform specific code needs to route
- * one of the Bridge's xtalk interrupts before the
- * xtalk infrastructure is available.
- */
-void
-pcibr_xintr_preset(void *which_widget,
-		   int which_widget_intr,
-		   xwidgetnum_t targ,
-		   iopaddr_t addr,
-		   xtalk_intr_vector_t vect)
-{
-    bridge_t               *bridge = (bridge_t *) which_widget;
-
-    if (which_widget_intr == -1) {
-	/* bridge widget error interrupt */
-	bridge->b_wid_int_upper = ( (0x000F0000 & (targ << 16)) |
-				   XTALK_ADDR_TO_UPPER(addr));
-	bridge->b_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
-	bridge->b_int_host_err = vect;
-
-	/* turn on all interrupts except
-	 * the PCI interrupt requests,
-	 * at least at heart.
-	 */
-	bridge->b_int_enable |= ~BRIDGE_IMR_INT_MSK;
-
-    } else {
-	/* routing a PCI device interrupt.
-	 * targ and low 38 bits of addr must
-	 * be the same as the already set
-	 * value for the widget error interrupt.
-	 */
-	bridge->b_int_addr[which_widget_intr].addr =
-	    ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) |
-	     (BRIDGE_INT_ADDR_FLD & vect));
-	/*
-	 * now bridge can let it through;
-	 * NB: still should be blocked at
-	 * xtalk provider end, until the service
-	 * function is set.
-	 */
-	bridge->b_int_enable |= 1 << vect;
-    }
-    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-}
-
-
-/*
- * pcibr_intr_func()
- *
- * This is the pcibr interrupt "wrapper" function that is called,
- * in interrupt context, to initiate the interrupt handler(s) registered
- * (via pcibr_intr_alloc/connect) for the occurring interrupt. Non-threaded 
- * handlers will be called directly, and threaded handlers will have their 
- * thread woken up.
- */
-void
-pcibr_intr_func(intr_arg_t arg)
-{
-    pcibr_intr_wrap_t       wrap = (pcibr_intr_wrap_t) arg;
-    reg_p                   wrbf;
-    pcibr_intr_t            intr;
-    pcibr_intr_list_t       list;
-    int                     clearit;
-    int			    do_nonthreaded = 1;
-    int			    is_threaded = 0;
-    int			    x = 0;
-
-	/*
-	 * If any handler is still running from a previous interrupt
-	 * just return. If there's a need to call the handler(s) again,
-	 * another interrupt will be generated either by the device or by
-	 * pcibr_force_interrupt().
-	 */
-
-	if (wrap->iw_hdlrcnt) {
-		return;
-	}
-
-    /*
-     * Call all interrupt handlers registered.
-     * First, the pcibr_intrd threads for any threaded handlers will be
-     * awoken, then any non-threaded handlers will be called sequentially.
-     */
-	
-	clearit = 1;
-	while (do_nonthreaded) {
-	    for (list = wrap->iw_list; list != NULL; list = list->il_next) {
-		if ((intr = list->il_intr) &&
-		    (intr->bi_flags & PCIIO_INTR_CONNECTED)) {
-
-		/*
-		 * This device may have initiated write
-		 * requests since the bridge last saw
-		 * an edge on this interrupt input; flushing
-		 * the buffer prior to invoking the handler
-		 * should help but may not be sufficient if we 
-		 * get more requests after the flush, followed
-		 * by the card deciding it wants service, before
-		 * the interrupt handler checks to see if things need
-		 * to be done.
-		 *
-		 * There is a similar race condition if
-		 * an interrupt handler loops around and
-		 * notices further service is required.
-		 * Perhaps we need to have an explicit
-		 * call that interrupt handlers need to
-		 * do between noticing that DMA to memory
-		 * has completed, but before observing the
-		 * contents of memory?
-		 */
-
-			if ((do_nonthreaded) && (!is_threaded)) {
-			/* Non-threaded. 
-			 * Call the interrupt handler at interrupt level
-			 */
-
-			/* Only need to flush write buffers if sharing */
-
-			if ((wrap->iw_shared) && (wrbf = list->il_wrbf)) {
-			    if ((x = *wrbf))	/* write request buffer flush */
-#ifdef SUPPORT_PRINTING_V_FORMAT
-				printk(KERN_ALERT  "pcibr_intr_func %v: \n"
-				    "write buffer flush failed, wrbf=0x%x\n", 
-				    list->il_intr->bi_dev, wrbf);
-#else
-				printk(KERN_ALERT  "pcibr_intr_func %p: \n"
-				    "write buffer flush failed, wrbf=0x%lx\n", 
-				    (void *)list->il_intr->bi_dev, (long) wrbf);
-#endif
-			}
-		    }
-
-		    clearit = 0;
-		}
-	    }
-
-		do_nonthreaded = 0;
-		/*
-		 * If the non-threaded handler was the last to complete,
-		 * (i.e., no threaded handlers still running) force an
-		 * interrupt to avoid a potential deadlock situation.
-		 */
-		if (wrap->iw_hdlrcnt == 0) {
-			pcibr_force_interrupt(wrap);
-		}
-	}
-
-	/* If there were no handlers,
-	 * disable the interrupt and return.
-	 * It will get enabled again after
-	 * a handler is connected.
-	 * If we don't do this, we would
-	 * sit here and spin through the
-	 * list forever.
-	 */
-	if (clearit) {
-	    pcibr_soft_t            pcibr_soft = wrap->iw_soft;
-	    bridge_t               *bridge = pcibr_soft->bs_base;
-	    bridgereg_t             b_int_enable;
-	    bridgereg_t		    mask = 1 << wrap->iw_intr;
-	    unsigned long           s;
-
-	    s = pcibr_lock(pcibr_soft);
-	    b_int_enable = bridge->b_int_enable;
-	    b_int_enable &= ~mask;
-	    bridge->b_int_enable = b_int_enable;
-	    bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
-	    pcibr_unlock(pcibr_soft, s);
-	    return;
-	}
-}
-
-/* =====================================================================
- *    CONFIGURATION MANAGEMENT
- */
-/*ARGSUSED */
-void
-pcibr_provider_startup(devfs_handle_t pcibr)
-{
-}
-
-/*ARGSUSED */
-void
-pcibr_provider_shutdown(devfs_handle_t pcibr)
-{
-}
-
-int
-pcibr_reset(devfs_handle_t conn)
-{
-    pciio_info_t            pciio_info = pciio_info_get(conn);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-    bridgereg_t             ctlreg;
-    unsigned                cfgctl[8];
-    unsigned long           s;
-    int                     f, nf;
-    pcibr_info_h            pcibr_infoh;
-    pcibr_info_t            pcibr_info;
-    int                     win;
-
-    if (pcibr_soft->bs_slot[pciio_slot].has_host) {
-	pciio_slot = pcibr_soft->bs_slot[pciio_slot].host_slot;
-	pcibr_info = pcibr_soft->bs_slot[pciio_slot].bss_infos[0];
-    }
-    if (pciio_slot < 4) {
-	s = pcibr_lock(pcibr_soft);
-	nf = pcibr_soft->bs_slot[pciio_slot].bss_ninfo;
-	pcibr_infoh = pcibr_soft->bs_slot[pciio_slot].bss_infos;
-	for (f = 0; f < nf; ++f)
-	    if (pcibr_infoh[f])
-		cfgctl[f] = bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_COMMAND / 4];
-
-	ctlreg = bridge->b_wid_control;
-	bridge->b_wid_control = ctlreg | BRIDGE_CTRL_RST(pciio_slot);
-	/* XXX delay? */
-	bridge->b_wid_control = ctlreg;
-	/* XXX delay? */
-
-	for (f = 0; f < nf; ++f)
-	    if ((pcibr_info = pcibr_infoh[f]))
-		for (win = 0; win < 6; ++win)
-		    if (pcibr_info->f_window[win].w_base != 0)
-			bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_BASE_ADDR(win) / 4] =
-			    pcibr_info->f_window[win].w_base;
-	for (f = 0; f < nf; ++f)
-	    if (pcibr_infoh[f])
-		bridge->b_type0_cfg_dev[pciio_slot].f[f].l[PCI_CFG_COMMAND / 4] = cfgctl[f];
-	pcibr_unlock(pcibr_soft, s);
-
-	return 0;
-    }
-#ifdef SUPPORT_PRINTING_V_FORMAT
-    printk(KERN_WARNING   "%v: pcibr_reset unimplemented for slot %d\n",
-	    conn, pciio_slot);
-#endif
-    return -1;
-}
-
-pciio_endian_t
-pcibr_endian_set(devfs_handle_t pconn_vhdl,
-		 pciio_endian_t device_end,
-		 pciio_endian_t desired_end)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridgereg_t             devreg;
-    unsigned long           s;
-
-    /*
-     * Bridge supports hardware swapping; so we can always
-     * arrange for the caller's desired endianness.
-     */
-
-    s = pcibr_lock(pcibr_soft);
-    devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
-    if (device_end != desired_end)
-	devreg |= BRIDGE_DEV_SWAP_BITS;
-    else
-	devreg &= ~BRIDGE_DEV_SWAP_BITS;
-
-    /* NOTE- if we ever put SWAP bits
-     * onto the disabled list, we will
-     * have to change the logic here.
-     */
-    if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
-	bridge_t               *bridge = pcibr_soft->bs_base;
-
-	bridge->b_device[pciio_slot].reg = devreg;
-	pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    }
-    pcibr_unlock(pcibr_soft, s);
-
-#if DEBUG && PCIBR_DEV_DEBUG
-    printk("pcibr Device(%d): 0x%p\n", pciio_slot, bridge->b_device[pciio_slot].reg);
-#endif
-
-    return desired_end;
-}
-
-/* This (re)sets the GBR and REALTIME bits and also keeps track of how
- * many sets are outstanding. Reset succeeds only if the number of outstanding
- * sets == 1.
- */
-int
-pcibr_priority_bits_set(pcibr_soft_t pcibr_soft,
-			pciio_slot_t pciio_slot,
-			pciio_priority_t device_prio)
-{
-    unsigned long           s;
-    int                    *counter;
-    bridgereg_t             rtbits = 0;
-    bridgereg_t             devreg;
-    int                     rc = PRIO_SUCCESS;
-
-    /* in dual-slot configurations, the host and the
-     * guest have separate DMA resources, so they
-     * have separate requirements for priority bits.
-     */
-
-    counter = &(pcibr_soft->bs_slot[pciio_slot].bss_pri_uctr);
-
-    /*
-     * Bridge supports PCI notions of LOW and HIGH priority
-     * arbitration rings via a "REAL_TIME" bit in the per-device
-     * Bridge register. The "GBR" bit controls access to the GBR
-     * ring on the xbow. These two bits are (re)set together.
-     *
-     * XXX- Bug in Rev B Bridge Si:
-     * Symptom: Prefetcher starts operating incorrectly. This happens
-     * due to corruption of the address storage ram in the prefetcher
-     * when a non-real time PCI request is pulled and a real-time one is
-     * put in it's place. Workaround: Use only a single arbitration ring
-     * on PCI bus. GBR and RR can still be uniquely used per
-     * device. NETLIST MERGE DONE, WILL BE FIXED IN REV C.
-     */
-
-    if (pcibr_soft->bs_rev_num != BRIDGE_PART_REV_B)
-	rtbits |= BRIDGE_DEV_RT;
-
-    /* NOTE- if we ever put DEV_RT or DEV_GBR on
-     * the disabled list, we will have to take
-     * it into account here.
-     */
-
-    s = pcibr_lock(pcibr_soft);
-    devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
-    if (device_prio == PCI_PRIO_HIGH) {
-	if ((++*counter == 1)) {
-	    if (rtbits)
-		devreg |= rtbits;
-	    else
-		rc = PRIO_FAIL;
-	}
-    } else if (device_prio == PCI_PRIO_LOW) {
-	if (*counter <= 0)
-	    rc = PRIO_FAIL;
-	else if (--*counter == 0)
-	    if (rtbits)
-		devreg &= ~rtbits;
-    }
-    if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
-	bridge_t               *bridge = pcibr_soft->bs_base;
-
-	bridge->b_device[pciio_slot].reg = devreg;
-	pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    }
-    pcibr_unlock(pcibr_soft, s);
-
-    return rc;
-}
-
-pciio_priority_t
-pcibr_priority_set(devfs_handle_t pconn_vhdl,
-		   pciio_priority_t device_prio)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-    (void) pcibr_priority_bits_set(pcibr_soft, pciio_slot, device_prio);
-
-    return device_prio;
-}
-
-/*
- * Interfaces to allow special (e.g. SGI) drivers to set/clear
- * Bridge-specific device flags.  Many flags are modified through
- * PCI-generic interfaces; we don't allow them to be directly
- * manipulated here.  Only flags that at this point seem pretty
- * Bridge-specific can be set through these special interfaces.
- * We may add more flags as the need arises, or remove flags and
- * create PCI-generic interfaces as the need arises.
- *
- * Returns 0 on failure, 1 on success
- */
-int
-pcibr_device_flags_set(devfs_handle_t pconn_vhdl,
-		       pcibr_device_flags_t flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = pciio_info_slot_get(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    bridgereg_t             set = 0;
-    bridgereg_t             clr = 0;
-
-    ASSERT((flags & PCIBR_DEVICE_FLAGS) == flags);
-
-    if (flags & PCIBR_WRITE_GATHER)
-	set |= BRIDGE_DEV_PMU_WRGA_EN;
-    if (flags & PCIBR_NOWRITE_GATHER)
-	clr |= BRIDGE_DEV_PMU_WRGA_EN;
-
-    if (flags & PCIBR_WRITE_GATHER)
-	set |= BRIDGE_DEV_DIR_WRGA_EN;
-    if (flags & PCIBR_NOWRITE_GATHER)
-	clr |= BRIDGE_DEV_DIR_WRGA_EN;
-
-    if (flags & PCIBR_PREFETCH)
-	set |= BRIDGE_DEV_PREF;
-    if (flags & PCIBR_NOPREFETCH)
-	clr |= BRIDGE_DEV_PREF;
-
-    if (flags & PCIBR_PRECISE)
-	set |= BRIDGE_DEV_PRECISE;
-    if (flags & PCIBR_NOPRECISE)
-	clr |= BRIDGE_DEV_PRECISE;
-
-    if (flags & PCIBR_BARRIER)
-	set |= BRIDGE_DEV_BARRIER;
-    if (flags & PCIBR_NOBARRIER)
-	clr |= BRIDGE_DEV_BARRIER;
-
-    if (flags & PCIBR_64BIT)
-	set |= BRIDGE_DEV_DEV_SIZE;
-    if (flags & PCIBR_NO64BIT)
-	clr |= BRIDGE_DEV_DEV_SIZE;
-
-    if (set || clr) {
-	bridgereg_t             devreg;
-	unsigned long           s;
-
-	s = pcibr_lock(pcibr_soft);
-	devreg = pcibr_soft->bs_slot[pciio_slot].bss_device;
-	devreg = (devreg & ~clr) | set;
-	if (pcibr_soft->bs_slot[pciio_slot].bss_device != devreg) {
-	    bridge_t               *bridge = pcibr_soft->bs_base;
-
-	    bridge->b_device[pciio_slot].reg = devreg;
-	    pcibr_soft->bs_slot[pciio_slot].bss_device = devreg;
-	    bridge->b_wid_tflush;	/* wait until Bridge PIO complete */
-	}
-	pcibr_unlock(pcibr_soft, s);
-#if DEBUG && PCIBR_DEV_DEBUG
-	printk("pcibr Device(%d): %R\n", pciio_slot, bridge->b_device[pciio_slot].regbridge->b_device[pciio_slot].reg, device_bits);
-#endif
-    }
-    return (1);
-}
-
-#ifdef LITTLE_ENDIAN
-/*
- * on sn-ia we need to twiddle the the addresses going out
- * the pci bus because we use the unswizzled synergy space
- * (the alternative is to use the swizzled synergy space
- * and byte swap the data)
- */
-#define	CB(b,r)	(((volatile uint8_t *) b)[((r)^4)])
-#define	CS(b,r)	(((volatile uint16_t *) b)[((r^4)/2)])
-#define	CW(b,r)	(((volatile uint32_t *) b)[((r^4)/4)])
-#else
-#define	CB(b,r)	(((volatile uint8_t *) cfgbase)[(r)^3])
-#define	CS(b,r)	(((volatile uint16_t *) cfgbase)[((r)/2)^1])
-#define	CW(b,r)	(((volatile uint32_t *) cfgbase)[(r)/4])
-#endif /* LITTLE_ENDIAN */
-
-
-LOCAL                   cfg_p
-pcibr_config_addr(devfs_handle_t conn,
-		  unsigned reg)
-{
-    pcibr_info_t            pcibr_info;
-    pciio_slot_t            pciio_slot;
-    pciio_function_t        pciio_func;
-    pcibr_soft_t            pcibr_soft;
-    bridge_t               *bridge;
-    cfg_p                   cfgbase = (cfg_p)0;
-
-    pcibr_info = pcibr_info_get(conn);
-
-    pciio_slot = pcibr_info->f_slot;
-    if (pciio_slot == PCIIO_SLOT_NONE)
-	pciio_slot = PCI_TYPE1_SLOT(reg);
-
-    pciio_func = pcibr_info->f_func;
-    if (pciio_func == PCIIO_FUNC_NONE)
-	pciio_func = PCI_TYPE1_FUNC(reg);
-
-    pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
-
-    bridge = pcibr_soft->bs_base;
-
-    cfgbase = bridge->b_type0_cfg_dev[pciio_slot].f[pciio_func].l;
-
-    return cfgbase;
-}
-
-uint64_t
-pcibr_config_get(devfs_handle_t conn,
-		 unsigned reg,
-		 unsigned size)
-{
-    return do_pcibr_config_get(pcibr_config_addr(conn, reg),
-			       PCI_TYPE1_REG(reg), size);
-}
-
-LOCAL uint64_t
-do_pcibr_config_get(
-		       cfg_p cfgbase,
-		       unsigned reg,
-		       unsigned size)
-{
-    unsigned                value;
-
-   
-    value = CW(cfgbase, reg);
-
-    if (reg & 3)
-	value >>= 8 * (reg & 3);
-    if (size < 4)
-	value &= (1 << (8 * size)) - 1;
-
-    return value;
-}
-
-void
-pcibr_config_set(devfs_handle_t conn,
-		 unsigned reg,
-		 unsigned size,
-		 uint64_t value)
-{
-    do_pcibr_config_set(pcibr_config_addr(conn, reg),
-			PCI_TYPE1_REG(reg), size, value);
-}
-
-LOCAL void
-do_pcibr_config_set(cfg_p cfgbase,
-		    unsigned reg,
-		    unsigned size,
-		    uint64_t value)
-{
-    switch (size) {
-    case 1:
-	CB(cfgbase, reg) = value;
-	break;
-    case 2:
-	if (reg & 1) {
-	    CB(cfgbase, reg) = value;
-	    CB(cfgbase, reg + 1) = value >> 8;
-	} else
-	    CS(cfgbase, reg) = value;
-	break;
-    case 3:
-	if (reg & 1) {
-	    CB(cfgbase, reg) = value;
-	    CS(cfgbase, (reg + 1)) = value >> 8;
-	} else {
-	    CS(cfgbase, reg) = value;
-	    CB(cfgbase, reg + 2) = value >> 16;
-	}
-	break;
-
-    case 4:
-	CW(cfgbase, reg) = value;
-	break;
-    }
-}
-
-pciio_provider_t        pcibr_provider =
-{
-    (pciio_piomap_alloc_f *) pcibr_piomap_alloc,
-    (pciio_piomap_free_f *) pcibr_piomap_free,
-    (pciio_piomap_addr_f *) pcibr_piomap_addr,
-    (pciio_piomap_done_f *) pcibr_piomap_done,
-    (pciio_piotrans_addr_f *) pcibr_piotrans_addr,
-    (pciio_piospace_alloc_f *) pcibr_piospace_alloc,
-    (pciio_piospace_free_f *) pcibr_piospace_free,
-
-    (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc,
-    (pciio_dmamap_free_f *) pcibr_dmamap_free,
-    (pciio_dmamap_addr_f *) pcibr_dmamap_addr,
-    (pciio_dmamap_list_f *) pcibr_dmamap_list,
-    (pciio_dmamap_done_f *) pcibr_dmamap_done,
-    (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr,
-    (pciio_dmatrans_list_f *) pcibr_dmatrans_list,
-    (pciio_dmamap_drain_f *) pcibr_dmamap_drain,
-    (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain,
-    (pciio_dmalist_drain_f *) pcibr_dmalist_drain,
-
-    (pciio_intr_alloc_f *) pcibr_intr_alloc,
-    (pciio_intr_free_f *) pcibr_intr_free,
-    (pciio_intr_connect_f *) pcibr_intr_connect,
-    (pciio_intr_disconnect_f *) pcibr_intr_disconnect,
-    (pciio_intr_cpu_get_f *) pcibr_intr_cpu_get,
-
-    (pciio_provider_startup_f *) pcibr_provider_startup,
-    (pciio_provider_shutdown_f *) pcibr_provider_shutdown,
-    (pciio_reset_f *) pcibr_reset,
-    (pciio_write_gather_flush_f *) pcibr_write_gather_flush,
-    (pciio_endian_set_f *) pcibr_endian_set,
-    (pciio_priority_set_f *) pcibr_priority_set,
-    (pciio_config_get_f *) pcibr_config_get,
-    (pciio_config_set_f *) pcibr_config_set,
-
-    (pciio_error_devenable_f *) 0,
-    (pciio_error_extract_f *) 0,
-
-#ifdef LATER
-    (pciio_driver_reg_callback_f *) pcibr_driver_reg_callback,
-    (pciio_driver_unreg_callback_f *) pcibr_driver_unreg_callback,
-#else
-    (pciio_driver_reg_callback_f *) 0,
-    (pciio_driver_unreg_callback_f *) 0,
-#endif
-    (pciio_device_unregister_f 	*) pcibr_device_unregister,
-    (pciio_dma_enabled_f		*) pcibr_dma_enabled,
-};
-
-LOCAL                   pcibr_hints_t
-pcibr_hints_get(devfs_handle_t xconn_vhdl, int alloc)
-{
-    arbitrary_info_t        ainfo = 0;
-    graph_error_t	    rv;
-    pcibr_hints_t           hint;
-
-    rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo);
-
-    if (alloc && (rv != GRAPH_SUCCESS)) {
-
-	NEW(hint);
-	hint->rrb_alloc_funct = NULL;
-	hint->ph_intr_bits = NULL;
-	rv = hwgraph_info_add_LBL(xconn_vhdl, 
-				  INFO_LBL_PCIBR_HINTS, 	
-				  (arbitrary_info_t) hint);
-	if (rv != GRAPH_SUCCESS)
-	    goto abnormal_exit;
-
-	rv = hwgraph_info_get_LBL(xconn_vhdl, INFO_LBL_PCIBR_HINTS, &ainfo);
-	
-	if (rv != GRAPH_SUCCESS)
-	    goto abnormal_exit;
-
-	if (ainfo != (arbitrary_info_t) hint)
-	    goto abnormal_exit;
-    }
-    return (pcibr_hints_t) ainfo;
-
-abnormal_exit:
-#ifdef LATER
-    printf("SHOULD NOT BE HERE\n");
-#endif
-    DEL(hint);
-    return(NULL);
-
-}
-
-void
-pcibr_hints_fix_some_rrbs(devfs_handle_t xconn_vhdl, unsigned mask)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->ph_rrb_fixed = mask;
-#if DEBUG
-    else
-	printk("pcibr_hints_fix_rrbs: pcibr_hints_get failed at\n"
-		"\t%p\n", xconn_vhdl);
-#endif
-}
-
-void
-pcibr_hints_fix_rrbs(devfs_handle_t xconn_vhdl)
-{
-    pcibr_hints_fix_some_rrbs(xconn_vhdl, 0xFF);
-}
-
-void
-pcibr_hints_dualslot(devfs_handle_t xconn_vhdl,
-		     pciio_slot_t host,
-		     pciio_slot_t guest)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->ph_host_slot[guest] = host + 1;
-#if DEBUG
-    else
-	printk("pcibr_hints_dualslot: pcibr_hints_get failed at\n"
-		"\t%p\n", xconn_vhdl);
-#endif
-}
-
-void
-pcibr_hints_intr_bits(devfs_handle_t xconn_vhdl,
-		      pcibr_intr_bits_f *xxx_intr_bits)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->ph_intr_bits = xxx_intr_bits;
-#if DEBUG
-    else
-	printk("pcibr_hints_intr_bits: pcibr_hints_get failed at\n"
-	       "\t%p\n", xconn_vhdl);
-#endif
-}
-
-void
-pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->rrb_alloc_funct = rrb_alloc_funct;
-}
-
-void
-pcibr_hints_handsoff(devfs_handle_t xconn_vhdl)
-{
-    pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
-
-    if (hint)
-	hint->ph_hands_off = 1;
-#if DEBUG
-    else
-	printk("pcibr_hints_handsoff: pcibr_hints_get failed at\n"
-		"\t%p\n", xconn_vhdl);
-#endif
-}
-
-void
-pcibr_hints_subdevs(devfs_handle_t xconn_vhdl,
-		    pciio_slot_t slot,
-		    uint64_t subdevs)
-{
-    arbitrary_info_t        ainfo = 0;
-    char                    sdname[16];
-    devfs_handle_t            pconn_vhdl = GRAPH_VERTEX_NONE;
-
-    sprintf(sdname, "pci/%d", slot);
-    (void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl);
-    if (pconn_vhdl == GRAPH_VERTEX_NONE) {
-#if DEBUG
-	printk("pcibr_hints_subdevs: hwgraph_path_create failed at\n"
-		"\t%p (seeking %s)\n", xconn_vhdl, sdname);
-#endif
-	return;
-    }
-    hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
-    if (ainfo == 0) {
-	uint64_t                *subdevp;
-
-	NEW(subdevp);
-	if (!subdevp) {
-#if DEBUG
-	    printk("pcibr_hints_subdevs: subdev ptr alloc failed at\n"
-		    "\t%p\n", pconn_vhdl);
-#endif
-	    return;
-	}
-	*subdevp = subdevs;
-	hwgraph_info_add_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, (arbitrary_info_t) subdevp);
-	hwgraph_info_get_LBL(pconn_vhdl, INFO_LBL_SUBDEVS, &ainfo);
-	if (ainfo == (arbitrary_info_t) subdevp)
-	    return;
-	DEL(subdevp);
-	if (ainfo == (arbitrary_info_t) NULL) {
-#if DEBUG
-	    printk("pcibr_hints_subdevs: null subdevs ptr at\n"
-		    "\t%p\n", pconn_vhdl);
-#endif
-	    return;
-	}
-#if DEBUG
-	printk("pcibr_subdevs_get: dup subdev add_LBL at\n"
-		"\t%p\n", pconn_vhdl);
-#endif
-    }
-    *(uint64_t *) ainfo = subdevs;
-}
-
-
-#ifdef LATER
-
-#include <sys/idbg.h>
-#include <sys/idbgentry.h>
-
-char *pci_space[] = {"NONE", 
-		     "ROM",
-		     "IO",
-		     "",
-		     "MEM",
-		     "MEM32",
-		     "MEM64",
-		     "CFG",
-		     "WIN0",
-		     "WIN1",
-		     "WIN2",
-		     "WIN3",
-		     "WIN4",
-		     "WIN5",
-		     "",
-		     "BAD"};
-
-void
-idbg_pss_func(pcibr_info_h pcibr_infoh, int func)
-{
-    pcibr_info_t	pcibr_info = pcibr_infoh[func];
-    char		name[MAXDEVNAME];
-    int			win;
-    
-    if (!pcibr_info)
-	return;
-    qprintf("Per-slot Function Info\n");
-#ifdef SUPPORT_PRINTING_V_FORMAT
-    sprintf(name, "%v", pcibr_info->f_vertex);
-#endif
-    qprintf("\tSlot Name : %s\n",name);
-    qprintf("\tPCI Bus : %d ",pcibr_info->f_bus);
-    qprintf("Slot : %d ", pcibr_info->f_slot);
-    qprintf("Function : %d ", pcibr_info->f_func);
-    qprintf("VendorId : 0x%x " , pcibr_info->f_vendor);
-    qprintf("DeviceId : 0x%x\n", pcibr_info->f_device);
-#ifdef SUPPORT_PRINTING_V_FORMAT
-    sprintf(name, "%v", pcibr_info->f_master);
-#endif
-    qprintf("\tBus provider : %s\n",name);
-    qprintf("\tProvider Fns : 0x%x ", pcibr_info->f_pops);
-    qprintf("Error Handler : 0x%x Arg 0x%x\n", 
-	    pcibr_info->f_efunc,pcibr_info->f_einfo);
-    for(win = 0 ; win < 6 ; win++) 
-	qprintf("\tBase Reg #%d space %s base 0x%x size 0x%x\n",
-		win,pci_space[pcibr_info->f_window[win].w_space],
-		pcibr_info->f_window[win].w_base,
-		pcibr_info->f_window[win].w_size);
-
-    qprintf("\tRom base 0x%x size 0x%x\n", 
-	    pcibr_info->f_rbase,pcibr_info->f_rsize);
-
-    qprintf("\tInterrupt Bit Map\n");
-    qprintf("\t\tPCI Int#\tBridge Pin#\n");
-    for (win = 0 ; win < 4; win++)
-	qprintf("\t\tINT%c\t\t%d\n",win+'A',pcibr_info->f_ibit[win]);
-    qprintf("\n");
-}
-
-
-void
-idbg_pss_info(pcibr_soft_t pcibr_soft, pciio_slot_t slot)
-{
-    pcibr_soft_slot_t	pss;
-    char		slot_conn_name[MAXDEVNAME];
-    int			func;
-
-    pss = &pcibr_soft->bs_slot[slot];
-    qprintf("PCI INFRASTRUCTURAL INFO FOR SLOT %d\n", slot);
-    qprintf("\tHost Present ? %s ", pss->has_host ? "yes" : "no");
-    qprintf("\tHost Slot : %d\n",pss->host_slot);
-    sprintf(slot_conn_name, "%v", pss->slot_conn);
-    qprintf("\tSlot Conn : %s\n",slot_conn_name);	
-    qprintf("\t#Functions : %d\n",pss->bss_ninfo);
-    for (func = 0; func < pss->bss_ninfo; func++)
-	idbg_pss_func(pss->bss_infos,func);
-    qprintf("\tSpace : %s ",pci_space[pss->bss_devio.bssd_space]);
-    qprintf("\tBase : 0x%x ", pss->bss_devio.bssd_base);
-    qprintf("\tShadow Devreg : 0x%x\n", pss->bss_device);
-    qprintf("\tUsage counts : pmu %d d32 %d d64 %d\n",
-	    pss->bss_pmu_uctr,pss->bss_d32_uctr,pss->bss_d64_uctr);
-    
-    qprintf("\tDirect Trans Info : d64_base 0x%x d64_flags 0x%x"
-	    "d32_base 0x%x d32_flags 0x%x\n",
-	    pss->bss_d64_base, pss->bss_d64_flags,
-	    pss->bss_d32_base, pss->bss_d32_flags);
-    
-    qprintf("\tExt ATEs active ? %s", 
-	    atomic_read(&pss->bss_ext_ates_active) ? "yes" : "no");
-    qprintf(" Command register : 0x%x ", pss->bss_cmd_pointer);
-    qprintf(" Shadow command val : 0x%x\n", pss->bss_cmd_shadow);
-
-    qprintf("\tRRB Info : Valid %d+%d Reserved %d\n",
-	    pcibr_soft->bs_rrb_valid[slot],
-	    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-	    pcibr_soft->bs_rrb_res[slot]);
-		
-}
-
-int	ips = 0;
-
-void
-idbg_pss(pcibr_soft_t pcibr_soft)
-{
-    pciio_slot_t	slot;
-
-    
-    if (ips >= 0 && ips < 8)
-	idbg_pss_info(pcibr_soft,ips);
-    else if (ips < 0)
-	for (slot = 0; slot < 8; slot++) 
-	    idbg_pss_info(pcibr_soft,slot);
-    else
-	qprintf("Invalid ips %d\n",ips);
-}
-
-#endif /* LATER */
-
-int
-pcibr_dma_enabled(devfs_handle_t pconn_vhdl)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-	
-
-    return xtalk_dma_enabled(pcibr_soft->bs_conn);
-}
diff -Nru a/arch/ia64/sn/io/sn2/Makefile b/arch/ia64/sn/io/sn2/Makefile
--- a/arch/ia64/sn/io/sn2/Makefile	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/sn/io/sn2/Makefile	Wed Jun 18 23:42:09 2003
@@ -11,10 +11,9 @@
 
 EXTRA_CFLAGS := -DLITTLE_ENDIAN
 
-obj-y += pcibr/ bte_error.o geo_op.o klconflib.o klgraph.o l1.o \
-	 l1_command.o ml_iograph.o ml_SN_init.o ml_SN_intr.o module.o \
-	 pci_bus_cvlink.o pciio.o pic.o sgi_io_init.o shub.o shuberror.o \
-	 shub_intr.o shubio.o xbow.o xtalk.o
+obj-y += pcibr/ ml_SN_intr.o shub_intr.o shuberror.o shub.o bte_error.o \
+	 pic.o geo_op.o l1.o l1_command.o klconflib.o klgraph.o ml_SN_init.o \
+	 ml_iograph.o module.o pciio.o xbow.o xtalk.o shubio.o
 
 obj-$(CONFIG_KDB) += kdba_io.o 
 obj-$(CONFIG_SHUB_1_0_SPECIFIC) += efi-rtc.o
diff -Nru a/arch/ia64/sn/io/sn2/bte_error.c b/arch/ia64/sn/io/sn2/bte_error.c
--- a/arch/ia64/sn/io/sn2/bte_error.c	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/sn/io/sn2/bte_error.c	Wed Jun 18 23:42:08 2003
@@ -1,10 +1,35 @@
-/* $Id: bte_error.c,v 1.1 2002/02/28 17:31:25 marcelo Exp $
+/*
  *
- * 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) 1992 - 1997, 2000,2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
  */
 
 
@@ -29,121 +54,208 @@
 #include <asm/sn/sn2/shubio.h>
 #include <asm/sn/bte.h>
 
-/************************************************************************
- *									*
- * 			 BTE ERROR RECOVERY				*
- *									*
- * Given a BTE error, the node causing the error must do the following: *
- *    a) Clear all crbs relating to that BTE				*
- *		1) Read CRBA value for crb in question			*
- *		2) Mark CRB as VALID, store local physical 		*
- *		   address known to be good in the address field	*
- *		   (bte_notification_targ is a known good local		*
- *		    address).						*
- *		3) Write CRBA						*
- *		4) Using ICCR, FLUSH the CRB, and wait for it to 	*
- *		   complete.						*
- *		... BTE BUSY bit should now be clear (or at least 	*
- *		    should be after ALL CRBs associated with the 	*
- *		    transfer are complete.				*
- *									*
- *    b) Re-enable BTE							*
- *		1) Write IMEM with BTE Enable + XXX bits
- *		2) Write IECLR with BTE clear bits
- *		3) Clear IIDSR INT_SENT bits.
- *									*
- ************************************************************************/
-
-/* 
- * >>> bte_crb_error_handler needs to be broken into two parts.  The
- * first should cleanup the CRB.  The second should wait until all bte
- * related CRB's are complete and then do the error reset.
+
+/*
+ * Bte error handling is done in two parts.  The first captures
+ * any crb related errors.  Since there can be multiple crbs per
+ * interface and multiple interfaces active, we need to wait until
+ * all active crbs are completed.  This is the first job of the
+ * second part error handler.  When all bte related CRBs are cleanly
+ * completed, it resets the interfaces and gets them ready for new
+ * transfers to be queued.
  */
-void
-bte_crb_error_handler(devfs_handle_t hub_v, int btenum, 
-		      int crbnum, ioerror_t *ioe, int bteop)
+
+
+void bte_error_handler(unsigned long);
+
+
 /*
- * Function: 	bte_crb_error_handler
- * Purpose:	Process a CRB for a specific HUB/BTE
- * Parameters:	hub_v	- vertex of hub in HW graph
- *		btenum	- bte number on hub (0 == a, 1 == b)
- *		crbnum	- crb number being processed
- * Notes: 
- *	This routine assumes serialization at a higher level. A CRB 
- *	should not be processed more than once. The error recovery 
- *	follows the following sequence - if you change this, be real
- *	sure about what you are doing. 
- *
+ * First part error handler.  This is called whenever any error CRB interrupt
+ * is generated by the II.
  */
+void
+bte_crb_error_handler(vertex_hdl_t hub_v, int btenum,
+		      int crbnum, ioerror_t * ioe, int bteop)
 {
-        hubinfo_t	hinfo;
-	icrba_t		crba; 
-	icrbb_t		crbb; 
-	nasid_t		n;
-	hubreg_t	iidsr, imem, ieclr;
+	hubinfo_t hinfo;
+	struct bteinfo_s *bte;
+
 
 	hubinfo_get(hub_v, &hinfo);
+	bte = &hinfo->h_nodepda->bte_if[btenum];
+
+	/*
+	 * The caller has already figured out the error type, we save that
+	 * in the bte handle structure for the thread excercising the
+	 * interface to consume.
+	 */
+	switch (ioe->ie_errortype) {
+	case IIO_ICRB_ECODE_PERR:
+		bte->bh_error = BTEFAIL_POISON;
+		break;
+	case IIO_ICRB_ECODE_WERR:
+		bte->bh_error = BTEFAIL_PROT;
+		break;
+	case IIO_ICRB_ECODE_AERR:
+		bte->bh_error = BTEFAIL_ACCESS;
+		break;
+	case IIO_ICRB_ECODE_TOUT:
+		bte->bh_error = BTEFAIL_TOUT;
+		break;
+	case IIO_ICRB_ECODE_XTERR:
+		bte->bh_error = BTEFAIL_XTERR;
+		break;
+	case IIO_ICRB_ECODE_DERR:
+		bte->bh_error = BTEFAIL_DIR;
+		break;
+	case IIO_ICRB_ECODE_PWERR:
+	case IIO_ICRB_ECODE_PRERR:
+		/* NO BREAK */
+	default:
+		bte->bh_error = BTEFAIL_ERROR;
+	}
+
+	bte->bte_error_count++;
 
+	BTE_PRINTK(("Got an error on cnode %d bte %d\n",
+		    bte->bte_cnode, bte->bte_num));
+	bte_error_handler((unsigned long) hinfo->h_nodepda);
+}
 
-	n = hinfo->h_nasid;
-	
 
+/*
+ * Second part error handler.  Wait until all BTE related CRBs are completed
+ * and then reset the interfaces.
+ */
+void
+bte_error_handler(unsigned long _nodepda)
+{
+	struct nodepda_s *err_nodepda = (struct nodepda_s *) _nodepda;
+	spinlock_t *recovery_lock = &err_nodepda->bte_recovery_lock;
+	struct timer_list *recovery_timer = &err_nodepda->bte_recovery_timer;
+	nasid_t nasid;
+	int i;
+	int valid_crbs;
+	unsigned long irq_flags;
+	volatile u64 *notify;
+	bte_result_t bh_error;
+	ii_imem_u_t imem;	/* II IMEM Register */
+	ii_icrb0_d_u_t icrbd;	/* II CRB Register D */
+	ii_ibcr_u_t ibcr;
+	ii_icmr_u_t icmr;
+
+
+	BTE_PRINTK(("bte_error_handler(%p) - %d\n", err_nodepda,
+		    smp_processor_id()));
+
+	spin_lock_irqsave(recovery_lock, irq_flags);
+
+	if ((err_nodepda->bte_if[0].bh_error == BTE_SUCCESS) &&
+	    (err_nodepda->bte_if[1].bh_error == BTE_SUCCESS)) {
+		BTE_PRINTK(("eh:%p:%d Nothing to do.\n", err_nodepda,
+			    smp_processor_id()));
+		spin_unlock_irqrestore(recovery_lock, irq_flags);
+		return;
+	}
 	/*
-	 * The following 10 lines (or so) are adapted from IRIXs
-	 * bte_crb_error function.  No clear documentation tells
-	 * why the crb needs to complete normally in order for
-	 * the BTE to resume normal operations.  This first step
-	 * appears vital!
+	 * Lock all interfaces on this node to prevent new transfers
+	 * from being queued.
 	 */
+	for (i = 0; i < BTES_PER_NODE; i++) {
+		if (err_nodepda->bte_if[i].cleanup_active) {
+			continue;
+		}
+		spin_lock(&err_nodepda->bte_if[i].spinlock);
+		BTE_PRINTK(("eh:%p:%d locked %d\n", err_nodepda,
+			    smp_processor_id(), i));
+		err_nodepda->bte_if[i].cleanup_active = 1;
+	}
+
+	/* Determine information about our hub */
+	nasid = cnodeid_to_nasid(err_nodepda->bte_if[0].bte_cnode);
+
 
 	/*
-	 * Zero error and error code to prevent error_dump complaining
-	 * about these CRBs. Copy the CRB to the notification line.
-	 * The crb address is in shub format (physical address shifted
-	 * right by cacheline size).
+	 * A BTE transfer can use multiple CRBs.  We need to make sure
+	 * that all the BTE CRBs are complete (or timed out) before
+	 * attempting to clean up the error.  Resetting the BTE while
+	 * there are still BTE CRBs active will hang the BTE.
+	 * We should look at all the CRBs to see if they are allocated
+	 * to the BTE and see if they are still active.  When none
+	 * are active, we can continue with the cleanup.
+	 *
+	 * We also want to make sure that the local NI port is up.
+	 * When a router resets the NI port can go down, while it
+	 * goes through the LLP handshake, but then comes back up.
 	 */
-	crbb.ii_icrb0_b_regval = REMOTE_HUB_L(n, IIO_ICRB_B(crbnum));
-	crbb.b_error=0;
-	crbb.b_ecode=0;
-	REMOTE_HUB_S(n, IIO_ICRB_B(crbnum), crbb.ii_icrb0_b_regval);
-
-	crba.ii_icrb0_a_regval = REMOTE_HUB_L(n, IIO_ICRB_A(crbnum));
-	crba.a_addr = TO_PHYS((u64)&nodepda->bte_if[btenum].notify) >> 3;
-	crba.a_valid = 1;
-	REMOTE_HUB_S(n, IIO_ICRB_A(crbnum), crba.ii_icrb0_a_regval);
-
-	REMOTE_HUB_S(n, IIO_ICCR, 
-		     IIO_ICCR_PENDING | IIO_ICCR_CMD_FLUSH | crbnum);
-
-	while (REMOTE_HUB_L(n, IIO_ICCR) & IIO_ICCR_PENDING)
-	    ;
-
-
-	/* Terminate the BTE. */
-	/* >>> The other bte transfer will need to be restarted. */
-	HUB_L((shubreg_t *)((nodepda->bte_if[btenum].bte_base_addr +
-		       IIO_IBCT0 - IIO_IBLS0)));
-
-	imem = REMOTE_HUB_L(n, IIO_IMEM);
-	ieclr = REMOTE_HUB_L(n, IIO_IECLR);
-	if (btenum == 0) {
-		imem |= IIO_IMEM_W0ESD | IIO_IMEM_B0ESD;
-		ieclr|= IECLR_BTE0;
-	} else {
-		imem |= IIO_IMEM_W0ESD | IIO_IMEM_B1ESD;
-		ieclr|= IECLR_BTE1;
-	}
-	REMOTE_HUB_S(n, IIO_IMEM, imem);
-	REMOTE_HUB_S(n, IIO_IECLR, ieclr);
-		
-	iidsr  = REMOTE_HUB_L(n, IIO_IIDSR);
-	iidsr &= ~IIO_IIDSR_SENT_MASK;
-	iidsr |= IIO_IIDSR_ENB_MASK;
-	REMOTE_HUB_S(n, IIO_IIDSR, iidsr);
+	icmr.ii_icmr_regval = REMOTE_HUB_L(nasid, IIO_ICMR);
+	if (icmr.ii_icmr_fld_s.i_crb_mark != 0) {
+		/*
+		 * There are errors which still need to be cleaned up by
+		 * hubiio_crb_error_handler
+		 */
+		mod_timer(recovery_timer, HZ * 5);
+		BTE_PRINTK(("eh:%p:%d Marked Giving up\n", err_nodepda,
+			    smp_processor_id()));
+		spin_unlock_irqrestore(recovery_lock, irq_flags);
+		return;
+	}
+	if (icmr.ii_icmr_fld_s.i_crb_vld != 0) {
 
+		valid_crbs = icmr.ii_icmr_fld_s.i_crb_vld;
 
- 	bte_reset_nasid(n);
+		for (i = 0; i < IIO_NUM_CRBS; i++) {
+			if (!((1 << i) & valid_crbs)) {
+				/* This crb was not marked as valid, ignore */
+				continue;
+			}
+			icrbd.ii_icrb0_d_regval =
+			    REMOTE_HUB_L(nasid, IIO_ICRB_D(i));
+			if (icrbd.d_bteop) {
+				mod_timer(recovery_timer, HZ * 5);
+				BTE_PRINTK(("eh:%p:%d Valid %d, Giving up\n",
+					 err_nodepda, smp_processor_id(), i));
+				spin_unlock_irqrestore(recovery_lock,
+						       irq_flags);
+				return;
+			}
+		}
+	}
 
-	*nodepda->bte_if[btenum].most_rcnt_na = IBLS_ERROR;
-}
 
+	BTE_PRINTK(("eh:%p:%d Cleaning up\n", err_nodepda,
+		    smp_processor_id()));
+	/* Reenable both bte interfaces */
+	imem.ii_imem_regval = REMOTE_HUB_L(nasid, IIO_IMEM);
+	imem.ii_imem_fld_s.i_b0_esd = imem.ii_imem_fld_s.i_b1_esd = 1;
+	REMOTE_HUB_S(nasid, IIO_IMEM, imem.ii_imem_regval);
+
+	/* Reinitialize both BTE state machines. */
+	ibcr.ii_ibcr_regval = REMOTE_HUB_L(nasid, IIO_IBCR);
+	ibcr.ii_ibcr_fld_s.i_soft_reset = 1;
+	REMOTE_HUB_S(nasid, IIO_IBCR, ibcr.ii_ibcr_regval);
+
+
+	for (i = 0; i < BTES_PER_NODE; i++) {
+		bh_error = err_nodepda->bte_if[i].bh_error;
+		if (bh_error != BTE_SUCCESS) {
+			/* There is an error which needs to be notified */
+			notify = err_nodepda->bte_if[i].most_rcnt_na;
+			BTE_PRINTK(("cnode %d bte %d error=0x%lx\n",
+				    err_nodepda->bte_if[i].bte_cnode,
+				    err_nodepda->bte_if[i].bte_num,
+				    IBLS_ERROR | (u64) bh_error));
+			*notify = IBLS_ERROR | bh_error;
+			err_nodepda->bte_if[i].bh_error = BTE_SUCCESS;
+		}
+
+		err_nodepda->bte_if[i].cleanup_active = 0;
+		BTE_PRINTK(("eh:%p:%d Unlocked %d\n", err_nodepda,
+			    smp_processor_id(), i));
+		spin_unlock(&pda->cpu_bte_if[i]->spinlock);
+	}
+
+	del_timer(recovery_timer);
+
+	spin_unlock_irqrestore(recovery_lock, irq_flags);
+}
diff -Nru a/arch/ia64/sn/io/sn2/kdba_io.c b/arch/ia64/sn/io/sn2/kdba_io.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/io/sn2/kdba_io.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,76 @@
+/*
+ * Kernel Debugger Architecture Dependent POD functions.
+ *
+ * Copyright (C) 1999-2003 Silicon Graphics, Inc.  All Rights Reserved
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of version 2 of the GNU General Public License
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it would be useful, but
+ * WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+ *
+ * Further, this software is distributed without any warranty that it is
+ * free of the rightful claim of any third person regarding infringement
+ * or the like.  Any license provided herein, whether implied or
+ * otherwise, applies only to this software file.  Patent licenses, if
+ * any, provided herein do not apply to combinations of this program with
+ * other software, or any other product whatsoever.
+ *
+ * You should have received a copy of the GNU General Public
+ * License along with this program; if not, write the Free Software
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ *
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy,
+ * Mountain View, CA  94043, or:
+ *
+ * http://www.sgi.com
+ *
+ * For further information regarding this notice, see:
+ *
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
+#include <linux/types.h>
+#include <linux/kdb.h>
+//#include <linux/kdbprivate.h>
+
+/**
+ * kdba_io - enter POD mode from kdb
+ * @argc: arg count
+ * @argv: arg values
+ * @envp: kdb env. vars
+ * @regs: current register state
+ *
+ * Enter POD mode from kdb using SGI SN specific SAL function call.
+ */
+static int
+kdba_io(int argc, const char **argv, const char **envp, struct pt_regs *regs)
+{
+	kdb_printf("kdba_io entered with addr 0x%p\n", (void *) regs);
+
+        return(0);
+}
+
+/**
+ * kdba_io_init - register 'io' command with kdb
+ *
+ * Register the 'io' command with kdb at load time.
+ */
+void
+kdba_io_init(void)
+{
+        kdb_register("io", kdba_io, "<vaddr>", "Display IO Contents", 0);
+}
+
+/**
+ * kdba_io_exit - unregister the 'io' command
+ *
+ * Tell kdb that the 'io' command is no longer available.
+ */
+static void __exit
+kdba_exit(void)
+{
+        kdb_unregister("io");
+}
diff -Nru a/arch/ia64/sn/io/sn2/klconflib.c b/arch/ia64/sn/io/sn2/klconflib.c
--- a/arch/ia64/sn/io/sn2/klconflib.c	Wed Jun 18 23:42:05 2003
+++ b/arch/ia64/sn/io/sn2/klconflib.c	Wed Jun 18 23:42:05 2003
@@ -24,8 +24,6 @@
 #include <asm/sn/router.h>
 #include <asm/sn/xtalk/xbow.h>
 
-#define printf printk
-int hasmetarouter;
 
 #define LDEBUG 0
 #define NIC_UNKNOWN ((nic_t) -1)
@@ -37,10 +35,11 @@
 #define DBG(x...)
 #endif /* DEBUG_KLGRAPH */
 
-static void sort_nic_names(lboard_t *) ;
-
 u64 klgraph_addr[MAX_COMPACT_NODES];
-int module_number = 0;
+static int hasmetarouter;
+
+
+char brick_types[MAX_BRICK_TYPES + 1] = "crikxdpn%#=012345";
 
 lboard_t *
 find_lboard(lboard_t *start, unsigned char brd_type)
@@ -135,23 +134,6 @@
         return (lboard_t *)NULL;
 }
 
-lboard_t *
-find_lboard_module_class(lboard_t *start, geoid_t geoid,
-                                                unsigned char brd_type)
-{
-	while (start) {
-		DBG("find_lboard_module_class: lboard 0x%p, start->brd_geoid 0x%x, mod 0x%x, start->brd_type 0x%x, brd_type 0x%x\n", start, start->brd_geoid, geoid, start->brd_type, brd_type);
-
-		if (geo_cmp(start->brd_geoid, geoid) &&
-			(KLCLASS(start->brd_type) == KLCLASS(brd_type)))
-			return start;
-		start = KLCF_NEXT(start);
-	}
-
-	/* Didn't find it. */
-	return (lboard_t *)NULL;
-}
-
 /*
  * Convert a NIC name to a name for use in the hardware graph.
  */
@@ -205,63 +187,6 @@
 }
 
 /*
- * Find the lboard structure and get the board name.
- * If we can't find the structure or it's too low a revision,
- * use default name.
- */
-lboard_t *
-get_board_name(nasid_t nasid, geoid_t geoid, slotid_t slot, char *name)
-{
-	lboard_t *brd;
-
-	brd = find_lboard_modslot((lboard_t *)KL_CONFIG_INFO(nasid),
-				  geoid);
-
-#ifndef _STANDALONE
-	{
-		cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
-
-		if (!brd && (NODEPDA(cnode)->xbow_peer != INVALID_NASID))
-			brd = find_lboard_modslot((lboard_t *)
-				KL_CONFIG_INFO(NODEPDA(cnode)->xbow_peer),
-				geoid);
-	}
-#endif
-
-	if (!brd || (brd->brd_sversion < 2)) {
-		strcpy(name, EDGE_LBL_XWIDGET);
-	} else {
-		nic_name_convert(brd->brd_name, name);
-	}
-
-	/*
-	 * PV # 540860
-	 * If the name is not 'baseio'
-	 * get the lowest of all the names in the nic string.
-	 * This is needed for boards like divo, which can have
-	 * a bunch of daughter cards, but would like to be called
-	 * divo. We could do this for baseio
-	 * but it has some special case names that we would not
-	 * like to disturb at this point.
-	 */
-
-	/* gfx boards don't need any of this name scrambling */
-	if (brd && (KLCLASS(brd->brd_type) == KLCLASS_GFX)) {
-		return(brd);
-	}
-
-	if (!(!strcmp(name, "baseio") )) {
-		if (brd) {
-			sort_nic_names(brd) ;
-			/* Convert to small case, '-' to '_' etc */
-			nic_name_convert(brd->brd_name, name) ;
-		}
-	}
-
-	return(brd);
-}
-
-/*
  * get_actual_nasid
  *
  *	Completely disabled brds have their klconfig on 
@@ -341,12 +266,20 @@
 			board_name = EDGE_LBL_IO;
 			break;
 		case KLCLASS_IOBRICK:
-			if (brd->brd_type == KLTYPE_PBRICK)
+			if (brd->brd_type == KLTYPE_PXBRICK)
+				board_name = EDGE_LBL_PXBRICK;
+			else if (brd->brd_type == KLTYPE_IXBRICK)
+				board_name = EDGE_LBL_IXBRICK;
+			else if (brd->brd_type == KLTYPE_PBRICK)
 				board_name = EDGE_LBL_PBRICK;
 			else if (brd->brd_type == KLTYPE_IBRICK)
 				board_name = EDGE_LBL_IBRICK;
 			else if (brd->brd_type == KLTYPE_XBRICK)
 				board_name = EDGE_LBL_XBRICK;
+			else if (brd->brd_type == KLTYPE_PEBRICK)
+				board_name = EDGE_LBL_PEBRICK;
+			else if (brd->brd_type == KLTYPE_CGBRICK)
+				board_name = EDGE_LBL_CGBRICK;
 			else
 				board_name = EDGE_LBL_IOBRICK;
 			break;
@@ -623,182 +556,6 @@
 
 #include "asm/sn/sn_private.h"
 
-xwidgetnum_t
-nodevertex_widgetnum_get(devfs_handle_t node_vtx)
-{
-	hubinfo_t hubinfo_p;
-
-	hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO, 
-			     (arbitrary_info_t *) &hubinfo_p);
-	return(hubinfo_p->h_widgetid);
-}
-
-devfs_handle_t
-nodevertex_xbow_peer_get(devfs_handle_t node_vtx)
-{
-	hubinfo_t hubinfo_p;
-	nasid_t xbow_peer_nasid;
-	cnodeid_t xbow_peer;
-
-	hwgraph_info_get_LBL(node_vtx, INFO_LBL_NODE_INFO,
-				     (arbitrary_info_t *) &hubinfo_p);
-	xbow_peer_nasid = hubinfo_p->h_nodepda->xbow_peer;
-	if(xbow_peer_nasid == INVALID_NASID) 
-			return ( (devfs_handle_t)-1);
-	xbow_peer = NASID_TO_COMPACT_NODEID(xbow_peer_nasid);
-	return(NODEPDA(xbow_peer)->node_vertex);
-}
-
-/* NIC Sorting Support */
-
-#define MAX_NICS_PER_STRING 	32
-#define MAX_NIC_NAME_LEN	32
-
-static char *
-get_nic_string(lboard_t *lb)
-{
-        int         	i;
-        klinfo_t    	*k = NULL ;
-    	klconf_off_t    mfg_off = 0 ;
-    	char            *mfg_nic = NULL ;
-
-        for (i = 0; i < KLCF_NUM_COMPS(lb); i++) {
-                k = KLCF_COMP(lb, i) ;
-                switch(k->struct_type) {
-                        case KLSTRUCT_BRI:
-            			mfg_off = ((klbri_t *)k)->bri_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_HUB:
-            			mfg_off = ((klhub_t *)k)->hub_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_ROU:
-            			mfg_off = ((klrou_t *)k)->rou_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_GFX:
-            			mfg_off = ((klgfx_t *)k)->gfx_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_TPU:
-            			mfg_off = ((kltpu_t *)k)->tpu_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_GSN_A:
-                        case KLSTRUCT_GSN_B:
-            			mfg_off = ((klgsn_t *)k)->gsn_mfg_nic ;
-				break ;
-
-                        case KLSTRUCT_XTHD:
-                                mfg_off = ((klxthd_t *)k)->xthd_mfg_nic ;
-                                break;
-
-			default:
-				mfg_off = 0 ;
-                                break ;
-                }
-		if (mfg_off)
-			break ;
-        }
-
-	if ((mfg_off) && (k))
-		mfg_nic = (char *)NODE_OFFSET_TO_K0(k->nasid, mfg_off) ;
-
-        return mfg_nic ;
-}
-
-char *
-get_first_string(char **ptrs, int n)
-{
-        int     i ;
-        char    *tmpptr ;
-
-        if ((ptrs == NULL) || (n == 0))
-                return NULL ;
-
-        tmpptr = ptrs[0] ;
-
-        if (n == 1)
-                return tmpptr ;
-
-        for (i = 0 ; i < n ; i++) {
-                if (strcmp(tmpptr, ptrs[i]) > 0)
-                        tmpptr = ptrs[i] ;
-        }
-
-        return tmpptr ;
-}
-
-int
-get_ptrs(char *idata, char **ptrs, int n, char *label)
-{
-        int     i = 0 ;
-        char    *tmp = idata ;
-
-        if ((ptrs == NULL) || (idata == NULL) || (label == NULL) || (n == 0))
-                return 0 ;
-
-        while  ( (tmp = strstr(tmp, label)) ){
-                tmp += strlen(label) ;
-                /* check for empty name field, and last NULL ptr */
-                if ((i < (n-1)) && (*tmp != ';')) {
-                        ptrs[i++] = tmp ;
-                }
-        }
-
-        ptrs[i] = NULL ;
-
-        return i ;
-}
-
-/*
- * sort_nic_names
- *
- * 	Does not really do sorting. Find the alphabetically lowest
- *	name among all the nic names found in a nic string.
- *
- * Return:
- *	Nothing
- *
- * Side Effects:
- *
- *	lb->brd_name gets the new name found
- */
-
-static void
-sort_nic_names(lboard_t *lb)
-{
-	char 	*nic_str ;
-        char    *ptrs[MAX_NICS_PER_STRING] ;
-        char    name[MAX_NIC_NAME_LEN] ;
-        char    *tmp, *tmp1 ;
-
-	*name = 0 ;
-
-	/* Get the nic pointer from the lb */
-
-	if ((nic_str = get_nic_string(lb)) == NULL)
-		return ;
-
-        tmp = get_first_string(ptrs,
-                        get_ptrs(nic_str, ptrs, MAX_NICS_PER_STRING, "Name:")) ;
-
-        if (tmp == NULL)
-		return ;
-
-        if  ( (tmp1 = strchr(tmp, ';')) )
-                strlcpy(name, tmp, tmp1-tmp);
-        else
-                strlcpy(name, tmp, (sizeof(name)));
-
-	strlcpy(lb->brd_name, name, sizeof(lb->brd_name)) ;
-}
-
-
-
-char brick_types[MAX_BRICK_TYPES + 1] = "crikxdpn%#012345";
-
 /*
  * Format a module id for printing.
  */
@@ -811,6 +568,7 @@
 	rack = MODULE_GET_RACK(m);
 	ASSERT(MODULE_GET_BTYPE(m) < MAX_BRICK_TYPES);
 	brickchar = MODULE_GET_BTCHAR(m);
+
 	position = MODULE_GET_BPOS(m);
 
 	if (fmt == MODULE_FORMAT_BRIEF) {
diff -Nru a/arch/ia64/sn/io/sn2/klgraph.c b/arch/ia64/sn/io/sn2/klgraph.c
--- a/arch/ia64/sn/io/sn2/klgraph.c	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/sn/io/sn2/klgraph.c	Wed Jun 18 23:42:08 2003
@@ -23,7 +23,6 @@
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
 #include <asm/sn/kldir.h>
-#include <asm/sn/gda.h> 
 #include <asm/sn/klconfig.h>
 #include <asm/sn/router.h>
 #include <asm/sn/xtalk/xbow.h>
@@ -42,7 +41,7 @@
 
 extern char arg_maxnodes[];
 extern u64 klgraph_addr[];
-void mark_cpuvertex_as_cpu(devfs_handle_t vhdl, cpuid_t cpuid);
+void mark_cpuvertex_as_cpu(vertex_hdl_t vhdl, cpuid_t cpuid);
 
 
 /*
@@ -69,7 +68,7 @@
  * Add detailed disabled cpu inventory info to the hardware graph.
  */
 void
-klhwg_disabled_cpu_invent_info(devfs_handle_t cpuv,
+klhwg_disabled_cpu_invent_info(vertex_hdl_t cpuv,
                                cnodeid_t cnode,
                                klcpu_t *cpu, slotid_t slot)
 {
@@ -118,7 +117,7 @@
  * Add detailed cpu inventory info to the hardware graph.
  */
 void
-klhwg_cpu_invent_info(devfs_handle_t cpuv,
+klhwg_cpu_invent_info(vertex_hdl_t cpuv,
 			cnodeid_t cnode,
 			klcpu_t *cpu)
 {
@@ -153,7 +152,7 @@
  * as a part of detailed inventory info in the hwgraph.
  */
 void
-klhwg_baseio_inventory_add(devfs_handle_t baseio_vhdl,cnodeid_t cnode)
+klhwg_baseio_inventory_add(vertex_hdl_t baseio_vhdl,cnodeid_t cnode)
 {
 	invent_miscinfo_t	*baseio_inventory;
 	unsigned char		version = 0,revision = 0;
@@ -177,20 +176,11 @@
 				sizeof(invent_miscinfo_t));
 }
 
-char	*hub_rev[] = {
-	"0.0",
-	"1.0",
-	"2.0",
-	"2.1",
-	"2.2",
-	"2.3"
-};
-
 /*
  * Add detailed cpu inventory info to the hardware graph.
  */
 void
-klhwg_hub_invent_info(devfs_handle_t hubv,
+klhwg_hub_invent_info(vertex_hdl_t hubv,
 		      cnodeid_t cnode, 
 		      klhub_t *hub)
 {
@@ -215,10 +205,10 @@
 
 /* ARGSUSED */
 void
-klhwg_add_hub(devfs_handle_t node_vertex, klhub_t *hub, cnodeid_t cnode)
+klhwg_add_hub(vertex_hdl_t node_vertex, klhub_t *hub, cnodeid_t cnode)
 {
-	devfs_handle_t myhubv;
-	devfs_handle_t hub_mon;
+	vertex_hdl_t myhubv;
+	vertex_hdl_t hub_mon;
 	int rc;
 	extern struct file_operations shub_mon_fops;
 
@@ -226,7 +216,7 @@
 	(void) hwgraph_path_add(node_vertex, EDGE_LBL_HUB, &myhubv);
 	rc = device_master_set(myhubv, node_vertex);
 	hub_mon = hwgraph_register(myhubv, EDGE_LBL_PERFMON,
-		0, DEVFS_FL_AUTO_DEVNUM,
+		0, 0,
 		0, 0,
 		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
 		&shub_mon_fops, (void *)(long)cnode);
@@ -234,9 +224,9 @@
 
 /* ARGSUSED */
 void
-klhwg_add_disabled_cpu(devfs_handle_t node_vertex, cnodeid_t cnode, klcpu_t *cpu, slotid_t slot)
+klhwg_add_disabled_cpu(vertex_hdl_t node_vertex, cnodeid_t cnode, klcpu_t *cpu, slotid_t slot)
 {
-        devfs_handle_t my_cpu;
+        vertex_hdl_t my_cpu;
         char name[120];
         cpuid_t cpu_id;
 	nasid_t nasid;
@@ -257,9 +247,9 @@
 
 /* ARGSUSED */
 void
-klhwg_add_cpu(devfs_handle_t node_vertex, cnodeid_t cnode, klcpu_t *cpu)
+klhwg_add_cpu(vertex_hdl_t node_vertex, cnodeid_t cnode, klcpu_t *cpu)
 {
-        devfs_handle_t my_cpu, cpu_dir;
+        vertex_hdl_t my_cpu, cpu_dir;
         char name[120];
         cpuid_t cpu_id;
 	nasid_t nasid;
@@ -295,7 +285,7 @@
 	nasid_t hub_nasid;
 	cnodeid_t hub_cnode;
 	int widgetnum;
-	devfs_handle_t xbow_v, hubv;
+	vertex_hdl_t xbow_v, hubv;
 	/*REFERENCED*/
 	graph_error_t err;
 
@@ -363,12 +353,12 @@
 
 /* ARGSUSED */
 void
-klhwg_add_node(devfs_handle_t hwgraph_root, cnodeid_t cnode, gda_t *gdap)
+klhwg_add_node(vertex_hdl_t hwgraph_root, cnodeid_t cnode)
 {
 	nasid_t nasid;
 	lboard_t *brd;
 	klhub_t *hub;
-	devfs_handle_t node_vertex = NULL;
+	vertex_hdl_t node_vertex = NULL;
 	char path_buffer[100];
 	int rv;
 	char *s;
@@ -382,7 +372,7 @@
 	ASSERT(brd);
 
 	do {
-		devfs_handle_t cpu_dir;
+		vertex_hdl_t cpu_dir;
 
 		/* Generate a hardware graph path for this board. */
 		board_to_path(brd, path_buffer);
@@ -443,7 +433,7 @@
 		while (cpu) {
 			cpuid_t cpu_id;
 			cpu_id = nasid_slice_to_cpuid(nasid,cpu->cpu_info.physid);
-			if (cpu_enabled(cpu_id))
+			if (cpu_online(cpu_id))
 				klhwg_add_cpu(node_vertex, cnode, cpu);
 			else
 				klhwg_add_disabled_cpu(node_vertex, cnode, cpu, brd->brd_slot);
@@ -466,12 +456,12 @@
 
 /* ARGSUSED */
 void
-klhwg_add_all_routers(devfs_handle_t hwgraph_root)
+klhwg_add_all_routers(vertex_hdl_t hwgraph_root)
 {
 	nasid_t nasid;
 	cnodeid_t cnode;
 	lboard_t *brd;
-	devfs_handle_t node_vertex;
+	vertex_hdl_t node_vertex;
 	char path_buffer[100];
 	int rv;
 
@@ -525,14 +515,14 @@
 
 /* ARGSUSED */
 void
-klhwg_connect_one_router(devfs_handle_t hwgraph_root, lboard_t *brd,
+klhwg_connect_one_router(vertex_hdl_t hwgraph_root, lboard_t *brd,
 			 cnodeid_t cnode, nasid_t nasid)
 {
 	klrou_t *router;
 	char path_buffer[50];
 	char dest_path[50];
-	devfs_handle_t router_hndl;
-	devfs_handle_t dest_hndl;
+	vertex_hdl_t router_hndl;
+	vertex_hdl_t dest_hndl;
 	int rc;
 	int port;
 	lboard_t *dest_brd;
@@ -619,7 +609,7 @@
 
 
 void
-klhwg_connect_routers(devfs_handle_t hwgraph_root)
+klhwg_connect_routers(vertex_hdl_t hwgraph_root)
 {
 	nasid_t nasid;
 	cnodeid_t cnode;
@@ -652,15 +642,15 @@
 
 
 void
-klhwg_connect_hubs(devfs_handle_t hwgraph_root)
+klhwg_connect_hubs(vertex_hdl_t hwgraph_root)
 {
 	nasid_t nasid;
 	cnodeid_t cnode;
 	lboard_t *brd;
 	klhub_t *hub;
 	lboard_t *dest_brd;
-	devfs_handle_t hub_hndl;
-	devfs_handle_t dest_hndl;
+	vertex_hdl_t hub_hndl;
+	vertex_hdl_t dest_hndl;
 	char path_buffer[50];
 	char dest_path[50];
 	graph_error_t rc;
@@ -796,12 +786,12 @@
 }
 
 void
-klhwg_add_all_modules(devfs_handle_t hwgraph_root)
+klhwg_add_all_modules(vertex_hdl_t hwgraph_root)
 {
 	cmoduleid_t	cm;
 	char		name[128];
-	devfs_handle_t	vhdl;
-	devfs_handle_t  module_vhdl;
+	vertex_hdl_t	vhdl;
+	vertex_hdl_t  module_vhdl;
 	int		rc;
 	char		buffer[16];
 
@@ -837,12 +827,12 @@
 }
 
 void
-klhwg_add_all_nodes(devfs_handle_t hwgraph_root)
+klhwg_add_all_nodes(vertex_hdl_t hwgraph_root)
 {
 	cnodeid_t	cnode;
 
 	for (cnode = 0; cnode < numnodes; cnode++) {
-		klhwg_add_node(hwgraph_root, cnode, NULL);
+		klhwg_add_node(hwgraph_root, cnode);
 	}
 
 	for (cnode = 0; cnode < numnodes; cnode++) {
diff -Nru a/arch/ia64/sn/io/sn2/l1.c b/arch/ia64/sn/io/sn2/l1.c
--- a/arch/ia64/sn/io/sn2/l1.c	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/sn/io/sn2/l1.c	Wed Jun 18 23:42:08 2003
@@ -29,6 +29,8 @@
 #include <linux/slab.h>
 #include <linux/spinlock.h>
 #include <linux/delay.h>
+#include <linux/interrupt.h>
+#include <asm/io.h>
 #include <asm/sn/sgi.h>
 #include <asm/sn/io.h>
 #include <asm/sn/iograph.h>
@@ -36,7 +38,6 @@
 #include <asm/sn/hcl.h>
 #include <asm/sn/hcl_util.h>
 #include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/router.h>
 #include <asm/sn/module.h>
 #include <asm/sn/ksys/l1.h>
@@ -50,6 +51,9 @@
 
 #define UART_BAUD_RATE          57600
 
+static int L1_connected;	/* non-zero when interrupts are enabled */
+
+
 int 
 get_L1_baud(void)
 {
@@ -62,7 +66,23 @@
 int
 l1_get_intr_value( void )
 {
-	return(0);
+	cpuid_t intr_cpuid;
+	nasid_t console_nasid;
+	int major, minor;
+	extern nasid_t get_console_nasid(void);
+
+	/* if it is an old prom, run in poll mode */
+
+	major = sn_sal_rev_major();
+	minor = sn_sal_rev_minor();
+	if ( (major < 1) || ((major == 1) && (minor < 10)) ) {
+		/* before version 1.10 doesn't work */
+		return (0);
+	}
+
+	console_nasid = get_console_nasid();
+	intr_cpuid = NODEPDA(NASID_TO_COMPACT_NODEID(console_nasid))->node_first_cpu;
+	return CPU_VECTOR_TO_IRQ(intr_cpuid, SGI_UART_VECTOR);
 }
 
 /* Disconnect the callup functions - throw away interrupts */
@@ -74,19 +94,45 @@
 
 /* Set up uart interrupt handling for this node's uart */
 
-void
-l1_connect_intr(void *rx_notify, void *tx_notify)
+int
+l1_connect_intr(void *intr_func, void *arg, struct pt_regs *ep)
 {
-#if 0
-	// Will need code here for sn2 - something like this
-	console_nodepda = NODEPDA(NASID_TO_COMPACT_NODEID(get_master_nasid());
-	intr_connect_level(console_nodepda->node_first_cpu,
-                                SGI_UART_VECTOR, INTPEND0_MAXMASK,
-                                dummy_intr_func);
-	request_irq(SGI_UART_VECTOR | (console_nodepda->node_first_cpu << 8),
-                                intr_func, SA_INTERRUPT | SA_SHIRQ,
-                                "l1_protocol_driver", (void *)sc);
-#endif
+	cpuid_t intr_cpuid;
+	nasid_t console_nasid;
+	unsigned int console_irq;
+	int result;
+	extern int intr_connect_level(cpuid_t, int, ilvl_t, intr_func_t);
+	extern nasid_t get_console_nasid(void);
+
+
+	/* don't call to connect multiple times - we DON'T support changing the handler */
+
+	if ( !L1_connected ) {
+		L1_connected++;
+		console_nasid = get_console_nasid();
+		intr_cpuid = NODEPDA(NASID_TO_COMPACT_NODEID(console_nasid))->node_first_cpu;
+		console_irq = CPU_VECTOR_TO_IRQ(intr_cpuid, SGI_UART_VECTOR);
+		result = intr_connect_level(intr_cpuid, SGI_UART_VECTOR,
+                                	0 /*not used*/, 0 /*not used*/);
+		if (result != SGI_UART_VECTOR) {
+			if (result < 0)
+				printk(KERN_WARNING "L1 console driver : intr_connect_level failed %d\n", result);
+        		else
+				printk(KERN_WARNING "L1 console driver : intr_connect_level returns wrong bit %d\n", result);
+			return (-1);
+		}
+
+		result = request_irq(console_irq, intr_func, SA_INTERRUPT,
+					"SGI L1 console driver", (void *)arg);
+		if (result < 0) {
+			printk(KERN_WARNING "L1 console driver : request_irq failed %d\n", result);
+			return (-1);
+		}
+
+		/* ask SAL to turn on interrupts in the UART itself */
+		ia64_sn_console_intr_enable(SAL_CONSOLE_INTR_RECV);
+	}
+	return (0);
 }
 
 
@@ -195,7 +241,7 @@
 int
 l1_serial_out( char *str, int len )
 {
-	int counter = len;
+	int tmp;
 
 	/* Ignore empty messages */
 	if ( len == 0 )
@@ -216,6 +262,8 @@
 	if ( IS_RUNNING_ON_SIMULATOR() ) {
 		extern u64 master_node_bedrock_address;
 		void early_sn_setup(void);
+		int counter = len;
+
 		if (!master_node_bedrock_address)
 			early_sn_setup();
 		if ( master_node_bedrock_address != (u64)0 ) {
@@ -237,8 +285,9 @@
 	}
 
 	/* Attempt to write things out thru the sal */
-	if ( ia64_sn_console_putb(str, len) )
-		return(0);
-
-	return((counter <= 0) ? 0 : (len - counter));
+	if ( L1_connected )
+		tmp = ia64_sn_console_xmit_chars(str, len);
+	else
+		tmp = ia64_sn_console_putb(str, len);
+	return ((tmp < 0) ? 0 : tmp);
 }
diff -Nru a/arch/ia64/sn/io/sn2/l1_command.c b/arch/ia64/sn/io/sn2/l1_command.c
--- a/arch/ia64/sn/io/sn2/l1_command.c	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/sn/io/sn2/l1_command.c	Wed Jun 18 23:42:06 2003
@@ -16,7 +16,6 @@
 #include <asm/sn/hcl.h>
 #include <asm/sn/hcl_util.h>
 #include <asm/sn/labelcl.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/router.h>
 #include <asm/sn/module.h>
 #include <asm/sn/ksys/l1.h>
@@ -26,37 +25,6 @@
 #include <asm/sn/sn_sal.h>
 #include <linux/ctype.h>
 
-#define ELSC_TIMEOUT	1000000		/* ELSC response timeout (usec) */
-#define LOCK_TIMEOUT	5000000		/* Hub lock timeout (usec) */
-
-#define hub_cpu_get()	0
-
-#define LBYTE(caddr)	(*(char *) caddr)
-
-extern char *bcopy(const char * src, char * dest, int count);
-
-#define LDEBUG		0
-
-/*
- * ELSC data is in NVRAM page 7 at the following offsets.
- */
-
-#define NVRAM_MAGIC_AD	0x700		/* magic number used for init */
-#define NVRAM_PASS_WD	0x701		/* password (4 bytes in length) */
-#define NVRAM_DBG1	0x705		/* virtual XOR debug switches */
-#define NVRAM_DBG2	0x706		/* physical XOR debug switches */
-#define NVRAM_CFG	0x707		/* ELSC Configuration info */
-#define NVRAM_MODULE	0x708		/* system module number */
-#define NVRAM_BIST_FLG	0x709		/* BIST flags (2 bits per nodeboard) */
-#define NVRAM_PARTITION 0x70a		/* module's partition id */
-#define	NVRAM_DOMAIN	0x70b		/* module's domain id */
-#define	NVRAM_CLUSTER	0x70c		/* module's cluster id */
-#define	NVRAM_CELL	0x70d		/* module's cellid */
-
-#define NVRAM_MAGIC_NO	0x37		/* value of magic number */
-#define NVRAM_SIZE	16		/* 16 bytes in nvram */
-
-
 /* elsc_display_line writes up to 12 characters to either the top or bottom
  * line of the L1 display.  line points to a buffer containing the message
  * to be displayed.  The zero-based line number is specified by lnum (so
@@ -69,6 +37,7 @@
     return 0;
 }
 
+
 /*
  * iobrick routines
  */
@@ -88,9 +57,9 @@
 	if ( ia64_sn_sysctl_iobrick_module_get(nasid, &result) )
 		return( ELSC_ERROR_CMD_SEND );
 
-	*rack = (result & L1_ADDR_RACK_MASK) >> L1_ADDR_RACK_SHFT;
-	*bay = (result & L1_ADDR_BAY_MASK) >> L1_ADDR_BAY_SHFT;
-	*brick_type = (result & L1_ADDR_TYPE_MASK) >> L1_ADDR_TYPE_SHFT;
+	*rack = (result & MODULE_RACK_MASK) >> MODULE_RACK_SHFT;
+	*bay = (result & MODULE_BPOS_MASK) >> MODULE_BPOS_SHFT;
+	*brick_type = (result & MODULE_BTYPE_MASK) >> MODULE_BTYPE_SHFT;
 	*brick_type = toupper(*brick_type);
 
 	return 0;
@@ -99,14 +68,12 @@
 
 int iomoduleid_get(nasid_t nasid)
 {
-
 	int result = 0;
 
 	if ( ia64_sn_sysctl_iobrick_module_get(nasid, &result) )
 		return( ELSC_ERROR_CMD_SEND );
 
 	return result;
-
 }
 
 int iobrick_module_get(nasid_t nasid)
@@ -142,11 +109,15 @@
     RACK_ADD_NUM(rack, t);
 
     switch( brick_type ) {
-      case 'I': 
+      case L1_BRICKTYPE_IX: 
+	brick_type = MODULE_IXBRICK; break;
+      case L1_BRICKTYPE_PX: 
+	brick_type = MODULE_PXBRICK; break;
+      case L1_BRICKTYPE_I: 
 	brick_type = MODULE_IBRICK; break;
-      case 'P':
+      case L1_BRICKTYPE_P:
 	brick_type = MODULE_PBRICK; break;
-      case 'X':
+      case L1_BRICKTYPE_X:
 	brick_type = MODULE_XBRICK; break;
     }
 
@@ -154,7 +125,7 @@
 
     return ret;
 }
-#ifdef CONFIG_PCI
+
 /*
  * iobrick_module_get_nasid() returns a module_id which has the brick
  * type encoded in bits 15-12, but this is not the true brick type...
@@ -179,29 +150,54 @@
 
     /* convert to a module.h brick type */
     for( t = 0; t < MAX_BRICK_TYPES; t++ ) {
-        if( brick_types[t] == type )
+        if( brick_types[t] == type ) {
             return t;
+	}
     }
 
     return -1;    /* unknown brick */
 }
-#endif
+
 int iobrick_module_get_nasid(nasid_t nasid)
 {
     int io_moduleid;
 
-#ifdef PIC_LATER
-    uint rack, bay;
+    io_moduleid = iobrick_module_get(nasid);
+    return io_moduleid;
+}
+
+/*
+ * given a L1 bricktype, return a bricktype string.  This string is the
+ * string that will be used in the hwpath for I/O bricks
+ */
+char *
+iobrick_L1bricktype_to_name(int type)
+{
+    switch (type)
+    {
+    default:
+        return("Unknown");
+
+    case L1_BRICKTYPE_X:
+        return("Xbrick");
 
-    if (PEBRICK_NODE(nasid)) {
-        if (peer_iobrick_rack_bay_get(nasid, &rack, &bay)) {
-            printf("Could not read rack and bay location "
-                   "of PEBrick at nasid %d\n", nasid);
-        }
+    case L1_BRICKTYPE_I:
+        return("Ibrick");
 
-        io_moduleid = peer_iobrick_module_get(sc, rack, bay);
+    case L1_BRICKTYPE_P:
+        return("Pbrick");
+
+    case L1_BRICKTYPE_PX:
+        return("PXbrick");
+
+    case L1_BRICKTYPE_IX:
+        return("IXbrick");
+
+    case L1_BRICKTYPE_C:
+        return("Cbrick");
+
+    case L1_BRICKTYPE_R:
+        return("Rbrick");
     }
-#endif	/* PIC_LATER */
-    io_moduleid = iobrick_module_get(nasid);
-    return io_moduleid;
 }
+
diff -Nru a/arch/ia64/sn/io/sn2/ml_SN_init.c b/arch/ia64/sn/io/sn2/ml_SN_init.c
--- a/arch/ia64/sn/io/sn2/ml_SN_init.c	Wed Jun 18 23:42:05 2003
+++ b/arch/ia64/sn/io/sn2/ml_SN_init.c	Wed Jun 18 23:42:05 2003
@@ -19,25 +19,12 @@
 #include <asm/sn/sn_private.h>
 #include <asm/sn/klconfig.h>
 #include <asm/sn/sn_cpuid.h>
-#include <asm/sn/snconfig.h>
 
-extern int numcpus;
-extern char arg_maxnodes[];
 extern cpuid_t master_procid;
-
-extern int hasmetarouter;
-
 int		maxcpus;
-cpumask_t	boot_cpumask;
-hubreg_t	region_mask = 0;
-
 
 extern xwidgetnum_t hub_widget_id(nasid_t);
 
-extern int valid_icache_reasons;	/* Reasons to flush the icache */
-extern int valid_dcache_reasons;	/* Reasons to flush the dcache */
-extern u_char miniroot;
-extern volatile int	need_utlbmiss_patch;
 extern void iograph_early_init(void);
 
 nasid_t master_nasid = INVALID_NASID;		/* This is the partition master nasid */
@@ -75,9 +62,6 @@
 
 	/* early initialization of iograph */
 	iograph_early_init();
-
-	/* Initialize Hub Pseudodriver Management */
-	hubdev_init();
 }
 
 
@@ -121,16 +105,6 @@
 	npda->geoid.any.type = GEO_TYPE_INVALID;
 
 	mutex_init_locked(&npda->xbow_sema); /* init it locked? */
-}
-
-/* XXX - Move the interrupt stuff to intr.c ? */
-/*
- * Set up the platform-dependent fields in the processor pda.
- * Must be done _after_ init_platform_nodepda().
- * If we need a lock here, something else is wrong!
- */
-void init_platform_pda(cpuid_t cpu)
-{
 }
 
 void
diff -Nru a/arch/ia64/sn/io/sn2/ml_SN_intr.c b/arch/ia64/sn/io/sn2/ml_SN_intr.c
--- a/arch/ia64/sn/io/sn2/ml_SN_intr.c	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/sn/io/sn2/ml_SN_intr.c	Wed Jun 18 23:42:08 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 /*
@@ -40,11 +40,14 @@
 #include <asm/sal.h>
 #include <asm/sn/sn_sal.h>
 
-extern irqpda_t	*irqpdaindr[];
-extern cnodeid_t master_node_get(devfs_handle_t vhdl);
+extern irqpda_t	*irqpdaindr;
+extern cnodeid_t master_node_get(vertex_hdl_t vhdl);
 extern nasid_t master_nasid;
 
 //  Initialize some shub registers for interrupts, both IO and error.
+//  
+
+
 
 void
 intr_init_vecblk( nodepda_t *npda,
@@ -58,6 +61,8 @@
 	nodepda_t		*lnodepda;
 	sh_ii_int0_enable_u_t	ii_int_enable;
 	sh_int_node_id_config_u_t	node_id_config;
+	sh_local_int5_config_u_t	local5_config;
+	sh_local_int5_enable_u_t	local5_enable;
 	extern void sn_init_cpei_timer(void);
 	static int timer_added = 0;
 
@@ -93,6 +98,19 @@
 	HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_ERROR_MASK), 0);
 	HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_PI_CRBP_ERROR_MASK), 0);
 
+	// Config and enable UART interrupt, all nodes.
+
+	local5_config.sh_local_int5_config_regval = 0;
+	local5_config.sh_local_int5_config_s.idx = SGI_UART_VECTOR;
+	local5_config.sh_local_int5_config_s.pid = cpu0;
+	HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT5_CONFIG),
+		local5_config.sh_local_int5_config_regval);
+
+	local5_enable.sh_local_int5_enable_regval = 0;
+	local5_enable.sh_local_int5_enable_s.uart_int = 1;
+	HUB_S( (unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_LOCAL_INT5_ENABLE),
+		local5_enable.sh_local_int5_enable_regval);
+
 
 	// The II_INT_CONFIG register for cpu 0.
 	ii_int_config.sh_ii_int0_config_regval = 0;
@@ -119,13 +137,6 @@
 	// Enable interrupts for II_INT0 and 1.
 	ii_int_enable.sh_ii_int0_enable_regval = 0;
 	ii_int_enable.sh_ii_int0_enable_s.ii_enable = 1;
-#ifdef BUS_INT_WAR
-	/* Dont enable any ints from II. We will poll for interrupts. */
-	ii_int_enable.sh_ii_int0_enable_s.ii_enable = 0;
-
-	/* Enable IPIs. We use them ONLY for send INITs to hung cpus */
-	*(volatile long*)GLOBAL_MMR_ADDR(nasid, SH_IPI_INT_ENABLE) = 1;
-#endif
 
 	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_II_INT0_ENABLE),
 		ii_int_enable.sh_ii_int0_enable_regval);
@@ -147,7 +158,8 @@
 			int reserve)
 {
 	int i;
-	irqpda_t	*irqs = irqpdaindr[cpu];
+	irqpda_t	*irqs = irqpdaindr;
+	int		min_shared;
 
 	if (reserve) {
 		if (bit < 0) {
@@ -158,8 +170,32 @@
 				}
 			}
 		}
-		if (bit < 0) {
-			return -1;
+		if (bit < 0) {  /* ran out of irqs.  Have to share.  This will be rare. */
+			min_shared = 256;
+			for (i=IA64_SN2_FIRST_DEVICE_VECTOR; i < IA64_SN2_LAST_DEVICE_VECTOR; i++) {
+				/* Share with the same device class */
+				if (irqpdaindr->current->vendor == irqpdaindr->device_dev[i]->vendor &&
+					irqpdaindr->current->device == irqpdaindr->device_dev[i]->device &&
+					irqpdaindr->share_count[i] < min_shared) {
+						min_shared = irqpdaindr->share_count[i];
+						bit = i;
+				}
+			}
+			min_shared = 256;
+			if (bit < 0) {  /* didn't find a matching device, just pick one. This will be */
+					/* exceptionally rare. */
+				for (i=IA64_SN2_FIRST_DEVICE_VECTOR; i < IA64_SN2_LAST_DEVICE_VECTOR; i++) {
+					if (irqpdaindr->share_count[i] < min_shared) {
+						min_shared = irqpdaindr->share_count[i];
+						bit = i;
+					}
+				}
+			}
+			irqpdaindr->share_count[bit]++;
+		}
+		if (irqs->irq_flags[bit] & SN2_IRQ_SHARED) {
+			irqs->irq_flags[bit] |= SN2_IRQ_RESERVED;
+			return bit;
 		}
 		if (irqs->irq_flags[bit] & SN2_IRQ_RESERVED) {
 			return -1;
@@ -183,7 +219,7 @@
 intr_reserve_level(cpuid_t cpu,
 		int bit,
 		int resflags,
-		devfs_handle_t owner_dev,
+		vertex_hdl_t owner_dev,
 		char *name)
 {
 	return(do_intr_reserve_level(cpu, bit, 1));
@@ -203,9 +239,13 @@
 			int bit,
 			int connect)
 {
-	irqpda_t	*irqs = irqpdaindr[cpu];
+	irqpda_t	*irqs = irqpdaindr;
 
 	if (connect) {
+		if (irqs->irq_flags[bit] & SN2_IRQ_SHARED) {
+			irqs->irq_flags[bit] |= SN2_IRQ_CONNECTED;
+			return bit;
+		}
 		if (irqs->irq_flags[bit] & SN2_IRQ_CONNECTED) {
 			return -1;
 		} else {
@@ -248,24 +288,29 @@
 	int		slice, min_count = 1000;
 	irqpda_t	*irqs;
 
-	for (slice = 0; slice < CPUS_PER_NODE; slice++) {
+	for (slice = CPUS_PER_NODE - 1; slice >= 0; slice--) {
 		int intrs;
 
 		cpu = cnode_slice_to_cpuid(cnode, slice);
-		if (cpu == CPU_NONE) {
+		if (cpu == num_online_cpus()) {
 			continue;
 		}
 
-		if (!cpu_enabled(cpu)) {
+		if (!cpu_online(cpu)) {
 			continue;
 		}
 
-		irqs = irqpdaindr[cpu];
+		irqs = irqpdaindr;
 		intrs = irqs->num_irq_used;
 
 		if (min_count > intrs) {
 			min_count = intrs;
 			best_cpu = cpu;
+			if ( enable_shub_wars_1_1() ) {
+				/* Rather than finding the best cpu, always return the first cpu*/
+				/* This forces all interrupts to the same cpu */
+				break;
+			}
 		}
 	}
 	return best_cpu;
@@ -285,7 +330,7 @@
 			cnodeid_t cnode,
 			int req_bit,
 			int resflags,
-			devfs_handle_t owner_dev,
+			vertex_hdl_t owner_dev,
 			char *name,
 			int *resp_bit)
 {
@@ -307,18 +352,18 @@
 // Find the node to assign for this interrupt.
 
 cpuid_t
-intr_heuristic(devfs_handle_t dev,
+intr_heuristic(vertex_hdl_t dev,
 		device_desc_t dev_desc,
 		int	req_bit,
 		int resflags,
-		devfs_handle_t owner_dev,
+		vertex_hdl_t owner_dev,
 		char *name,
 		int *resp_bit)
 {
 	cpuid_t		cpuid;
 	cpuid_t		candidate = CPU_NONE;
 	cnodeid_t	candidate_node;
-	devfs_handle_t	pconn_vhdl;
+	vertex_hdl_t	pconn_vhdl;
 	pcibr_soft_t	pcibr_soft;
 	int 		bit;
 
@@ -369,8 +414,8 @@
 	if (candidate  != CPU_NONE) {
 		printk("Cannot target interrupt to target node (%ld).\n",candidate);
 		return CPU_NONE; } else {
-		printk("Cannot target interrupt to closest node (%d) 0x%p\n",
-			master_node_get(dev), (void *)owner_dev);
+		/* printk("Cannot target interrupt to closest node (%d) 0x%p\n",
+			master_node_get(dev), (void *)owner_dev); */
 	}
 
 	// We couldn't put it on the closest node.  Try to find another one.
diff -Nru a/arch/ia64/sn/io/sn2/ml_iograph.c b/arch/ia64/sn/io/sn2/ml_iograph.c
--- a/arch/ia64/sn/io/sn2/ml_iograph.c	Wed Jun 18 23:42:05 2003
+++ b/arch/ia64/sn/io/sn2/ml_iograph.c	Wed Jun 18 23:42:05 2003
@@ -22,7 +22,6 @@
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/pci/bridge.h>
 #include <asm/sn/klconfig.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/sn_private.h>
 #include <asm/sn/pci/pcibr.h>
 #include <asm/sn/xtalk/xtalk.h>
@@ -43,8 +42,6 @@
 /* At most 2 hubs can be connected to an xswitch */
 #define NUM_XSWITCH_VOLUNTEER 2
 
-extern unsigned char Is_pic_on_this_nasid[512];
-
 /*
  * Track which hubs have volunteered to manage devices hanging off of
  * a Crosstalk Switch (e.g. xbow).  This structure is allocated,
@@ -54,11 +51,11 @@
 typedef struct xswitch_vol_s {
 	mutex_t xswitch_volunteer_mutex;
 	int		xswitch_volunteer_count;
-	devfs_handle_t	xswitch_volunteer[NUM_XSWITCH_VOLUNTEER];
+	vertex_hdl_t	xswitch_volunteer[NUM_XSWITCH_VOLUNTEER];
 } *xswitch_vol_t;
 
 void
-xswitch_vertex_init(devfs_handle_t xswitch)
+xswitch_vertex_init(vertex_hdl_t xswitch)
 {
 	xswitch_vol_t xvolinfo;
 	int rc;
@@ -78,7 +75,7 @@
  * xswitch volunteer structure hanging around.  Destroy it.
  */
 static void
-xswitch_volunteer_delete(devfs_handle_t xswitch)
+xswitch_volunteer_delete(vertex_hdl_t xswitch)
 {
 	xswitch_vol_t xvolinfo;
 	int rc;
@@ -94,10 +91,10 @@
  */
 /* ARGSUSED */
 static void
-volunteer_for_widgets(devfs_handle_t xswitch, devfs_handle_t master)
+volunteer_for_widgets(vertex_hdl_t xswitch, vertex_hdl_t master)
 {
 	xswitch_vol_t xvolinfo = NULL;
-	devfs_handle_t hubv;
+	vertex_hdl_t hubv;
 	hubinfo_t hubinfo;
 
 	(void)hwgraph_info_get_LBL(xswitch, 
@@ -140,7 +137,7 @@
  */
 /* ARGSUSED */
 static void
-assign_widgets_to_volunteers(devfs_handle_t xswitch, devfs_handle_t hubv)
+assign_widgets_to_volunteers(vertex_hdl_t xswitch, vertex_hdl_t hubv)
 {
 	xswitch_info_t xswitch_info;
 	xswitch_vol_t xvolinfo = NULL;
@@ -223,18 +220,6 @@
 
                        	bt = iobrick_type_get_nasid(nasid);
                         if (bt >= 0) {
-				/*
-				 * PXBRICK has two busses per widget so this
-				 * algorithm wouldn't work (all busses would
-				 * be assigned to one volunteer). Change the
-				 * bricktype to PBRICK whose mapping is setup
-				 * suchthat 2 of the PICs will be assigned to
-				 * one volunteer and the other one will be
-				 * assigned to the other volunteer.
-				 */
-				if (bt == MODULE_PXBRICK) 
-					bt = MODULE_PBRICK;
-
 			        i = io_brick_map_widget(bt, widgetnum) & 1;
                         }
                 }
@@ -281,8 +266,6 @@
 			DBG("iograph_early_init: Found board 0x%p\n", board);
 		}
 	}
-
-	hubio_init();
 }
 
 /*
@@ -307,7 +290,7 @@
  * hwid for our use.
  */
 static void
-early_probe_for_widget(devfs_handle_t hubv, xwidget_hwid_t hwid)
+early_probe_for_widget(vertex_hdl_t hubv, xwidget_hwid_t hwid)
 {
 	hubreg_t llp_csr_reg;
 	nasid_t nasid;
@@ -351,7 +334,7 @@
  * added as inventory information.
  */
 static void
-xwidget_inventory_add(devfs_handle_t 		widgetv,
+xwidget_inventory_add(vertex_hdl_t 		widgetv,
 		      lboard_t 			*board,
 		      struct xwidget_hwid_s 	hwid)
 {
@@ -374,14 +357,13 @@
  */
 
 void
-io_xswitch_widget_init(devfs_handle_t  	xswitchv,
-		       devfs_handle_t	hubv,
-		       xwidgetnum_t	widgetnum,
-		       async_attach_t	aa)
+io_xswitch_widget_init(vertex_hdl_t  	xswitchv,
+		       vertex_hdl_t	hubv,
+		       xwidgetnum_t	widgetnum)
 {
 	xswitch_info_t		xswitch_info;
 	xwidgetnum_t		hub_widgetid;
-	devfs_handle_t		widgetv;
+	vertex_hdl_t		widgetv;
 	cnodeid_t		cnode;
 	widgetreg_t		widget_id;
 	nasid_t			nasid, peer_nasid;
@@ -427,6 +409,7 @@
 		char			name[4];
 		lboard_t dummy;
 
+
 		/*
 		 * If the current hub is not supposed to be the master 
 		 * for this widgetnum, then skip this widget.
@@ -470,12 +453,15 @@
 
 		memset(buffer, 0, 16);
 		format_module_id(buffer, geo_module(board->brd_geoid), MODULE_FORMAT_BRIEF);
-		sprintf(pathname, EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d" "/%cbrick" "/%s/%d",
+
+		sprintf(pathname, EDGE_LBL_MODULE "/%s/" EDGE_LBL_SLAB "/%d" "/%s" "/%s/%d",
 			buffer,
 			geo_slab(board->brd_geoid),
-			(board->brd_type == KLTYPE_IBRICK) ? 'I' :
-			(board->brd_type == KLTYPE_PBRICK) ? 'P' :
-			(board->brd_type == KLTYPE_XBRICK) ? 'X' : '?',
+			(board->brd_type == KLTYPE_IBRICK) ? EDGE_LBL_IBRICK :
+			(board->brd_type == KLTYPE_PBRICK) ? EDGE_LBL_PBRICK :
+			(board->brd_type == KLTYPE_PXBRICK) ? EDGE_LBL_PXBRICK :
+			(board->brd_type == KLTYPE_IXBRICK) ? EDGE_LBL_IXBRICK :
+			(board->brd_type == KLTYPE_XBRICK) ? EDGE_LBL_XBRICK : "?brick",
 			EDGE_LBL_XTALK, widgetnum);
 		
 		DBG("io_xswitch_widget_init: path= %s\n", pathname);
@@ -514,36 +500,46 @@
 		xwidget_inventory_add(widgetv,board,hwid);
 
 		(void)xwidget_register(&hwid, widgetv, widgetnum,
-				       hubv, hub_widgetid,
-				       aa);
+				       hubv, hub_widgetid);
 
 		ia64_sn_sysctl_iobrick_module_get(nasid, &io_module);
 
 		if (io_module >= 0) {
 			char			buffer[16];
-			devfs_handle_t		to, from;
+			vertex_hdl_t		to, from;
+			char           		*brick_name;
+			extern char *iobrick_L1bricktype_to_name(int type);
+
 
 			memset(buffer, 0, 16);
 			format_module_id(buffer, geo_module(board->brd_geoid), MODULE_FORMAT_BRIEF);
 
-			bt = toupper(MODULE_GET_BTCHAR(io_module));
+			if ( islower(MODULE_GET_BTCHAR(io_module)) ) {
+				bt = toupper(MODULE_GET_BTCHAR(io_module));
+			}
+			else {
+				bt = MODULE_GET_BTCHAR(io_module);
+			}
+
+			brick_name = iobrick_L1bricktype_to_name(bt);
+
 			/* Add a helper vertex so xbow monitoring
 			* can identify the brick type. It's simply
 			* an edge from the widget 0 vertex to the
 			*  brick vertex.
 			*/
 
-			sprintf(pathname, "/dev/hw/" EDGE_LBL_MODULE "/%s/"
+			sprintf(pathname, EDGE_LBL_HW "/" EDGE_LBL_MODULE "/%s/"
 				EDGE_LBL_SLAB "/%d/"
 				EDGE_LBL_NODE "/" EDGE_LBL_XTALK "/"
 				"0",
 				buffer, geo_slab(board->brd_geoid));
 			from = hwgraph_path_to_vertex(pathname);
 			ASSERT_ALWAYS(from);
-			sprintf(pathname, "/dev/hw/" EDGE_LBL_MODULE "/%s/"
+			sprintf(pathname, EDGE_LBL_HW "/" EDGE_LBL_MODULE "/%s/"
 				EDGE_LBL_SLAB "/%d/"
-				"%cbrick",
-				buffer, geo_slab(board->brd_geoid), bt);
+				"%s",
+				buffer, geo_slab(board->brd_geoid), brick_name);
 
 			to = hwgraph_path_to_vertex(pathname);
 			ASSERT_ALWAYS(to);
@@ -566,12 +562,9 @@
 
 
 static void
-io_init_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnode)
+io_init_xswitch_widgets(vertex_hdl_t xswitchv, cnodeid_t cnode)
 {
 	xwidgetnum_t		widgetnum;
-	async_attach_t          aa;
-
-	aa = async_attach_new();
 	
 	DBG("io_init_xswitch_widgets: xswitchv 0x%p for cnode %d\n", xswitchv, cnode);
 
@@ -579,13 +572,8 @@
 	     widgetnum++) {
 		io_xswitch_widget_init(xswitchv,
 				       cnodeid_to_vertex(cnode),
-				       widgetnum, aa);
+				       widgetnum);
 	}
-	/* 
-	 * Wait for parallel attach threads, if any, to complete.
-	 */
-	async_attach_waitall(aa);
-	async_attach_free(aa);
 }
 
 /*
@@ -595,11 +583,11 @@
  * graph and risking hangs.
  */
 static void
-io_link_xswitch_widgets(devfs_handle_t xswitchv, cnodeid_t cnodeid)
+io_link_xswitch_widgets(vertex_hdl_t xswitchv, cnodeid_t cnodeid)
 {
 	xwidgetnum_t		widgetnum;
 	char 			pathname[128];
-	devfs_handle_t		vhdl;
+	vertex_hdl_t		vhdl;
 	nasid_t			nasid, peer_nasid;
 	lboard_t		*board;
 
@@ -638,21 +626,12 @@
 			return;
 		}
 
-		if ( Is_pic_on_this_nasid[nasid] ) {
-			/* Check both buses */
-			sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum);
-			if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS)
-				board->brd_graph_link = vhdl;
-			else {
-				sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum);
-				if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS)
-					board->brd_graph_link = vhdl;
-				else
-					board->brd_graph_link = GRAPH_VERTEX_NONE;
-			}
-		}
+		/* Check both buses */
+		sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum);
+		if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS)
+			board->brd_graph_link = vhdl;
 		else {
-			sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
+			sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum);
 			if (hwgraph_traverse(xswitchv, pathname, &vhdl) == GRAPH_SUCCESS)
 				board->brd_graph_link = vhdl;
 			else
@@ -668,16 +647,14 @@
 io_init_node(cnodeid_t cnodeid)
 {
 	/*REFERENCED*/
-	devfs_handle_t hubv, switchv, widgetv;
+	vertex_hdl_t hubv, switchv, widgetv;
 	struct xwidget_hwid_s hwid;
 	hubinfo_t hubinfo;
 	int is_xswitch;
 	nodepda_t	*npdap;
 	struct semaphore *peer_sema = 0;
 	uint32_t	widget_partnum;
-	nodepda_router_info_t *npda_rip;
 	cpu_cookie_t	c = 0;
-	extern int hubdev_docallouts(devfs_handle_t);
 
 	npdap = NODEPDA(cnodeid);
 
@@ -693,23 +670,6 @@
 
 	ASSERT(hubv != GRAPH_VERTEX_NONE);
 
-	hubdev_docallouts(hubv);
-
-	/*
-	 * Set up the dependent routers if we have any.
-	 */
-	npda_rip = npdap->npda_rip_first;
-
-	while(npda_rip) {
-		/* If the router info has not been initialized
-		 * then we need to do the router initialization
-		 */
-		if (!npda_rip->router_infop) {
-			router_init(cnodeid,0,npda_rip);
-		}
-		npda_rip = npda_rip->router_next;
-	}
-
 	/*
 	 * Read mfg info on this hub
 	 */
@@ -833,7 +793,7 @@
 		 */
 		hubinfo_get(hubv, &hubinfo);
 
-		(void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid, NULL);
+		(void)xwidget_register(&hwid, widgetv, npdap->basew_id, hubv, hubinfo->h_widgetid);
 
 		if (!is_xswitch) {
 			/* io_init_done takes cpu cookie as 2nd argument 
@@ -915,231 +875,9 @@
  * XXX Irix legacy..controller numbering should be part of devfsd's job
  */
 int num_base_io_scsi_ctlr = 2; /* used by syssgi */
-devfs_handle_t		base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR];
-static devfs_handle_t	baseio_enet_vhdl,baseio_console_vhdl;
-
-/*
- * Put the logical controller number information in the 
- * scsi controller vertices for each scsi controller that
- * is in a "fixed position".
- */
-static void
-scsi_ctlr_nums_add(devfs_handle_t pci_vhdl)
-{
-	{
-		int i;
-
-		num_base_io_scsi_ctlr = NUM_BASE_IO_SCSI_CTLR;
-
-		/* Initialize base_io_scsi_ctlr_vhdl array */
-		for (i=0; i<num_base_io_scsi_ctlr; i++)
-			base_io_scsi_ctlr_vhdl[i] = GRAPH_VERTEX_NONE;
-	}
-	{
-	/*
-	 * May want to consider changing the SN0 code, above, to work more like
-	 * the way this works.
-	 */
-	devfs_handle_t base_ibrick_xbridge_vhdl;
-	devfs_handle_t base_ibrick_xtalk_widget_vhdl;
-	devfs_handle_t scsi_ctlr_vhdl;
-	int i;
-	graph_error_t rv;
-
-	/*
-	 * This is a table of "well-known" SCSI controllers and their well-known
-	 * controller numbers.  The names in the table start from the base IBrick's
-	 * Xbridge vertex, so the first component is the xtalk widget number.
-	 */
-	static struct {
-		char	*base_ibrick_scsi_path;
-		int	controller_number;
-	} hardwired_scsi_controllers[] = {
-		{"15/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 0},
-		{"15/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 1},
-		{"15/" EDGE_LBL_PCI "/3/" EDGE_LBL_SCSI_CTLR "/0", 2},
-		{"14/" EDGE_LBL_PCI "/1/" EDGE_LBL_SCSI_CTLR "/0", 3},
-		{"14/" EDGE_LBL_PCI "/2/" EDGE_LBL_SCSI_CTLR "/0", 4},
-		{"15/" EDGE_LBL_PCI "/6/ohci/0/" EDGE_LBL_SCSI_CTLR "/0", 5},
-		{NULL, -1} /* must be last */
-	};
-
-	base_ibrick_xtalk_widget_vhdl = hwgraph_connectpt_get(pci_vhdl);
-	ASSERT_ALWAYS(base_ibrick_xtalk_widget_vhdl != GRAPH_VERTEX_NONE);
-
-	base_ibrick_xbridge_vhdl = hwgraph_connectpt_get(base_ibrick_xtalk_widget_vhdl);
-	ASSERT_ALWAYS(base_ibrick_xbridge_vhdl != GRAPH_VERTEX_NONE);
-	hwgraph_vertex_unref(base_ibrick_xtalk_widget_vhdl);
-
-	/*
-	 * Iterate through the list of well-known SCSI controllers.
-	 * For each controller found, set it's controller number according
-	 * to the table.
-	 */
-	for (i=0; hardwired_scsi_controllers[i].base_ibrick_scsi_path != NULL; i++) {
-		rv = hwgraph_path_lookup(base_ibrick_xbridge_vhdl,
-			hardwired_scsi_controllers[i].base_ibrick_scsi_path, &scsi_ctlr_vhdl, NULL);
-
-		if (rv != GRAPH_SUCCESS) /* No SCSI at this path */
-			continue;
-
-		ASSERT(hardwired_scsi_controllers[i].controller_number < NUM_BASE_IO_SCSI_CTLR);
-		base_io_scsi_ctlr_vhdl[hardwired_scsi_controllers[i].controller_number] = scsi_ctlr_vhdl;
-		device_controller_num_set(scsi_ctlr_vhdl, hardwired_scsi_controllers[i].controller_number);
-		hwgraph_vertex_unref(scsi_ctlr_vhdl); /* (even though we're actually keeping a reference) */
-	}
-
-	hwgraph_vertex_unref(base_ibrick_xbridge_vhdl);
-	}
-}
-
+vertex_hdl_t		base_io_scsi_ctlr_vhdl[NUM_BASE_IO_SCSI_CTLR];
 
 #include <asm/sn/ioerror_handling.h>
-devfs_handle_t		sys_critical_graph_root = GRAPH_VERTEX_NONE;
-
-/* Define the system critical vertices and connect them through
- * a canonical parent-child relationships for easy traversal
- * during io error handling.
- */
-static void
-sys_critical_graph_init(void)
-{
-	devfs_handle_t		bridge_vhdl,master_node_vhdl;
-	devfs_handle_t  		xbow_vhdl = GRAPH_VERTEX_NONE;
-	extern devfs_handle_t	hwgraph_root;
-	devfs_handle_t		pci_slot_conn;
-	int			slot;
-	devfs_handle_t		baseio_console_conn;
-
-	DBG("sys_critical_graph_init: FIXME.\n");
-	baseio_console_conn = hwgraph_connectpt_get(baseio_console_vhdl);
-
-	if (baseio_console_conn == NULL) {
-		return;
-	}
-
-	/* Get the vertex handle for the baseio bridge */
-	bridge_vhdl = device_master_get(baseio_console_conn);
-
-	/* Get the master node of the baseio card */
-	master_node_vhdl = cnodeid_to_vertex(
-				master_node_get(baseio_console_vhdl));
-	
-	/* Add the "root->node" part of the system critical graph */
-
-	sys_critical_graph_vertex_add(hwgraph_root,master_node_vhdl);
-
-	/* Check if we have a crossbow */
-	if (hwgraph_traverse(master_node_vhdl,
-			     EDGE_LBL_XTALK"/0",
-			     &xbow_vhdl) == GRAPH_SUCCESS) {
-		/* We have a crossbow.Add "node->xbow" part of the system 
-		 * critical graph.
-		 */
-		sys_critical_graph_vertex_add(master_node_vhdl,xbow_vhdl);
-		
-		/* Add "xbow->baseio bridge" of the system critical graph */
-		sys_critical_graph_vertex_add(xbow_vhdl,bridge_vhdl);
-
-		hwgraph_vertex_unref(xbow_vhdl);
-	} else 
-		/* We donot have a crossbow. Add "node->baseio_bridge"
-		 * part of the system critical graph.
-		 */
-		sys_critical_graph_vertex_add(master_node_vhdl,bridge_vhdl);
-
-	/* Add all the populated PCI slot vertices to the system critical
-	 * graph with the bridge vertex as the parent.
-	 */
-	for (slot = 0 ; slot < 8; slot++) {
-		char	slot_edge[10];
-
-		sprintf(slot_edge,"%d",slot);
-		if (hwgraph_traverse(bridge_vhdl,slot_edge, &pci_slot_conn)
-		    != GRAPH_SUCCESS)
-			continue;
-		sys_critical_graph_vertex_add(bridge_vhdl,pci_slot_conn);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	hwgraph_vertex_unref(bridge_vhdl);
-
-	/* Add the "ioc3 pci connection point  -> console ioc3" part 
-	 * of the system critical graph
-	 */
-
-	if (hwgraph_traverse(baseio_console_vhdl,"..",&pci_slot_conn) ==
-	    GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      baseio_console_vhdl);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	/* Add the "ethernet pci connection point  -> base ethernet" part of 
-	 * the system  critical graph
-	 */
-	if (hwgraph_traverse(baseio_enet_vhdl,"..",&pci_slot_conn) ==
-	    GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      baseio_enet_vhdl);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-
-	/* Add the "scsi controller pci connection point  -> base scsi 
-	 * controller" part of the system critical graph
-	 */
-	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[0],
-			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      base_io_scsi_ctlr_vhdl[0]);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-	if (hwgraph_traverse(base_io_scsi_ctlr_vhdl[1],
-			     "../..",&pci_slot_conn) == GRAPH_SUCCESS) {
-		sys_critical_graph_vertex_add(pci_slot_conn, 
-					      base_io_scsi_ctlr_vhdl[1]);
-		hwgraph_vertex_unref(pci_slot_conn);
-	}
-	hwgraph_vertex_unref(baseio_console_conn);
-
-}
-
-static void
-baseio_ctlr_num_set(void)
-{
-	char 			name[MAXDEVNAME];
-	devfs_handle_t		console_vhdl, pci_vhdl, enet_vhdl;
-	devfs_handle_t		ioc3_console_vhdl_get(void);
-
-
-	DBG("baseio_ctlr_num_set; FIXME\n");
-	console_vhdl = ioc3_console_vhdl_get();
-	if (console_vhdl == GRAPH_VERTEX_NONE)
-		return;
-	/* Useful for setting up the system critical graph */
-	baseio_console_vhdl = console_vhdl;
-
-	vertex_to_name(console_vhdl,name,MAXDEVNAME);
-
-	strcat(name,__DEVSTR1);
-	pci_vhdl =  hwgraph_path_to_vertex(name);
-	scsi_ctlr_nums_add(pci_vhdl);
-	/* Unref the pci_vhdl due to the reference by hwgraph_path_to_vertex
-	 */
-	hwgraph_vertex_unref(pci_vhdl);
-
-	vertex_to_name(console_vhdl, name, MAXDEVNAME);
-	strcat(name, __DEVSTR4);
-	enet_vhdl = hwgraph_path_to_vertex(name);
-
-	/* Useful for setting up the system critical graph */
-	baseio_enet_vhdl = enet_vhdl;
-
-	device_controller_num_set(enet_vhdl, 0);
-	/* Unref the enet_vhdl due to the reference by hwgraph_path_to_vertex
-	 */
-	hwgraph_vertex_unref(enet_vhdl);
-}
 /* #endif */
 
 /*
@@ -1168,13 +906,6 @@
 		 */
 		update_node_information(cnodeid);
 
-	baseio_ctlr_num_set();
-	/* Setup the system critical graph (which is a subgraph of the
-	 * main hwgraph). This information is useful during io error
-	 * handling.
-	 */
-	sys_critical_graph_init();
-
 #if HWG_PRINT
 	hwgraph_print();
 #endif
@@ -1300,6 +1031,20 @@
     }
  },
 
+/* IXbrick widget number to PCI bus number map */
+ {      MODULE_IXBRICK,                         /* IXbrick type   */ 
+    /*  PCI Bus #                                  Widget #       */
+    {   0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7      */
+        0,                                      /* 0x8            */
+        0,                                      /* 0x9            */
+        0, 0,                                   /* 0xa - 0xb      */
+        1,                                      /* 0xc            */
+        5,                                      /* 0xd            */
+        0,                                      /* 0xe            */
+        3                                       /* 0xf            */
+    }
+ },
+
 /* Xbrick widget to XIO slot map */
  {      MODULE_XBRICK,                          /* Xbrick type    */ 
     /*  XIO Slot #                                 Widget #       */
@@ -1333,63 +1078,5 @@
         }
 
         return 0;
-
-}
-
-/*
- * Use the device's vertex to map the device's widget to a meaningful int
- */
-int
-io_path_map_widget(devfs_handle_t vertex)
-{
-        char hw_path_name[MAXDEVNAME];
-        char *wp, *bp, *sp = NULL;
-        int  widget_num;
-	long atoi(char *);
-	int hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen);
-
-
-        /* Get the full path name of the vertex */
-        if (GRAPH_SUCCESS != hwgraph_vertex_name_get(vertex, hw_path_name,
-                                                     MAXDEVNAME))
-                return 0;
-
-        /* Find the widget number in the path name */
-        wp = strstr(hw_path_name, "/"EDGE_LBL_XTALK"/");
-        if (wp == NULL)
-                return 0;
-        widget_num = atoi(wp+7);
-        if (widget_num < XBOW_PORT_8 || widget_num > XBOW_PORT_F)
-                return 0;
-
-        /* Find "brick" in the path name */
-        bp = strstr(hw_path_name, "brick");
-        if (bp == NULL)
-                return 0;
-
-        /* Find preceding slash */
-        sp = bp;
-        while (sp > hw_path_name) {
-                sp--;
-                if (*sp == '/')
-                        break;
-        }
-
-        /* Invalid if no preceding slash */
-        if (!sp)
-                return 0;
-
-        /* Bump slash pointer to "brick" prefix */
-        sp++;
-        /*
-         * Verify "brick" prefix length;  valid exaples:
-         * 'I' from "/Ibrick"
-         * 'P' from "/Pbrick"
-         * 'X' from "/Xbrick"
-         */
-         if ((bp - sp) != 1)
-                return 0;
-
-        return (io_brick_map_widget((int)*sp, widget_num));
 
 }
diff -Nru a/arch/ia64/sn/io/sn2/module.c b/arch/ia64/sn/io/sn2/module.c
--- a/arch/ia64/sn/io/sn2/module.c	Wed Jun 18 23:42:05 2003
+++ b/arch/ia64/sn/io/sn2/module.c	Wed Jun 18 23:42:05 2003
@@ -18,7 +18,6 @@
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/pci/bridge.h>
 #include <asm/sn/klconfig.h>
-#include <asm/sn/sn1/hubdev.h>
 #include <asm/sn/module.h>
 #include <asm/sn/pci/pcibr.h>
 #include <asm/sn/xtalk/xswitch.h>
diff -Nru a/arch/ia64/sn/io/sn2/pci_bus_cvlink.c b/arch/ia64/sn/io/sn2/pci_bus_cvlink.c
--- a/arch/ia64/sn/io/sn2/pci_bus_cvlink.c	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,719 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-#include <linux/pci_ids.h>
-#include <linux/sched.h>
-#include <linux/ioport.h>
-#include <asm/sn/types.h>
-#include <asm/sn/hack.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/iograph.h>
-#include <asm/param.h>
-#include <asm/sn/pio.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/xtalk/xtalkaddrs.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_bus_cvlink.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/sn_cpuid.h>
-
-extern int bridge_rev_b_data_check_disable;
-
-devfs_handle_t busnum_to_pcibr_vhdl[MAX_PCI_XWIDGET];
-nasid_t busnum_to_nid[MAX_PCI_XWIDGET];
-void * busnum_to_atedmamaps[MAX_PCI_XWIDGET];
-unsigned char num_bridges;
-static int done_probing = 0;
-
-static int pci_bus_map_create(devfs_handle_t xtalk, char * io_moduleid);
-devfs_handle_t devfn_to_vertex(unsigned char busnum, unsigned int devfn);
-
-extern unsigned char Is_pic_on_this_nasid[512];
-
-extern void sn_init_irq_desc(void);
-extern void register_pcibr_intr(int irq, pcibr_intr_t intr);
-
-
-/*
- * For the given device, initialize whether it is a PIC device.
- */
-static void
-set_isPIC(struct sn_device_sysdata *device_sysdata)
-{
-	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
-	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-	device_sysdata->isPIC = IS_PIC_SOFT(pcibr_soft);;
-}
-
-/*
- * pci_bus_cvlink_init() - To be called once during initialization before 
- *	SGI IO Infrastructure init is called.
- */
-void
-pci_bus_cvlink_init(void)
-{
-
-	extern void ioconfig_bus_init(void);
-
-	memset(busnum_to_pcibr_vhdl, 0x0, sizeof(devfs_handle_t) * MAX_PCI_XWIDGET);
-	memset(busnum_to_nid, 0x0, sizeof(nasid_t) * MAX_PCI_XWIDGET);
-
-	memset(busnum_to_atedmamaps, 0x0, sizeof(void *) * MAX_PCI_XWIDGET);
-
-	num_bridges = 0;
-
-	ioconfig_bus_init();
-}
-
-/*
- * pci_bus_to_vertex() - Given a logical Linux Bus Number returns the associated 
- *	pci bus vertex from the SGI IO Infrastructure.
- */
-devfs_handle_t
-pci_bus_to_vertex(unsigned char busnum)
-{
-
-	devfs_handle_t	pci_bus = NULL;
-
-
-	/*
-	 * First get the xwidget vertex.
-	 */
-	pci_bus = busnum_to_pcibr_vhdl[busnum];
-	return(pci_bus);
-}
-
-/*
- * devfn_to_vertex() - returns the vertex of the device given the bus, slot, 
- *	and function numbers.
- */
-devfs_handle_t
-devfn_to_vertex(unsigned char busnum, unsigned int devfn)
-{
-
-	int slot = 0;
-	int func = 0;
-	char	name[16];
-	devfs_handle_t  pci_bus = NULL;
-	devfs_handle_t	device_vertex = (devfs_handle_t)NULL;
-
-	/*
-	 * Go get the pci bus vertex.
-	 */
-	pci_bus = pci_bus_to_vertex(busnum);
-	if (!pci_bus) {
-		/*
-		 * During probing, the Linux pci code invents non existant
-		 * bus numbers and pci_dev structures and tries to access
-		 * them to determine existance. Don't crib during probing.
-		 */
-		if (done_probing)
-			printk("devfn_to_vertex: Invalid bus number %d given.\n", busnum);
-		return(NULL);
-	}
-
-
-	/*
-	 * Go get the slot&function vertex.
-	 * Should call pciio_slot_func_to_name() when ready.
-	 */
-	slot = PCI_SLOT(devfn);
-	func = PCI_FUNC(devfn);
-
-	/*
-	 * For a NON Multi-function card the name of the device looks like:
-	 * ../pci/1, ../pci/2 ..
-	 */
-	if (func == 0) {
-        	sprintf(name, "%d", slot);
-		if (hwgraph_traverse(pci_bus, name, &device_vertex) == 
-			GRAPH_SUCCESS) {
-			if (device_vertex) {
-				return(device_vertex);
-			}
-		}
-	}
-			
-	/*
-	 * This maybe a multifunction card.  It's names look like:
-	 * ../pci/1a, ../pci/1b, etc.
-	 */
-	sprintf(name, "%d%c", slot, 'a'+func);
-	if (hwgraph_traverse(pci_bus, name, &device_vertex) != GRAPH_SUCCESS) {
-		if (!device_vertex) {
-			return(NULL);
-		}
-	}
-
-	return(device_vertex);
-}
-
-/*
- * For the given device, initialize the addresses for both the Device(x) Flush 
- * Write Buffer register and the Xbow Flush Register for the port the PCI bus 
- * is connected.
- */
-static void
-set_flush_addresses(struct pci_dev *device_dev, 
-	struct sn_device_sysdata *device_sysdata)
-{
-	pciio_info_t pciio_info = pciio_info_get(device_sysdata->vhdl);
-	pciio_slot_t pciio_slot = pciio_info_slot_get(pciio_info);
-	pcibr_soft_t pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    	bridge_t               *bridge = pcibr_soft->bs_base;
-	nasid_t			nasid;
-
-	/*
-	 * Get the nasid from the bridge.
-	 */
-	nasid = NASID_GET(device_sysdata->dma_buf_sync);
-	if (IS_PIC_DEVICE(device_dev)) {
-		device_sysdata->dma_buf_sync = (volatile unsigned int *)
-			&bridge->b_wr_req_buf[pciio_slot].reg;
-		device_sysdata->xbow_buf_sync = (volatile unsigned int *)
-			XBOW_PRIO_LINKREGS_PTR(NODE_SWIN_BASE(nasid, 0),
-			pcibr_soft->bs_xid);
-	} else {
-		/*
-		 * Accessing Xbridge and Xbow register when SHUB swapoper is on!.
-		 */
-		device_sysdata->dma_buf_sync = (volatile unsigned int *)
-			((uint64_t)&(bridge->b_wr_req_buf[pciio_slot].reg)^4);
-		device_sysdata->xbow_buf_sync = (volatile unsigned int *)
-			((uint64_t)(XBOW_PRIO_LINKREGS_PTR(
-			NODE_SWIN_BASE(nasid, 0), pcibr_soft->bs_xid)) ^ 4);
-	}
-
-#ifdef DEBUG
-	printk("set_flush_addresses: dma_buf_sync %p xbow_buf_sync %p\n", 
-		device_sysdata->dma_buf_sync, device_sysdata->xbow_buf_sync);
-
-printk("set_flush_addresses: dma_buf_sync\n");
-	while((volatile unsigned int )*device_sysdata->dma_buf_sync);
-printk("set_flush_addresses: xbow_buf_sync\n");
-	while((volatile unsigned int )*device_sysdata->xbow_buf_sync);
-#endif
-
-}
-
-/*
- * Most drivers currently do not properly tell the arch specific pci dma
- * interfaces whether they can handle A64. Here is where we privately
- * keep track of this.
- */
-static void __init
-set_sn_pci64(struct pci_dev *dev)
-{
-	unsigned short vendor = dev->vendor;
-	unsigned short device = dev->device;
-
-	if (vendor == PCI_VENDOR_ID_QLOGIC) {
-		if ((device == PCI_DEVICE_ID_QLOGIC_ISP2100) ||
-				(device == PCI_DEVICE_ID_QLOGIC_ISP2200)) {
-			SET_PCIA64(dev);
-			return;
-		}
-	}
-
-	if (vendor == PCI_VENDOR_ID_SGI) {
-		if (device == PCI_DEVICE_ID_SGI_IOC3) {
-			SET_PCIA64(dev);
-			return;
-		}
-	}
-
-}
-
-/*
- * sn_pci_fixup() - This routine is called when platform_pci_fixup() is 
- *	invoked at the end of pcibios_init() to link the Linux pci 
- *	infrastructure to SGI IO Infrasturcture - ia64/kernel/pci.c
- *
- *	Other platform specific fixup can also be done here.
- */
-void
-sn_pci_fixup(int arg)
-{
-	struct list_head *ln;
-	struct pci_bus *pci_bus = NULL;
-	struct pci_dev *device_dev = NULL;
-	struct sn_widget_sysdata *widget_sysdata;
-	struct sn_device_sysdata *device_sysdata;
-	pciio_intr_t intr_handle;
-	int cpuid, bit;
-	devfs_handle_t device_vertex;
-	pciio_intr_line_t lines;
-	extern void sn_pci_find_bios(void);
-	extern int numnodes;
-	int cnode;
-	extern void io_sh_swapper(int, int);
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] )
-			io_sh_swapper((cnodeid_to_nasid(cnode)), 0);
-	}
-
-	if (arg == 0) {
-#ifdef CONFIG_PROC_FS
-		extern void register_sn_procfs(void);
-#endif
-
-		sn_init_irq_desc();
-		sn_pci_find_bios();
-		for (cnode = 0; cnode < numnodes; cnode++) {
-			extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int);
-			intr_init_vecblk(NODEPDA(cnode), cnode, 0);
-		} 
-
-		/*
-		 * When we return to generic Linux, Swapper is always on ..
-		 */
-		for (cnode = 0; cnode < numnodes; cnode++) {
-			if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] )
-				io_sh_swapper((cnodeid_to_nasid(cnode)), 1);
-		}
-#ifdef CONFIG_PROC_FS
-		register_sn_procfs();
-#endif
-		return;
-	}
-
-
-	done_probing = 1;
-
-	/*
-	 * Initialize the pci bus vertex in the pci_bus struct.
-	 */
-	for( ln = pci_root_buses.next; ln != &pci_root_buses; ln = ln->next) {
-		pci_bus = pci_bus_b(ln);
-		widget_sysdata = kmalloc(sizeof(struct sn_widget_sysdata), 
-					GFP_KERNEL);
-		widget_sysdata->vhdl = pci_bus_to_vertex(pci_bus->number);
-		pci_bus->sysdata = (void *)widget_sysdata;
-	}
-
-	/*
- 	 * set the root start and end so that drivers calling check_region()
-	 * won't see a conflict
-	 */
-	ioport_resource.start  = 0xc000000000000000;
-	ioport_resource.end =    0xcfffffffffffffff;
-
-	/*
-	 * Initialize the device vertex in the pci_dev struct.
-	 */
-	while ((device_dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, device_dev)) != NULL) {
-		unsigned int irq;
-		int idx;
-		u16 cmd;
-		devfs_handle_t vhdl;
-		unsigned long size;
-		extern int bit_pos_to_irq(int);
-
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-				device_dev->device == PCI_DEVICE_ID_SGI_IOC3) {
-			extern void pci_fixup_ioc3(struct pci_dev *d);
-			pci_fixup_ioc3(device_dev);
-		}
-
-		/* Set the device vertex */
-
-		device_sysdata = kmalloc(sizeof(struct sn_device_sysdata),
-					GFP_KERNEL);
-		device_sysdata->vhdl = devfn_to_vertex(device_dev->bus->number, device_dev->devfn);
-		device_sysdata->isa64 = 0;
-		/*
-		 * Set the xbridge Device(X) Write Buffer Flush and Xbow Flush 
-		 * register addresses.
-		 */
-		(void) set_flush_addresses(device_dev, device_sysdata);
-
-		device_dev->sysdata = (void *) device_sysdata;
-		set_sn_pci64(device_dev);
-		set_isPIC(device_sysdata);
-
-		pci_read_config_word(device_dev, PCI_COMMAND, &cmd);
-
-		/*
-		 * Set the resources address correctly.  The assumption here 
-		 * is that the addresses in the resource structure has been
-		 * read from the card and it was set in the card by our
-		 * Infrastructure ..
-		 */
-		vhdl = device_sysdata->vhdl;
-		for (idx = 0; idx < PCI_ROM_RESOURCE; idx++) {
-			size = 0;
-			size = device_dev->resource[idx].end -
-				device_dev->resource[idx].start;
-			if (size) {
-				device_dev->resource[idx].start = (unsigned long)pciio_pio_addr(vhdl, 0, PCIIO_SPACE_WIN(idx), 0, size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
-				device_dev->resource[idx].start |= __IA64_UNCACHED_OFFSET;
-			}
-			else
-				continue;
-
-			device_dev->resource[idx].end = 
-				device_dev->resource[idx].start + size;
-
-			if (device_dev->resource[idx].flags & IORESOURCE_IO)
-				cmd |= PCI_COMMAND_IO;
-
-			if (device_dev->resource[idx].flags & IORESOURCE_MEM)
-				cmd |= PCI_COMMAND_MEMORY;
-		}
-#if 0
-	/*
-	 * Software WAR for a Software BUG.
-	 * This is only temporary.
-	 * See PV 872791
-	 */
-
-		/*
-		 * Now handle the ROM resource ..
-		 */
-		size = device_dev->resource[PCI_ROM_RESOURCE].end -
-			device_dev->resource[PCI_ROM_RESOURCE].start;
-
-		if (size) {
-			device_dev->resource[PCI_ROM_RESOURCE].start =
-			(unsigned long) pciio_pio_addr(vhdl, 0, PCIIO_SPACE_ROM, 0, 
-				size, 0, (IS_PIC_DEVICE(device_dev)) ? 0 : PCIIO_BYTE_STREAM);
-			device_dev->resource[PCI_ROM_RESOURCE].start |= __IA64_UNCACHED_OFFSET;
-			device_dev->resource[PCI_ROM_RESOURCE].end =
-			device_dev->resource[PCI_ROM_RESOURCE].start + size;
-		}
-#endif
-
-		/*
-		 * Update the Command Word on the Card.
-		 */
-		cmd |= PCI_COMMAND_MASTER; /* If the device doesn't support */
-					   /* bit gets dropped .. no harm */
-		pci_write_config_word(device_dev, PCI_COMMAND, cmd);
-
-		pci_read_config_byte(device_dev, PCI_INTERRUPT_PIN, (unsigned char *)&lines);
-		if (device_dev->vendor == PCI_VENDOR_ID_SGI &&
-			device_dev->device == PCI_DEVICE_ID_SGI_IOC3 ) {
-				lines = 1;
-		}
- 
-		device_sysdata = (struct sn_device_sysdata *)device_dev->sysdata;
-		device_vertex = device_sysdata->vhdl;
- 
-		intr_handle = pciio_intr_alloc(device_vertex, NULL, lines, device_vertex);
-
-		bit = intr_handle->pi_irq;
-		cpuid = intr_handle->pi_cpu;
-		irq = bit;
-		irq = irq + (cpuid << 8);
-		pciio_intr_connect(intr_handle, (intr_func_t)0, (intr_arg_t)0);
-		device_dev->irq = irq;
-		register_pcibr_intr(irq, (pcibr_intr_t)intr_handle);
-#ifdef ajmtestintr
-		{
-			int slot = PCI_SLOT(device_dev->devfn);
-			static int timer_set = 0;
-			pcibr_intr_t	pcibr_intr = (pcibr_intr_t)intr_handle;
-			pcibr_soft_t	pcibr_soft = pcibr_intr->bi_soft;
-			extern void intr_test_handle_intr(int, void*, struct pt_regs *);
-
-			if (!timer_set) {
-				intr_test_set_timer();
-				timer_set = 1;
-			}
-			intr_test_register_irq(irq, pcibr_soft, slot);
-			request_irq(irq, intr_test_handle_intr,0,NULL, NULL);
-		}
-#endif
-
-	}
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		if ( !Is_pic_on_this_nasid[cnodeid_to_nasid(cnode)] )
-			io_sh_swapper((cnodeid_to_nasid(cnode)), 1);
-	}
-}
-
-/*
- * linux_bus_cvlink() Creates a link between the Linux PCI Bus number 
- *	to the actual hardware component that it represents:
- *	/dev/hw/linux/busnum/0 -> ../../../hw/module/001c01/slab/0/Ibrick/xtalk/15/pci
- *
- *	The bus vertex, when called to devfs_generate_path() returns:
- *		hw/module/001c01/slab/0/Ibrick/xtalk/15/pci
- *		hw/module/001c01/slab/1/Pbrick/xtalk/12/pci-x/0
- *		hw/module/001c01/slab/1/Pbrick/xtalk/12/pci-x/1
- */
-void
-linux_bus_cvlink(void)
-{
-	char name[8];
-	int index;
-	
-	for (index=0; index < MAX_PCI_XWIDGET; index++) {
-		if (!busnum_to_pcibr_vhdl[index])
-			continue;
-
-		sprintf(name, "%x", index);
-		(void) hwgraph_edge_add(linux_busnum, busnum_to_pcibr_vhdl[index], 
-				name);
-	}
-}
-
-/*
- * pci_bus_map_create() - Called by pci_bus_to_hcl_cvlink() to finish the job.
- *
- *	Linux PCI Bus numbers are assigned from lowest module_id numbers
- *	(rack/slot etc.) starting from HUB_WIDGET_ID_MAX down to 
- *	HUB_WIDGET_ID_MIN:
- *		widgetnum 15 gets lower Bus Number than widgetnum 14 etc.
- *
- *	Given 2 modules 001c01 and 001c02 we get the following mappings:
- *		001c01, widgetnum 15 = Bus number 0
- *		001c01, widgetnum 14 = Bus number 1
- *		001c02, widgetnum 15 = Bus number 3
- *		001c02, widgetnum 14 = Bus number 4
- *		etc.
- *
- * The rational for starting Bus Number 0 with Widget number 15 is because 
- * the system boot disks are always connected via Widget 15 Slot 0 of the 
- * I-brick.  Linux creates /dev/sd* devices(naming) strating from Bus Number 0 
- * Therefore, /dev/sda1 will be the first disk, on Widget 15 of the lowest 
- * module id(Master Cnode) of the system.
- *	
- */
-static int 
-pci_bus_map_create(devfs_handle_t xtalk, char * io_moduleid)
-{
-
-	devfs_handle_t master_node_vertex = NULL;
-	devfs_handle_t xwidget = NULL;
-	devfs_handle_t pci_bus = NULL;
-	hubinfo_t hubinfo = NULL;
-	xwidgetnum_t widgetnum;
-	char pathname[128];
-	graph_error_t rv;
-	int bus;
-	int basebus_num;
-	int bus_number;
-
-	/*
-	 * Loop throught this vertex and get the Xwidgets ..
-	 */
-
-
-	/* PCI devices */
-
-	for (widgetnum = HUB_WIDGET_ID_MAX; widgetnum >= HUB_WIDGET_ID_MIN; widgetnum--) {
-		sprintf(pathname, "%d", widgetnum);
-		xwidget = NULL;
-		
-		/*
-		 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
-		 *	     /hw/module/001c16/Pbrick/xtalk/8/pci/1 is device
-		 */
-		rv = hwgraph_traverse(xtalk, pathname, &xwidget);
-		if ( (rv != GRAPH_SUCCESS) ) {
-			if (!xwidget) {
-				continue;
-			}
-		}
-
-		sprintf(pathname, "%d/"EDGE_LBL_PCI, widgetnum);
-		pci_bus = NULL;
-		if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
-			if (!pci_bus) {
-				continue;
-}
-
-		/*
-		 * Assign the correct bus number and also the nasid of this 
-		 * pci Xwidget.
-		 * 
-		 * Should not be any race here ...
-		 */
-		num_bridges++;
-		busnum_to_pcibr_vhdl[num_bridges - 1] = pci_bus;
-
-		/*
-		 * Get the master node and from there get the NASID.
-		 */
-		master_node_vertex = device_master_get(xwidget);
-		if (!master_node_vertex) {
-			printk("WARNING: pci_bus_map_create: Unable to get .master for vertex 0x%p\n", (void *)xwidget);
-		}
-	
-		hubinfo_get(master_node_vertex, &hubinfo);
-		if (!hubinfo) {
-			printk("WARNING: pci_bus_map_create: Unable to get hubinfo for master node vertex 0x%p\n", (void *)master_node_vertex);
-			return(1);
-		} else {
-			busnum_to_nid[num_bridges - 1] = hubinfo->h_nasid;
-		}
-
-		/*
-		 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
-		 */
-		busnum_to_atedmamaps[num_bridges - 1] = (void *) kmalloc(
-			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
-		if (!busnum_to_atedmamaps[num_bridges - 1])
-			printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
-
-		memset(busnum_to_atedmamaps[num_bridges - 1], 0x0, 
-			sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
-
-	}
-
-	/*
-	 * PCIX devices
-	 * We number busses differently for PCI-X devices.
-	 * We start from Lowest Widget on up ..
-	 */
-
-        (void) ioconfig_get_busnum((char *)io_moduleid, &basebus_num);
-
-	for (widgetnum = HUB_WIDGET_ID_MIN; widgetnum <= HUB_WIDGET_ID_MAX; widgetnum++) {
-
-		/* Do both buses */
-		for ( bus = 0; bus < 2; bus++ ) {
-			sprintf(pathname, "%d", widgetnum);
-			xwidget = NULL;
-			
-			/*
-			 * Example - /hw/module/001c16/Pbrick/xtalk/8 is the xwidget
-			 *	     /hw/module/001c16/Pbrick/xtalk/8/pci-x/0 is the bus
-			 *	     /hw/module/001c16/Pbrick/xtalk/8/pci-x/0/1 is device
-			 */
-			rv = hwgraph_traverse(xtalk, pathname, &xwidget);
-			if ( (rv != GRAPH_SUCCESS) ) {
-				if (!xwidget) {
-					continue;
-				}
-			}
-	
-			if ( bus == 0 )
-				sprintf(pathname, "%d/"EDGE_LBL_PCIX_0, widgetnum);
-			else
-				sprintf(pathname, "%d/"EDGE_LBL_PCIX_1, widgetnum);
-			pci_bus = NULL;
-			if (hwgraph_traverse(xtalk, pathname, &pci_bus) != GRAPH_SUCCESS)
-				if (!pci_bus) {
-					continue;
-				}
-	
-			/*
-			 * Assign the correct bus number and also the nasid of this 
-			 * pci Xwidget.
-			 * 
-			 * Should not be any race here ...
-			 */
-			bus_number = basebus_num + bus + io_brick_map_widget(MODULE_PXBRICK, widgetnum);
-#ifdef DEBUG
-			printk("bus_number %d basebus_num %d bus %d io %d\n", 
-				bus_number, basebus_num, bus, 
-				io_brick_map_widget(MODULE_PXBRICK, widgetnum));
-#endif
-			busnum_to_pcibr_vhdl[bus_number] = pci_bus;
-	
-			/*
-			 * Pre assign DMA maps needed for 32 Bits Page Map DMA.
-			 */
-			busnum_to_atedmamaps[bus_number] = (void *) kmalloc(
-				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS, GFP_KERNEL);
-			if (!busnum_to_atedmamaps[bus_number])
-				printk("WARNING: pci_bus_map_create: Unable to precreate ATE DMA Maps for busnum %d vertex 0x%p\n", num_bridges - 1, (void *)xwidget);
-	
-			memset(busnum_to_atedmamaps[bus_number], 0x0, 
-				sizeof(struct sn_dma_maps_s) * MAX_ATE_MAPS);
-		}
-	}
-
-        return(0);
-}
-
-/*
- * pci_bus_to_hcl_cvlink() - This routine is called after SGI IO Infrastructure   
- *      initialization has completed to set up the mappings between Xbridge
- *      and logical pci bus numbers.  We also set up the NASID for each of these
- *      xbridges.
- *
- *      Must be called before pci_init() is invoked.
- */
-int
-pci_bus_to_hcl_cvlink(void) 
-{
-
-	devfs_handle_t devfs_hdl = NULL;
-	devfs_handle_t xtalk = NULL;
-	int rv = 0;
-	char name[256];
-	char tmp_name[256];
-	int i, ii;
-
-	/*
-	 * Figure out which IO Brick is connected to the Compute Bricks.
-	 */
-	for (i = 0; i < nummodules; i++) {
-		extern int iomoduleid_get(nasid_t);
-		moduleid_t iobrick_id;
-		nasid_t nasid = -1;
-		int nodecnt;
-		int n = 0;
-
-		nodecnt = modules[i]->nodecnt;
-		for ( n = 0; n < nodecnt; n++ ) {
-			nasid = cnodeid_to_nasid(modules[i]->nodes[n]);
-			iobrick_id = iomoduleid_get(nasid);
-			if ((int)iobrick_id > 0) { /* Valid module id */
-				char name[12];
-				memset(name, 0, 12);
-				format_module_id((char *)&(modules[i]->io[n].moduleid), iobrick_id, MODULE_FORMAT_BRIEF);
-			}
-		}
-	}
-				
-	devfs_hdl = hwgraph_path_to_vertex("/dev/hw/module");
-	for (i = 0; i < nummodules ; i++) {
-		for ( ii = 0; ii < 2 ; ii++ ) {
-			memset(name, 0, 256);
-			memset(tmp_name, 0, 256);
-			format_module_id(name, modules[i]->id, MODULE_FORMAT_BRIEF);
-			sprintf(tmp_name, "/slab/%d/Pbrick/xtalk", geo_slab(modules[i]->geoid[ii]));
-			strcat(name, tmp_name);
-			xtalk = NULL;
-			rv = hwgraph_edge_get(devfs_hdl, name, &xtalk);
-			pci_bus_map_create(xtalk, (char *)&(modules[i]->io[ii].moduleid));
-		}
-	}
-
-	/*
-	 * Create the Linux PCI bus number vertex link.
-	 */
-	(void)linux_bus_cvlink();
-	(void)ioconfig_bus_new_entries();
-
-	return(0);
-}
diff -Nru a/arch/ia64/sn/io/sn2/pcibr/Makefile b/arch/ia64/sn/io/sn2/pcibr/Makefile
--- a/arch/ia64/sn/io/sn2/pcibr/Makefile	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/sn/io/sn2/pcibr/Makefile	Wed Jun 18 23:42:09 2003
@@ -11,11 +11,5 @@
 
 EXTRA_CFLAGS    := -DLITTLE_ENDIAN
 
-ifdef CONFIG_IA64_SGI_SN2
-EXTRA_CFLAGS    += -DSHUB_SWAP_WAR
-endif
-
-obj-$(CONFIG_IA64_SGI_SN2)	+= pcibr_dvr.o pcibr_ate.o pcibr_config.o \
-                                   pcibr_dvr.o pcibr_hints.o \
-				   pcibr_intr.o pcibr_rrb.o pcibr_slot.o \
-				   pcibr_error.o
+obj-y += pcibr_ate.o pcibr_config.o pcibr_dvr.o pcibr_hints.o pcibr_intr.o pcibr_rrb.o \
+	 pcibr_slot.o pcibr_error.o
diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_ate.c	Wed Jun 18 23:42:06 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,7 +27,6 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
@@ -101,73 +100,26 @@
     int                     i, j;
     bridgereg_t             old_enable, new_enable;
     int                     s;
-    int			    this_is_pic = is_pic(bridge);
 
     /* Probe SSRAM to determine its size. */
-    if ( this_is_pic ) {
-	old_enable = bridge->b_int_enable;
-	new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-	bridge->b_int_enable = new_enable;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		old_enable = BRIDGE_REG_GET32((&bridge->b_int_enable));
-		new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-		BRIDGE_REG_SET32((&bridge->b_int_enable)) = new_enable;
-	}
-	else {
-		old_enable = bridge->b_int_enable;
-		new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-		bridge->b_int_enable = new_enable;
-	}
-    }
+    old_enable = bridge->b_int_enable;
+    new_enable = old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
+    bridge->b_int_enable = new_enable;
 
     for (i = 1; i < ATE_NUM_SIZES; i++) {
 	/* Try writing a value */
-	if ( this_is_pic ) {
-		bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge)))
-			bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = __swab64(ATE_PROBE_VALUE);
-		else
-			bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
-	}
+	bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] = ATE_PROBE_VALUE;
 
 	/* Guard against wrap */
 	for (j = 1; j < i; j++)
 	    bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(j) - 1] = 0;
 
 	/* See if value was written */
-	if ( this_is_pic ) {
-		if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
+	if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
 				largest_working_size = i;
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge))) {
-			if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == __swab64(ATE_PROBE_VALUE))
-					largest_working_size = i;
-			else {
-				if (bridge->b_ext_ate_ram[ATE_NUM_ENTRIES(i) - 1] == ATE_PROBE_VALUE)
-					largest_working_size = i;
-			}
-		}
-	}
-    }
-    if ( this_is_pic ) {
-	bridge->b_int_enable = old_enable;
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		BRIDGE_REG_SET32((&bridge->b_int_enable)) = old_enable;
-		BRIDGE_REG_GET32((&bridge->b_wid_tflush));   /* wait until Bridge PIO complete */
-	}
-	else {
-		bridge->b_int_enable = old_enable;
-		bridge->b_wid_tflush;               /* wait until Bridge PIO complete */
-	}
     }
+    bridge->b_int_enable = old_enable;
+    bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
 
     /*
      * ensure that we write and read without any interruption.
@@ -175,26 +127,10 @@
      */
 
     s = splhi();
-    if ( this_is_pic ) {
-	bridge->b_wid_control = (bridge->b_wid_control
+    bridge->b_wid_control = (bridge->b_wid_control
 			& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
 			| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
-	bridge->b_wid_control;		/* inval addr bug war */
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		BRIDGE_REG_SET32((&(bridge->b_wid_control))) = 
-				__swab32((BRIDGE_REG_GET32((&bridge->b_wid_control))
-					& ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
-					| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size));
-		BRIDGE_REG_GET32((&bridge->b_wid_control));/* inval addr bug war */
-	}
-	else {
-		bridge->b_wid_control = (bridge->b_wid_control & ~BRIDGE_CTRL_SSRAM_SIZE_MASK)
-				| BRIDGE_CTRL_SSRAM_SIZE(largest_working_size);
-		bridge->b_wid_control;              /* inval addr bug war */
-	}
-    }
+    bridge->b_wid_control;		/* inval addr bug war */
     splx(s);
 
     num_entries = ATE_NUM_ENTRIES(largest_working_size);
@@ -423,16 +359,7 @@
 			    /* Flush the write buffer associated with this
 			     * PCI device which might be using dma map RAM.
 			     */
-			if ( is_pic(bridge) ) {
-				bridge->b_wr_req_buf[slot].reg;
-			}
-			else {
-				if (io_get_sh_swapper(NASID_GET(bridge)) ) {
-					BRIDGE_REG_GET32((&bridge->b_wr_req_buf[slot].reg));
-				}
-				else
-					bridge->b_wr_req_buf[slot].reg;
-			}
+			bridge->b_wr_req_buf[slot].reg;
 		    }
 	    }
     }
diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_config.c	Wed Jun 18 23:42:08 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -28,19 +28,16 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
-extern pcibr_info_t      pcibr_info_get(devfs_handle_t);
+extern pcibr_info_t      pcibr_info_get(vertex_hdl_t);
 
-uint64_t          pcibr_config_get(devfs_handle_t, unsigned, unsigned);
-uint64_t          do_pcibr_config_get(int, cfg_p, unsigned, unsigned);
-void              pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t);
-void       	  do_pcibr_config_set(int, cfg_p, unsigned, unsigned, uint64_t);
-static void	  swap_do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t);
+uint64_t          pcibr_config_get(vertex_hdl_t, unsigned, unsigned);
+uint64_t          do_pcibr_config_get(cfg_p, unsigned, unsigned);
+void              pcibr_config_set(vertex_hdl_t, unsigned, unsigned, uint64_t);
+void       	  do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t);
 
-#ifdef LITTLE_ENDIAN
 /*
  * on sn-ia we need to twiddle the the addresses going out
  * the pci bus because we use the unswizzled synergy space
@@ -51,18 +48,13 @@
 #define CS(b,r) (((volatile uint16_t *) b)[((r^4)/2)])
 #define CW(b,r) (((volatile uint32_t *) b)[((r^4)/4)])
 
-#define	CBP(b,r) (((volatile uint8_t *) b)[(r)^3])
-#define	CSP(b,r) (((volatile uint16_t *) b)[((r)/2)^1])
+#define	CBP(b,r) (((volatile uint8_t *) b)[(r)])
+#define	CSP(b,r) (((volatile uint16_t *) b)[((r)/2)])
 #define	CWP(b,r) (((volatile uint32_t *) b)[(r)/4])
 
 #define SCB(b,r) (((volatile uint8_t *) b)[((r)^3)])
 #define SCS(b,r) (((volatile uint16_t *) b)[((r^2)/2)])
 #define SCW(b,r) (((volatile uint32_t *) b)[((r)/4)])
-#else
-#define	CB(b,r)	(((volatile uint8_t *) cfgbase)[(r)^3])
-#define	CS(b,r)	(((volatile uint16_t *) cfgbase)[((r)/2)^1])
-#define	CW(b,r)	(((volatile uint32_t *) cfgbase)[(r)/4])
-#endif
 
 /*
  * Return a config space address for given slot / func / offset.  Note the
@@ -84,8 +76,7 @@
 	/*
 	 * Type 0 config space
 	 */
-	if (is_pic(bridge))
-		slot++;
+	slot++;
 	return &bridge->b_type0_cfg_dev[slot].f[func].l[offset];
 }
 
@@ -109,7 +100,7 @@
 	cfg_p  cfg_base;
 	
 	cfg_base = pcibr_slot_config_addr(bridge, slot, 0);
-	return (do_pcibr_config_get(is_pic(bridge), cfg_base, offset, sizeof(unsigned)));
+	return (do_pcibr_config_get(cfg_base, offset, sizeof(unsigned)));
 }
 
 /*
@@ -122,7 +113,7 @@
 	cfg_p  cfg_base;
 
 	cfg_base = pcibr_func_config_addr(bridge, 0, slot, func, 0);
-	return (do_pcibr_config_get(is_pic(bridge), cfg_base, offset, sizeof(unsigned)));
+	return (do_pcibr_config_get(cfg_base, offset, sizeof(unsigned)));
 }
 
 /*
@@ -135,7 +126,7 @@
 	cfg_p  cfg_base;
 
 	cfg_base = pcibr_slot_config_addr(bridge, slot, 0);
-	do_pcibr_config_set(is_pic(bridge), cfg_base, offset, sizeof(unsigned), val);
+	do_pcibr_config_set(cfg_base, offset, sizeof(unsigned), val);
 }
 
 /*
@@ -148,13 +139,13 @@
 	cfg_p  cfg_base;
 
 	cfg_base = pcibr_func_config_addr(bridge, 0, slot, func, 0);
-	do_pcibr_config_set(is_pic(bridge), cfg_base, offset, sizeof(unsigned), val);
+	do_pcibr_config_set(cfg_base, offset, sizeof(unsigned), val);
 }
 
 int pcibr_config_debug = 0;
 
 cfg_p
-pcibr_config_addr(devfs_handle_t conn,
+pcibr_config_addr(vertex_hdl_t conn,
 		  unsigned reg)
 {
     pcibr_info_t            pcibr_info;
@@ -183,19 +174,6 @@
 	pciio_func = PCI_TYPE1_FUNC(reg);
 
 	ASSERT(pciio_bus != 0);
-#if 0
-    } else if (conn != pciio_info_hostdev_get(pciio_info)) {
-	/*
-	 * Conn is on a subordinate bus, so get bus/slot/func directly from
-	 * its pciio_info_t structure.
-	 */
-	pciio_bus = pciio_info->c_bus;
-	pciio_slot = pciio_info->c_slot;
-	pciio_func = pciio_info->c_func;
-	if (pciio_func == PCIIO_FUNC_NONE) {
-		pciio_func = 0;
-	}
-#endif
     } else {
 	/*
 	 * Conn is directly connected to the host bus.  PCI bus number is
@@ -224,44 +202,23 @@
     return cfgbase;
 }
 
-extern unsigned char Is_pic_on_this_nasid[];
 uint64_t
-pcibr_config_get(devfs_handle_t conn,
+pcibr_config_get(vertex_hdl_t conn,
 		 unsigned reg,
 		 unsigned size)
 {
-    if ( !Is_pic_on_this_nasid[ NASID_GET((pcibr_config_addr(conn, reg)))] )
-    	return do_pcibr_config_get(0, pcibr_config_addr(conn, reg),
-				PCI_TYPE1_REG(reg), size);
-    else
-    	return do_pcibr_config_get(1, pcibr_config_addr(conn, reg),
+	return do_pcibr_config_get(pcibr_config_addr(conn, reg),
 				PCI_TYPE1_REG(reg), size);
 }
 
 uint64_t
-do_pcibr_config_get(
-		       int pic,
-		       cfg_p cfgbase,
+do_pcibr_config_get(cfg_p cfgbase,
 		       unsigned reg,
 		       unsigned size)
 {
     unsigned                value;
 
-    if ( pic ) {
-	value = CWP(cfgbase, reg);
-    }
-    else {
-	if ( io_get_sh_swapper(NASID_GET(cfgbase)) ) {
-	    /*
-	     * Shub Swapper on - 0 returns PCI Offset 0 but byte swapped!
-	     * Do not swizzle address and byte swap the result.
-	     */
-	    value = SCW(cfgbase, reg);
-	    value = __swab32(value);
-	} else {
-    	    value = CW(cfgbase, reg);
-	}
-    }
+    value = CWP(cfgbase, reg);
     if (reg & 3)
 	value >>= 8 * (reg & 3);
     if (size < 4)
@@ -270,108 +227,43 @@
 }
 
 void
-pcibr_config_set(devfs_handle_t conn,
+pcibr_config_set(vertex_hdl_t conn,
 		 unsigned reg,
 		 unsigned size,
 		 uint64_t value)
 {
-    if ( Is_pic_on_this_nasid[ NASID_GET((pcibr_config_addr(conn, reg)))] )
-    	do_pcibr_config_set(1, pcibr_config_addr(conn, reg),
-			PCI_TYPE1_REG(reg), size, value);
-    else
-	swap_do_pcibr_config_set(pcibr_config_addr(conn, reg),
+	do_pcibr_config_set(pcibr_config_addr(conn, reg),
 			PCI_TYPE1_REG(reg), size, value);
 }
 
 void
-do_pcibr_config_set(int pic,
-		    cfg_p cfgbase,
+do_pcibr_config_set(cfg_p cfgbase,
 		    unsigned reg,
 		    unsigned size,
 		    uint64_t value)
 {
-	if ( pic ) {
-		switch (size) {
-		case 1:
+	switch (size) {
+	case 1:
+		CBP(cfgbase, reg) = value;
+		break;
+	case 2:
+		if (reg & 1) {
 			CBP(cfgbase, reg) = value;
-			break;
-		case 2:
-			if (reg & 1) {
-				CBP(cfgbase, reg) = value;
-				CBP(cfgbase, reg + 1) = value >> 8;
-			} else
-				CSP(cfgbase, reg) = value;
-			break;
-		case 3:
-			if (reg & 1) {
-				CBP(cfgbase, reg) = value;
-				CSP(cfgbase, (reg + 1)) = value >> 8;
-			} else {
-				CSP(cfgbase, reg) = value;
-				CBP(cfgbase, reg + 2) = value >> 16;
-			}
-			break;
-		case 4:
-			CWP(cfgbase, reg) = value;
-			break;
-   		}
-	}
-	else {
-		switch (size) {
-		case 1:
-			CB(cfgbase, reg) = value;
-			break;
-		case 2:
-			if (reg & 1) {
-				CB(cfgbase, reg) = value;
-				CB(cfgbase, reg + 1) = value >> 8;
-			} else
-				CS(cfgbase, reg) = value;
-			break;
-		case 3:
-			if (reg & 1) {
-				CB(cfgbase, reg) = value;
-				CS(cfgbase, (reg + 1)) = value >> 8;
-			} else {
-				CS(cfgbase, reg) = value;
-				CB(cfgbase, reg + 2) = value >> 16;
-			}
-			break;
-		case 4:
-			CW(cfgbase, reg) = value;
-			break;
-   		}
-	}
-}
-
-void
-swap_do_pcibr_config_set(cfg_p cfgbase,
-                    unsigned reg,
-                    unsigned size,
-                    uint64_t value)
-{
-
-    uint64_t temp_value = 0;
-
-    switch (size) {
-    case 1:
-        SCB(cfgbase, reg) = value;
-        break;
-    case 2:
-	temp_value = __swab16(value);
-        if (reg & 1) {
-            SCB(cfgbase, reg) = temp_value;
-            SCB(cfgbase, reg + 1) = temp_value >> 8;
-        } else
-            SCS(cfgbase, reg) = temp_value;
-        break;
-    case 3:
-	BUG();
-        break;
-
-    case 4:
-	temp_value = __swab32(value);
-        SCW(cfgbase, reg) = temp_value;
-        break;
-    }
+			CBP(cfgbase, reg + 1) = value >> 8;
+		} else
+			CSP(cfgbase, reg) = value;
+		break;
+	case 3:
+		if (reg & 1) {
+			CBP(cfgbase, reg) = value;
+			CSP(cfgbase, (reg + 1)) = value >> 8;
+		} else {
+			CSP(cfgbase, reg) = value;
+			CBP(cfgbase, reg + 2) = value >> 16;
+		}
+		break;
+	case 4:
+		CWP(cfgbase, reg) = value;
+		break;
+ 	}
 }
diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_dvr.c	Wed Jun 18 23:42:09 2003
@@ -4,13 +4,16 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/module.h>
+#include <linux/string.h>
+#include <linux/interrupt.h>
 #include <asm/sn/sgi.h>
+#include <asm/sn/sn_sal.h>
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/arch.h>
@@ -18,6 +21,7 @@
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
+#include <asm/sn/klconfig.h>
 #include <asm/sn/xtalk/xwidget.h>
 #include <asm/sn/pci/bridge.h>
 #include <asm/sn/pci/pciio.h>
@@ -27,7 +31,6 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
@@ -74,32 +77,6 @@
 #define USS302_BRIDGE_TIMEOUT_HLD	4
 #endif
 
-int                     pcibr_devflag = D_MP;
-
-/*
- * This is the file operation table for the pcibr driver.
- * As each of the functions are implemented, put the
- * appropriate function name below.
- */
-struct file_operations pcibr_fops = {
-	owner:  THIS_MODULE,
-	llseek: NULL,
-	read: NULL,
-	write: NULL,
-	readdir: NULL,
-	poll: NULL,
-	ioctl: NULL,
-	mmap: NULL,
-	open: NULL,
-	flush: NULL,
-	release: NULL,
-	fsync: NULL,
-	fasync: NULL,
-	lock: NULL,
-	readv: NULL,
-	writev: NULL
-};
-
 /* kbrick widgetnum-to-bus layout */
 int p_busnum[MAX_PORT_NUM] = {                  /* widget#      */
         0, 0, 0, 0, 0, 0, 0, 0,                 /* 0x0 - 0x7    */
@@ -116,17 +93,16 @@
 pcibr_list_p            pcibr_list = 0;
 #endif
 
-extern int              hwgraph_vertex_name_get(devfs_handle_t vhdl, char *buf, uint buflen);
-extern int              hub_device_flags_set(devfs_handle_t widget_dev, hub_widget_flags_t flags);
+extern int              hwgraph_vertex_name_get(vertex_hdl_t vhdl, char *buf, uint buflen);
 extern long             atoi(register char *p);
-extern cnodeid_t        nodevertex_to_cnodeid(devfs_handle_t vhdl);
-extern char             *dev_to_name(devfs_handle_t dev, char *buf, uint buflen);
+extern cnodeid_t        nodevertex_to_cnodeid(vertex_hdl_t vhdl);
+extern char             *dev_to_name(vertex_hdl_t dev, char *buf, uint buflen);
 extern struct map       *atemapalloc(uint64_t);
 extern void             atefree(struct map *, size_t, uint64_t);
 extern void             atemapfree(struct map *);
-extern pciio_dmamap_t   get_free_pciio_dmamap(devfs_handle_t);
+extern pciio_dmamap_t   get_free_pciio_dmamap(vertex_hdl_t);
 extern void		free_pciio_dmamap(pcibr_dmamap_t);
-extern void		xwidget_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t);
+extern void		xwidget_error_register(vertex_hdl_t, error_handler_f *, error_handler_arg_t);
 
 #define	ATE_WRITE()    ate_write(pcibr_soft, ate_ptr, ate_count, ate)
 #if PCIBR_FREEZE_TIME
@@ -153,9 +129,9 @@
 extern int		 do_pcibr_rrb_free_all(pcibr_soft_t, bridge_t *, pciio_slot_t);
 extern void              do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int, int);
 
-extern int  		 pcibr_wrb_flush(devfs_handle_t);
-extern int               pcibr_rrb_alloc(devfs_handle_t, int *, int *);
-extern void              pcibr_rrb_flush(devfs_handle_t);
+extern int  		 pcibr_wrb_flush(vertex_hdl_t);
+extern int               pcibr_rrb_alloc(vertex_hdl_t, int *, int *);
+extern void              pcibr_rrb_flush(vertex_hdl_t);
 
 static int                pcibr_try_set_device(pcibr_soft_t, pciio_slot_t, unsigned, bridgereg_t);
 void                     pcibr_release_device(pcibr_soft_t, pciio_slot_t, bridgereg_t);
@@ -166,21 +142,15 @@
 extern iopaddr_t         pcibr_bus_addr_alloc(pcibr_soft_t, pciio_win_info_t,
                                               pciio_space_t, int, int, int);
 
-void                     pcibr_init(void);
-int                      pcibr_attach(devfs_handle_t);
-int			 pcibr_attach2(devfs_handle_t, bridge_t *, devfs_handle_t,
+int                      pcibr_attach(vertex_hdl_t);
+int			 pcibr_attach2(vertex_hdl_t, bridge_t *, vertex_hdl_t,
 				       int, pcibr_soft_t *);
-int			 pcibr_detach(devfs_handle_t);
-int                      pcibr_open(devfs_handle_t *, int, int, cred_t *);
-int                      pcibr_close(devfs_handle_t, int, int, cred_t *);
-int                      pcibr_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint);
-int                      pcibr_unmap(devfs_handle_t, vhandl_t *);
-int                      pcibr_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *);
+int			 pcibr_detach(vertex_hdl_t);
 int			 pcibr_pcix_rbars_calc(pcibr_soft_t);
 extern int               pcibr_init_ext_ate_ram(bridge_t *);
 extern int               pcibr_ate_alloc(pcibr_soft_t, int);
 extern void              pcibr_ate_free(pcibr_soft_t, int, int);
-extern int 		 pcibr_widget_to_bus(devfs_handle_t pcibr_vhdl);
+extern int 		 pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl);
 
 extern unsigned ate_freeze(pcibr_dmamap_t pcibr_dmamap,
 #if PCIBR_FREEZE_TIME
@@ -197,45 +167,43 @@
 	 		unsigned *cmd_regs,
 	 		unsigned s);
 
-pcibr_info_t      pcibr_info_get(devfs_handle_t);
+pcibr_info_t      pcibr_info_get(vertex_hdl_t);
 
-static iopaddr_t         pcibr_addr_pci_to_xio(devfs_handle_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned);
+static iopaddr_t         pcibr_addr_pci_to_xio(vertex_hdl_t, pciio_slot_t, pciio_space_t, iopaddr_t, size_t, unsigned);
 
-pcibr_piomap_t          pcibr_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
+pcibr_piomap_t          pcibr_piomap_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
 void                    pcibr_piomap_free(pcibr_piomap_t);
 caddr_t                 pcibr_piomap_addr(pcibr_piomap_t, iopaddr_t, size_t);
 void                    pcibr_piomap_done(pcibr_piomap_t);
-caddr_t                 pcibr_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-iopaddr_t               pcibr_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
-void                    pcibr_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
+caddr_t                 pcibr_piotrans_addr(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
+iopaddr_t               pcibr_piospace_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, size_t, size_t);
+void                    pcibr_piospace_free(vertex_hdl_t, pciio_space_t, iopaddr_t, size_t);
 
 static iopaddr_t         pcibr_flags_to_d64(unsigned, pcibr_soft_t);
 extern bridge_ate_t     pcibr_flags_to_ate(unsigned);
 
-pcibr_dmamap_t          pcibr_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
+pcibr_dmamap_t          pcibr_dmamap_alloc(vertex_hdl_t, device_desc_t, size_t, unsigned);
 void                    pcibr_dmamap_free(pcibr_dmamap_t);
 extern bridge_ate_p     pcibr_ate_addr(pcibr_soft_t, int);
 static iopaddr_t         pcibr_addr_xio_to_pci(pcibr_soft_t, iopaddr_t, size_t);
 iopaddr_t               pcibr_dmamap_addr(pcibr_dmamap_t, paddr_t, size_t);
-alenlist_t              pcibr_dmamap_list(pcibr_dmamap_t, alenlist_t, unsigned);
 void                    pcibr_dmamap_done(pcibr_dmamap_t);
-cnodeid_t		pcibr_get_dmatrans_node(devfs_handle_t);
-iopaddr_t               pcibr_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              pcibr_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
+cnodeid_t		pcibr_get_dmatrans_node(vertex_hdl_t);
+iopaddr_t               pcibr_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned);
 void                    pcibr_dmamap_drain(pcibr_dmamap_t);
-void                    pcibr_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
-void                    pcibr_dmalist_drain(devfs_handle_t, alenlist_t);
+void                    pcibr_dmaaddr_drain(vertex_hdl_t, paddr_t, size_t);
+void                    pcibr_dmalist_drain(vertex_hdl_t, alenlist_t);
 iopaddr_t               pcibr_dmamap_pciaddr_get(pcibr_dmamap_t);
 
 extern unsigned		pcibr_intr_bits(pciio_info_t info, 
 					pciio_intr_line_t lines, int nslots);
-extern pcibr_intr_t     pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
+extern pcibr_intr_t     pcibr_intr_alloc(vertex_hdl_t, device_desc_t, pciio_intr_line_t, vertex_hdl_t);
 extern void             pcibr_intr_free(pcibr_intr_t);
 extern void             pcibr_setpciint(xtalk_intr_t);
 extern int              pcibr_intr_connect(pcibr_intr_t, intr_func_t, intr_arg_t);
 extern void             pcibr_intr_disconnect(pcibr_intr_t);
 
-extern devfs_handle_t     pcibr_intr_cpu_get(pcibr_intr_t);
+extern vertex_hdl_t     pcibr_intr_cpu_get(pcibr_intr_t);
 extern void             pcibr_intr_func(intr_arg_t);
 
 extern void             print_bridge_errcmd(uint32_t, char *);
@@ -253,51 +221,48 @@
 extern int              pcibr_dmawr_error(pcibr_soft_t, int, ioerror_mode_t, ioerror_t *);
 extern int              pcibr_error_handler(error_handler_arg_t, int, ioerror_mode_t, ioerror_t *);
 extern int              pcibr_error_handler_wrapper(error_handler_arg_t, int, ioerror_mode_t, ioerror_t *);
-void                    pcibr_provider_startup(devfs_handle_t);
-void                    pcibr_provider_shutdown(devfs_handle_t);
+void                    pcibr_provider_startup(vertex_hdl_t);
+void                    pcibr_provider_shutdown(vertex_hdl_t);
 
-int                     pcibr_reset(devfs_handle_t);
-pciio_endian_t          pcibr_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
+int                     pcibr_reset(vertex_hdl_t);
+pciio_endian_t          pcibr_endian_set(vertex_hdl_t, pciio_endian_t, pciio_endian_t);
 int                     pcibr_priority_bits_set(pcibr_soft_t, pciio_slot_t, pciio_priority_t);
-pciio_priority_t        pcibr_priority_set(devfs_handle_t, pciio_priority_t);
-int                     pcibr_device_flags_set(devfs_handle_t, pcibr_device_flags_t);
+pciio_priority_t        pcibr_priority_set(vertex_hdl_t, pciio_priority_t);
+int                     pcibr_device_flags_set(vertex_hdl_t, pcibr_device_flags_t);
 
-extern cfg_p            pcibr_config_addr(devfs_handle_t, unsigned);
-extern uint64_t         pcibr_config_get(devfs_handle_t, unsigned, unsigned);
-extern void             pcibr_config_set(devfs_handle_t, unsigned, unsigned, uint64_t);
-
-extern pcibr_hints_t    pcibr_hints_get(devfs_handle_t, int);
-extern void             pcibr_hints_fix_rrbs(devfs_handle_t);
-extern void             pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t);
-extern void	 	pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *);
-extern void             pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t);
-extern void             pcibr_hints_handsoff(devfs_handle_t);
-extern void             pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, uint64_t);
-
-extern int		pcibr_slot_reset(devfs_handle_t,pciio_slot_t);
-extern int		pcibr_slot_info_init(devfs_handle_t,pciio_slot_t);
-extern int		pcibr_slot_info_free(devfs_handle_t,pciio_slot_t);
+extern cfg_p            pcibr_config_addr(vertex_hdl_t, unsigned);
+extern uint64_t         pcibr_config_get(vertex_hdl_t, unsigned, unsigned);
+extern void             pcibr_config_set(vertex_hdl_t, unsigned, unsigned, uint64_t);
+
+extern pcibr_hints_t    pcibr_hints_get(vertex_hdl_t, int);
+extern void             pcibr_hints_fix_rrbs(vertex_hdl_t);
+extern void             pcibr_hints_dualslot(vertex_hdl_t, pciio_slot_t, pciio_slot_t);
+extern void	 	pcibr_hints_intr_bits(vertex_hdl_t, pcibr_intr_bits_f *);
+extern void             pcibr_set_rrb_callback(vertex_hdl_t, rrb_alloc_funct_t);
+extern void             pcibr_hints_handsoff(vertex_hdl_t);
+extern void             pcibr_hints_subdevs(vertex_hdl_t, pciio_slot_t, uint64_t);
+
+extern int		pcibr_slot_info_init(vertex_hdl_t,pciio_slot_t);
+extern int		pcibr_slot_info_free(vertex_hdl_t,pciio_slot_t);
 extern int	        pcibr_slot_info_return(pcibr_soft_t, pciio_slot_t,
                                                pcibr_slot_info_resp_t);
 extern void       	pcibr_slot_func_info_return(pcibr_info_h, int,
                                                     pcibr_slot_func_info_resp_t);
-extern int		pcibr_slot_addr_space_init(devfs_handle_t,pciio_slot_t);
+extern int		pcibr_slot_addr_space_init(vertex_hdl_t,pciio_slot_t);
 extern int		pcibr_slot_pcix_rbar_init(pcibr_soft_t, pciio_slot_t);
-extern int		pcibr_slot_device_init(devfs_handle_t, pciio_slot_t);
-extern int		pcibr_slot_guest_info_init(devfs_handle_t,pciio_slot_t);
-extern int		pcibr_slot_call_device_attach(devfs_handle_t,
+extern int		pcibr_slot_device_init(vertex_hdl_t, pciio_slot_t);
+extern int		pcibr_slot_guest_info_init(vertex_hdl_t,pciio_slot_t);
+extern int		pcibr_slot_call_device_attach(vertex_hdl_t,
 						      pciio_slot_t, int);
-extern int		pcibr_slot_call_device_detach(devfs_handle_t,
+extern int		pcibr_slot_call_device_detach(vertex_hdl_t,
 						      pciio_slot_t, int);
-extern int              pcibr_slot_attach(devfs_handle_t, pciio_slot_t, int, 
+extern int              pcibr_slot_attach(vertex_hdl_t, pciio_slot_t, int, 
                                                       char *, int *);
-extern int              pcibr_slot_detach(devfs_handle_t, pciio_slot_t, int,
+extern int              pcibr_slot_detach(vertex_hdl_t, pciio_slot_t, int,
                                                       char *, int *);
-extern int 		pcibr_is_slot_sys_critical(devfs_handle_t, pciio_slot_t);
-
-extern int		pcibr_slot_initial_rrb_alloc(devfs_handle_t, pciio_slot_t);
-extern int		pcibr_initial_rrb(devfs_handle_t, pciio_slot_t, pciio_slot_t);
 
+extern int		pcibr_slot_initial_rrb_alloc(vertex_hdl_t, pciio_slot_t);
+extern int		pcibr_initial_rrb(vertex_hdl_t, pciio_slot_t, pciio_slot_t);
 
 /* =====================================================================
  *    Device(x) register management
@@ -623,172 +588,47 @@
  */
 
 
-/*
- *    pcibr_init: called once during system startup or
- *      when a loadable driver is loaded.
- *
- *      The driver_register function should normally
- *      be in _reg, not _init.  But the pcibr driver is
- *      required by devinit before the _reg routines
- *      are called, so this is an exception.
- */
-void
-pcibr_init(void)
+static int
+pcibr_mmap(struct file * file, struct vm_area_struct * vma)
 {
-    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INIT, NULL, "pcibr_init()\n"));
+	vertex_hdl_t		pcibr_vhdl = file->f_dentry->d_fsdata;
+	pcibr_soft_t            pcibr_soft;
+	bridge_t               *bridge;
+	unsigned long		phys_addr;
+	int			error = 0;
 
-    xwidget_driver_register(XBRIDGE_WIDGET_PART_NUM,
-			    XBRIDGE_WIDGET_MFGR_NUM,
-			    "pcibr_",
-			    0);
-    xwidget_driver_register(BRIDGE_WIDGET_PART_NUM,
-			    BRIDGE_WIDGET_MFGR_NUM,
-			    "pcibr_",
-			    0);
+	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
+	bridge = pcibr_soft->bs_base;
+	phys_addr = (unsigned long)bridge & ~0xc000000000000000; /* Mask out the Uncache bits */
+        vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+        vma->vm_flags |= VM_RESERVED | VM_IO;
+        error = io_remap_page_range(vma, phys_addr, vma->vm_start,
+				    vma->vm_end - vma->vm_start,
+				    vma->vm_page_prot);
+	return(error);
 }
 
 /*
- * open/close mmap/munmap interface would be used by processes
- * that plan to map the PCI bridge, and muck around with the
- * registers. This is dangerous to do, and will be allowed
- * to a select brand of programs. Typically these are
- * diagnostics programs, or some user level commands we may
- * write to do some weird things.
- * To start with expect them to have root priveleges.
- * We will ask for more later.
+ * This is the file operation table for the pcibr driver.
+ * As each of the functions are implemented, put the
+ * appropriate function name below.
  */
-/* ARGSUSED */
-int
-pcibr_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-pcibr_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-pcibr_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-    int                     error;
-    devfs_handle_t            vhdl = dev_to_vhdl(dev);
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get(vhdl);
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    ASSERT(pcibr_soft);
-    len = ctob(btoc(len));		/* Make len page aligned */
-    error = v_mapphys(vt, (void *) ((__psunsigned_t) bridge + off), len);
-
-    /*
-     * If the offset being mapped corresponds to the flash prom
-     * base, and if the mapping succeeds, and if the user
-     * has requested the protections to be WRITE, enable the
-     * flash prom to be written.
-     *
-     * XXX- deprecate this in favor of using the
-     * real flash driver ...
-     */
-    if (IS_BRIDGE_SOFT(pcibr_soft) && !error &&
-	((off == BRIDGE_EXTERNAL_FLASH) ||
-	 (len > BRIDGE_EXTERNAL_FLASH))) {
-	int                     s;
-
-	/*
-	 * ensure that we write and read without any interruption.
-	 * The read following the write is required for the Bridge war
-	 */
-	s = splhi();
-
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		BRIDGE_REG_SET32((&bridge->b_wid_control)) |= __swab32(BRIDGE_CTRL_FLASH_WR_EN);
-		BRIDGE_REG_GET32((&bridge->b_wid_control));          /* inval addr bug war */
-	} else {
-		bridge->b_wid_control |= BRIDGE_CTRL_FLASH_WR_EN;
-		bridge->b_wid_control;          /* inval addr bug war */
-	}
-	splx(s);
-    }
-    return error;
-}
-
-/*ARGSUSED */
-int
-pcibr_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-    devfs_handle_t            pcibr_vhdl = hwgraph_connectpt_get((devfs_handle_t) dev);
-    pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    bridge_t               *bridge = pcibr_soft->bs_base;
-
-    hwgraph_vertex_unref(pcibr_vhdl);
-
-    if ( IS_PIC_SOFT(pcibr_soft) ) {
-	/*
-	 * If flashprom write was enabled, disable it, as
-	 * this is the last unmap.
-	 */
-	if (IS_BRIDGE_SOFT(pcibr_soft) && 
-			(bridge->b_wid_control & BRIDGE_CTRL_FLASH_WR_EN)) {
-		int                     s;
-
-		/*
-		 * ensure that we write and read without any interruption.
-		 * The read following the write is required for the Bridge war
-		 */
-		s = splhi();
-		bridge->b_wid_control &= ~BRIDGE_CTRL_FLASH_WR_EN;
-		bridge->b_wid_control;		/* inval addr bug war */
-		splx(s);
-	}
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		if (BRIDGE_REG_GET32((&bridge->b_wid_control)) & BRIDGE_CTRL_FLASH_WR_EN) {
-			int                     s;
+static int pcibr_mmap(struct file * file, struct vm_area_struct * vma);
+struct file_operations pcibr_fops = {
+	.owner		= THIS_MODULE,
+	.mmap		= pcibr_mmap,
+};
 
-			/*
-			 * ensure that we write and read without any interruption.
-			 * The read following the write is required for the Bridge war
-			 */
-			s = splhi();
-			BRIDGE_REG_SET32((&bridge->b_wid_control)) &= __swab32((unsigned int)~BRIDGE_CTRL_FLASH_WR_EN);
-			BRIDGE_REG_GET32((&bridge->b_wid_control));          /* inval addr bug war */
-			splx(s);
-		} else {
-			if (bridge->b_wid_control & BRIDGE_CTRL_FLASH_WR_EN) {
-				int                     s;
-
-				/*
-				 * ensure that we write and read without any interruption.
-				 * The read following the write is required for the Bridge war
-				 */
-				s = splhi();
-				bridge->b_wid_control &= ~BRIDGE_CTRL_FLASH_WR_EN;
-				bridge->b_wid_control;          /* inval addr bug war */
-				splx(s);
-    			}
-		}
-	}
-    }
-    return 0;
-}
 
 /* This is special case code used by grio. There are plans to make
  * this a bit more general in the future, but till then this should
  * be sufficient.
  */
 pciio_slot_t
-pcibr_device_slot_get(devfs_handle_t dev_vhdl)
+pcibr_device_slot_get(vertex_hdl_t dev_vhdl)
 {
     char                    devname[MAXDEVNAME];
-    devfs_handle_t            tdev;
+    vertex_hdl_t            tdev;
     pciio_info_t            pciio_info;
     pciio_slot_t            slot = PCIIO_SLOT_NONE;
 
@@ -812,20 +652,8 @@
     return slot;
 }
 
-/*ARGSUSED */
-int
-pcibr_ioctl(devfs_handle_t dev,
-	    int cmd,
-	    void *arg,
-	    int flag,
-	    struct cred *cr,
-	    int *rvalp)
-{
-    return 0;
-}
-
 pcibr_info_t
-pcibr_info_get(devfs_handle_t vhdl)
+pcibr_info_get(vertex_hdl_t vhdl)
 {
     return (pcibr_info_t) pciio_info_get(vhdl);
 }
@@ -902,10 +730,10 @@
  *	This is usually used at the time of shutting down of the PCI card.
  */
 int
-pcibr_device_unregister(devfs_handle_t pconn_vhdl)
+pcibr_device_unregister(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t	 pciio_info;
-    devfs_handle_t	 pcibr_vhdl;
+    vertex_hdl_t	 pcibr_vhdl;
     pciio_slot_t	 slot;
     pcibr_soft_t	 pcibr_soft;
     bridge_t		*bridge;
@@ -982,12 +810,12 @@
  *      slot's device status to be set.
  */
 void
-pcibr_driver_reg_callback(devfs_handle_t pconn_vhdl,
+pcibr_driver_reg_callback(vertex_hdl_t pconn_vhdl,
 			  int key1, int key2, int error)
 {
     pciio_info_t	 pciio_info;
     pcibr_info_t         pcibr_info;
-    devfs_handle_t	 pcibr_vhdl;
+    vertex_hdl_t	 pcibr_vhdl;
     pciio_slot_t	 slot;
     pcibr_soft_t	 pcibr_soft;
 
@@ -1033,12 +861,12 @@
  *      slot's device status to be set.
  */
 void
-pcibr_driver_unreg_callback(devfs_handle_t pconn_vhdl, 
+pcibr_driver_unreg_callback(vertex_hdl_t pconn_vhdl, 
                             int key1, int key2, int error)
 {
     pciio_info_t	 pciio_info;
     pcibr_info_t         pcibr_info;
-    devfs_handle_t	 pcibr_vhdl;
+    vertex_hdl_t	 pcibr_vhdl;
     pciio_slot_t	 slot;
     pcibr_soft_t	 pcibr_soft;
 
@@ -1084,14 +912,14 @@
  * depends on hwgraph separator == '/'
  */
 int
-pcibr_bus_cnvlink(devfs_handle_t f_c)
+pcibr_bus_cnvlink(vertex_hdl_t f_c)
 {
         char dst[MAXDEVNAME];
 	char *dp = dst;
         char *cp, *xp;
         int widgetnum;
         char pcibus[8];
-	devfs_handle_t nvtx, svtx;
+	vertex_hdl_t nvtx, svtx;
 	int rv;
 
 	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, f_c, "pcibr_bus_cnvlink\n"));
@@ -1145,11 +973,11 @@
  */
 /*ARGSUSED */
 int
-pcibr_attach(devfs_handle_t xconn_vhdl)
+pcibr_attach(vertex_hdl_t xconn_vhdl)
 {
     /* REFERENCED */
     graph_error_t           rc;
-    devfs_handle_t            pcibr_vhdl;
+    vertex_hdl_t            pcibr_vhdl;
     bridge_t               *bridge;
 
     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, xconn_vhdl, "pcibr_attach\n"));
@@ -1180,11 +1008,11 @@
 
 /*ARGSUSED */
 int
-pcibr_attach2(devfs_handle_t xconn_vhdl, bridge_t *bridge, 
-	      devfs_handle_t pcibr_vhdl, int busnum, pcibr_soft_t *ret_softp)
+pcibr_attach2(vertex_hdl_t xconn_vhdl, bridge_t *bridge, 
+	      vertex_hdl_t pcibr_vhdl, int busnum, pcibr_soft_t *ret_softp)
 {
     /* REFERENCED */
-    devfs_handle_t            ctlr_vhdl;
+    vertex_hdl_t            ctlr_vhdl;
     bridgereg_t             id;
     int                     rev;
     pcibr_soft_t            pcibr_soft;
@@ -1193,7 +1021,7 @@
     xtalk_intr_t            xtalk_intr;
     int                     slot;
     int                     ibit;
-    devfs_handle_t            noslot_conn;
+    vertex_hdl_t            noslot_conn;
     char                    devnm[MAXDEVNAME], *s;
     pcibr_hints_t           pcibr_hints;
     uint64_t              int_enable;
@@ -1209,23 +1037,15 @@
     nasid_t		    nasid;
     int	                    iobrick_type_get_nasid(nasid_t nasid);
     int                     iobrick_module_get_nasid(nasid_t nasid);
-    extern unsigned char    Is_pic_on_this_nasid[512];
-
-
-    async_attach_t          aa = NULL;
 
     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl,
 	        "pcibr_attach2: bridge=0x%p, busnum=%d\n", bridge, busnum));
 
-    aa = async_attach_get_info(xconn_vhdl);
-
     ctlr_vhdl = NULL;
-    ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER,
-                0, DEVFS_FL_AUTO_DEVNUM,
-                0, 0,
-                S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-                &pcibr_fops, NULL);
-
+    ctlr_vhdl = hwgraph_register(pcibr_vhdl, EDGE_LBL_CONTROLLER, 0, 
+                0, 0, 0,
+		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0, 
+		(struct file_operations *)&pcibr_fops, (void *)pcibr_vhdl);
     ASSERT(ctlr_vhdl != NULL);
 
     /*
@@ -1261,13 +1081,7 @@
     pcibr_soft->bs_min_slot = 0;		/* lowest possible slot# */
     pcibr_soft->bs_max_slot = 7;		/* highest possible slot# */
     pcibr_soft->bs_busnum = busnum;
-    if (is_xbridge(bridge)) {
-	pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_XBRIDGE;
-    } else if (is_pic(bridge)) {
-	pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_PIC;
-    } else {
-	pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_BRIDGE;
-    }
+    pcibr_soft->bs_bridge_type = PCIBR_BRIDGETYPE_PIC;
     switch(pcibr_soft->bs_bridge_type) {
     case PCIBR_BRIDGETYPE_BRIDGE:
 	pcibr_soft->bs_int_ate_size = BRIDGE_INTERNAL_ATES;
@@ -1367,10 +1181,6 @@
 
     nasid = NASID_GET(bridge);
 
-    /* set whether it is a PIC or not */
-    Is_pic_on_this_nasid[nasid] = (IS_PIC_SOFT(pcibr_soft)) ? 1 : 0;
-
-
     if ((pcibr_soft->bs_bricktype = iobrick_type_get_nasid(nasid)) < 0)
 	printk(KERN_WARNING "0x%p: Unknown bricktype : 0x%x\n", (void *)xconn_vhdl,
 				(unsigned int)pcibr_soft->bs_bricktype);
@@ -1380,11 +1190,27 @@
     if (pcibr_soft->bs_bricktype > 0) {
 	switch (pcibr_soft->bs_bricktype) {
 	case MODULE_PXBRICK:
+	case MODULE_IXBRICK:
 	    pcibr_soft->bs_first_slot = 0;
 	    pcibr_soft->bs_last_slot = 1;
 	    pcibr_soft->bs_last_reset = 1;
+
+	    /* If Bus 1 has IO9 then there are 4 devices in that bus.  Note
+	     * we figure this out from klconfig since the kernel has yet to 
+	     * probe
+	     */
+	    if (pcibr_widget_to_bus(pcibr_vhdl) == 1) {
+		lboard_t *brd = (lboard_t *)KL_CONFIG_INFO(nasid);
+
+		while (brd) {
+		    if (brd->brd_flags & LOCAL_MASTER_IO6) {
+			pcibr_soft->bs_last_slot = 3;
+			pcibr_soft->bs_last_reset = 3;
+		    }
+		    brd = KLCF_NEXT(brd);
+		}
+	    }
 	    break;
-	case MODULE_PEBRICK:
 	case MODULE_PBRICK:
             pcibr_soft->bs_first_slot = 1;
             pcibr_soft->bs_last_slot = 2;
@@ -1527,7 +1353,7 @@
 	/* enable parity checking on PICs internal RAM */
 	pic_ctrl_reg |= PIC_CTRL_PAR_EN_RESP;
 	pic_ctrl_reg |= PIC_CTRL_PAR_EN_ATE;
-	/* PIC BRINGUP WAR (PV# 862253): don't enable write request
+	/* PIC BRINGUP WAR (PV# 862253): dont enable write request
 	 * parity checking.
 	 */
 	if (!PCIBR_WAR_ENABLED(PV862253, pcibr_soft)) {
@@ -1559,11 +1385,6 @@
 	int                     entry;
 	cnodeid_t		cnodeid;
 	nasid_t			nasid;
-#ifdef PIC_LATER
-	char		       *node_val;
-	devfs_handle_t		node_vhdl;
-	char			vname[MAXDEVNAME];
-#endif
 
 	/* Set the Bridge's 32-bit PCI to XTalk
 	 * Direct Map register to the most useful
@@ -1582,30 +1403,6 @@
 	 */
 
 	cnodeid = 0;  /* default node id */
-	/*
-	 * Determine the base address node id to be used for all 32-bit
-	 * Direct Mapping I/O. The default is node 0, but this can be changed
-	 * via a DEVICE_ADMIN directive and the PCIBUS_DMATRANS_NODE
-	 * attribute in the irix.sm config file. A device driver can obtain
-	 * this node value via a call to pcibr_get_dmatrans_node().
-	 */
-#ifdef PIC_LATER
-// This probably needs to be addressed - pfg
-	node_val = device_admin_info_get(pcibr_vhdl, ADMIN_LBL_DMATRANS_NODE);
-	if (node_val != NULL) {
-	    node_vhdl = hwgraph_path_to_vertex(node_val);
-	    if (node_vhdl != GRAPH_VERTEX_NONE) {
-		cnodeid = nodevertex_to_cnodeid(node_vhdl);
-	    }
-	    if ((node_vhdl == GRAPH_VERTEX_NONE) || (cnodeid == CNODEID_NONE)) {
-		cnodeid = 0;
-		vertex_to_name(pcibr_vhdl, vname, sizeof(vname));
-		printk(KERN_WARNING "Invalid hwgraph node path specified:\n"
-			"    DEVICE_ADMIN: %s %s=%s\n",
-			vname, ADMIN_LBL_DMATRANS_NODE, node_val);
-	    }
-	}
-#endif	/* PIC_LATER */
 	nasid = COMPACT_TO_NASID_NODEID(cnodeid);
 	paddr = NODE_OFFSET(nasid) + 0;
 
@@ -1763,6 +1560,13 @@
      */
 
     xtalk_intr = xtalk_intr_alloc(xconn_vhdl, (device_desc_t)0, pcibr_vhdl);
+	{
+		int irq = ((hub_intr_t)xtalk_intr)->i_bit;
+		int cpu = ((hub_intr_t)xtalk_intr)->i_cpuid;
+
+		intr_unreserve_level(cpu, irq);
+		((hub_intr_t)xtalk_intr)->i_bit = SGI_PCIBR_ERROR;
+	}
     ASSERT(xtalk_intr != NULL);
 
     pcibr_soft->bsi_err_intr = xtalk_intr;
@@ -1778,12 +1582,8 @@
     xtalk_intr_connect(xtalk_intr, (intr_func_t) pcibr_error_intr_handler,
 		(intr_arg_t) pcibr_soft, (xtalk_intr_setfunc_t)pcibr_setwidint, (void *)bridge);
 
-#ifdef BUS_INT_WAR_NOT_YET
-    request_irq(CPU_VECTOR_TO_IRQ(((hub_intr_t)xtalk_intr)->i_cpuid,
-			((hub_intr_t)xtalk_intr)->i_bit),
-				(intr_func_t)pcibr_error_intr_handler, 0, "PCIBR error",
+    request_irq(SGI_PCIBR_ERROR, (void *)pcibr_error_intr_handler, SA_SHIRQ, "PCIBR error",
 					(intr_arg_t) pcibr_soft);
-#endif
 
     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INTR_ALLOC, pcibr_vhdl,
 		"pcibr_setwidint: b_wid_int_upper=0x%x, b_wid_int_lower=0x%x\n",
@@ -1801,18 +1601,16 @@
     if (IS_PIC_SOFT(pcibr_soft)) {
 	int_enable_64 = bridge->p_int_enable_64 | BRIDGE_ISR_ERRORS;
         int_enable = (uint64_t)int_enable_64;
+#ifdef PFG_TEST
+	int_enable = (uint64_t)0x7ffffeff7ffffeff;
+#endif
     } else {
 	int_enable_32 = bridge->b_int_enable | (BRIDGE_ISR_ERRORS & 0xffffffff);
 	int_enable = ((uint64_t)int_enable_32 & 0xffffffff);
-    }
-#ifdef BUS_INT_WAR_NOT_YET
-    {
-	extern void sn_add_polled_interrupt(int irq, int interval);
-
-        sn_add_polled_interrupt(CPU_VECTOR_TO_IRQ(((hub_intr_t)xtalk_intr)->i_cpuid,
-				((hub_intr_t)xtalk_intr)->i_bit), 20000);
-    }
+#ifdef PFG_TEST
+	int_enable = (uint64_t)0x7ffffeff;
 #endif
+    }
 
 
 #if BRIDGE_ERROR_INTR_WAR
@@ -1849,24 +1647,6 @@
     }
 #endif
 
-#ifdef BRIDGE_B_DATACORR_WAR
-
-    /* WAR panic for Rev B silent data corruption.
-     * PIOERR turned off here because there is a problem
-     * with not re-arming it in pcibr_error_intr_handler.
-     * We don't get LLP error interrupts if we don't
-     * re-arm PIOERR interrupts! Just disable them here
-     */
-
-    if (pcibr_soft->bs_rev_num == BRIDGE_PART_REV_B) {
-	int_enable |= BRIDGE_IMR_LLP_REC_CBERR;
-	int_enable &= ~BRIDGE_ISR_PCIBUS_PIOERR;
-
-	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, pcibr_vhdl,
-		    "Turning on LLP_REC_CBERR for Rev B Bridge.\n"));
-    }
-#endif
-
     /* PIC BRINGUP WAR (PV# 856864 & 856865): allow the tnums that are
      * locked out to be freed up sooner (by timing out) so that the
      * read tnums are never completely used up.
@@ -1918,16 +1698,12 @@
     if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_B)
 	pcibr_soft->bs_dma_flags |= PCIBR_NOPREFETCH;
     else if (pcibr_soft->bs_rev_num < 
-		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_prefetch_enable_rev))
+		(BRIDGE_WIDGET_PART_NUM << 4))
 	pcibr_soft->bs_dma_flags |= PCIIO_NOPREFETCH;
 
-    /* WRITE_GATHER:
-     * Disabled up to but not including the
-     * rev number in pcibr_wg_enable_rev. There
-     * is no "WAR range" as with prefetch.
-     */
+    /* WRITE_GATHER: Disabled */
     if (pcibr_soft->bs_rev_num < 
-		(BRIDGE_WIDGET_PART_NUM << 4 | pcibr_wg_enable_rev))
+		(BRIDGE_WIDGET_PART_NUM << 4))
 	pcibr_soft->bs_dma_flags |= PCIBR_NOWRITE_GATHER;
 
     /* PIC only supports 64-bit direct mapping in PCI-X mode.  Since
@@ -2064,7 +1840,23 @@
      */
     if (pcibr_soft->bs_bricktype > 0) {
 	switch (pcibr_soft->bs_bricktype) {
+	case MODULE_PBRICK:
+		do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8);
+		do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8);
+		break;
+	case MODULE_IBRICK:
+	  	/* port 0xe on the Ibrick only has slots 1 and 2 */
+		if (pcibr_soft->bs_xid == 0xe) {
+			do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8);
+			do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8);
+		}
+		else {
+		    	/* allocate one RRB for the serial port */
+			do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 1);
+		}
+		break;
 	case MODULE_PXBRICK:
+	case MODULE_IXBRICK:
 		/* 
 		 * If the IO9 is in the PXBrick (bus1, slot1) allocate
                  * RRBs to all the devices
@@ -2080,23 +1872,6 @@
 			do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 8);
 			do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8);
 		}
-
-		break;
-	case MODULE_PEBRICK:
-	case MODULE_PBRICK:
-		do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8);
-		do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8);
-		break;
-	case MODULE_IBRICK:
-	  	/* port 0xe on the Ibrick only has slots 1 and 2 */
-		if (pcibr_soft->bs_xid == 0xe) {
-			do_pcibr_rrb_autoalloc(pcibr_soft, 1, VCHAN0, 8);
-			do_pcibr_rrb_autoalloc(pcibr_soft, 2, VCHAN0, 8);
-		}
-		else {
-		    	/* allocate one RRB for the serial port */
-			do_pcibr_rrb_autoalloc(pcibr_soft, 0, VCHAN0, 1);
-		}
 		break;
 	} /* switch */
     }
@@ -2113,78 +1888,8 @@
 	/* Call the device attach */
 	(void)pcibr_slot_call_device_attach(pcibr_vhdl, slot, 0);
 
-#ifdef PIC_LATER
-#if (defined(USS302_TIMEOUT_WAR))
-    /*
-     * If this bridge holds a Lucent USS-302 or USS-312 pci/usb controller,
-     * increase the Bridge PCI retry backoff interval.  This part seems
-     * to go away for long periods of time if a DAC appears on the bus during
-     * a read command that is being retried.
-     */
-
-{
-    ii_ixtt_u_t ixtt;
-
-    for (slot = pcibr_soft->bs_min_slot; 
-				slot < PCIBR_NUM_SLOTS(pcibr_soft); ++slot) {
-	if (pcibr_soft->bs_slot[slot].bss_vendor_id ==
-					LUCENT_USBHC_VENDOR_ID_NUM &&
-	    (pcibr_soft->bs_slot[slot].bss_device_id ==
-					LUCENT_USBHC302_DEVICE_ID_NUM ||
-	     pcibr_soft->bs_slot[slot].bss_device_id ==
-					LUCENT_USBHC312_DEVICE_ID_NUM)) {
-	    printk(KERN_NOTICE
-		    "pcibr_attach: %x Bus holds a usb part - setting"
-		    "bridge PCI_RETRY_HLD to %d\n",
-		    pcibr_vhdl, USS302_BRIDGE_TIMEOUT_HLD);
-
-	    bridge->b_bus_timeout &= ~BRIDGE_BUS_PCI_RETRY_HLD_MASK;
-	    bridge->b_bus_timeout |=
-			BRIDGE_BUS_PCI_RETRY_HLD(USS302_BRIDGE_TIMEOUT_HLD);
-
-	    /*
-	     * Have to consider the read response timer in the hub II as well
-	     */
-
-	    hubii_ixtt_get(xconn_vhdl, &ixtt);
-
-	    /*
-	     * bump rrsp_ps to allow at least 1ms for read
- 	     * responses from this widget
-	     */
-
-	    ixtt.ii_ixtt_fld_s.i_rrsp_ps = 20000;
-	    hubii_ixtt_set(xconn_vhdl, &ixtt);
-
-	    /*
-	     * print the current setting
-	     */
-
-	    hubii_ixtt_get(xconn_vhdl, &ixtt);
-	    printk( "Setting hub ixtt.rrsp_ps field to 0x%x\n",
-		    ixtt.ii_ixtt_fld_s.i_rrsp_ps);
-
-	    break;	/* only need to do it once */
-	}
-    }
-}
-#endif	/* (defined(USS302_TIMEOUT_WAR)) */
-#else
-	FIXME("pcibr_attach: Call do_pcibr_rrb_autoalloc nicinfo\n");
-#endif	/* PIC_LATER */
-
-    if (aa)
-	    async_attach_add_info(noslot_conn, aa);
-
     pciio_device_attach(noslot_conn, (int)0);
 
-    /* 
-     * Tear down pointer to async attach info -- async threads for
-     * bridge's descendants may be running but the bridge's work is done.
-     */
-    if (aa)
-	    async_attach_del_info(xconn_vhdl);
-
     return 0;
 }
 
@@ -2195,10 +1900,10 @@
  */
 
 int
-pcibr_detach(devfs_handle_t xconn)
+pcibr_detach(vertex_hdl_t xconn)
 {
     pciio_slot_t	slot;
-    devfs_handle_t	pcibr_vhdl;
+    vertex_hdl_t	pcibr_vhdl;
     pcibr_soft_t	pcibr_soft;
     bridge_t		*bridge;
     unsigned             s;
@@ -2265,9 +1970,9 @@
 }
 
 int
-pcibr_asic_rev(devfs_handle_t pconn_vhdl)
+pcibr_asic_rev(vertex_hdl_t pconn_vhdl)
 {
-    devfs_handle_t          pcibr_vhdl;
+    vertex_hdl_t          pcibr_vhdl;
     int                     tmp_vhdl;
     arbitrary_info_t        ainfo;
 
@@ -2294,7 +1999,7 @@
 }
 
 int
-pcibr_write_gather_flush(devfs_handle_t pconn_vhdl)
+pcibr_write_gather_flush(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t  pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t  pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
@@ -2309,7 +2014,7 @@
  */
 
 static iopaddr_t
-pcibr_addr_pci_to_xio(devfs_handle_t pconn_vhdl,
+pcibr_addr_pci_to_xio(vertex_hdl_t pconn_vhdl,
 		      pciio_slot_t slot,
 		      pciio_space_t space,
 		      iopaddr_t pci_addr,
@@ -2323,6 +2028,8 @@
 
     unsigned                bar;	/* which BASE reg on device is decoding */
     iopaddr_t               xio_addr = XIO_NOWHERE;
+    iopaddr_t               base;	/* base of devio(x) mapped area on PCI */
+    iopaddr_t               limit;	/* base of devio(x) mapped area on PCI */
 
     pciio_space_t           wspace;	/* which space device is decoding */
     iopaddr_t               wbase;	/* base of device decode on PCI */
@@ -2533,8 +2240,6 @@
 		PCIBR_DEBUG((PCIBR_DEBUG_DEVREG, pconn_vhdl, 
 			    "pcibr_addr_pci_to_xio: Device(%d): %x\n",
 			    win, devreg, device_bits));
-#else
-	        printk("pcibr_addr_pci_to_xio: Device(%d): %x\n", win, devreg);
 #endif
 	    }
 	    pcibr_soft->bs_slot[win].bss_devio.bssd_space = space;
@@ -2620,18 +2325,46 @@
 	 */
     case PCIIO_SPACE_MEM:		/* "mem space" */
     case PCIIO_SPACE_MEM32:		/* "mem, use 32-bit-wide bus" */
-	if ((pci_addr + BRIDGE_PCI_MEM32_BASE + req_size - 1) <=
-	    BRIDGE_PCI_MEM32_LIMIT)
-	    xio_addr = pci_addr + BRIDGE_PCI_MEM32_BASE;
+	if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 0)) {	/* PIC bus 0 */
+		base = PICBRIDGE0_PCI_MEM32_BASE;
+		limit = PICBRIDGE0_PCI_MEM32_LIMIT;
+	} else if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 1)) {	/* PIC bus 1 */
+		base = PICBRIDGE1_PCI_MEM32_BASE;
+		limit = PICBRIDGE1_PCI_MEM32_LIMIT;
+	} else {					/* Bridge/Xbridge */
+		base = BRIDGE_PCI_MEM32_BASE;
+		limit = BRIDGE_PCI_MEM32_LIMIT;
+	}
+
+	if ((pci_addr + base + req_size - 1) <= limit)
+	    xio_addr = pci_addr + base;
 	break;
 
     case PCIIO_SPACE_MEM64:		/* "mem, use 64-bit-wide bus" */
-	if ((pci_addr + BRIDGE_PCI_MEM64_BASE + req_size - 1) <=
-	    BRIDGE_PCI_MEM64_LIMIT)
-	    xio_addr = pci_addr + BRIDGE_PCI_MEM64_BASE;
+	if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 0)) {	/* PIC bus 0 */
+		base = PICBRIDGE0_PCI_MEM64_BASE;
+		limit = PICBRIDGE0_PCI_MEM64_LIMIT;
+	} else if (IS_PIC_BUSNUM_SOFT(pcibr_soft, 1)) {	/* PIC bus 1 */
+		base = PICBRIDGE1_PCI_MEM64_BASE;
+		limit = PICBRIDGE1_PCI_MEM64_LIMIT;
+	} else {					/* Bridge/Xbridge */
+		base = BRIDGE_PCI_MEM64_BASE;
+		limit = BRIDGE_PCI_MEM64_LIMIT;
+	}
+
+	if ((pci_addr + base + req_size - 1) <= limit)
+	    xio_addr = pci_addr + base;
 	break;
 
     case PCIIO_SPACE_IO:		/* "i/o space" */
+	/*
+	 * PIC bridges do not support big-window aliases into PCI I/O space
+	 */
+	if (IS_PIC_SOFT(pcibr_soft)) {
+		xio_addr = XIO_NOWHERE;
+		break;
+	}
+
 	/* Bridge Hardware Bug WAR #482741:
 	 * The 4G area that maps directly from
 	 * XIO space to PCI I/O space is busted
@@ -2725,7 +2458,7 @@
 
 /*ARGSUSED6 */
 pcibr_piomap_t
-pcibr_piomap_alloc(devfs_handle_t pconn_vhdl,
+pcibr_piomap_alloc(vertex_hdl_t pconn_vhdl,
 		   device_desc_t dev_desc,
 		   pciio_space_t space,
 		   iopaddr_t pci_addr,
@@ -2737,7 +2470,7 @@
     pciio_info_t            pciio_info = &pcibr_info->f_c;
     pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
 
     pcibr_piomap_t         *mapptr;
     pcibr_piomap_t          maplist;
@@ -2867,7 +2600,7 @@
 
 /*ARGSUSED */
 caddr_t
-pcibr_piotrans_addr(devfs_handle_t pconn_vhdl,
+pcibr_piotrans_addr(vertex_hdl_t pconn_vhdl,
 		    device_desc_t dev_desc,
 		    pciio_space_t space,
 		    iopaddr_t pci_addr,
@@ -2877,7 +2610,7 @@
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
 
     iopaddr_t               xio_addr;
     caddr_t		    addr;
@@ -2908,7 +2641,7 @@
 
 /*ARGSUSED */
 iopaddr_t
-pcibr_piospace_alloc(devfs_handle_t pconn_vhdl,
+pcibr_piospace_alloc(vertex_hdl_t pconn_vhdl,
 		     device_desc_t dev_desc,
 		     pciio_space_t space,
 		     size_t req_size,
@@ -3010,7 +2743,7 @@
 
 /*ARGSUSED */
 void
-pcibr_piospace_free(devfs_handle_t pconn_vhdl,
+pcibr_piospace_free(vertex_hdl_t pconn_vhdl,
 		    pciio_space_t space,
 		    iopaddr_t pciaddr,
 		    size_t req_size)
@@ -3161,14 +2894,14 @@
 
 /*ARGSUSED */
 pcibr_dmamap_t
-pcibr_dmamap_alloc(devfs_handle_t pconn_vhdl,
+pcibr_dmamap_alloc(vertex_hdl_t pconn_vhdl,
 		   device_desc_t dev_desc,
 		   size_t req_size_max,
 		   unsigned flags)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
     pciio_slot_t            slot;
     xwidgetnum_t            xio_port;
 
@@ -3454,6 +3187,29 @@
     iopaddr_t               pci_addr;
     pciio_slot_t            slot;
 
+    if (IS_PIC_BUSNUM_SOFT(soft, 0)) {
+    	if ((xio_addr >= PICBRIDGE0_PCI_MEM32_BASE) &&
+	    (xio_lim <= PICBRIDGE0_PCI_MEM32_LIMIT)) {
+	    pci_addr = xio_addr - PICBRIDGE0_PCI_MEM32_BASE;
+	    return pci_addr;
+    	}
+    	if ((xio_addr >= PICBRIDGE0_PCI_MEM64_BASE) &&
+	    (xio_lim <= PICBRIDGE0_PCI_MEM64_LIMIT)) {
+	    pci_addr = xio_addr - PICBRIDGE0_PCI_MEM64_BASE;
+	    return pci_addr;
+    	}
+    } else if (IS_PIC_BUSNUM_SOFT(soft, 1)) {
+    	if ((xio_addr >= PICBRIDGE1_PCI_MEM32_BASE) &&
+	    (xio_lim <= PICBRIDGE1_PCI_MEM32_LIMIT)) {
+	    pci_addr = xio_addr - PICBRIDGE1_PCI_MEM32_BASE;
+	    return pci_addr;
+    	}
+    	if ((xio_addr >= PICBRIDGE1_PCI_MEM64_BASE) &&
+	    (xio_lim <= PICBRIDGE1_PCI_MEM64_LIMIT)) {
+	    pci_addr = xio_addr - PICBRIDGE1_PCI_MEM64_BASE;
+	    return pci_addr;
+    	}
+    } else {
     if ((xio_addr >= BRIDGE_PCI_MEM32_BASE) &&
 	(xio_lim <= BRIDGE_PCI_MEM32_LIMIT)) {
 	pci_addr = xio_addr - BRIDGE_PCI_MEM32_BASE;
@@ -3464,6 +3220,7 @@
 	pci_addr = xio_addr - BRIDGE_PCI_MEM64_BASE;
 	return pci_addr;
     }
+    }
     for (slot = soft->bs_min_slot; slot < PCIBR_NUM_SLOTS(soft); ++slot)
 	if ((xio_addr >= PCIBR_BRIDGE_DEVIO(soft, slot)) &&
 	    (xio_lim < PCIBR_BRIDGE_DEVIO(soft, slot + 1))) {
@@ -3644,243 +3401,6 @@
 }
 
 /*ARGSUSED */
-alenlist_t
-pcibr_dmamap_list(pcibr_dmamap_t pcibr_dmamap,
-		  alenlist_t palenlist,
-		  unsigned flags)
-{
-    pcibr_soft_t            pcibr_soft;
-    bridge_t               *bridge=NULL;
-
-    unsigned                al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
-    int                     inplace = flags & PCIIO_INPLACE;
-
-    alenlist_t              pciio_alenlist = 0;
-    alenlist_t              xtalk_alenlist;
-    size_t                  length;
-    iopaddr_t               offset;
-    unsigned                direct64;
-    int                     ate_index = 0;
-    int                     ate_count = 0;
-    int                     ate_total = 0;
-    bridge_ate_p            ate_ptr = (bridge_ate_p)0;
-    bridge_ate_t            ate_proto = (bridge_ate_t)0;
-    bridge_ate_t            ate_prev;
-    bridge_ate_t            ate;
-    alenaddr_t              xio_addr;
-    xwidgetnum_t            xio_port;
-    iopaddr_t               pci_addr;
-    alenaddr_t              new_addr;
-    unsigned                cmd_regs[8];
-    unsigned                s = 0;
-
-#if PCIBR_FREEZE_TIME
-    unsigned                freeze_time;
-#endif
-    int			    ate_freeze_done = 0;	/* To pair ATE_THAW
-							 * with an ATE_FREEZE
-							 */
-
-    pcibr_soft = pcibr_dmamap->bd_soft;
-
-    xtalk_alenlist = xtalk_dmamap_list(pcibr_dmamap->bd_xtalk, palenlist,
-				       flags & DMAMAP_FLAGS);
-    if (!xtalk_alenlist) {
-        PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-                    "pcibr_dmamap_list: xtalk_dmamap_list() failed, "
-		    "pcibr_dmamap=0x%x\n", pcibr_dmamap));
-	goto fail;
-    }
-    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
-
-    if (inplace) {
-	pciio_alenlist = xtalk_alenlist;
-    } else {
-	pciio_alenlist = alenlist_create(al_flags);
-	if (!pciio_alenlist) {
-	    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-			"pcibr_dmamap_list: alenlist_create() failed, "
-			"pcibr_dmamap=0x%lx\n", (unsigned long)pcibr_dmamap));
-	    goto fail;
-	}
-    }
-
-    direct64 = pcibr_dmamap->bd_flags & PCIIO_DMA_A64;
-    if (!direct64) {
-	bridge = pcibr_soft->bs_base;
-	ate_ptr = pcibr_dmamap->bd_ate_ptr;
-	ate_index = pcibr_dmamap->bd_ate_index;
-	ate_proto = pcibr_dmamap->bd_ate_proto;
-	ATE_FREEZE();
-	ate_freeze_done = 1;	/* Remember that we need to do an ATE_THAW */
-    }
-    pci_addr = pcibr_dmamap->bd_pci_addr;
-
-    ate_prev = 0;			/* matches no valid ATEs */
-    while (ALENLIST_SUCCESS ==
-	   alenlist_get(xtalk_alenlist, NULL, 0,
-			&xio_addr, &length, al_flags)) {
-	if (XIO_PACKED(xio_addr)) {
-	    xio_port = XIO_PORT(xio_addr);
-	    xio_addr = XIO_ADDR(xio_addr);
-	} else
-	    xio_port = pcibr_dmamap->bd_xio_port;
-
-	if (xio_port == pcibr_soft->bs_xid) {
-	    new_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, length);
-	    if (new_addr == PCI_NOWHERE) {
-                PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-                            "pcibr_dmamap_list: pcibr_addr_xio_to_pci failed, "
-                            "pcibr_dmamap=0x%x\n", pcibr_dmamap));
-		goto fail;
-	    }
-	} else if (direct64) {
-	    new_addr = pci_addr | xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-
-	    /* Bridge Hardware WAR #482836:
-	     * If the transfer is not cache aligned
-	     * and the Bridge Rev is <= B, force
-	     * prefetch to be off.
-	     */
-	    if (flags & PCIBR_NOPREFETCH)
-		new_addr &= ~PCI64_ATTR_PREF;
-
-	} else {
-	    /* calculate the ate value for
-	     * the first address. If it
-	     * matches the previous
-	     * ATE written (ie. we had
-	     * multiple blocks in the
-	     * same IOPG), then back up
-	     * and reuse that ATE.
-	     *
-	     * We are NOT going to
-	     * aggressively try to
-	     * reuse any other ATEs.
-	     */
-	    offset = IOPGOFF(xio_addr);
-	    ate = ate_proto
-		| (xio_port << ATE_TIDSHIFT)
-		| (xio_addr - offset);
-	    if (ate == ate_prev) {
-		PCIBR_DEBUG((PCIBR_DEBUG_ATE, pcibr_dmamap->bd_dev,
-			    "pcibr_dmamap_list: ATE share\n"));
-		ate_ptr--;
-		ate_index--;
-		pci_addr -= IOPGSIZE;
-	    }
-	    new_addr = pci_addr + offset;
-
-	    /* Fill in the hardware ATEs
-	     * that contain this block.
-	     */
-	    ate_count = IOPG(offset + length - 1) + 1;
-	    ate_total += ate_count;
-
-	    /* Ensure that this map contains enough ATE's */
-	    if (ate_total > pcibr_dmamap->bd_ate_count) {
-		PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATE, pcibr_dmamap->bd_dev,
-			     "pcibr_dmamap_list :\n"
-			     "\twanted xio_addr [0x%x..0x%x]\n"
-			     "\tate_total 0x%x bd_ate_count 0x%x\n"
-			     "\tATE's required > number allocated\n",
-			     xio_addr, xio_addr + length - 1,
-			     ate_total, pcibr_dmamap->bd_ate_count));
-		goto fail;
-	    }
-
-	    ATE_WRITE();
-
-	    ate_index += ate_count;
-	    ate_ptr += ate_count;
-
-	    ate_count <<= IOPFNSHIFT;
-	    ate += ate_count;
-	    pci_addr += ate_count;
-	}
-
-	/* write the PCI DMA address
-	 * out to the scatter-gather list.
-	 */
-	if (inplace) {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_replace(pciio_alenlist, NULL,
-				 &new_addr, &length, al_flags)) {
-                PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-                            "pcibr_dmamap_list: alenlist_replace() failed, "
-                            "pcibr_dmamap=0x%x\n", pcibr_dmamap));
-
-		goto fail;
-	    }
-	} else {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_append(pciio_alenlist,
-				new_addr, length, al_flags)) {
-                PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-                            "pcibr_dmamap_list: alenlist_append() failed, "
-                            "pcibr_dmamap=0x%x\n", pcibr_dmamap));
-		goto fail;
-	    }
-	}
-    }
-    if (!inplace)
-	alenlist_done(xtalk_alenlist);
-
-    /* Reset the internal cursor of the alenlist to be returned back
-     * to the caller.
-     */
-    alenlist_cursor_init(pciio_alenlist, 0, NULL);
-
-
-    /* In case an ATE_FREEZE was done do the ATE_THAW to unroll all the
-     * changes that ATE_FREEZE has done to implement the external SSRAM
-     * bug workaround.
-     */
-    if (ate_freeze_done) {
-	ATE_THAW();
-	if ( IS_PIC_SOFT(pcibr_soft) ) {
-		bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge))) {
-			BRIDGE_REG_GET32((&bridge->b_wid_tflush));
-		} else {
-			bridge->b_wid_tflush;
-		}
-	}
-    }
-    PCIBR_DEBUG((PCIBR_DEBUG_DMAMAP, pcibr_dmamap->bd_dev,
-		"pcibr_dmamap_list: pcibr_dmamap=0x%x, pciio_alenlist=0x%x\n",
-		pcibr_dmamap, pciio_alenlist));
-
-    return pciio_alenlist;
-
-  fail:
-    /* There are various points of failure after doing an ATE_FREEZE
-     * We need to do an ATE_THAW. Otherwise the ATEs are locked forever.
-     * The decision to do an ATE_THAW needs to be based on whether a
-     * an ATE_FREEZE was done before.
-     */
-    if (ate_freeze_done) {
-	ATE_THAW();
-	if ( IS_PIC_SOFT(pcibr_soft) ) {
-		bridge->b_wid_tflush;
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge))) {
-			BRIDGE_REG_GET32((&bridge->b_wid_tflush));
-		} else {
-			bridge->b_wid_tflush;
-		}
-	}
-    }
-    if (pciio_alenlist && !inplace)
-	alenlist_destroy(pciio_alenlist);
-    return 0;
-}
-
-/*ARGSUSED */
 void
 pcibr_dmamap_done(pcibr_dmamap_t pcibr_dmamap)
 {
@@ -3917,7 +3437,7 @@
 
 /*ARGSUSED */
 cnodeid_t
-pcibr_get_dmatrans_node(devfs_handle_t pconn_vhdl)
+pcibr_get_dmatrans_node(vertex_hdl_t pconn_vhdl)
 {
 
 	pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
@@ -3928,7 +3448,7 @@
 
 /*ARGSUSED */
 iopaddr_t
-pcibr_dmatrans_addr(devfs_handle_t pconn_vhdl,
+pcibr_dmatrans_addr(vertex_hdl_t pconn_vhdl,
 		    device_desc_t dev_desc,
 		    paddr_t paddr,
 		    size_t req_size,
@@ -3936,7 +3456,7 @@
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
     pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
     pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
 
@@ -4149,213 +3669,6 @@
     return 0;
 }
 
-/*ARGSUSED */
-alenlist_t
-pcibr_dmatrans_list(devfs_handle_t pconn_vhdl,
-		    device_desc_t dev_desc,
-		    alenlist_t palenlist,
-		    unsigned flags)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-    pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
-    pcibr_soft_slot_t       slotp = &pcibr_soft->bs_slot[pciio_slot];
-    xwidgetnum_t            xio_port;
-
-    alenlist_t              pciio_alenlist = 0;
-    alenlist_t              xtalk_alenlist = 0;
-
-    int                     inplace;
-    unsigned                direct64;
-    unsigned                al_flags;
-
-    iopaddr_t               xio_base;
-    alenaddr_t              xio_addr;
-    size_t                  xio_size;
-
-    size_t                  map_size;
-    iopaddr_t               pci_base;
-    alenaddr_t              pci_addr;
-
-    unsigned                relbits = 0;
-
-    /* merge in forced flags */
-    flags |= pcibr_soft->bs_dma_flags;
-
-    inplace = flags & PCIIO_INPLACE;
-    direct64 = flags & PCIIO_DMA_A64;
-    al_flags = (flags & PCIIO_NOSLEEP) ? AL_NOSLEEP : 0;
-
-    if (direct64) {
-	map_size = 1ull << 48;
-	xio_base = 0;
-	pci_base = slotp->bss_d64_base;
-	if ((pci_base != PCIBR_D64_BASE_UNSET) &&
-	    (flags == slotp->bss_d64_flags)) {
-	    /* reuse previous base info */
-	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D64_BITS) < 0) {
-	    /* DMA configuration conflict */
-	    PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: DMA configuration conflict "
-			"for direct64, flags=0x%x\n", flags));
-	    goto fail;
-	} else {
-	    relbits = BRIDGE_DEV_D64_BITS;
-	    pci_base =
-		pcibr_flags_to_d64(flags, pcibr_soft);
-	}
-    } else {
-	xio_base = pcibr_soft->bs_dir_xbase;
-	map_size = 1ull << 31;
-	pci_base = slotp->bss_d32_base;
-	if ((pci_base != PCIBR_D32_BASE_UNSET) &&
-	    (flags == slotp->bss_d32_flags)) {
-	    /* reuse previous base info */
-	} else if (pcibr_try_set_device(pcibr_soft, pciio_slot, flags, BRIDGE_DEV_D32_BITS) < 0) {
-	    /* DMA configuration conflict */
-	    PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: DMA configuration conflict "
-			"for direct32, flags=0x%x\n", flags));
-	    goto fail;
-	} else {
-	    relbits = BRIDGE_DEV_D32_BITS;
-	    pci_base = PCI32_DIRECT_BASE;
-	}
-    }
-
-    xtalk_alenlist = xtalk_dmatrans_list(xconn_vhdl, 0, palenlist,
-					 flags & DMAMAP_FLAGS);
-    if (!xtalk_alenlist) {
-	    PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: xtalk_dmatrans_list failed "
-			"xtalk_alenlist=0x%x\n", xtalk_alenlist));
-	goto fail;
-    }
-
-    alenlist_cursor_init(xtalk_alenlist, 0, NULL);
-
-    if (inplace) {
-	pciio_alenlist = xtalk_alenlist;
-    } else {
-	pciio_alenlist = alenlist_create(al_flags);
-	if (!pciio_alenlist) {
-	    PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: alenlist_create failed with "
-			" 0x%x\n", pciio_alenlist));
-	    goto fail;
-	}
-    }
-
-    while (ALENLIST_SUCCESS ==
-	   alenlist_get(xtalk_alenlist, NULL, 0,
-			&xio_addr, &xio_size, al_flags)) {
-
-	/*
-	 * find which XIO port this goes to.
-	 */
-	if (XIO_PACKED(xio_addr)) {
-	    if (xio_addr == XIO_NOWHERE) {
-	        PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: xio_addr == XIO_NOWHERE\n"));
-		return 0;
-	    }
-	    xio_port = XIO_PORT(xio_addr);
-	    xio_addr = XIO_ADDR(xio_addr);
-	} else
-	    xio_port = pcibr_soft->bs_mxid;
-
-	/*
-	 * If this DMA comes back to us,
-	 * return the PCI MEM address on
-	 * which it would land, or NULL
-	 * if the target is something
-	 * on bridge other than PCI MEM.
-	 */
-	if (xio_port == pcibr_soft->bs_xid) {
-	    pci_addr = pcibr_addr_xio_to_pci(pcibr_soft, xio_addr, xio_size);
-	    if (pci_addr == (alenaddr_t)NULL) {
-	        PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			"pcibr_dmatrans_list: pcibr_addr_xio_to_pci failed "
-			"xio_addr=0x%x, xio_size=0x%x\n", xio_addr, xio_size));
-		goto fail;
-	    }
-	} else if (direct64) {
-	    ASSERT(xio_port != 0);
-	    pci_addr = pci_base | xio_addr
-		| ((uint64_t) xio_port << PCI64_ATTR_TARG_SHFT);
-	} else {
-	    iopaddr_t               offset = xio_addr - xio_base;
-	    iopaddr_t               endoff = xio_size + offset;
-
-	    if ((xio_size > map_size) ||
-		(xio_addr < xio_base) ||
-		(xio_port != pcibr_soft->bs_dir_xport) ||
-		(endoff > map_size)) {
-		PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			    "pcibr_dmatrans_list: xio_size > map_size fail\n"
-			    "xio_addr=0x%x, xio_size=0x%x. map_size=0x%x, "
-			    "xio_port=0x%x, endoff=0x%x\n", 
-			    xio_addr, xio_size, map_size, xio_port, endoff));
-		goto fail;
-	    }
-
-	    pci_addr = pci_base + (xio_addr - xio_base);
-	}
-
-	/* write the PCI DMA address
-	 * out to the scatter-gather list.
-	 */
-	if (inplace) {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_replace(pciio_alenlist, NULL,
-				 &pci_addr, &xio_size, al_flags)) {
-		PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			    "pcibr_dmatrans_list: alenlist_replace failed\n"));
-		goto fail;
-	    }
-	} else {
-	    if (ALENLIST_SUCCESS !=
-		alenlist_append(pciio_alenlist,
-				pci_addr, xio_size, al_flags)) {
-		PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-			    "pcibr_dmatrans_list: alenlist_append failed\n"));
-		goto fail;
-	    }
-	}
-    }
-
-    if (relbits) {
-	if (direct64) {
-	    slotp->bss_d64_flags = flags;
-	    slotp->bss_d64_base = pci_base;
-	} else {
-	    slotp->bss_d32_flags = flags;
-	    slotp->bss_d32_base = pci_base;
-	}
-    }
-    if (!inplace)
-	alenlist_done(xtalk_alenlist);
-
-    /* Reset the internal cursor of the alenlist to be returned back
-     * to the caller.
-     */
-    alenlist_cursor_init(pciio_alenlist, 0, NULL);
-
-    PCIBR_DEBUG((PCIBR_DEBUG_DMADIR, pconn_vhdl,
-		"pcibr_dmatrans_list: pciio_alenlist=0x%x\n",
-		 pciio_alenlist));
-
-    return pciio_alenlist;
-
-  fail:
-    if (relbits)
-	pcibr_release_device(pcibr_soft, pciio_slot, relbits);
-    if (pciio_alenlist && !inplace)
-	alenlist_destroy(pciio_alenlist);
-    return 0;
-}
-
 void
 pcibr_dmamap_drain(pcibr_dmamap_t map)
 {
@@ -4363,24 +3676,24 @@
 }
 
 void
-pcibr_dmaaddr_drain(devfs_handle_t pconn_vhdl,
+pcibr_dmaaddr_drain(vertex_hdl_t pconn_vhdl,
 		    paddr_t paddr,
 		    size_t bytes)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
 
     xtalk_dmaaddr_drain(xconn_vhdl, paddr, bytes);
 }
 
 void
-pcibr_dmalist_drain(devfs_handle_t pconn_vhdl,
+pcibr_dmalist_drain(vertex_hdl_t pconn_vhdl,
 		    alenlist_t list)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
 
     xtalk_dmalist_drain(xconn_vhdl, list);
 }
@@ -4402,18 +3715,18 @@
  */
 /*ARGSUSED */
 void
-pcibr_provider_startup(devfs_handle_t pcibr)
+pcibr_provider_startup(vertex_hdl_t pcibr)
 {
 }
 
 /*ARGSUSED */
 void
-pcibr_provider_shutdown(devfs_handle_t pcibr)
+pcibr_provider_shutdown(vertex_hdl_t pcibr)
 {
 }
 
 int
-pcibr_reset(devfs_handle_t conn)
+pcibr_reset(vertex_hdl_t conn)
 {
 #ifdef PIC_LATER
     pciio_info_t            pciio_info = pciio_info_get(conn);
@@ -4484,7 +3797,7 @@
 }
 
 pciio_endian_t
-pcibr_endian_set(devfs_handle_t pconn_vhdl,
+pcibr_endian_set(vertex_hdl_t pconn_vhdl,
 		 pciio_endian_t device_end,
 		 pciio_endian_t desired_end)
 {
@@ -4629,7 +3942,7 @@
 }
 
 pciio_priority_t
-pcibr_priority_set(devfs_handle_t pconn_vhdl,
+pcibr_priority_set(vertex_hdl_t pconn_vhdl,
 		   pciio_priority_t device_prio)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
@@ -4653,7 +3966,7 @@
  * Returns 0 on failure, 1 on success
  */
 int
-pcibr_device_flags_set(devfs_handle_t pconn_vhdl,
+pcibr_device_flags_set(vertex_hdl_t pconn_vhdl,
 		       pcibr_device_flags_t flags)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
@@ -4792,10 +4105,8 @@
     (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc,
     (pciio_dmamap_free_f *) pcibr_dmamap_free,
     (pciio_dmamap_addr_f *) pcibr_dmamap_addr,
-    (pciio_dmamap_list_f *) pcibr_dmamap_list,
     (pciio_dmamap_done_f *) pcibr_dmamap_done,
     (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr,
-    (pciio_dmatrans_list_f *) pcibr_dmatrans_list,
     (pciio_dmamap_drain_f *) pcibr_dmamap_drain,
     (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain,
     (pciio_dmalist_drain_f *) pcibr_dmalist_drain,
@@ -4814,23 +4125,16 @@
     (pciio_priority_set_f *) pcibr_priority_set,
     (pciio_config_get_f *) pcibr_config_get,
     (pciio_config_set_f *) pcibr_config_set,
-#ifdef PIC_LATER
-    (pciio_error_devenable_f *) pcibr_error_devenable,
-    (pciio_error_extract_f *) pcibr_error_extract,
-    (pciio_driver_reg_callback_f *) pcibr_driver_reg_callback,
-    (pciio_driver_unreg_callback_f *) pcibr_driver_unreg_callback,
-#else
     (pciio_error_devenable_f *) 0,
     (pciio_error_extract_f *) 0,
     (pciio_driver_reg_callback_f *) 0,
     (pciio_driver_unreg_callback_f *) 0,
-#endif	/* PIC_LATER */
     (pciio_device_unregister_f 	*) pcibr_device_unregister,
     (pciio_dma_enabled_f		*) pcibr_dma_enabled,
 };
 
 int
-pcibr_dma_enabled(devfs_handle_t pconn_vhdl)
+pcibr_dma_enabled(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
@@ -4857,7 +4161,7 @@
  * parameter 'format' is sent to the console.
  */
 void
-pcibr_debug(uint32_t type, devfs_handle_t vhdl, char *format, ...)
+pcibr_debug(uint32_t type, vertex_hdl_t vhdl, char *format, ...)
 {
     char hwpath[MAXDEVNAME] = "\0";
     char copy_of_hwpath[MAXDEVNAME];
@@ -4865,7 +4169,6 @@
     short widget = -1;
     short slot = -1;
     va_list ap;
-    char *strtok_r(char *string, const char *sepset, char **lasts);
 
     if (pcibr_debug_mask & type) {
         if (vhdl) {
@@ -4873,13 +4176,12 @@
                 char *cp;
 
                 if (strcmp(module, pcibr_debug_module)) {
-		    /* strtok_r() wipes out string, use a copy */
+		    /* use a copy */
                     (void)strcpy(copy_of_hwpath, hwpath);
                     cp = strstr(copy_of_hwpath, "/module/");
                     if (cp) {
-                        char *last = NULL;
                         cp += strlen("/module");
-                        module = strtok_r(cp, "/", &last);
+                        module = strsep(&cp, "/");
                     }
                 }
                 if (pcibr_debug_widget != -1) {
@@ -4917,4 +4219,27 @@
 	    va_end(ap);
         }
     }
+}
+
+int
+isIO9(nasid_t nasid) {
+	lboard_t *brd = (lboard_t *)KL_CONFIG_INFO(nasid);
+
+	while (brd) {
+		if (brd->brd_flags & LOCAL_MASTER_IO6) {
+			return 1;
+		}
+		brd = KLCF_NEXT(brd);
+	}
+	/* if it's dual ported, check the peer also */
+	nasid = NODEPDA(NASID_TO_COMPACT_NODEID(nasid))->xbow_peer;
+	if (nasid < 0) return 0;
+	brd = (lboard_t *)KL_CONFIG_INFO(nasid);
+	while (brd) {
+		if (brd->brd_flags & LOCAL_MASTER_IO6) {
+			return 1;
+		}
+		brd = KLCF_NEXT(brd);
+	}
+	return 0;
 }
diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c	Wed Jun 18 23:42:05 2003
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_error.c	Wed Jun 18 23:42:05 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,26 +27,11 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
-#ifdef __ia64
-#define rmallocmap atemapalloc
-#define rmfreemap atemapfree
-#define rmfree atefree
-#define rmalloc atealloc
-#endif
-
 extern int	hubii_check_widget_disabled(nasid_t, int);
-#ifdef BRIDGE_B_DATACORR_WAR
-extern int              ql_bridge_rev_b_war(devfs_handle_t);
-extern int              bridge_rev_b_data_check_disable;
-char                   *rev_b_datacorr_warning =
-"***************************** WARNING! ******************************\n";
-char                   *rev_b_datacorr_mesg =
-"UNRECOVERABLE IO LINK ERROR. CONTACT SERVICE PROVIDER\n";
-#endif
+
 
 /* =====================================================================
  *    ERROR HANDLING
@@ -76,13 +61,9 @@
                                    BRIDGE_ISR_PCIBUS_PIOERR;
 #endif
 
-#if defined (PCIBR_LLP_CONTROL_WAR)
-int                     pcibr_llp_control_war_cnt;
-#endif				/* PCIBR_LLP_CONTROL_WAR */
+int                     pcibr_llp_control_war_cnt; /* PCIBR_LLP_CONTROL_WAR */
 
-/* FIXME: can these arrays be local ? */
-
-struct reg_values xio_cmd_pactyp[] =
+static struct reg_values xio_cmd_pactyp[] =
 {
     {0x0, "RdReq"},
     {0x1, "RdResp"},
@@ -103,7 +84,7 @@
     {0}
 };
 
-struct reg_desc   xio_cmd_bits[] =
+static struct reg_desc   xio_cmd_bits[] =
 {
     {WIDGET_DIDN, -28, "DIDN", "%x"},
     {WIDGET_SIDN, -24, "SIDN", "%x"},
@@ -120,58 +101,7 @@
 
 #define F(s,n)          { 1l<<(s),-(s), n }
 
-struct reg_desc         bridge_int_status_desc[] =
-{
-    F(45, "PCI_X_SPLIT_MES_PE"),/* PIC ONLY */
-    F(44, "PCI_X_SPLIT_EMES"),	/* PIC ONLY */
-    F(43, "PCI_X_SPLIT_TO"),	/* PIC ONLY */
-    F(42, "PCI_X_UNEX_COMP"),	/* PIC ONLY */
-    F(41, "INT_RAM_PERR"),	/* PIC ONLY */
-    F(40, "PCI_X_ARB_ERR"),	/* PIC ONLY */
-    F(39, "PCI_X_REQ_TOUT"),	/* PIC ONLY */
-    F(38, "PCI_X_TABORT"),	/* PIC ONLY */
-    F(37, "PCI_X_PERR"),	/* PIC ONLY */
-    F(36, "PCI_X_SERR"),	/* PIC ONLY */
-    F(35, "PCI_X_MRETRY"),	/* PIC ONLY */
-    F(34, "PCI_X_MTOUT"),	/* PIC ONLY */
-    F(33, "PCI_X_DA_PARITY"),	/* PIC ONLY */
-    F(32, "PCI_X_AD_PARITY"),	/* PIC ONLY */
-    F(31, "MULTI_ERR"),		/* BRIDGE ONLY */
-    F(30, "PMU_ESIZE_EFAULT"),
-    F(29, "UNEXPECTED_RESP"),
-    F(28, "BAD_XRESP_PACKET"),
-    F(27, "BAD_XREQ_PACKET"),
-    F(26, "RESP_XTALK_ERROR"),
-    F(25, "REQ_XTALK_ERROR"),
-    F(24, "INVALID_ADDRESS"),
-    F(23, "UNSUPPORTED_XOP"),
-    F(22, "XREQ_FIFO_OFLOW"),
-    F(21, "LLP_REC_SNERROR"),
-    F(20, "LLP_REC_CBERROR"),
-    F(19, "LLP_RCTY"),
-    F(18, "LLP_TX_RETRY"),
-    F(17, "LLP_TCTY"),
-    F(16, "SSRAM_PERR"),	/* BRIDGE ONLY */
-    F(15, "PCI_ABORT"),
-    F(14, "PCI_PARITY"),
-    F(13, "PCI_SERR"),
-    F(12, "PCI_PERR"),
-    F(11, "PCI_MASTER_TOUT"),
-    F(10, "PCI_RETRY_CNT"),
-    F(9, "XREAD_REQ_TOUT"),
-    F(8, "GIO_BENABLE_ERR"),	/* BRIDGE ONLY */
-    F(7, "INT7"),
-    F(6, "INT6"),
-    F(5, "INT5"),
-    F(4, "INT4"),
-    F(3, "INT3"),
-    F(2, "INT2"),
-    F(1, "INT1"),
-    F(0, "INT0"),
-    {0}
-};
-
-struct reg_values       space_v[] =
+static struct reg_values       space_v[] =
 {
     {PCIIO_SPACE_NONE, "none"},
     {PCIIO_SPACE_ROM, "ROM"},
@@ -189,13 +119,13 @@
     {PCIIO_SPACE_BAD, "BAD"},
     {0}
 };
-struct reg_desc         space_desc[] =
+static struct reg_desc         space_desc[] =
 {
     {0xFF, 0, "space", 0, space_v},
     {0}
 };
 #define	device_desc	device_bits
-struct reg_desc   device_bits[] =
+static struct reg_desc   device_bits[] =
 {
     {BRIDGE_DEV_ERR_LOCK_EN, 0, "ERR_LOCK_EN"},
     {BRIDGE_DEV_PAGE_CHK_DIS, 0, "PAGE_CHK_DIS"},
@@ -218,14 +148,14 @@
     {0}
 };
 
-void
+static void
 print_bridge_errcmd(uint32_t cmdword, char *errtype)
 {
     printk("\t    Bridge %s Error Command Word Register ", errtype);
     print_register(cmdword, xio_cmd_bits);
 }
 
-char             *pcibr_isr_errs[] =
+static char             *pcibr_isr_errs[] =
 {
     "", "", "", "", "", "", "", "",
     "08: GIO non-contiguous byte enable in crosstalk packet", /* BRIDGE ONLY */
@@ -279,7 +209,7 @@
 /*
  * display memory directory state
  */
-void
+static void
 pcibr_show_dir_state(paddr_t paddr, char *prefix)
 {
 #ifdef LATER
@@ -428,7 +358,6 @@
 		break;
 
 	    case BRIDGE_ISR_PAGE_FAULT:	    /* bit30	PMU_PAGE_FAULT */
-/*	    case BRIDGE_ISR_PMU_ESIZE_FAULT:   bit30	PMU_ESIZE_FAULT */
 		if (IS_XBRIDGE_OR_PIC_SOFT(pcibr_soft))
 		    reg_desc = "Map Fault Address";
 		else
@@ -592,31 +521,9 @@
 		printk( "\t%s\n", pcibr_isr_errs[i]);
 	}
     }
-
-#if BRIDGE_ERROR_INTR_WAR
-    if (pcibr_soft->bs_rev_num == BRIDGE_PART_REV_A) {	/* known bridge bug */
-	/*
-	 * Should never receive interrupts for these reasons on Rev 1 bridge
-	 * as they are not enabled. Assert for it.
-	 */
-	ASSERT((int_status & (BRIDGE_IMR_PCI_MST_TIMEOUT |
-			      BRIDGE_ISR_RESP_XTLK_ERR |
-			      BRIDGE_ISR_LLP_TX_RETRY)) == 0);
-    }
-    if (pcibr_soft->bs_rev_num < BRIDGE_PART_REV_C) {	/* known bridge bug */
-	/*
-	 * This interrupt is turned off at init time. So, should never
-	 * see this interrupt.
-	 */
-	ASSERT((int_status & BRIDGE_ISR_BAD_XRESP_PKT) == 0);
-    }
-#endif
 }
 
-#define PCIBR_ERRINTR_GROUP(error)	\
-		(( error & (BRIDGE_IRR_PCI_GRP|BRIDGE_IRR_GIO_GRP)
-
-uint32_t
+static uint32_t
 pcibr_errintr_group(uint32_t error)
 {
     uint32_t              group = BRIDGE_IRR_MULTI_CLR;
@@ -741,15 +648,7 @@
     picreg_t                int_status_64;
     int			    number_bits;
     int                     i;
-
-    /* REFERENCED */
     uint64_t		    disable_errintr_mask = 0;
-#ifdef EHE_ENABLE
-    int 		    rv;
-    int 		    error_code = IOECODE_DMA | IOECODE_READ;
-    ioerror_mode_t 	    mode = MODE_DEVERROR;
-    ioerror_t 	            ioe;
-#endif /* EHE_ENABLE */
     nasid_t		    nasid;
 
 
@@ -806,10 +705,6 @@
 	pcibr_soft->bs_errinfo.bserr_toutcnt++;
 	/* Let's go recursive */
 	return(pcibr_error_intr_handler(irq, arg, ep));
-#ifdef LATER
-	timeout(pcibr_error_intr_handler, pcibr_soft, BRIDGE_PIOERR_TIMEOUT);
-#endif
-	return;
     }
 
     /* We read the INT_STATUS register as a 64bit picreg_t for PIC and a
@@ -847,24 +742,6 @@
 	pcibr_pioerr_check(pcibr_soft);
     }
 
-#ifdef BRIDGE_B_DATACORR_WAR
-    if ((pcibr_soft->bs_rev_num == BRIDGE_PART_REV_B) &&
-	(err_status & BRIDGE_IMR_LLP_REC_CBERR)) {
-	if (bridge_rev_b_data_check_disable)
-	    printk(KERN_WARNING "\n%s%s: %s%s\n", rev_b_datacorr_warning,
-		    pcibr_soft->bs_name, rev_b_datacorr_mesg,
-		    rev_b_datacorr_warning);
-	else {
-	    ql_bridge_rev_b_war(pcibr_soft->bs_vhdl);
-	    PRINT_PANIC( "\n%s%s: %s%s\n", rev_b_datacorr_warning,
-		    pcibr_soft->bs_name, rev_b_datacorr_mesg,
-		    rev_b_datacorr_warning);
-	}
-
-	err_status &= ~BRIDGE_IMR_LLP_REC_CBERR;
-    }
-#endif				/* BRIDGE_B_DATACORR_WAR */
-
     if (err_status) {
 	struct bs_errintr_stat_s *bs_estat = pcibr_soft->bs_errintr_stat;
 
@@ -1024,9 +901,8 @@
 	(0x00402000 == (0x00F07F00 & bridge->b_wid_err_cmdword))) {
 	err_status &= ~BRIDGE_ISR_INVLD_ADDR;
     }
-#if defined (PCIBR_LLP_CONTROL_WAR)
     /*
-     * The bridge bug, where the llp_config or control registers
+     * The bridge bug (PCIBR_LLP_CONTROL_WAR), where the llp_config or control registers
      * need to be read back after being written, affects an MP
      * system since there could be small windows between writing
      * the register and reading it back on one cpu while another
@@ -1039,40 +915,9 @@
     if ((err_status & BRIDGE_ISR_INVLD_ADDR) &&
 	((((uint64_t) bridge->b_wid_err_upper << 32) | (bridge->b_wid_err_lower))
 	 == (BRIDGE_INT_RST_STAT & 0xff0))) {
-#if 0
-	if (kdebug)
-	    printk(KERN_NOTICE "%s bridge: ignoring llp/control address interrupt",
-		    pcibr_soft->bs_name);
-#endif
 	pcibr_llp_control_war_cnt++;
 	err_status &= ~BRIDGE_ISR_INVLD_ADDR;
     }
-#endif				/* PCIBR_LLP_CONTROL_WAR */
-
-#ifdef EHE_ENABLE
-    /* Check if this is the RESP_XTALK_ERROR interrupt. 
-     * This can happen due to a failed DMA READ operation.
-     */
-    if (err_status & BRIDGE_ISR_RESP_XTLK_ERR) {
-	/* Phase 1 : Look at the error state in the bridge and further
-	 * down in the device layers.
-	 */
-	(void)error_state_set(pcibr_soft->bs_conn, ERROR_STATE_LOOKUP);
-	IOERROR_SETVALUE(&ioe, widgetnum, pcibr_soft->bs_xid);
-	(void)pcibr_error_handler((error_handler_arg_t)pcibr_soft,
-				  error_code,
-				  mode,
-				  &ioe);
-	/* Phase 2 : Perform the action agreed upon in phase 1.
-	 */
-	(void)error_state_set(pcibr_soft->bs_conn, ERROR_STATE_ACTION);
-	rv = pcibr_error_handler((error_handler_arg_t)pcibr_soft,
-				 error_code,
-				 mode,
-				 &ioe);
-    }
-    if (rv != IOERROR_HANDLED) {
-#endif /* EHE_ENABLE */
 
     bridge_errors_to_dump |= BRIDGE_ISR_PCIBUS_PIOERR;
 
@@ -1089,25 +934,16 @@
      */
     if (IS_PIC_SOFT(pcibr_soft) && PCIBR_WAR_ENABLED(PV867308, pcibr_soft) &&
         (err_status & (BRIDGE_ISR_LLP_REC_SNERR | BRIDGE_ISR_LLP_REC_CBERR))) {
-        printk("BRIDGE ERR_STATUS 0x%x\n", err_status);
+        printk("BRIDGE ERR_STATUS 0x%lx\n", err_status);
         pcibr_error_dump(pcibr_soft);
-#ifdef LATER
-        machine_error_dump("");
-#endif
         PRINT_PANIC("PCI Bridge Error interrupt killed the system");
     }
 
     if (err_status & BRIDGE_ISR_ERROR_FATAL) {
-#ifdef LATER
-	machine_error_dump("");
-#endif
 	PRINT_PANIC("PCI Bridge Error interrupt killed the system");
 	    /*NOTREACHED */
     }
 
-#ifdef EHE_ENABLE
-    }
-#endif
 
     /*
      * We can't return without re-enabling the interrupt, since
@@ -1137,136 +973,6 @@
     pcibr_soft->bs_errinfo.bserr_intstat = 0;
 }
 
-/*
- * pcibr_addr_toslot
- *      Given the 'pciaddr' find out which slot this address is
- *      allocated to, and return the slot number.
- *      While we have the info handy, construct the
- *      function number, space code and offset as well.
- *
- * NOTE: if this routine is called, we don't know whether
- * the address is in CFG, MEM, or I/O space. We have to guess.
- * This will be the case on PIO stores, where the only way
- * we have of getting the address is to check the Bridge, which
- * stores the PCI address but not the space and not the xtalk
- * address (from which we could get it).
- */
-int
-pcibr_addr_toslot(pcibr_soft_t pcibr_soft,
-		  iopaddr_t pciaddr,
-		  pciio_space_t *spacep,
-		  iopaddr_t *offsetp,
-		  pciio_function_t *funcp)
-{
-    int                     s, f = 0, w;
-    iopaddr_t               base;
-    size_t                  size;
-    pciio_piospace_t        piosp;
-
-    /*
-     * Check if the address is in config space
-     */
-
-    if ((pciaddr >= BRIDGE_CONFIG_BASE) && (pciaddr < BRIDGE_CONFIG_END)) {
-
-	if (pciaddr >= BRIDGE_CONFIG1_BASE)
-	    pciaddr -= BRIDGE_CONFIG1_BASE;
-	else
-	    pciaddr -= BRIDGE_CONFIG_BASE;
-
-	s = pciaddr / BRIDGE_CONFIG_SLOT_SIZE;
-	pciaddr %= BRIDGE_CONFIG_SLOT_SIZE;
-
-	if (funcp) {
-	    f = pciaddr / 0x100;
-	    pciaddr %= 0x100;
-	}
-	if (spacep)
-	    *spacep = PCIIO_SPACE_CFG;
-	if (offsetp)
-	    *offsetp = pciaddr;
-	if (funcp)
-	    *funcp = f;
-
-	return s;
-    }
-    for (s = pcibr_soft->bs_min_slot; s < PCIBR_NUM_SLOTS(pcibr_soft); ++s) {
-	int                     nf = pcibr_soft->bs_slot[s].bss_ninfo;
-	pcibr_info_h            pcibr_infoh = pcibr_soft->bs_slot[s].bss_infos;
-
-	for (f = 0; f < nf; f++) {
-	    pcibr_info_t            pcibr_info = pcibr_infoh[f];
-
-	    if (!pcibr_info)
-		continue;
-	    for (w = 0; w < 6; w++) {
-		if (pcibr_info->f_window[w].w_space == PCIIO_SPACE_NONE) {
-		    continue;
-		}
-		base = pcibr_info->f_window[w].w_base;
-		size = pcibr_info->f_window[w].w_size;
-
-		if ((pciaddr >= base) && (pciaddr < (base + size))) {
-		    if (spacep)
-			*spacep = PCIIO_SPACE_WIN(w);
-		    if (offsetp)
-			*offsetp = pciaddr - base;
-		    if (funcp)
-			*funcp = f;
-		    return s;
-		}			/* endif match */
-	    }				/* next window */
-	}				/* next func */
-    }					/* next slot */
-
-    /*
-     * Check if the address was allocated as part of the
-     * pcibr_piospace_alloc calls.
-     */
-    for (s = pcibr_soft->bs_min_slot; s < PCIBR_NUM_SLOTS(pcibr_soft); ++s) {
-	int                     nf = pcibr_soft->bs_slot[s].bss_ninfo;
-	pcibr_info_h            pcibr_infoh = pcibr_soft->bs_slot[s].bss_infos;
-
-	for (f = 0; f < nf; f++) {
-	    pcibr_info_t            pcibr_info = pcibr_infoh[f];
-
-	    if (!pcibr_info)
-		continue;
-	    piosp = pcibr_info->f_piospace;
-	    while (piosp) {
-		if ((piosp->start <= pciaddr) &&
-		    ((piosp->count + piosp->start) > pciaddr)) {
-		    if (spacep)
-			*spacep = piosp->space;
-		    if (offsetp)
-			*offsetp = pciaddr - piosp->start;
-		    return s;
-		}			/* endif match */
-		piosp = piosp->next;
-	    }				/* next piosp */
-	}				/* next func */
-    }					/* next slot */
-
-    /*
-     * Some other random address on the PCI bus ...
-     * we have no way of knowing whether this was
-     * a MEM or I/O access; so, for now, we just
-     * assume that the low 1G is MEM, the next
-     * 3G is I/O, and anything above the 4G limit
-     * is obviously MEM.
-     */
-
-    if (spacep)
-	*spacep = ((pciaddr < (1ul << 30)) ? PCIIO_SPACE_MEM :
-		   (pciaddr < (4ul << 30)) ? PCIIO_SPACE_IO :
-		   PCIIO_SPACE_MEM);
-    if (offsetp)
-	*offsetp = pciaddr;
-
-    return PCIIO_SLOT_NONE;
-
-}
-
 void
 pcibr_error_cleanup(pcibr_soft_t pcibr_soft, int error_code)
 {
@@ -1286,59 +992,6 @@
     (void) bridge->b_wid_tflush;	/* flushbus */
 }
 
-/*
- * pcibr_error_extract
- *      Given the 'pcibr vertex handle' find out which slot
- *      the bridge status error address (from pcibr_soft info
- *      hanging off the vertex)
- *      allocated to, and return the slot number.
- *      While we have the info handy, construct the
- *      space code and offset as well.
- *
- * NOTE: if this routine is called, we don't know whether
- * the address is in CFG, MEM, or I/O space. We have to guess.
- * This will be the case on PIO stores, where the only way
- * we have of getting the address is to check the Bridge, which
- * stores the PCI address but not the space and not the xtalk
- * address (from which we could get it).
- *
- * XXX- this interface has no way to return the function
- * number on a multifunction card, even though that data
- * is available.
- */
-
-pciio_slot_t
-pcibr_error_extract(devfs_handle_t pcibr_vhdl,
-		    pciio_space_t *spacep,
-		    iopaddr_t *offsetp)
-{
-    pcibr_soft_t            pcibr_soft = 0;
-    iopaddr_t               bserr_addr;
-    bridge_t               *bridge;
-    pciio_slot_t            slot = PCIIO_SLOT_NONE;
-    arbitrary_info_t	    rev;
-
-    /* Do a sanity check as to whether we really got a 
-     * bridge vertex handle.
-     */
-    if (hwgraph_info_get_LBL(pcibr_vhdl, INFO_LBL_PCIBR_ASIC_REV, &rev) !=
-	GRAPH_SUCCESS) 
-	return(slot);
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    if (pcibr_soft) {
-	bridge = pcibr_soft->bs_base;
-	bserr_addr =
-	    bridge->b_pci_err_lower |
-	    ((uint64_t) (bridge->b_pci_err_upper &
-			   BRIDGE_ERRUPPR_ADDRMASK) << 32);
-
-	slot = pcibr_addr_toslot(pcibr_soft, bserr_addr,
-				 spacep, offsetp, NULL);
-    }
-    return slot;
-}
-
 /*ARGSUSED */
 void
 pcibr_device_disable(pcibr_soft_t pcibr_soft, int devnum)
@@ -1426,7 +1079,7 @@
 {
     int                     retval = IOERROR_HANDLED;
 
-    devfs_handle_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
+    vertex_hdl_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
     bridge_t               *bridge = pcibr_soft->bs_base;
 
     iopaddr_t               bad_xaddr;
@@ -1837,7 +1490,7 @@
 		     ioerror_mode_t mode,
 		     ioerror_t *ioe)
 {
-    devfs_handle_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
+    vertex_hdl_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
     bridge_t               *bridge = pcibr_soft->bs_base;
     bridgereg_t             bus_lowaddr, bus_uppraddr;
     int                     retval = 0;
@@ -1946,7 +1599,7 @@
 		     ioerror_mode_t mode,
 		     ioerror_t *ioe)
 {
-    devfs_handle_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
+    vertex_hdl_t            pcibr_vhdl = pcibr_soft->bs_vhdl;
     int                     retval;
 
     retval = pciio_error_handler(pcibr_vhdl, error_code, mode, ioe);
@@ -1982,34 +1635,12 @@
     pcibr_soft_t            pcibr_soft;
     int                     retval = IOERROR_BADERRORCODE;
 
-#ifdef EHE_ENABLE
-    devfs_handle_t	    xconn_vhdl,pcibr_vhdl;
-    error_state_t	    e_state;
-#endif /* EHE_ENABLE */
-
     pcibr_soft = (pcibr_soft_t) einfo;
 
     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ERROR_HDLR, pcibr_soft->bs_conn,
 		"pcibr_error_handler: pcibr_soft=0x%x, error_code=0x%x\n",
 		pcibr_soft, error_code));
 
-#ifdef EHE_ENABLE
-    xconn_vhdl = pcibr_soft->bs_conn;
-    pcibr_vhdl = pcibr_soft->bs_vhdl;
-
-    e_state = error_state_get(xconn_vhdl);
-    
-    if (error_state_set(pcibr_vhdl, e_state) == 
-	ERROR_RETURN_CODE_CANNOT_SET_STATE)
-	return(IOERROR_UNHANDLED);
-
-    /* If we are in the action handling phase clean out the error state
-     * on the xswitch.
-     */
-    if (e_state == ERROR_STATE_ACTION)
-	(void)error_state_set(xconn_vhdl, ERROR_STATE_NONE);
-#endif /* EHE_ENABLE */
-
 #if DEBUG && ERROR_DEBUG
     printk( "%s: pcibr_error_handler\n", pcibr_soft->bs_name);
 #endif
@@ -2086,11 +1717,6 @@
      * the error from the PIO address.
      */
 
-#if 0
-    if (mode == MODE_DEVPROBE)
-	pio_retval = IOERROR_HANDLED;
-    else {
-#endif
     if (error_code & IOECODE_PIO) {
 	iopaddr_t               bad_xaddr;
 	/*
@@ -2123,9 +1749,6 @@
 	    pio_retval = IOERROR_UNHANDLED;
 	}
     } 
-#if 0
-    } /* MODE_DEVPROBE */
-#endif
 
     /* 
      * If the error was a result of a DMA Write, we tell what bus on the PIC
@@ -2200,38 +1823,4 @@
     } else {
 	return IOERROR_HANDLED;
     }
-}
-
-
-/*
- * Reenable a device after handling the error.
- * This is called by the lower layers when they wish to be reenabled
- * after an error.
- * Note that each layer would be calling the previous layer to reenable
- * first, before going ahead with their own re-enabling.
- */
-
-int
-pcibr_error_devenable(devfs_handle_t pconn_vhdl, int error_code)
-{
-    pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
-    pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
-    pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pciio_info_mfast_get(pciio_info);
-
-    ASSERT(error_code & IOECODE_PIO);
-
-    /* If the error is not known to be a write,
-     * we have to call devenable.
-     * write errors are isolated to the bridge.
-     */
-    if (!(error_code & IOECODE_WRITE)) {
-	devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
-	int                     rc;
-
-	rc = xtalk_error_devenable(xconn_vhdl, pciio_slot, error_code);
-	if (rc != IOERROR_HANDLED)
-	    return rc;
-    }
-    pcibr_error_cleanup(pcibr_soft, error_code);
-    return IOERROR_HANDLED;
 }
diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_hints.c	Wed Jun 18 23:42:09 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,20 +27,19 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
-pcibr_hints_t           pcibr_hints_get(devfs_handle_t, int);
-void                    pcibr_hints_fix_rrbs(devfs_handle_t);
-void                    pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t);
-void			pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *);
-void                    pcibr_set_rrb_callback(devfs_handle_t, rrb_alloc_funct_t);
-void                    pcibr_hints_handsoff(devfs_handle_t);
-void                    pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, uint64_t);
+pcibr_hints_t           pcibr_hints_get(vertex_hdl_t, int);
+void                    pcibr_hints_fix_rrbs(vertex_hdl_t);
+void                    pcibr_hints_dualslot(vertex_hdl_t, pciio_slot_t, pciio_slot_t);
+void			pcibr_hints_intr_bits(vertex_hdl_t, pcibr_intr_bits_f *);
+void                    pcibr_set_rrb_callback(vertex_hdl_t, rrb_alloc_funct_t);
+void                    pcibr_hints_handsoff(vertex_hdl_t);
+void                    pcibr_hints_subdevs(vertex_hdl_t, pciio_slot_t, uint64_t);
 
 pcibr_hints_t
-pcibr_hints_get(devfs_handle_t xconn_vhdl, int alloc)
+pcibr_hints_get(vertex_hdl_t xconn_vhdl, int alloc)
 {
     arbitrary_info_t        ainfo = 0;
     graph_error_t	    rv;
@@ -79,7 +78,7 @@
 }
 
 void
-pcibr_hints_fix_some_rrbs(devfs_handle_t xconn_vhdl, unsigned mask)
+pcibr_hints_fix_some_rrbs(vertex_hdl_t xconn_vhdl, unsigned mask)
 {
     pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
 
@@ -91,13 +90,13 @@
 }
 
 void
-pcibr_hints_fix_rrbs(devfs_handle_t xconn_vhdl)
+pcibr_hints_fix_rrbs(vertex_hdl_t xconn_vhdl)
 {
     pcibr_hints_fix_some_rrbs(xconn_vhdl, 0xFF);
 }
 
 void
-pcibr_hints_dualslot(devfs_handle_t xconn_vhdl,
+pcibr_hints_dualslot(vertex_hdl_t xconn_vhdl,
 		     pciio_slot_t host,
 		     pciio_slot_t guest)
 {
@@ -111,7 +110,7 @@
 }
 
 void
-pcibr_hints_intr_bits(devfs_handle_t xconn_vhdl,
+pcibr_hints_intr_bits(vertex_hdl_t xconn_vhdl,
 		      pcibr_intr_bits_f *xxx_intr_bits)
 {
     pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
@@ -124,7 +123,7 @@
 }
 
 void
-pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct)
+pcibr_set_rrb_callback(vertex_hdl_t xconn_vhdl, rrb_alloc_funct_t rrb_alloc_funct)
 {
     pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
 
@@ -133,7 +132,7 @@
 }
 
 void
-pcibr_hints_handsoff(devfs_handle_t xconn_vhdl)
+pcibr_hints_handsoff(vertex_hdl_t xconn_vhdl)
 {
     pcibr_hints_t           hint = pcibr_hints_get(xconn_vhdl, 1);
 
@@ -145,13 +144,13 @@
 }
 
 void
-pcibr_hints_subdevs(devfs_handle_t xconn_vhdl,
+pcibr_hints_subdevs(vertex_hdl_t xconn_vhdl,
 		    pciio_slot_t slot,
 		    uint64_t subdevs)
 {
     arbitrary_info_t        ainfo = 0;
     char                    sdname[16];
-    devfs_handle_t            pconn_vhdl = GRAPH_VERTEX_NONE;
+    vertex_hdl_t            pconn_vhdl = GRAPH_VERTEX_NONE;
 
     sprintf(sdname, "%s/%d", EDGE_LBL_PCI, slot);
     (void) hwgraph_path_add(xconn_vhdl, sdname, &pconn_vhdl);
diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_idbg.c	Wed Jun 18 23:42:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,147 +0,0 @@
-/*
- *
- * 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) 2001-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/pci/pcibr.h>
-#include <asm/sn/pci/pcibr_private.h>
-#include <asm/sn/pci/pci_defs.h>
-#include <asm/sn/prio.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_private.h>
-
-#ifdef LATER
-
-char *pci_space[] = {"NONE", 
-		     "ROM",
-		     "IO",
-		     "",
-		     "MEM",
-		     "MEM32",
-		     "MEM64",
-		     "CFG",
-		     "WIN0",
-		     "WIN1",
-		     "WIN2",
-		     "WIN3",
-		     "WIN4",
-		     "WIN5",
-		     "",
-		     "BAD"};
-
-void
-idbg_pss_func(pcibr_info_h pcibr_infoh, int func)
-{
-    pcibr_info_t	pcibr_info = pcibr_infoh[func];
-    char		name[MAXDEVNAME];
-    int			win;
-    
-    if (!pcibr_info)
-	return;
-    qprintf("Per-slot Function Info\n");
-    sprintf(name, "%v", pcibr_info->f_vertex);
-    qprintf("\tSlot Name : %s\n",name);
-    qprintf("\tPCI Bus : %d ",pcibr_info->f_bus);
-    qprintf("Slot : %d ", pcibr_info->f_slot);
-    qprintf("Function : %d ", pcibr_info->f_func);
-    qprintf("VendorId : 0x%x " , pcibr_info->f_vendor);
-    qprintf("DeviceId : 0x%x\n", pcibr_info->f_device);
-    sprintf(name, "%v", pcibr_info->f_master);
-    qprintf("\tBus provider : %s\n",name);
-    qprintf("\tProvider Fns : 0x%x ", pcibr_info->f_pops);
-    qprintf("Error Handler : 0x%x Arg 0x%x\n", 
-	    pcibr_info->f_efunc,pcibr_info->f_einfo);
-    for(win = 0 ; win < 6 ; win++) 
-	qprintf("\tBase Reg #%d space %s base 0x%x size 0x%x\n",
-		win,pci_space[pcibr_info->f_window[win].w_space],
-		pcibr_info->f_window[win].w_base,
-		pcibr_info->f_window[win].w_size);
-
-    qprintf("\tRom base 0x%x size 0x%x\n", 
-	    pcibr_info->f_rbase,pcibr_info->f_rsize);
-
-    qprintf("\tInterrupt Bit Map\n");
-    qprintf("\t\tPCI Int#\tBridge Pin#\n");
-    for (win = 0 ; win < 4; win++)
-	qprintf("\t\tINT%c\t\t%d\n",win+'A',pcibr_info->f_ibit[win]);
-    qprintf("\n");
-}
-
-
-void
-idbg_pss_info(pcibr_soft_t pcibr_soft, pciio_slot_t slot)
-{
-    pcibr_soft_slot_t	pss;
-    char		slot_conn_name[MAXDEVNAME];
-    int			func;
-
-    pss = &pcibr_soft->bs_slot[slot];
-    qprintf("PCI INFRASTRUCTURAL INFO FOR SLOT %d\n", slot);
-    qprintf("\tHost Present ? %s ", pss->has_host ? "yes" : "no");
-    qprintf("\tHost Slot : %d\n",pss->host_slot);
-    sprintf(slot_conn_name, "%v", pss->slot_conn);
-    qprintf("\tSlot Conn : %s\n",slot_conn_name);	
-    qprintf("\t#Functions : %d\n",pss->bss_ninfo);
-    for (func = 0; func < pss->bss_ninfo; func++)
-	idbg_pss_func(pss->bss_infos,func);
-    qprintf("\tSpace : %s ",pci_space[pss->bss_devio.bssd_space]);
-    qprintf("\tBase : 0x%x ", pss->bss_devio.bssd_base);
-    qprintf("\tShadow Devreg : 0x%x\n", pss->bss_device);
-    qprintf("\tUsage counts : pmu %d d32 %d d64 %d\n",
-	    pss->bss_pmu_uctr,pss->bss_d32_uctr,pss->bss_d64_uctr);
-    
-    qprintf("\tDirect Trans Info : d64_base 0x%x d64_flags 0x%x"
-	    "d32_base 0x%x d32_flags 0x%x\n",
-	    pss->bss_d64_base, pss->bss_d64_flags,
-	    pss->bss_d32_base, pss->bss_d32_flags);
-    
-    qprintf("\tExt ATEs active ? %s", 
-	    pss->bss_ext_ates_active ? "yes" : "no");
-    qprintf(" Command register : 0x%x ", pss->bss_cmd_pointer);
-    qprintf(" Shadow command val : 0x%x\n", pss->bss_cmd_shadow);
-
-    qprintf("\tRRB Info : Valid %d+%d Reserved %d\n",
-	    pcibr_soft->bs_rrb_valid[slot],
-	    pcibr_soft->bs_rrb_valid[slot + PCIBR_RRB_SLOT_VIRTUAL],
-	    pcibr_soft->bs_rrb_res[slot]);
-		
-}
-
-int	ips = 0;
-
-void
-idbg_pss(pcibr_soft_t pcibr_soft)
-{
-    pciio_slot_t	slot;
-
-    
-    if (ips >= 0 && ips < 8)
-	idbg_pss_info(pcibr_soft,ips);
-    else if (ips < 0)
-	for (slot = 0; slot < 8; slot++) 
-	    idbg_pss_info(pcibr_soft,slot);
-    else
-	qprintf("Invalid ips %d\n",ips);
-}
-#endif	/* LATER */
diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_intr.c	Wed Jun 18 23:42:08 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,7 +27,6 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
@@ -36,20 +35,32 @@
 #define rmfreemap atemapfree
 #define rmfree atefree
 #define rmalloc atealloc
+
+inline int
+compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr)
+{
+	FIXME("compare_and_swap_ptr : NOT ATOMIC");
+	if (*location == old_ptr) {
+		*location = new_ptr;
+		return(1);
+	}
+	else
+		return(0);
+}
 #endif
 
 unsigned		pcibr_intr_bits(pciio_info_t info, pciio_intr_line_t lines, int nslots);
-pcibr_intr_t            pcibr_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
+pcibr_intr_t            pcibr_intr_alloc(vertex_hdl_t, device_desc_t, pciio_intr_line_t, vertex_hdl_t);
 void                    pcibr_intr_free(pcibr_intr_t);
 void              pcibr_setpciint(xtalk_intr_t);
 int                     pcibr_intr_connect(pcibr_intr_t, intr_func_t, intr_arg_t);
 void                    pcibr_intr_disconnect(pcibr_intr_t);
 
-devfs_handle_t            pcibr_intr_cpu_get(pcibr_intr_t);
+vertex_hdl_t            pcibr_intr_cpu_get(pcibr_intr_t);
 void                    pcibr_xintr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
 void                    pcibr_intr_func(intr_arg_t);
 
-extern pcibr_info_t      pcibr_info_get(devfs_handle_t);
+extern pcibr_info_t      pcibr_info_get(vertex_hdl_t);
 
 /* =====================================================================
  *    INTERRUPT MANAGEMENT
@@ -132,6 +143,102 @@
 }
 
 /*
+ *	On SN systems there is a race condition between a PIO read response
+ *	and DMA's.  In rare cases, the read response may beat the DMA, causing
+ *	the driver to think that data in memory is complete and meaningful.
+ *	This code eliminates that race.
+ *	This routine is called by the PIO read routines after doing the read.
+ *	This routine then forces a fake interrupt on another line, which
+ *	is logically associated with the slot that the PIO is addressed to.
+ *	(see sn_dma_flush_init() )
+ *	It then spins while watching the memory location that the interrupt
+ *	is targetted to.  When the interrupt response arrives, we are sure
+ *	that the DMA has landed in memory and it is safe for the driver
+ *	to proceed.
+ */
+
+extern struct sn_flush_nasid_entry flush_nasid_list[MAX_NASIDS];
+
+void
+sn_dma_flush(unsigned long addr) {
+	nasid_t nasid;
+	int wid_num;
+	volatile struct sn_flush_device_list *p;
+	int i,j;
+	int bwin;
+	unsigned long flags;
+
+	nasid = NASID_GET(addr);
+	wid_num = SWIN_WIDGETNUM(addr);
+	bwin = BWIN_WINDOWNUM(addr);
+
+	if (flush_nasid_list[nasid].widget_p == NULL) return;
+	if (bwin > 0) {
+		bwin--;
+		switch (bwin) {
+			case 0:
+				wid_num = ((flush_nasid_list[nasid].iio_itte1) >> 8) & 0xf;
+				break;
+			case 1:
+				wid_num = ((flush_nasid_list[nasid].iio_itte2) >> 8) & 0xf;
+				break;
+			case 2: 
+				wid_num = ((flush_nasid_list[nasid].iio_itte3) >> 8) & 0xf;
+				break;
+			case 3: 
+				wid_num = ((flush_nasid_list[nasid].iio_itte4) >> 8) & 0xf;
+				break;
+			case 4: 
+				wid_num = ((flush_nasid_list[nasid].iio_itte5) >> 8) & 0xf;
+				break;
+			case 5: 
+				wid_num = ((flush_nasid_list[nasid].iio_itte6) >> 8) & 0xf;
+				break;
+			case 6: 
+				wid_num = ((flush_nasid_list[nasid].iio_itte7) >> 8) & 0xf;
+				break;
+		}
+	}
+	if (flush_nasid_list[nasid].widget_p == NULL) return;
+	if (flush_nasid_list[nasid].widget_p[wid_num] == NULL) return;
+	p = &flush_nasid_list[nasid].widget_p[wid_num][0];
+
+	// find a matching BAR
+
+	for (i=0; i<DEV_PER_WIDGET;i++) {
+		for (j=0; j<PCI_ROM_RESOURCE;j++) {
+			if (p->bar_list[j].start == 0) break;
+			if (addr >= p->bar_list[j].start && addr <= p->bar_list[j].end) break;
+		}
+		if (j < PCI_ROM_RESOURCE && p->bar_list[j].start != 0) break;
+		p++;
+	}
+
+	// if no matching BAR, return without doing anything.
+
+	if (i == DEV_PER_WIDGET) return;
+
+	spin_lock_irqsave(&p->flush_lock, flags);
+
+	p->flush_addr = 0;
+
+	// force an interrupt.
+
+	*(bridgereg_t *)(p->force_int_addr) = 1;
+
+	// wait for the interrupt to come back.
+
+	while (p->flush_addr != 0x10f);
+
+	// okay, everything is synched up.
+	spin_unlock_irqrestore(&p->flush_lock, flags);
+
+	return;
+}
+
+EXPORT_SYMBOL(sn_dma_flush);
+
+/*
  *	There are end cases where a deadlock can occur if interrupt 
  *	processing completes and the Bridge b_int_status bit is still set.
  *
@@ -164,51 +271,42 @@
  *	to check if a specific Bridge b_int_status bit is set, and if so,
  *	cause the setting of the corresponding interrupt bit.
  *
- *	On a XBridge (SN1), we do this by writing the appropriate Bridge Force 
- *	Interrupt register. On SN0, or SN1 with an older Bridge, the Bridge 
- *	Force Interrupt register does not exist, so we write the Hub 
- *	INT_PEND_MOD register directly. Likewise for Octane, where we write the 
- *	Heart Set Interrupt Status register directly.
+ *	On a XBridge (SN1) and PIC (SN2), we do this by writing the appropriate Bridge Force 
+ *	Interrupt register.
  */
 void
-pcibr_force_interrupt(pcibr_intr_wrap_t wrap)
+pcibr_force_interrupt(pcibr_intr_t intr)
 {
-#ifdef PIC_LATER
 	unsigned	bit;
-	pcibr_soft_t    pcibr_soft = wrap->iw_soft;
+	unsigned	bits;
+	pcibr_soft_t    pcibr_soft = intr->bi_soft;
 	bridge_t       *bridge = pcibr_soft->bs_base;
 
-	bit = wrap->iw_ibit;
+	bits = intr->bi_ibits;
+	for (bit = 0; bit < 8; bit++) {
+		if (bits & (1 << bit)) {
 
-	PCIBR_DEBUG((PCIBR_DEBUG_INTR, pcibr_soft->bs_vhdl,
-		    "pcibr_force_interrupt: bit=0x%x\n", bit));
+			PCIBR_DEBUG((PCIBR_DEBUG_INTR, pcibr_soft->bs_vhdl,
+		    		"pcibr_force_interrupt: bit=0x%x\n", bit));
 
-	if (IS_XBRIDGE_OR_PIC_SOFT(pcibr_soft)) {
-	    bridge->b_force_pin[bit].intr = 1;
-	} else if ((1 << bit) & *wrap->iw_stat) {
-	    cpuid_t	    cpu;
-	    unsigned        intr_bit;
-	    xtalk_intr_t    xtalk_intr =
-				pcibr_soft->bs_intr[bit].bsi_xtalk_intr;
-
-	    intr_bit = (short) xtalk_intr_vector_get(xtalk_intr);
-	    cpu = xtalk_intr_cpuid_get(xtalk_intr);
-	    REMOTE_CPU_SEND_INTR(cpu, intr_bit);
+			if (IS_XBRIDGE_OR_PIC_SOFT(pcibr_soft)) {
+	    			bridge->b_force_pin[bit].intr = 1;
+			}
+		}
 	}
-#endif	/* PIC_LATER */
 }
 
 /*ARGSUSED */
 pcibr_intr_t
-pcibr_intr_alloc(devfs_handle_t pconn_vhdl,
+pcibr_intr_alloc(vertex_hdl_t pconn_vhdl,
 		 device_desc_t dev_desc,
 		 pciio_intr_line_t lines,
-		 devfs_handle_t owner_dev)
+		 vertex_hdl_t owner_dev)
 {
     pcibr_info_t            pcibr_info = pcibr_info_get(pconn_vhdl);
     pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pcibr_info);
     pcibr_soft_t            pcibr_soft = (pcibr_soft_t) pcibr_info->f_mfast;
-    devfs_handle_t            xconn_vhdl = pcibr_soft->bs_conn;
+    vertex_hdl_t            xconn_vhdl = pcibr_soft->bs_conn;
     bridge_t               *bridge = pcibr_soft->bs_base;
     int                     is_threaded = 0;
 
@@ -498,25 +596,18 @@
 {
     iopaddr_t		 addr;
     xtalk_intr_vector_t	 vect;
-    devfs_handle_t	 vhdl;
+    vertex_hdl_t	 vhdl;
     bridge_t		*bridge;
+    picreg_t	*int_addr;
 
     addr = xtalk_intr_addr_get(xtalk_intr);
     vect = xtalk_intr_vector_get(xtalk_intr);
     vhdl = xtalk_intr_dev_get(xtalk_intr);
     bridge = (bridge_t *)xtalk_piotrans_addr(vhdl, 0, 0, sizeof(bridge_t), 0);
 
-    if (is_pic(bridge)) {
-	picreg_t	*int_addr;
-	int_addr = (picreg_t *)xtalk_intr_sfarg_get(xtalk_intr);
-	*int_addr = ((PIC_INT_ADDR_FLD & ((uint64_t)vect << 48)) |
+    int_addr = (picreg_t *)xtalk_intr_sfarg_get(xtalk_intr);
+    *int_addr = ((PIC_INT_ADDR_FLD & ((uint64_t)vect << 48)) |
 		     (PIC_INT_ADDR_HOST & addr));
-    } else {
-	bridgereg_t	*int_addr;
-	int_addr = (bridgereg_t *)xtalk_intr_sfarg_get(xtalk_intr);
-	*int_addr = ((BRIDGE_INT_ADDR_HOST & (addr >> 30)) |
-		     (BRIDGE_INT_ADDR_FLD & vect));
-    }
 }
 
 /*ARGSUSED */
@@ -582,8 +673,7 @@
 	    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INTR_ALLOC, pcibr_intr->bi_dev,
 			"pcibr_setpciint: int_addr=0x%x, *int_addr=0x%x, "
 			"pcibr_int_bit=0x%x\n", int_addr,
-			(is_pic(bridge) ? 
-			 *(picreg_t *)int_addr : *(bridgereg_t *)int_addr),
+			 *(picreg_t *)int_addr,
 			pcibr_int_bit));
 	}
 
@@ -699,7 +789,7 @@
 	    xtalk_intr_connect(pcibr_soft->bs_intr[pcibr_int_bit].bsi_xtalk_intr,
 				pcibr_intr_func, (intr_arg_t) intr_wrap,
 			       (xtalk_intr_setfunc_t)pcibr_setpciint,
-			       (void *)pcibr_int_bit);
+			       (void *)(long)pcibr_int_bit);
 	    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INTR_ALLOC, pcibr_intr->bi_dev,
 			"pcibr_intr_disconnect: now-sharing int_bits=0x%x\n",
 			pcibr_int_bit));
@@ -707,7 +797,7 @@
 }
 
 /*ARGSUSED */
-devfs_handle_t
+vertex_hdl_t
 pcibr_intr_cpu_get(pcibr_intr_t pcibr_intr)
 {
     pcibr_soft_t            pcibr_soft = pcibr_intr->bi_soft;
@@ -780,9 +870,6 @@
     bridge->b_wid_int_lower = NEW_b_wid_int_lower;
     bridge->b_int_host_err = vect;
 
-printk("pcibr_setwidint: b_wid_int_upper 0x%x b_wid_int_lower 0x%x b_int_host_err 0x%x\n",
-	NEW_b_wid_int_upper, NEW_b_wid_int_lower, vect);
-
 }
 
 /*
@@ -957,7 +1044,7 @@
 	     * interrupt to avoid a potential deadlock situation.
 	     */
 	    if (wrap->iw_hdlrcnt == 0) {
-		pcibr_force_interrupt(wrap);
+		pcibr_force_interrupt((pcibr_intr_t) wrap);
 	    }
 	}
 
diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_rrb.c	Wed Jun 18 23:42:09 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -27,7 +27,6 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
@@ -41,11 +40,11 @@
 
 void              do_pcibr_rrb_autoalloc(pcibr_soft_t, int, int, int);
 
-int		  pcibr_wrb_flush(devfs_handle_t);
-int               pcibr_rrb_alloc(devfs_handle_t, int *, int *);
-int               pcibr_rrb_check(devfs_handle_t, int *, int *, int *, int *);
-void              pcibr_rrb_flush(devfs_handle_t);
-int		  pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t);
+int		  pcibr_wrb_flush(vertex_hdl_t);
+int               pcibr_rrb_alloc(vertex_hdl_t, int *, int *);
+int               pcibr_rrb_check(vertex_hdl_t, int *, int *, int *, int *);
+void              pcibr_rrb_flush(vertex_hdl_t);
+int		  pcibr_slot_initial_rrb_alloc(vertex_hdl_t,pciio_slot_t);
 
 void		  pcibr_rrb_debug(char *, pcibr_soft_t);
 
@@ -70,17 +69,15 @@
 #define RRB_SIZE (4)			/* sizeof rrb within reg (bits) */
  
 #define RRB_ENABLE_BIT(bridge)		(0x8)  /* [BRIDGE | PIC]_RRB_EN */
-#define NUM_PDEV_BITS(bridge)		(is_pic((bridge)) ? 1 : 2)
-#define NUM_VDEV_BITS(bridge)		(is_pic((bridge)) ? 2 : 1)
-#define NUMBER_VCHANNELS(bridge)	(is_pic((bridge)) ? 4 : 2)
+#define NUM_PDEV_BITS(bridge)		(1)
+#define NUM_VDEV_BITS(bridge)		(2)
+#define NUMBER_VCHANNELS(bridge)	(4)
 #define SLOT_2_PDEV(bridge, slot)	((slot) >> 1)
 #define SLOT_2_RRB_REG(bridge, slot)	((slot) & 0x1)
  
 /* validate that the slot and virtual channel are valid for a given bridge */
 #define VALIDATE_SLOT_n_VCHAN(bridge, s, v) \
-  (is_pic((bridge)) ? \
-    (((((s) != PCIIO_SLOT_NONE) && ((s) <= (pciio_slot_t)3)) && (((v) >= 0) && ((v) <= 3))) ? 1 : 0) : \
-    (((((s) != PCIIO_SLOT_NONE) && ((s) <= (pciio_slot_t)7)) && (((v) >= 0) && ((v) <= 1))) ? 1 : 0))
+    (((((s) != PCIIO_SLOT_NONE) && ((s) <= (pciio_slot_t)3)) && (((v) >= 0) && ((v) <= 3))) ? 1 : 0)
  
 /*  
  * Count how many RRBs are marked valid for the specified PCI slot
@@ -105,16 +102,7 @@
     pdev_bits = SLOT_2_PDEV(bridge, slot);
     rrb_bits = enable_bit | vchan_bits | pdev_bits;
     
-    if ( is_pic(bridge) ) {
-	tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		tmp = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg));
-	} else {
-		tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-	}
-    }
+    tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
 
     for (rrb_index = 0; rrb_index < 8; rrb_index++) {
 	if ((tmp & RRB_MASK) == rrb_bits)
@@ -144,16 +132,7 @@
     
     enable_bit = RRB_ENABLE_BIT(bridge);
 
-    if ( is_pic(bridge) ) {
-	tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		tmp = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg));
-	} else {
-		tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-	}
-    }
+    tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
 
     for (rrb_index = 0; rrb_index < 8; rrb_index++) {
 	if ((tmp & enable_bit) != enable_bit)
@@ -192,17 +171,8 @@
     pdev_bits = SLOT_2_PDEV(bridge, slot);
     rrb_bits = enable_bit | vchan_bits | pdev_bits;
 
-    if ( is_pic(bridge) ) {
-	reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		reg = tmp = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg));
-	} else {
-		reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-	}
-    }
-    
+    reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
+
     for (rrb_index = 0; ((rrb_index < 8) && (more > 0)); rrb_index++) {
 	if ((tmp & enable_bit) != enable_bit) {
 	    /* clear the rrb and OR in the new rrb into 'reg' */
@@ -213,16 +183,7 @@
 	tmp = (tmp >> RRB_SIZE);
     }
 
-    if ( is_pic(bridge) ) {
-	bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		BRIDGE_REG_SET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)) = reg;
-	} else {
-		bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
-	}
-    }
+    bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
     return (more ? -1 : 0);
 }
  
@@ -255,17 +216,8 @@
     pdev_bits = SLOT_2_PDEV(bridge, slot);
     rrb_bits = enable_bit | vchan_bits | pdev_bits;
 
-    if ( is_pic(bridge) ) {
-	reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		reg = BRIDGE_REG_GET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg));
-	} else {
-		reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
-	}
-    }
-    
+    reg = tmp = bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg;
+
     for (rrb_index = 0; ((rrb_index < 8) && (less > 0)); rrb_index++) {
 	if ((tmp & RRB_MASK) == rrb_bits) {
 	   /*
@@ -281,16 +233,7 @@
 	tmp = (tmp >> RRB_SIZE);
     }
 
-    if ( is_pic(bridge) ) {
-	bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		BRIDGE_REG_SET32((&bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg)) = reg;
-	} else {
-		bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
-	}
-    }
+    bridge->b_rrb_map[SLOT_2_RRB_REG(bridge, slot)].reg = reg;
 
     /* call do_pcibr_rrb_clear() for all the rrbs we've freed */
     for (rrb_index = 0; rrb_index < 8; rrb_index++) {
@@ -337,50 +280,18 @@
      * this RRB must be disabled.
      */
 
-    if ( is_pic(bridge) ) {
-	/* wait until RRB has no outstanduing XIO packets. */
-	while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) {
-		;				/* XXX- beats on bridge. bad idea? */
-	}
-
-	/* if the RRB has data, drain it. */
-	if (status & BRIDGE_RRB_VALID(rrb)) {
-		bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb);
-
-		/* wait until RRB is no longer valid. */
-		while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) {
-			;				/* XXX- beats on bridge. bad idea? */
-		}
-	}
+    /* wait until RRB has no outstanduing XIO packets. */
+    while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) {
+	;				/* XXX- beats on bridge. bad idea? */
     }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		while ((status = BRIDGE_REG_GET32((&bridge->b_resp_status))) & BRIDGE_RRB_INUSE(rrb)) {
-			;                               /* XXX- beats on bridge. bad idea? */
-		}
-
-		/* if the RRB has data, drain it. */
-		if (status & BRIDGE_RRB_VALID(rrb)) {
-			BRIDGE_REG_SET32((&bridge->b_resp_clear)) = __swab32(BRIDGE_RRB_CLEAR(rrb));
-
-			/* wait until RRB is no longer valid. */
-			while ((status = BRIDGE_REG_GET32((&bridge->b_resp_status))) & BRIDGE_RRB_VALID(rrb)) {
-				;                           /* XXX- beats on bridge. bad idea? */
-			}
-		}
-	} else { /* io_get_sh_swapper(NASID_GET(bridge)) */
-		while ((status = bridge->b_resp_status) & BRIDGE_RRB_INUSE(rrb)) {
-			;                               /* XXX- beats on bridge. bad idea? */
-		}
-
-		/* if the RRB has data, drain it. */
-		if (status & BRIDGE_RRB_VALID(rrb)) {
-			bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb);
-			/* wait until RRB is no longer valid. */
-			while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) {
-				;                           /* XXX- beats on bridge. bad idea? */
-			}
-		}
+
+    /* if the RRB has data, drain it. */
+    if (status & BRIDGE_RRB_VALID(rrb)) {
+	bridge->b_resp_clear = BRIDGE_RRB_CLEAR(rrb);
+
+	/* wait until RRB is no longer valid. */
+	while ((status = bridge->b_resp_status) & BRIDGE_RRB_VALID(rrb)) {
+		;				/* XXX- beats on bridge. bad idea? */
 	}
     }
 }
@@ -399,43 +310,16 @@
     int		 shft = (RRB_SIZE * (rrbn >> 1));
     unsigned long	 ebit = RRB_ENABLE_BIT(bridge) << shft;
 
-    if ( is_pic(bridge) ) {
-	rrbv = *rrbp;
-    }
-    else {
-	if (io_get_sh_swapper(NASID_GET(bridge))) {
-		rrbv = BRIDGE_REG_GET32((&rrbp));
-	} else {
-		rrbv = *rrbp;
-	}
-    }
+    rrbv = *rrbp;
 
     if (rrbv & ebit) {
-    	if ( is_pic(bridge) ) {
-		*rrbp = rrbv & ~ebit;
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge))) {
-			BRIDGE_REG_SET32((&rrbp)) = __swab32((rrbv & ~ebit));
-		} else {
-			*rrbp = rrbv & ~ebit;
-		}
-	}
+	*rrbp = rrbv & ~ebit;
     }
 
     do_pcibr_rrb_clear(bridge, rrbn);
 
     if (rrbv & ebit) {
-	if ( is_pic(bridge) ) {
-		*rrbp = rrbv;
-	}
-	else {
-		if (io_get_sh_swapper(NASID_GET(bridge))) {
-			BRIDGE_REG_SET32((&rrbp)) = __swab32(rrbv);
-		} else {
-			*rrbp = rrbv;
-		}
-	}
+	*rrbp = rrbv;
     }
 }
 
@@ -475,7 +359,7 @@
  * Flush all the rrb's assigned to the specified connection point.
  */
 void
-pcibr_rrb_flush(devfs_handle_t pconn_vhdl)
+pcibr_rrb_flush(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t  pciio_info = pciio_info_get(pconn_vhdl);
     pcibr_soft_t  pcibr_soft = (pcibr_soft_t)pciio_info_mfast_get(pciio_info);
@@ -510,7 +394,7 @@
  * device hanging off the bridge.
  */
 int
-pcibr_wrb_flush(devfs_handle_t pconn_vhdl)
+pcibr_wrb_flush(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
     pciio_slot_t            pciio_slot = PCIBR_INFO_SLOT_GET_INT(pciio_info);
@@ -546,7 +430,7 @@
  * as best we can and return 0.
  */
 int
-pcibr_rrb_alloc(devfs_handle_t pconn_vhdl,
+pcibr_rrb_alloc(vertex_hdl_t pconn_vhdl,
 		int *count_vchan0,
 		int *count_vchan1)
 {
@@ -753,7 +637,7 @@
  */
 
 int
-pcibr_rrb_check(devfs_handle_t pconn_vhdl,
+pcibr_rrb_check(vertex_hdl_t pconn_vhdl,
 		int *count_vchan0,
 		int *count_vchan1,
 		int *count_reserved,
@@ -802,7 +686,7 @@
  */
 
 int
-pcibr_slot_initial_rrb_alloc(devfs_handle_t pcibr_vhdl,
+pcibr_slot_initial_rrb_alloc(vertex_hdl_t pcibr_vhdl,
 			     pciio_slot_t slot)
 {
     pcibr_soft_t	 pcibr_soft;
@@ -889,7 +773,7 @@
  */
 
 int
-pcibr_initial_rrb(devfs_handle_t pcibr_vhdl,
+pcibr_initial_rrb(vertex_hdl_t pcibr_vhdl,
 			     pciio_slot_t first, pciio_slot_t last)
 {
     pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
diff -Nru a/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c b/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c
--- a/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/sn/io/sn2/pcibr/pcibr_slot.c	Wed Jun 18 23:42:07 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -28,7 +28,6 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 #include <asm/sn/ate_utils.h>
@@ -41,42 +40,41 @@
 #endif
 
 
-extern pcibr_info_t     pcibr_info_get(devfs_handle_t);
-extern int              pcibr_widget_to_bus(devfs_handle_t pcibr_vhdl);
+extern pcibr_info_t     pcibr_info_get(vertex_hdl_t);
+extern int              pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl);
 extern pcibr_info_t     pcibr_device_info_new(pcibr_soft_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
-extern int		pcibr_slot_initial_rrb_alloc(devfs_handle_t,pciio_slot_t);
+extern int		pcibr_slot_initial_rrb_alloc(vertex_hdl_t,pciio_slot_t);
 extern int		pcibr_pcix_rbars_calc(pcibr_soft_t);
 
-int pcibr_slot_info_init(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);
-int pcibr_slot_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);
-int pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);
+int pcibr_slot_info_init(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot);
+int pcibr_slot_info_free(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot);
+int pcibr_slot_addr_space_init(vertex_hdl_t pcibr_vhdl,  pciio_slot_t slot);
 int pcibr_slot_pcix_rbar_init(pcibr_soft_t pcibr_soft,  pciio_slot_t slot);
-int pcibr_slot_device_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);
-int pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl,  pciio_slot_t slot);
-int pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl,
+int pcibr_slot_device_init(vertex_hdl_t pcibr_vhdl,  pciio_slot_t slot);
+int pcibr_slot_guest_info_init(vertex_hdl_t pcibr_vhdl,  pciio_slot_t slot);
+int pcibr_slot_call_device_attach(vertex_hdl_t pcibr_vhdl,
 		 pciio_slot_t slot, int drv_flags);
-int pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl,
+int pcibr_slot_call_device_detach(vertex_hdl_t pcibr_vhdl,
 		 pciio_slot_t slot, int drv_flags);
-int pcibr_slot_detach(devfs_handle_t pcibr_vhdl, pciio_slot_t slot,
+int pcibr_slot_detach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot,
                  int drv_flags, char *l1_msg, int *sub_errorp);
-int pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl, pciio_slot_t slot);
 static int pcibr_probe_slot(bridge_t *, cfg_p, unsigned int *);
-void pcibr_device_info_free(devfs_handle_t, pciio_slot_t);
+void pcibr_device_info_free(vertex_hdl_t, pciio_slot_t);
 iopaddr_t pcibr_bus_addr_alloc(pcibr_soft_t, pciio_win_info_t, 
                                pciio_space_t, int, int, int);
 void pciibr_bus_addr_free(pcibr_soft_t, pciio_win_info_t);
 cfg_p pcibr_find_capability(cfg_p, unsigned);
-extern uint64_t  do_pcibr_config_get(int, cfg_p, unsigned, unsigned);
-void do_pcibr_config_set(int, cfg_p, unsigned, unsigned, uint64_t); 
+extern uint64_t  do_pcibr_config_get(cfg_p, unsigned, unsigned);
+void do_pcibr_config_set(cfg_p, unsigned, unsigned, uint64_t); 
 
-int pcibr_slot_attach(devfs_handle_t pcibr_vhdl, pciio_slot_t slot,
+int pcibr_slot_attach(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot,
                 int drv_flags, char *l1_msg, int *sub_errorp);
 
 int pcibr_slot_info_return(pcibr_soft_t pcibr_soft, pciio_slot_t slot,
                  pcibr_slot_info_resp_t respp);
 
-extern devfs_handle_t baseio_pci_vhdl;
-int scsi_ctlr_nums_add(devfs_handle_t, devfs_handle_t);
+extern vertex_hdl_t baseio_pci_vhdl;
+int scsi_ctlr_nums_add(vertex_hdl_t, vertex_hdl_t);
 
 
 /* For now .... */
@@ -111,7 +109,7 @@
 #ifdef PIC_LATER
 
 int
-pcibr_slot_startup(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp)
+pcibr_slot_startup(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp)
 {
     pcibr_soft_t                   pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     pciio_slot_t                   slot;
@@ -127,11 +125,6 @@
     /* req_slot is the 'external' slot number, convert for internal use */
     slot = PCIBR_SLOT_TO_DEVICE(pcibr_soft, reqp->req_slot);
 
-    /* Do not allow start-up of a slot in a shoehorn */
-    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {
-       return(PCI_SLOT_IN_SHOEHORN);
-    }
- 
     /* Check for the valid slot */
     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
         return(PCI_NOT_A_SLOT);
@@ -170,7 +163,7 @@
  *	Software shut-down the PCI slot
  */
 int
-pcibr_slot_shutdown(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp)
+pcibr_slot_shutdown(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp)
 {
     pcibr_soft_t                   pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     bridge_t                      *bridge;
@@ -194,11 +187,6 @@
     if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
         return(PCI_NOT_A_SLOT);
 
-    /* Do not allow shut-down of a slot in a shoehorn */
-    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {
-       return(PCI_SLOT_IN_SHOEHORN);
-    }
-
 #ifdef PIC_LATER
     /* Acquire update access to the bus */
     mrlock(pcibr_soft->bs_bus_lock, MR_UPDATE, PZERO);
@@ -284,7 +272,6 @@
 {
     pcibr_info_t                 pcibr_info = pcibr_infoh[func];
     int                          win;
-    boolean_t is_sys_critical_vertex(devfs_handle_t);
 
     funcp->resp_f_status = 0;
 
@@ -296,9 +283,6 @@
 #if defined(SUPPORT_PRINTING_V_FORMAT)
     sprintf(funcp->resp_f_slot_name, "%v", pcibr_info->f_vertex);
 #endif
-    if(is_sys_critical_vertex(pcibr_info->f_vertex)) {
-        funcp->resp_f_status |= FUNC_IS_SYS_CRITICAL;
-    }
 
     funcp->resp_f_bus = pcibr_info->f_bus;
     funcp->resp_f_slot = PCIBR_INFO_SLOT_GET_EXT(pcibr_info);
@@ -345,7 +329,6 @@
     reg_p                        b_respp;
     pcibr_slot_info_resp_t       slotp;
     pcibr_slot_func_info_resp_t  funcp;
-    boolean_t is_sys_critical_vertex(devfs_handle_t);
     extern void snia_kmem_free(void *, int);
 
     slotp = snia_kmem_zalloc(sizeof(*slotp), 0);
@@ -368,11 +351,6 @@
     slotp->resp_slot_status = pss->slot_status;
 
     slotp->resp_l1_bus_num = pcibr_widget_to_bus(pcibr_soft->bs_vhdl);
-
-    if (is_sys_critical_vertex(pss->slot_conn)) {
-        slotp->resp_slot_status |= SLOT_IS_SYS_CRITICAL;
-    }
-
     slotp->resp_bss_ninfo = pss->bss_ninfo;
 
     for (func = 0; func < pss->bss_ninfo; func++) {
@@ -455,7 +433,7 @@
  *		External SSRAM workaround info
  */
 int
-pcibr_slot_query(devfs_handle_t pcibr_vhdl, pcibr_slot_req_t reqp)
+pcibr_slot_query(vertex_hdl_t pcibr_vhdl, pcibr_slot_req_t reqp)
 {
     pcibr_soft_t            pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     pciio_slot_t            slot;
@@ -481,11 +459,6 @@
         return(PCI_NOT_A_SLOT);
     }
 
-    /* Do not allow a query of a slot in a shoehorn */
-    if(nic_vertex_info_match(pcibr_soft->bs_conn, XTALK_PCI_PART_NUM)) {
-       return(PCI_SLOT_IN_SHOEHORN);
-    }
-
     /* Return information for the requested PCI slot */
     if (slot != PCIIO_SLOT_NONE) {
         if (size < sizeof(*respp)) {
@@ -534,88 +507,6 @@
     return(error);
 }
 
-#if 0
-/*
- * pcibr_slot_reset
- *	Reset the PCI device in the particular slot.
- *
- *      The Xbridge does not comply with the PCI Specification
- *      when resetting an indiviaudl slot.  An individual slot is
- *      is reset by toggling the slot's bit in the Xbridge Control
- *      Register.  The Xbridge will assert the target slot's 
- *      (non-bussed) RST signal, but does not assert the (bussed) 
- *      REQ64 signal as required by the specification.   As
- *      designed, the Xbridge cannot assert the REQ64 signal
- *      becuase it may interfere with a bus transaction in progress.
- *      The practical effects of this Xbridge implementation is
- *      device dependent;  it probably will not adversely effect
- *      32-bit cards, but may disable 64-bit data transfers by those
- *      cards that normally support 64-bit data transfers.  
- *
- *      The Xbridge will assert REQ64 when all four slots are reset
- *      by simultaneously toggling all four slot reset bits in the
- *      Xbridge Control Register.  This is basically a PCI bus reset
- *      and asserting the (bussed) REQ64 signal will not interfere
- *      with any bus transactions in progress.
- *
- *      The Xbridge (and the SN0 Bridge) support resetting only
- *      four PCI bus slots via the (X)bridge Control Register.
- *
- *      To reset an individual slot for the PCI Hot-Plug feature
- *      use the L1 console commands to power-down and then 
- *      power-up the slot, or use the kernel infrastructure
- *      functions to power-down/up the slot when they are
- *      implemented for SN1.
- */
-int
-pcibr_slot_reset(devfs_handle_t pcibr_vhdl, pciio_slot_t slot)
-{
-	pcibr_soft_t		 pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-	bridge_t		*bridge;
-	bridgereg_t		 ctrlreg,tmp;
-	volatile bridgereg_t	*wrb_flush;
-
-	if (!pcibr_soft)
-		return(EINVAL);
-
-	if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
-		return(EINVAL);
-
-	/* Enable the DMA operations from this device of the xtalk widget
-	 * (PCI host bridge in this case).
-	 */
-	xtalk_widgetdev_enable(pcibr_soft->bs_conn, slot);
-
-	/* Set the reset slot bit in the bridge's wid control register
-	 * to reset the PCI slot 
-	 */
-	bridge = pcibr_soft->bs_base;
-
-	/* Read the bridge widget control and clear out the reset pin
-	 * bit for the corresponding slot. 
-	 */
-	tmp = ctrlreg = bridge->b_wid_control;
-
-	tmp &= ~BRIDGE_CTRL_RST_PIN(slot); 
-
-	bridge->b_wid_control = tmp;
-	tmp = bridge->b_wid_control;
-
-	/* Restore the old control register back.
-	 * NOTE : PCI card gets reset when the reset pin bit
-	 * changes from 0 (set above) to 1 (going to be set now).
-	 */
-
-	bridge->b_wid_control = ctrlreg;
-
-	/* Flush the write buffers if any !! */
-	wrb_flush = &(bridge->b_wr_req_buf[slot].reg);
-	while (*wrb_flush);
-
-	return(0);
-}
-#endif
-
 #define PROBE_LOCK 0	/* FIXME: we're attempting to lock around accesses
 			 * to b_int_enable.   This hangs pcibr_probe_slot()
 			 */
@@ -627,7 +518,7 @@
  * 	information associated with this particular PCI device.
  */
 int
-pcibr_slot_info_init(devfs_handle_t 	pcibr_vhdl,
+pcibr_slot_info_init(vertex_hdl_t 	pcibr_vhdl,
 		     pciio_slot_t 	slot)
 {
     pcibr_soft_t	    pcibr_soft;
@@ -650,7 +541,7 @@
     int			    nfunc;
     pciio_function_t	    rfunc;
     int			    func;
-    devfs_handle_t	    conn_vhdl;
+    vertex_hdl_t	    conn_vhdl;
     pcibr_soft_slot_t	    slotp;
     
     /* Get the basic software information required to proceed */
@@ -669,10 +560,6 @@
 	return(0);    
     }
 
-    /* Check for a slot with any system critical functions */
-    if (pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
-        return(EPERM);
-
     /* Try to read the device-id/vendor-id from the config space */
     cfgw = pcibr_slot_config_addr(bridge, slot, 0);
 
@@ -701,7 +588,7 @@
     if (vendor == 0xFFFF) 
 	return(ENODEV);			
     
-    htype = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_HEADER_TYPE, 1);
+    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
     nfunc = 1;
     rfunc = PCIIO_FUNC_NONE;
     pfail = 0;
@@ -750,7 +637,7 @@
 	    cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0);
 	    
 	    device = 0xFFFF & (idword >> 16);
-	    htype = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_HEADER_TYPE, 1);
+	    htype = do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1);
 	    rfunc = func;
 	}
 	htype &= 0x7f;
@@ -810,16 +697,10 @@
 	 * Timer for these devices
 	 */
 
-	lt_time = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_LATENCY_TIMER, 1);
+	lt_time = do_pcibr_config_get(cfgw, PCI_CFG_LATENCY_TIMER, 1);
 
 	if ((lt_time == 0) && !(bridge->b_device[slot].reg & BRIDGE_DEV_RT) &&
-	    !((vendor == IOC3_VENDOR_ID_NUM) && 
-	      (
-#ifdef PIC_LATER
-	       (device == IOC3_DEVICE_ID_NUM) ||
-	       (device == LINC_DEVICE_ID_NUM) ||
-#endif
-	       (device == 0x5 /* RAD_DEV */)))) {
+				       (device == 0x5 /* RAD_DEV */)) {
 	     unsigned	min_gnt;
 	     unsigned	min_gnt_mult;
 	    
@@ -827,7 +708,7 @@
 	     * needs in increments of 250ns.  But latency timer is in
 	     * PCI clock cycles, so a conversion is needed.
 	     */
-	    min_gnt = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_MIN_GNT, 1);
+	    min_gnt = do_pcibr_config_get(cfgw, PCI_MIN_GNT, 1);
 
 	    if (IS_133MHZ(pcibr_soft))
 		min_gnt_mult = 32;	/* 250ns @ 133MHz in clocks */
@@ -843,7 +724,7 @@
 	    else
 		lt_time = 4 * min_gnt_mult;	  /* 1 micro second */
 
-	    do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_LATENCY_TIMER, 1, lt_time);
+	    do_pcibr_config_set(cfgw, PCI_CFG_LATENCY_TIMER, 1, lt_time);
 
 	    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_CONFIG, pcibr_vhdl,
                     "pcibr_slot_info_init: set Latency Timer for slot=%d, "
@@ -851,12 +732,27 @@
 		    PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), func, lt_time));
 	}
 
-	/* Get the PCI-X capability if running in PCI-X mode.  If the func
-	 * doesn't have a pcix capability, allocate a PCIIO_VENDOR_ID_NONE
-	 * pcibr_info struct so the device driver for that function is not
-	 * called.
+
+	/* In our architecture the setting of the cacheline size isn't 
+	 * beneficial for cards in PCI mode, but in PCI-X mode devices
+	 * can optionally use the cacheline size value for internal 
+	 * device optimizations    (See 7.1.5 of the PCI-X v1.0 spec).
+	 * NOTE: cachline size is in doubleword increments
 	 */
 	if (IS_PCIX(pcibr_soft)) {
+	    if (!do_pcibr_config_get(cfgw, PCI_CFG_CACHE_LINE, 1)) {
+		do_pcibr_config_set(cfgw, PCI_CFG_CACHE_LINE, 1, 0x20);
+		PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_CONFIG, pcibr_vhdl,
+			"pcibr_slot_info_init: set CacheLine for slot=%d, "
+			"func=%d, to 0x20\n",
+			PCIBR_DEVICE_TO_SLOT(pcibr_soft, slot), func));
+	    }
+
+	    /* Get the PCI-X capability if running in PCI-X mode.  If the func
+	     * doesnt have a pcix capability, allocate a PCIIO_VENDOR_ID_NONE
+	     * pcibr_info struct so the device driver for that function is not
+	     * called.
+	     */
 	    if (!(pcix_cap = pcibr_find_capability(cfgw, PCI_CAP_PCIX))) {
 		printk(KERN_WARNING
 #if defined(SUPPORT_PRINTING_V_FORMAT)
@@ -898,7 +794,7 @@
 	if (func == 0)
 	    slotp->slot_conn = conn_vhdl;
 
-	cmd_reg = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4);
+	cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4);
 	
 	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
 
@@ -949,7 +845,7 @@
 	     * this could be pushed up into pciio, when we
 	     * start supporting more PCI providers.
 	     */
-	    base = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4);
+	    base = do_pcibr_config_get(wptr, (win * 4), 4);
 
 	    if (base & PCI_BA_IO_SPACE) {
 		/* BASE is in I/O space. */
@@ -975,7 +871,7 @@
 		} else if (base & 0xC0000000) {
 		    base = 0;	/* outside permissable range */
 		} else if ((code == PCI_BA_MEM_64BIT) &&
-			   (do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, ((win + 1)*4), 4) != 0)) {
+			   (do_pcibr_config_get(wptr, ((win + 1)*4), 4) != 0)) {
 		    base = 0;	/* outside permissable range */
 		}
 	    }
@@ -983,8 +879,8 @@
 	    if (base != 0) {	/* estimate size */
 		size = base & -base;
 	    } else {		/* calculate size */
-		do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4, ~0);    /* write 1's */
-		size = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4); /* read back */
+		do_pcibr_config_set(wptr, (win * 4), 4, ~0);    /* write 1's */
+		size = do_pcibr_config_get(wptr, (win * 4), 4); /* read back */
 		size &= mask;	/* keep addr */
 		size &= -size;	/* keep lsbit */
 		if (size == 0)
@@ -995,45 +891,9 @@
 	    pcibr_info->f_window[win].w_base = base;
 	    pcibr_info->f_window[win].w_size = size;
 
-#if defined(IOC3_VENDOR_ID_NUM) && defined(IOC3_DEVICE_ID_NUM)
-	    /*
-	     * IOC3 BASE_ADDR* BUG WORKAROUND
-	     *
-	     
-	     * If we write to BASE1 on the IOC3, the
-	     * data in BASE0 is replaced. The
-	     * original workaround was to remember
-	     * the value of BASE0 and restore it
-	     * when we ran off the end of the BASE
-	     * registers; however, a later
-	     * workaround was added (I think it was
-	     * rev 1.44) to avoid setting up
-	     * anything but BASE0, with the comment
-	     * that writing all ones to BASE1 set
-	     * the enable-parity-error test feature
-	     * in IOC3's SCR bit 14.
-	     *
-	     * So, unless we defer doing any PCI
-	     * space allocation until drivers
-	     * attach, and set up a way for drivers
-	     * (the IOC3 in paricular) to tell us
-	     * generically to keep our hands off
-	     * BASE registers, we gotta "know" about
-	     * the IOC3 here.
-	     *
-	     * Too bad the PCI folks didn't reserve the
-	     * all-zero value for 'no BASE here' (it is a
-	     * valid code for an uninitialized BASE in
-	     * 32-bit PCI memory space).
-	     */
-	    
-	    if ((vendor == IOC3_VENDOR_ID_NUM) &&
-		(device == IOC3_DEVICE_ID_NUM))
-		break;
-#endif
 	    if (code == PCI_BA_MEM_64BIT) {
 		win++;		/* skip upper half */
-		do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4, 0);  /* must be zero */
+		do_pcibr_config_set(wptr, (win * 4), 4, 0);  /* must be zero */
 	    }
 	}				/* next win */
     }				/* next func */
@@ -1056,7 +916,7 @@
     int			defend_against_circular_linkedlist = 0;
 
     /* Check to see if there is a capabilities pointer in the cfg header */
-    if (!(do_pcibr_config_get(1, cfgw, PCI_CFG_STATUS, 2) & PCI_STAT_CAP_LIST)) {
+    if (!(do_pcibr_config_get(cfgw, PCI_CFG_STATUS, 2) & PCI_STAT_CAP_LIST)) {
 	return (NULL);
     }
 
@@ -1067,14 +927,14 @@
      * significant bits of the next pointer must be ignored,  so we mask
      * with 0xfc).
      */
-    cap_nxt = (do_pcibr_config_get(1, cfgw, PCI_CAPABILITIES_PTR, 1) & 0xfc);
+    cap_nxt = (do_pcibr_config_get(cfgw, PCI_CAPABILITIES_PTR, 1) & 0xfc);
 
     while (cap_nxt && (defend_against_circular_linkedlist <= 48)) {
-	cap_id = do_pcibr_config_get(1, cfgw, cap_nxt, 1);
+	cap_id = do_pcibr_config_get(cfgw, cap_nxt, 1);
 	if (cap_id == capability) {
 	    return ((cfg_p)((char *)cfgw + cap_nxt));
 	}
-	cap_nxt = (do_pcibr_config_get(1, cfgw, cap_nxt+1, 1) & 0xfc);
+	cap_nxt = (do_pcibr_config_get(cfgw, cap_nxt+1, 1) & 0xfc);
 	defend_against_circular_linkedlist++;
     }
 
@@ -1087,7 +947,7 @@
  * 	with a particular PCI device.
  */
 int
-pcibr_slot_info_free(devfs_handle_t pcibr_vhdl,
+pcibr_slot_info_free(vertex_hdl_t pcibr_vhdl,
                      pciio_slot_t slot)
 {
     pcibr_soft_t	pcibr_soft;
@@ -1223,20 +1083,21 @@
  * 	the base registers in the card.
  */
 int
-pcibr_slot_addr_space_init(devfs_handle_t pcibr_vhdl,
+pcibr_slot_addr_space_init(vertex_hdl_t pcibr_vhdl,
 			   pciio_slot_t	slot)
 {
     pcibr_soft_t	 pcibr_soft;
     pcibr_info_h	 pcibr_infoh;
     pcibr_info_t	 pcibr_info;
     bridge_t		*bridge;
-    size_t               align_slot;
     iopaddr_t            mask;
     int		       	 nbars;
     int		       	 nfunc;
     int			 func;
     int			 win;
     int                  rc = 0;
+    int			 align;
+    int			 align_slot;
 
     pcibr_soft = pcibr_soft_get(pcibr_vhdl);
 
@@ -1275,7 +1136,8 @@
      * the entire "lo" area is only a
      * megabyte, total ...
      */
-    align_slot = (slot < 2) ? 0x200000 : 0x100000;
+    align_slot = 0x100000;
+    align = align_slot;
 
     for (func = 0; func < nfunc; ++func) {
 	cfg_p                   cfgw;
@@ -1300,7 +1162,7 @@
         cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0);
 	wptr = cfgw + PCI_CFG_BASE_ADDR_0 / 4;
 
-	if ((do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_HEADER_TYPE, 1) & 0x7f) != 0)
+	if ((do_pcibr_config_get(cfgw, PCI_CFG_HEADER_TYPE, 1) & 0x7f) != 0)
 	    nbars = 2;
 	else
 	    nbars = PCI_CFG_BASE_ADDRS;
@@ -1333,23 +1195,24 @@
 		continue;		/* already allocated */
 	    }
 
+	    align = (win) ? size : align_slot; 
+
+	    if (align < _PAGESZ)
+		align = _PAGESZ;        /* ie. 0x00004000 */
+ 
 	    switch (space) {
 	    case PCIIO_SPACE_IO:
                 base = pcibr_bus_addr_alloc(pcibr_soft,
                                             &pcibr_info->f_window[win],
                                             PCIIO_SPACE_IO,
-                                            0, size, align_slot);
+                                            0, size, align);
                 if (!base)
                     rc = ENOSPC;
 		break;
 		
 	    case PCIIO_SPACE_MEM:
-		if ((do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4) &
+		if ((do_pcibr_config_get(wptr, (win * 4), 4) &
 		     PCI_BA_MEM_LOCATION) == PCI_BA_MEM_1MEG) {
-                    int align = size;           /* ie. 0x00001000 */
-                    
-                    if (align < _PAGESZ)
-                        align = _PAGESZ;        /* ie. 0x00004000 */
  
 		    /* allocate from 20-bit PCI space */
                     base = pcibr_bus_addr_alloc(pcibr_soft,
@@ -1363,7 +1226,7 @@
                     base = pcibr_bus_addr_alloc(pcibr_soft,
                                                 &pcibr_info->f_window[win],
                                                 PCIIO_SPACE_MEM32,
-                                                0, size, align_slot);
+                                                0, size, align);
 		    if (!base) 
 			rc = ENOSPC;
 		}
@@ -1377,7 +1240,7 @@
 			    PCIBR_DEVICE_TO_SLOT(pcibr_soft,slot), win, space));
 	    }
 	    pcibr_info->f_window[win].w_base = base;
-	    do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, (win * 4), 4, base);
+	    do_pcibr_config_set(wptr, (win * 4), 4, base);
 
 #if defined(SUPPORT_PRINTING_R_FORMAT)
 	    if (pcibr_debug_mask & PCIBR_DEBUG_BAR) {
@@ -1405,26 +1268,22 @@
 
 	/*
 	 * Allocate space for the EXPANSION ROM
-	 * NOTE: DO NOT DO THIS ON AN IOC3,
-	 * as it blows the system away.
 	 */
 	base = size = 0;
-	if ((pcibr_soft->bs_slot[slot].bss_vendor_id != IOC3_VENDOR_ID_NUM) ||
-	    (pcibr_soft->bs_slot[slot].bss_device_id != IOC3_DEVICE_ID_NUM)) {
-
+	{
 	    wptr = cfgw + PCI_EXPANSION_ROM / 4;
-	    do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, 0, 4, 0xFFFFF000);
-	    mask = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), wptr, 0, 4);
+	    do_pcibr_config_set(wptr, 0, 4, 0xFFFFF000);
+	    mask = do_pcibr_config_get(wptr, 0, 4);
 	    if (mask & 0xFFFFF000) {
 		size = mask & -mask;
                 base = pcibr_bus_addr_alloc(pcibr_soft,
                                             &pcibr_info->f_rwindow,
                                             PCIIO_SPACE_MEM32, 
-                                            0, size, align_slot);
+                                            0, size, align);
 		if (!base)
 		    rc = ENOSPC;
 		else {
-		    do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), wptr, 0, 4, base);
+		    do_pcibr_config_set(wptr, 0, 4, base);
 		    PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_BAR, pcibr_vhdl,
 				"pcibr_slot_addr_space_init: slot=%d, func=%d, "
 				"ROM in [0x%X..0x%X], allocated by pcibr\n",
@@ -1435,7 +1294,7 @@
 	}
 	pcibr_info->f_rbase = base;
 	pcibr_info->f_rsize = size;
-	
+
 	/*
 	 * if necessary, update the board's
 	 * command register to enable decoding
@@ -1463,7 +1322,7 @@
 
 	pci_cfg_cmd_reg_add |= PCI_CMD_BUS_MASTER;
 
-	pci_cfg_cmd_reg = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4);
+	pci_cfg_cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4);
 
 #if PCI_FBBE	/* XXX- check here to see if dev can do fast-back-to-back */
 	if (!((pci_cfg_cmd_reg >> 16) & PCI_STAT_F_BK_BK_CAP))
@@ -1471,7 +1330,7 @@
 #endif
 	pci_cfg_cmd_reg &= 0xFFFF;
 	if (pci_cfg_cmd_reg_add & ~pci_cfg_cmd_reg)
-	    do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4, 
+	    do_pcibr_config_set(cfgw, PCI_CFG_COMMAND, 4, 
 				pci_cfg_cmd_reg | pci_cfg_cmd_reg_add);
     }				/* next func */
     return(rc);
@@ -1483,7 +1342,7 @@
  */
 
 int
-pcibr_slot_device_init(devfs_handle_t pcibr_vhdl,
+pcibr_slot_device_init(vertex_hdl_t pcibr_vhdl,
 		       pciio_slot_t slot)
 {
     pcibr_soft_t	 pcibr_soft;
@@ -1525,8 +1384,6 @@
     PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_DEVREG, pcibr_vhdl,
 		"pcibr_slot_device_init: Device(%d): %R\n",
 		slot, devreg, device_bits));
-#else
-    printk("pcibr_slot_device_init: Device(%d) 0x%x\n", slot, devreg);
 #endif
     return(0);
 }
@@ -1536,7 +1393,7 @@
  *	Setup the host/guest relations for a PCI slot.
  */
 int
-pcibr_slot_guest_info_init(devfs_handle_t pcibr_vhdl,
+pcibr_slot_guest_info_init(vertex_hdl_t pcibr_vhdl,
 			   pciio_slot_t	slot)
 {
     pcibr_soft_t	pcibr_soft;
@@ -1605,18 +1462,17 @@
  * 	card in this slot.
  */
 int
-pcibr_slot_call_device_attach(devfs_handle_t pcibr_vhdl,
+pcibr_slot_call_device_attach(vertex_hdl_t pcibr_vhdl,
 			      pciio_slot_t slot,
 			      int          drv_flags)
 {
     pcibr_soft_t	pcibr_soft;
     pcibr_info_h	pcibr_infoh;
     pcibr_info_t	pcibr_info;
-    async_attach_t	aa = NULL;
     int			func;
-    devfs_handle_t	xconn_vhdl, conn_vhdl;
+    vertex_hdl_t	xconn_vhdl, conn_vhdl;
 #ifdef PIC_LATER
-    devfs_handle_t	scsi_vhdl;
+    vertex_hdl_t	scsi_vhdl;
 #endif
     int			nfunc;
     int                 error_func;
@@ -1639,7 +1495,6 @@
     }
     
     xconn_vhdl = pcibr_soft->bs_conn;
-    aa = async_attach_get_info(xconn_vhdl);
 
     nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
     pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
@@ -1656,13 +1511,6 @@
 
 	conn_vhdl = pcibr_info->f_vertex;
 
-#ifdef LATER
-	/*
-	 * Activate if and when we support cdl.
-	 */
-	if (aa)
-	    async_attach_add_info(conn_vhdl, aa);
-#endif	/* LATER */
 
 	error_func = pciio_device_attach(conn_vhdl, drv_flags);
 
@@ -1728,7 +1576,7 @@
  * 	card in this slot.
  */
 int
-pcibr_slot_call_device_detach(devfs_handle_t pcibr_vhdl,
+pcibr_slot_call_device_detach(vertex_hdl_t pcibr_vhdl,
 			      pciio_slot_t slot,
 			      int          drv_flags)
 {
@@ -1736,7 +1584,7 @@
     pcibr_info_h	pcibr_infoh;
     pcibr_info_t	pcibr_info;
     int			func;
-    devfs_handle_t	conn_vhdl = GRAPH_VERTEX_NONE;
+    vertex_hdl_t	conn_vhdl = GRAPH_VERTEX_NONE;
     int			nfunc;
     int                 error_func;
     int                 error_slot = 0;
@@ -1811,7 +1659,7 @@
  * 	PCI card on the bus.
  */
 int
-pcibr_slot_attach(devfs_handle_t pcibr_vhdl,
+pcibr_slot_attach(vertex_hdl_t pcibr_vhdl,
 		  pciio_slot_t slot,
 		  int          drv_flags,
 		  char        *l1_msg,
@@ -1850,7 +1698,7 @@
  *	slot-specific freeing that needs to be done.
  */
 int
-pcibr_slot_detach(devfs_handle_t pcibr_vhdl,
+pcibr_slot_detach(vertex_hdl_t pcibr_vhdl,
 		  pciio_slot_t slot,
 		  int          drv_flags,
 		  char        *l1_msg,
@@ -1859,10 +1707,6 @@
     pcibr_soft_t  pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     int		  error;
     
-    /* Make sure that we do not detach a system critical function vertex */
-    if(pcibr_is_slot_sys_critical(pcibr_vhdl, slot))
-        return(PCI_IS_SYS_CRITICAL);
-
     /* Call the device detach function */
     error = (pcibr_slot_call_device_detach(pcibr_vhdl, slot, drv_flags));
     if (error) {
@@ -1892,61 +1736,6 @@
 }
 
 /*
- * pcibr_is_slot_sys_critical
- *      Check slot for any functions that are system critical.
- *      Return 1 if any are system critical or 0 otherwise.
- *
- *      This function will always return 0 when called by 
- *      pcibr_attach() because the system critical vertices 
- *      have not yet been set in the hwgraph.
- */
-int
-pcibr_is_slot_sys_critical(devfs_handle_t pcibr_vhdl,
-                      pciio_slot_t slot)
-{
-    pcibr_soft_t        pcibr_soft;
-    pcibr_info_h        pcibr_infoh;
-    pcibr_info_t        pcibr_info;
-    devfs_handle_t        conn_vhdl = GRAPH_VERTEX_NONE;
-    int                 nfunc;
-    int                 func;
-    boolean_t is_sys_critical_vertex(devfs_handle_t);
-
-    pcibr_soft = pcibr_soft_get(pcibr_vhdl);
-    if (!pcibr_soft)
-	return(EINVAL);
-
-    if (!PCIBR_VALID_SLOT(pcibr_soft, slot))
-	return(EINVAL);
-
-    nfunc = pcibr_soft->bs_slot[slot].bss_ninfo;
-    pcibr_infoh = pcibr_soft->bs_slot[slot].bss_infos;
-
-    for (func = 0; func < nfunc; ++func) {
-
-        pcibr_info = pcibr_infoh[func];
-        if (!pcibr_info)
-            continue;
-
-        if (pcibr_info->f_vendor == PCIIO_VENDOR_ID_NONE)
-            continue;
-
-        conn_vhdl = pcibr_info->f_vertex;
-        if (is_sys_critical_vertex(conn_vhdl)) { 
-#if defined(SUPPORT_PRINTING_V_FORMAT)
-            printk(KERN_WARNING  "%v is a system critical device vertex\n", conn_vhdl);
-#else
-            printk(KERN_WARNING  "%p is a system critical device vertex\n", (void *)conn_vhdl);
-#endif
-            return(1); 
-        }
-
-    }
-
-    return(0);
-}
-
-/*
  * pcibr_probe_slot_pic: read a config space word
  * while trapping any errors; return zero if
  * all went OK, or nonzero if there was an error.
@@ -1984,57 +1773,6 @@
 }
 
 /*
- * pcibr_probe_slot_non_pic: read a config space word
- * while trapping any errors; return zero if
- * all went OK, or nonzero if there was an error.
- * The value read, if any, is passed back
- * through the valp parameter.
- */
-static int
-pcibr_probe_slot_non_pic(bridge_t *bridge,
-                 cfg_p cfg,
-                 unsigned *valp)
-{
-	int                     rv;
-	bridgereg_t             b_old_enable = (bridgereg_t)0, b_new_enable = (bridgereg_t)0;
-	extern int              badaddr_val(volatile void *, int, volatile void *);
-
-        b_old_enable = bridge->b_int_enable;
-        b_new_enable = b_old_enable & ~BRIDGE_IMR_PCI_MST_TIMEOUT;
-        bridge->b_int_enable = b_new_enable;
-
-	/*
-	 * The xbridge doesn't clear b_err_int_view unless
-	 * multi-err is cleared...
-	 */
-	if (is_xbridge(bridge)) {
-	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT)
-		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
-	}
-
-        if (bridge->b_int_status & BRIDGE_IRR_PCI_GRP) {
-	    bridge->b_int_rst_stat = BRIDGE_IRR_PCI_GRP_CLR;
-	    (void) bridge->b_wid_tflush;	/* flushbus */
-        }
-	rv = badaddr_val((void *) (((uint64_t)cfg) ^ 4), 4, valp);
-	/*
-	 * The xbridge doesn't set master timeout in b_int_status
-	 * here.  Fortunately it's in error_interrupt_view.
-	 */
-	if (is_xbridge(bridge)) {
-	    if (bridge->b_err_int_view & BRIDGE_ISR_PCI_MST_TIMEOUT) {
-		bridge->b_int_rst_stat = BRIDGE_IRR_MULTI_CLR;
-		rv = 1;		/* unoccupied slot */
-	    }
-	}
-        bridge->b_int_enable = b_old_enable;
-	bridge->b_wid_tflush;		/* wait until Bridge PIO complete */
-
-    	return(rv);
-}
-
-
-/*
  * pcibr_probe_slot: read a config space word
  * while trapping any errors; return zero if
  * all went OK, or nonzero if there was an error.
@@ -2046,15 +1784,12 @@
 		 cfg_p cfg,
 		 unsigned *valp)
 {
-    if ( is_pic(bridge) )
-	return(pcibr_probe_slot_pic(bridge, cfg, valp));
-    else
-	return(pcibr_probe_slot_non_pic(bridge, cfg, valp));
+    return(pcibr_probe_slot_pic(bridge, cfg, valp));
 }
 
 
 void
-pcibr_device_info_free(devfs_handle_t pcibr_vhdl, pciio_slot_t slot)
+pcibr_device_info_free(vertex_hdl_t pcibr_vhdl, pciio_slot_t slot)
 {
     pcibr_soft_t	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     pcibr_info_t	pcibr_info;
@@ -2079,9 +1814,9 @@
 
         /* Disable memory and I/O BARs */
 	cfgw = pcibr_func_config_addr(bridge, 0, slot, func, 0);
-	cmd_reg = do_pcibr_config_get(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4);
+	cmd_reg = do_pcibr_config_get(cfgw, PCI_CFG_COMMAND, 4);
 	cmd_reg &= (PCI_CMD_MEM_SPACE | PCI_CMD_IO_SPACE);
-	do_pcibr_config_set(IS_PIC_SOFT(pcibr_soft), cfgw, PCI_CFG_COMMAND, 4, cmd_reg);
+	do_pcibr_config_set(cfgw, PCI_CFG_COMMAND, 4, cmd_reg);
 
         for (bar = 0; bar < PCI_CFG_BASE_ADDRS; bar++) {
             if (pcibr_info->f_window[bar].w_space == PCIIO_SPACE_NONE)
@@ -2181,7 +1916,7 @@
  * io_brick_tab[] array defined in ml/SN/iograph.c
  */
 int
-pcibr_widget_to_bus(devfs_handle_t pcibr_vhdl) 
+pcibr_widget_to_bus(vertex_hdl_t pcibr_vhdl) 
 {
     pcibr_soft_t	pcibr_soft = pcibr_soft_get(pcibr_vhdl);
     xwidgetnum_t	widget = pcibr_soft->bs_xid;
diff -Nru a/arch/ia64/sn/io/sn2/pciio.c b/arch/ia64/sn/io/sn2/pciio.c
--- a/arch/ia64/sn/io/sn2/pciio.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/sn/io/sn2/pciio.c	Wed Jun 18 23:42:09 2003
@@ -7,8 +7,6 @@
  * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
-#define	USRPCI	0
-
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/pci.h>
@@ -44,13 +42,8 @@
 #undef DEBUG_PCIIO	/* turn this on for yet more console output */
 
 
-#define GET_NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define DO_DEL(ptr)	(kfree(ptr))
-
 char                    pciio_info_fingerprint[] = "pciio_info";
 
-cdl_p                   pciio_registry = NULL;
-
 int
 badaddr_val(volatile void *addr, int len, volatile void *ptr)
 {
@@ -97,8 +90,6 @@
 	extern char master_baseio_wid;
 
 	if (master_baseio_nasid < 0) {
-		nasid_t tmp;
-
 		master_baseio_nasid = ia64_sn_get_master_baseio_nasid();
 
 		if ( master_baseio_nasid >= 0 ) {
@@ -109,13 +100,13 @@
 }
 
 int
-hub_dma_enabled(devfs_handle_t xconn_vhdl)
+hub_dma_enabled(vertex_hdl_t xconn_vhdl)
 {
 	return(0);
 }
 
 int
-hub_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code)
+hub_error_devenable(vertex_hdl_t xconn_vhdl, int devnum, int error_code)
 {
 	return(0);
 }
@@ -153,66 +144,64 @@
  */
 
 #if !defined(DEV_FUNC)
-static pciio_provider_t *pciio_to_provider_fns(devfs_handle_t dev);
+static pciio_provider_t *pciio_to_provider_fns(vertex_hdl_t dev);
 #endif
 
-pciio_piomap_t          pciio_piomap_alloc(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
+pciio_piomap_t          pciio_piomap_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, size_t, unsigned);
 void                    pciio_piomap_free(pciio_piomap_t);
 caddr_t                 pciio_piomap_addr(pciio_piomap_t, iopaddr_t, size_t);
 
 void                    pciio_piomap_done(pciio_piomap_t);
-caddr_t                 pciio_piotrans_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
-caddr_t			pciio_pio_addr(devfs_handle_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned);
+caddr_t                 pciio_piotrans_addr(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, unsigned);
+caddr_t			pciio_pio_addr(vertex_hdl_t, device_desc_t, pciio_space_t, iopaddr_t, size_t, pciio_piomap_t *, unsigned);
 
-iopaddr_t               pciio_piospace_alloc(devfs_handle_t, device_desc_t, pciio_space_t, size_t, size_t);
-void                    pciio_piospace_free(devfs_handle_t, pciio_space_t, iopaddr_t, size_t);
+iopaddr_t               pciio_piospace_alloc(vertex_hdl_t, device_desc_t, pciio_space_t, size_t, size_t);
+void                    pciio_piospace_free(vertex_hdl_t, pciio_space_t, iopaddr_t, size_t);
 
-pciio_dmamap_t          pciio_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
+pciio_dmamap_t          pciio_dmamap_alloc(vertex_hdl_t, device_desc_t, size_t, unsigned);
 void                    pciio_dmamap_free(pciio_dmamap_t);
 iopaddr_t               pciio_dmamap_addr(pciio_dmamap_t, paddr_t, size_t);
-alenlist_t              pciio_dmamap_list(pciio_dmamap_t, alenlist_t, unsigned);
 void                    pciio_dmamap_done(pciio_dmamap_t);
-iopaddr_t               pciio_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              pciio_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
+iopaddr_t               pciio_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned);
 void			pciio_dmamap_drain(pciio_dmamap_t);
-void			pciio_dmaaddr_drain(devfs_handle_t, paddr_t, size_t);
-void			pciio_dmalist_drain(devfs_handle_t, alenlist_t);
-iopaddr_t               pciio_dma_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned);
+void			pciio_dmaaddr_drain(vertex_hdl_t, paddr_t, size_t);
+void			pciio_dmalist_drain(vertex_hdl_t, alenlist_t);
+iopaddr_t               pciio_dma_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, pciio_dmamap_t *, unsigned);
 
-pciio_intr_t            pciio_intr_alloc(devfs_handle_t, device_desc_t, pciio_intr_line_t, devfs_handle_t);
+pciio_intr_t            pciio_intr_alloc(vertex_hdl_t, device_desc_t, pciio_intr_line_t, vertex_hdl_t);
 void                    pciio_intr_free(pciio_intr_t);
 int                     pciio_intr_connect(pciio_intr_t, intr_func_t, intr_arg_t);
 void                    pciio_intr_disconnect(pciio_intr_t);
-devfs_handle_t            pciio_intr_cpu_get(pciio_intr_t);
+vertex_hdl_t            pciio_intr_cpu_get(pciio_intr_t);
 
 void			pciio_slot_func_to_name(char *, pciio_slot_t, pciio_function_t);
 
-void                    pciio_provider_startup(devfs_handle_t);
-void                    pciio_provider_shutdown(devfs_handle_t);
+void                    pciio_provider_startup(vertex_hdl_t);
+void                    pciio_provider_shutdown(vertex_hdl_t);
 
-pciio_endian_t          pciio_endian_set(devfs_handle_t, pciio_endian_t, pciio_endian_t);
-pciio_priority_t        pciio_priority_set(devfs_handle_t, pciio_priority_t);
-devfs_handle_t            pciio_intr_dev_get(pciio_intr_t);
+pciio_endian_t          pciio_endian_set(vertex_hdl_t, pciio_endian_t, pciio_endian_t);
+pciio_priority_t        pciio_priority_set(vertex_hdl_t, pciio_priority_t);
+vertex_hdl_t            pciio_intr_dev_get(pciio_intr_t);
 
-devfs_handle_t            pciio_pio_dev_get(pciio_piomap_t);
+vertex_hdl_t            pciio_pio_dev_get(pciio_piomap_t);
 pciio_slot_t            pciio_pio_slot_get(pciio_piomap_t);
 pciio_space_t           pciio_pio_space_get(pciio_piomap_t);
 iopaddr_t               pciio_pio_pciaddr_get(pciio_piomap_t);
 ulong                   pciio_pio_mapsz_get(pciio_piomap_t);
 caddr_t                 pciio_pio_kvaddr_get(pciio_piomap_t);
 
-devfs_handle_t            pciio_dma_dev_get(pciio_dmamap_t);
+vertex_hdl_t            pciio_dma_dev_get(pciio_dmamap_t);
 pciio_slot_t            pciio_dma_slot_get(pciio_dmamap_t);
 
-pciio_info_t            pciio_info_chk(devfs_handle_t);
-pciio_info_t            pciio_info_get(devfs_handle_t);
-void                    pciio_info_set(devfs_handle_t, pciio_info_t);
-devfs_handle_t            pciio_info_dev_get(pciio_info_t);
+pciio_info_t            pciio_info_chk(vertex_hdl_t);
+pciio_info_t            pciio_info_get(vertex_hdl_t);
+void                    pciio_info_set(vertex_hdl_t, pciio_info_t);
+vertex_hdl_t            pciio_info_dev_get(pciio_info_t);
 pciio_slot_t            pciio_info_slot_get(pciio_info_t);
 pciio_function_t        pciio_info_function_get(pciio_info_t);
 pciio_vendor_id_t       pciio_info_vendor_id_get(pciio_info_t);
 pciio_device_id_t       pciio_info_device_id_get(pciio_info_t);
-devfs_handle_t            pciio_info_master_get(pciio_info_t);
+vertex_hdl_t            pciio_info_master_get(pciio_info_t);
 arbitrary_info_t        pciio_info_mfast_get(pciio_info_t);
 pciio_provider_t       *pciio_info_pops_get(pciio_info_t);
 error_handler_f	       *pciio_info_efunc_get(pciio_info_t);
@@ -223,30 +212,28 @@
 iopaddr_t		pciio_info_rom_base_get(pciio_info_t);
 size_t			pciio_info_rom_size_get(pciio_info_t);
 
-void                    pciio_init(void);
-int                     pciio_attach(devfs_handle_t);
+int                     pciio_attach(vertex_hdl_t);
 
-void                    pciio_provider_register(devfs_handle_t, pciio_provider_t *pciio_fns);
-void                    pciio_provider_unregister(devfs_handle_t);
-pciio_provider_t       *pciio_provider_fns_get(devfs_handle_t);
+void                    pciio_provider_register(vertex_hdl_t, pciio_provider_t *pciio_fns);
+void                    pciio_provider_unregister(vertex_hdl_t);
+pciio_provider_t       *pciio_provider_fns_get(vertex_hdl_t);
 
 int                     pciio_driver_register(pciio_vendor_id_t, pciio_device_id_t, char *driver_prefix, unsigned);
-void                    pciio_driver_unregister(char *driver_prefix);
 
-devfs_handle_t            pciio_device_register(devfs_handle_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
+vertex_hdl_t            pciio_device_register(vertex_hdl_t, vertex_hdl_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
 
-void			pciio_device_unregister(devfs_handle_t);
-pciio_info_t		pciio_device_info_new(pciio_info_t, devfs_handle_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
+void			pciio_device_unregister(vertex_hdl_t);
+pciio_info_t		pciio_device_info_new(pciio_info_t, vertex_hdl_t, pciio_slot_t, pciio_function_t, pciio_vendor_id_t, pciio_device_id_t);
 void			pciio_device_info_free(pciio_info_t);
-devfs_handle_t		pciio_device_info_register(devfs_handle_t, pciio_info_t);
-void			pciio_device_info_unregister(devfs_handle_t, pciio_info_t);
-int                     pciio_device_attach(devfs_handle_t, int);
-int			pciio_device_detach(devfs_handle_t, int);
-void                    pciio_error_register(devfs_handle_t, error_handler_f *, error_handler_arg_t);
-
-int                     pciio_reset(devfs_handle_t);
-int                     pciio_write_gather_flush(devfs_handle_t);
-int                     pciio_slot_inuse(devfs_handle_t);
+vertex_hdl_t		pciio_device_info_register(vertex_hdl_t, pciio_info_t);
+void			pciio_device_info_unregister(vertex_hdl_t, pciio_info_t);
+int                     pciio_device_attach(vertex_hdl_t, int);
+int			pciio_device_detach(vertex_hdl_t, int);
+void                    pciio_error_register(vertex_hdl_t, error_handler_f *, error_handler_arg_t);
+
+int                     pciio_reset(vertex_hdl_t);
+int                     pciio_write_gather_flush(vertex_hdl_t);
+int                     pciio_slot_inuse(vertex_hdl_t);
 
 /* =====================================================================
  *    Provider Function Location
@@ -261,7 +248,7 @@
 #if !defined(DEV_FUNC)
 
 static pciio_provider_t *
-pciio_to_provider_fns(devfs_handle_t dev)
+pciio_to_provider_fns(vertex_hdl_t dev)
 {
     pciio_info_t            card_info;
     pciio_provider_t       *provider_fns;
@@ -316,7 +303,7 @@
  */
 
 pciio_piomap_t
-pciio_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
+pciio_piomap_alloc(vertex_hdl_t dev,	/* set up mapping for this device */
 		   device_desc_t dev_desc,	/* device descriptor */
 		   pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
 		   iopaddr_t addr,	/* lowest address (or offset in window) */
@@ -354,7 +341,7 @@
 }
 
 caddr_t
-pciio_piotrans_addr(devfs_handle_t dev,	/* translate for this device */
+pciio_piotrans_addr(vertex_hdl_t dev,	/* translate for this device */
 		    device_desc_t dev_desc,	/* device descriptor */
 		    pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
 		    iopaddr_t addr,	/* starting address (or offset in window) */
@@ -366,7 +353,7 @@
 }
 
 caddr_t
-pciio_pio_addr(devfs_handle_t dev,	/* translate for this device */
+pciio_pio_addr(vertex_hdl_t dev,	/* translate for this device */
 	       device_desc_t dev_desc,	/* device descriptor */
 	       pciio_space_t space,	/* CFG, MEM, IO, or a device-decoded window */
 	       iopaddr_t addr,		/* starting address (or offset in window) */
@@ -410,7 +397,7 @@
 }
 
 iopaddr_t
-pciio_piospace_alloc(devfs_handle_t dev,	/* Device requiring space */
+pciio_piospace_alloc(vertex_hdl_t dev,	/* Device requiring space */
 		     device_desc_t dev_desc,	/* Device descriptor */
 		     pciio_space_t space,	/* MEM32/MEM64/IO */
 		     size_t byte_count,	/* Size of mapping */
@@ -423,7 +410,7 @@
 }
 
 void
-pciio_piospace_free(devfs_handle_t dev,	/* Device freeing space */
+pciio_piospace_free(vertex_hdl_t dev,	/* Device freeing space */
 		    pciio_space_t space,	/* Type of space        */
 		    iopaddr_t pciaddr,	/* starting address */
 		    size_t byte_count)
@@ -440,7 +427,7 @@
  */
 
 pciio_dmamap_t
-pciio_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */
+pciio_dmamap_alloc(vertex_hdl_t dev,	/* set up mappings for this device */
 		   device_desc_t dev_desc,	/* device descriptor */
 		   size_t byte_count_max,	/* max size of a mapping */
 		   unsigned flags)
@@ -465,15 +452,6 @@
 	(CAST_DMAMAP(pciio_dmamap), paddr, byte_count);
 }
 
-alenlist_t
-pciio_dmamap_list(pciio_dmamap_t pciio_dmamap,	/* use these mapping resources */
-		  alenlist_t alenlist,	/* map this Address/Length List */
-		  unsigned flags)
-{
-    return DMAMAP_FUNC(pciio_dmamap, dmamap_list)
-	(CAST_DMAMAP(pciio_dmamap), alenlist, flags);
-}
-
 void
 pciio_dmamap_done(pciio_dmamap_t pciio_dmamap)
 {
@@ -482,7 +460,7 @@
 }
 
 iopaddr_t
-pciio_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */
+pciio_dmatrans_addr(vertex_hdl_t dev,	/* translate for this device */
 		    device_desc_t dev_desc,	/* device descriptor */
 		    paddr_t paddr,	/* system physical address */
 		    size_t byte_count,	/* length */
@@ -492,18 +470,8 @@
 	(dev, dev_desc, paddr, byte_count, flags);
 }
 
-alenlist_t
-pciio_dmatrans_list(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    alenlist_t palenlist,	/* system address/length list */
-		    unsigned flags)
-{					/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_list)
-	(dev, dev_desc, palenlist, flags);
-}
-
 iopaddr_t
-pciio_dma_addr(devfs_handle_t dev,	/* translate for this device */
+pciio_dma_addr(vertex_hdl_t dev,	/* translate for this device */
 	       device_desc_t dev_desc,	/* device descriptor */
 	       paddr_t paddr,		/* system physical address */
 	       size_t byte_count,	/* length */
@@ -553,14 +521,14 @@
 }
 
 void
-pciio_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
+pciio_dmaaddr_drain(vertex_hdl_t dev, paddr_t addr, size_t size)
 {
     DEV_FUNC(dev, dmaaddr_drain)
 	(dev, addr, size);
 }
 
 void
-pciio_dmalist_drain(devfs_handle_t dev, alenlist_t list)
+pciio_dmalist_drain(vertex_hdl_t dev, alenlist_t list)
 {
     DEV_FUNC(dev, dmalist_drain)
 	(dev, list);
@@ -577,10 +545,10 @@
  * Return resource handle in intr_hdl.
  */
 pciio_intr_t
-pciio_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */
+pciio_intr_alloc(vertex_hdl_t dev,	/* which Crosstalk device */
 		 device_desc_t dev_desc,	/* device descriptor */
 		 pciio_intr_line_t lines,	/* INTR line(s) to attach */
-		 devfs_handle_t owner_dev)
+		 vertex_hdl_t owner_dev)
 {					/* owner of this interrupt */
     return (pciio_intr_t) DEV_FUNC(dev, intr_alloc)
 	(dev, dev_desc, lines, owner_dev);
@@ -624,7 +592,7 @@
  * Return a hwgraph vertex that represents the CPU currently
  * targeted by an interrupt.
  */
-devfs_handle_t
+vertex_hdl_t
 pciio_intr_cpu_get(pciio_intr_t intr_hdl)
 {
     return INTR_FUNC(intr_hdl, intr_cpu_get)
@@ -663,12 +631,12 @@
  */
 static pciio_info_t
 pciio_cardinfo_get(
-		      devfs_handle_t pciio_vhdl,
+		      vertex_hdl_t pciio_vhdl,
 		      pciio_slot_t pci_slot)
 {
     char                    namebuf[16];
     pciio_info_t	    info = 0;
-    devfs_handle_t	    conn;
+    vertex_hdl_t	    conn;
 
     pciio_slot_func_to_name(namebuf, pci_slot, PCIIO_FUNC_NONE);
     if (GRAPH_SUCCESS ==
@@ -699,22 +667,16 @@
 /*ARGSUSED */
 int
 pciio_error_handler(
-		       devfs_handle_t pciio_vhdl,
+		       vertex_hdl_t pciio_vhdl,
 		       int error_code,
 		       ioerror_mode_t mode,
 		       ioerror_t *ioerror)
 {
     pciio_info_t            pciio_info;
-    devfs_handle_t            pconn_vhdl;
-#if USRPCI
-    devfs_handle_t            usrpci_v;
-#endif
+    vertex_hdl_t            pconn_vhdl;
     pciio_slot_t            slot;
 
     int                     retval;
-#ifdef EHE_ENABLE
-    error_state_t	    e_state;
-#endif /* EHE_ENABLE */
 
 #if DEBUG && ERROR_DEBUG
     printk("%v: pciio_error_handler\n", pciio_vhdl);
@@ -733,16 +695,6 @@
     if (pciio_info && pciio_info->c_efunc) {
 	pconn_vhdl = pciio_info_dev_get(pciio_info);
 
-#ifdef EHE_ENABLE
-	e_state = error_state_get(pciio_vhdl);
-
-	if (e_state == ERROR_STATE_ACTION)
-	    (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE);
-
-	if (error_state_set(pconn_vhdl,e_state) == ERROR_RETURN_CODE_CANNOT_SET_STATE)
-	    return(IOERROR_UNHANDLED);
-#endif 
-
 	retval = pciio_info->c_efunc
 	    (pciio_info->c_einfo, error_code, mode, ioerror);
 	if (retval != IOERROR_UNHANDLED)
@@ -770,49 +722,11 @@
 
 		pconn_vhdl = pciio_info_dev_get(pciio_info);
 
-#ifdef EHE_ENABLE
-		e_state = error_state_get(pciio_vhdl);
-
-		if (e_state == ERROR_STATE_ACTION)
-		    (void)error_state_set(pciio_vhdl, ERROR_STATE_NONE);
-
-		if (error_state_set(pconn_vhdl,e_state) ==
-		    ERROR_RETURN_CODE_CANNOT_SET_STATE)
-		    return(IOERROR_UNHANDLED);
-#endif /* EHE_ENABLE */
-
 		retval = pciio_info->c_efunc
 		    (pciio_info->c_einfo, error_code, mode, ioerror);
 		if (retval != IOERROR_UNHANDLED)
 		    return retval;
 	    }
-
-#if USRPCI
-	    /* If the USRPCI driver is available and
-	     * knows about this connection point,
-	     * deliver the error to it.
-	     *
-	     * OK to use pconn_vhdl here, even though we
-	     * have already UNREF'd it, since we know that
-	     * it is not going away.
-	     */
-	    pconn_vhdl = pciio_info_dev_get(pciio_info);
-	    if (GRAPH_SUCCESS == hwgraph_traverse(pconn_vhdl, EDGE_LBL_USRPCI, &usrpci_v)) {
-		iopaddr_t busaddr;
-		IOERROR_GETVALUE(busaddr, ioerror, busaddr);
-		retval = usrpci_error_handler (usrpci_v, error_code, busaddr);
-		hwgraph_vertex_unref(usrpci_v);
-		if (retval != IOERROR_UNHANDLED) {
-		    /*
-		     * This unref is not needed.  If this code is called often enough,
-		     * the system will crash, due to vertex reference count reaching 0,
-		     * causing vertex to be unallocated.  -jeremy
-		     * hwgraph_vertex_unref(pconn_vhdl);
-		     */
-		    return retval;
-		}
-	    }
-#endif
 	}
     }
 
@@ -829,7 +743,7 @@
  * Startup a crosstalk provider
  */
 void
-pciio_provider_startup(devfs_handle_t pciio_provider)
+pciio_provider_startup(vertex_hdl_t pciio_provider)
 {
     DEV_FUNC(pciio_provider, provider_startup)
 	(pciio_provider);
@@ -839,7 +753,7 @@
  * Shutdown a crosstalk provider
  */
 void
-pciio_provider_shutdown(devfs_handle_t pciio_provider)
+pciio_provider_shutdown(vertex_hdl_t pciio_provider)
 {
     DEV_FUNC(pciio_provider, provider_shutdown)
 	(pciio_provider);
@@ -851,7 +765,7 @@
  * how things will actually appear in memory.
  */
 pciio_endian_t
-pciio_endian_set(devfs_handle_t dev,
+pciio_endian_set(vertex_hdl_t dev,
 		 pciio_endian_t device_end,
 		 pciio_endian_t desired_end)
 {
@@ -880,7 +794,7 @@
  * Specify PCI arbitration priority.
  */
 pciio_priority_t
-pciio_priority_set(devfs_handle_t dev,
+pciio_priority_set(vertex_hdl_t dev,
 		   pciio_priority_t device_prio)
 {
     ASSERT((device_prio == PCI_PRIO_HIGH) || (device_prio == PCI_PRIO_LOW));
@@ -893,7 +807,7 @@
  * Read value of configuration register
  */
 uint64_t
-pciio_config_get(devfs_handle_t	dev,
+pciio_config_get(vertex_hdl_t	dev,
 		 unsigned	reg,
 		 unsigned	size)
 {
@@ -923,7 +837,7 @@
  * Change value of configuration register
  */
 void
-pciio_config_set(devfs_handle_t	dev,
+pciio_config_set(vertex_hdl_t	dev,
 		 unsigned	reg,
 		 unsigned	size,
 		 uint64_t	value)
@@ -953,7 +867,7 @@
  * Issue a hardware reset to a card.
  */
 int
-pciio_reset(devfs_handle_t dev)
+pciio_reset(vertex_hdl_t dev)
 {
     return DEV_FUNC(dev, reset) (dev);
 }
@@ -962,19 +876,19 @@
  * flush write gather buffers
  */
 int
-pciio_write_gather_flush(devfs_handle_t dev)
+pciio_write_gather_flush(vertex_hdl_t dev)
 {
     return DEV_FUNC(dev, write_gather_flush) (dev);
 }
 
-devfs_handle_t
+vertex_hdl_t
 pciio_intr_dev_get(pciio_intr_t pciio_intr)
 {
     return (pciio_intr->pi_dev);
 }
 
 /****** Generic crosstalk pio interfaces ******/
-devfs_handle_t
+vertex_hdl_t
 pciio_pio_dev_get(pciio_piomap_t pciio_piomap)
 {
     return (pciio_piomap->pp_dev);
@@ -1011,7 +925,7 @@
 }
 
 /****** Generic crosstalk dma interfaces ******/
-devfs_handle_t
+vertex_hdl_t
 pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap)
 {
     return (pciio_dmamap->pd_dev);
@@ -1026,7 +940,7 @@
 /****** Generic pci slot information interfaces ******/
 
 pciio_info_t
-pciio_info_chk(devfs_handle_t pciio)
+pciio_info_chk(vertex_hdl_t pciio)
 {
     arbitrary_info_t        ainfo = 0;
 
@@ -1035,7 +949,7 @@
 }
 
 pciio_info_t
-pciio_info_get(devfs_handle_t pciio)
+pciio_info_get(vertex_hdl_t pciio)
 {
     pciio_info_t            pciio_info;
 
@@ -1051,18 +965,17 @@
 #endif /* DEBUG_PCIIO */
 
     if ((pciio_info != NULL) &&
-	(pciio_info->c_fingerprint != pciio_info_fingerprint)
-	&& (pciio_info->c_fingerprint != NULL)) {
+        (pciio_info->c_fingerprint != pciio_info_fingerprint)
+        && (pciio_info->c_fingerprint != NULL)) {
 
-	return((pciio_info_t)-1); /* Should panic .. */
+        return((pciio_info_t)-1); /* Should panic .. */
     }
-	
 
     return pciio_info;
 }
 
 void
-pciio_info_set(devfs_handle_t pciio, pciio_info_t pciio_info)
+pciio_info_set(vertex_hdl_t pciio, pciio_info_t pciio_info)
 {
     if (pciio_info != NULL)
 	pciio_info->c_fingerprint = pciio_info_fingerprint;
@@ -1076,7 +989,7 @@
 			 (arbitrary_info_t) pciio_info);
 }
 
-devfs_handle_t
+vertex_hdl_t
 pciio_info_dev_get(pciio_info_t pciio_info)
 {
     return (pciio_info->c_vertex);
@@ -1106,7 +1019,7 @@
     return (pciio_info->c_device);
 }
 
-devfs_handle_t
+vertex_hdl_t
 pciio_info_master_get(pciio_info_t pciio_info)
 {
     return (pciio_info->c_master);
@@ -1172,47 +1085,12 @@
  */
 
 /*
- *    pciioinit: called once during device driver
- *      initializtion if this driver is configured into
- *      the system.
- */
-void
-pciio_init(void)
-{
-    cdl_p                   cp;
-
-#if DEBUG && ATTACH_DEBUG
-    printf("pciio_init\n");
-#endif
-    /* Allocate the registry.
-     * We might already have one.
-     * If we don't, go get one.
-     * MPness: someone might have
-     * set one up for us while we
-     * were not looking; use an atomic
-     * compare-and-swap to commit to
-     * using the new registry if and
-     * only if nobody else did first.
-     * If someone did get there first,
-     * toss the one we allocated back
-     * into the pool.
-     */
-    if (pciio_registry == NULL) {
-	cp = cdl_new(EDGE_LBL_PCI, "vendor", "device");
-	if (!compare_and_swap_ptr((void **) &pciio_registry, NULL, (void *) cp)) {
-	    cdl_del(cp);
-	}
-    }
-    ASSERT(pciio_registry != NULL);
-}
-
-/*
  *    pciioattach: called for each vertex in the graph
  *      that is a PCI provider.
  */
 /*ARGSUSED */
 int
-pciio_attach(devfs_handle_t pciio)
+pciio_attach(vertex_hdl_t pciio)
 {
 #if DEBUG && ATTACH_DEBUG
 #if defined(SUPPORT_PRINTING_V_FORMAT)
@@ -1228,7 +1106,7 @@
  * Associate a set of pciio_provider functions with a vertex.
  */
 void
-pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns)
+pciio_provider_register(vertex_hdl_t provider, pciio_provider_t *pciio_fns)
 {
     hwgraph_info_add_LBL(provider, INFO_LBL_PFUNCS, (arbitrary_info_t) pciio_fns);
 }
@@ -1237,7 +1115,7 @@
  * Disassociate a set of pciio_provider functions with a vertex.
  */
 void
-pciio_provider_unregister(devfs_handle_t provider)
+pciio_provider_unregister(vertex_hdl_t provider)
 {
     arbitrary_info_t        ainfo;
 
@@ -1249,7 +1127,7 @@
  * provider.
  */
 pciio_provider_t       *
-pciio_provider_fns_get(devfs_handle_t provider)
+pciio_provider_fns_get(vertex_hdl_t provider)
 {
     arbitrary_info_t        ainfo = 0;
 
@@ -1265,86 +1143,13 @@
 			 char *driver_prefix,
 			 unsigned flags)
 {
-    /* a driver's init routine might call
-     * pciio_driver_register before the
-     * system calls pciio_init; so we
-     * make the init call ourselves here.
-     */
-    if (pciio_registry == NULL)
-	pciio_init();
-
-    return cdl_add_driver(pciio_registry,
-			  vendor_id, device_id,
-			  driver_prefix, flags, NULL);
-}
-
-/*
- * Remove an initialization function.
- */
-void
-pciio_driver_unregister(
-			   char *driver_prefix)
-{
-    /* before a driver calls unregister,
-     * it must have called register; so
-     * we can assume we have a registry here.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    cdl_del_driver(pciio_registry, driver_prefix, NULL);
-}
-
-/* 
- * Set the slot status for a device supported by the 
- * driver being registered.
- */
-void
-pciio_driver_reg_callback(
-                           devfs_handle_t pconn_vhdl,
-			   int key1,
-			   int key2,
-                           int error)
-{
-}
-
-/* 
- * Set the slot status for a device supported by the 
- * driver being unregistered.
- */
-void
-pciio_driver_unreg_callback(
-                           devfs_handle_t pconn_vhdl,
-			   int key1,
-			   int key2,
-                           int error)
-{
-}
-
-/*
- * Call some function with each vertex that
- * might be one of this driver's attach points.
- */
-void
-pciio_iterate(char *driver_prefix,
-	      pciio_iter_f * func)
-{
-    /* a driver's init routine might call
-     * pciio_iterate before the
-     * system calls pciio_init; so we
-     * make the init call ourselves here.
-     */
-    if (pciio_registry == NULL)
-	pciio_init();
-
-    ASSERT(pciio_registry != NULL);
-
-    cdl_iterate(pciio_registry, driver_prefix, (cdl_iter_f *) func);
+	return(0);
 }
 
-devfs_handle_t
+vertex_hdl_t
 pciio_device_register(
-		devfs_handle_t connectpt,	/* vertex for /hw/.../pciio/%d */
-		devfs_handle_t master,	/* card's master ASIC (PCI provider) */
+		vertex_hdl_t connectpt,	/* vertex for /hw/.../pciio/%d */
+		vertex_hdl_t master,	/* card's master ASIC (PCI provider) */
 		pciio_slot_t slot,	/* card's slot */
 		pciio_function_t func,	/* card's func */
 		pciio_vendor_id_t vendor_id,
@@ -1356,7 +1161,7 @@
 }
 
 void
-pciio_device_unregister(devfs_handle_t pconn)
+pciio_device_unregister(vertex_hdl_t pconn)
 {
     DEV_FUNC(pconn,device_unregister)(pconn);
 }
@@ -1364,14 +1169,14 @@
 pciio_info_t
 pciio_device_info_new(
 		pciio_info_t pciio_info,
-		devfs_handle_t master,
+		vertex_hdl_t master,
 		pciio_slot_t slot,
 		pciio_function_t func,
 		pciio_vendor_id_t vendor_id,
 		pciio_device_id_t device_id)
 {
     if (!pciio_info)
-	GET_NEW(pciio_info);
+	NEW(pciio_info);
     ASSERT(pciio_info != NULL);
 
     pciio_info->c_slot = slot;
@@ -1396,14 +1201,14 @@
     BZERO((char *)pciio_info,sizeof(pciio_info));
 }
 
-devfs_handle_t
+vertex_hdl_t
 pciio_device_info_register(
-		devfs_handle_t connectpt,		/* vertex at center of bus */
+		vertex_hdl_t connectpt,		/* vertex at center of bus */
 		pciio_info_t pciio_info)	/* details about the connectpt */
 {
     char		name[32];
-    devfs_handle_t	pconn;
-    int device_master_set(devfs_handle_t, devfs_handle_t);
+    vertex_hdl_t	pconn;
+    int device_master_set(vertex_hdl_t, vertex_hdl_t);
 
     pciio_slot_func_to_name(name,
 			    pciio_info->c_slot,
@@ -1429,25 +1234,15 @@
      */
 
     device_master_set(pconn, pciio_info->c_master);
-
-#if USRPCI
-    /*
-     * Call into usrpci provider to let it initialize for
-     * the given slot.
-     */
-    if (pciio_info->c_slot != PCIIO_SLOT_NONE)
-	usrpci_device_register(pconn, pciio_info->c_master, pciio_info->c_slot);
-#endif
-
     return pconn;
 }
 
 void
-pciio_device_info_unregister(devfs_handle_t connectpt,
+pciio_device_info_unregister(vertex_hdl_t connectpt,
 			     pciio_info_t pciio_info)
 {
     char		name[32];
-    devfs_handle_t	pconn;
+    vertex_hdl_t	pconn;
 
     if (!pciio_info)
 	return;
@@ -1470,7 +1265,7 @@
 /* Add the pci card inventory information to the hwgraph
  */
 static void
-pciio_device_inventory_add(devfs_handle_t pconn_vhdl)
+pciio_device_inventory_add(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t	pciio_info = pciio_info_get(pconn_vhdl);
 
@@ -1488,7 +1283,7 @@
 
 /*ARGSUSED */
 int
-pciio_device_attach(devfs_handle_t pconn,
+pciio_device_attach(vertex_hdl_t pconn,
 		    int          drv_flags)
 {
     pciio_info_t            pciio_info;
@@ -1507,34 +1302,15 @@
      * pciio_init) have been called; so we
      * can assume here that we have a registry.
      */
-    ASSERT(pciio_registry != NULL);
 
-    return(cdl_add_connpt(pciio_registry, vendor_id, device_id, pconn, drv_flags));
+    return(cdl_add_connpt(vendor_id, device_id, pconn, drv_flags));
 }
 
 int
-pciio_device_detach(devfs_handle_t pconn,
+pciio_device_detach(vertex_hdl_t pconn,
 		    int          drv_flags)
 {
-    pciio_info_t            pciio_info;
-    pciio_vendor_id_t       vendor_id;
-    pciio_device_id_t       device_id;
-
-    pciio_info = pciio_info_get(pconn);
-
-    vendor_id = pciio_info->c_vendor;
-    device_id = pciio_info->c_device;
-
-    /* we don't start attaching things until
-     * all the driver init routines (including
-     * pciio_init) have been called; so we
-     * can assume here that we have a registry.
-     */
-    ASSERT(pciio_registry != NULL);
-
-    return(cdl_del_connpt(pciio_registry, vendor_id, device_id,
-		          pconn, drv_flags));
-
+    return(0);
 }
 
 /* SN2 */
@@ -1728,7 +1504,7 @@
  * cooperating drivers, well, cooperate ...
  */
 void
-pciio_error_register(devfs_handle_t pconn,
+pciio_error_register(vertex_hdl_t pconn,
 		     error_handler_f *efunc,
 		     error_handler_arg_t einfo)
 {
@@ -1746,7 +1522,7 @@
  * vhdl is the vertex for the slot
  */
 int
-pciio_slot_inuse(devfs_handle_t pconn_vhdl)
+pciio_slot_inuse(vertex_hdl_t pconn_vhdl)
 {
     pciio_info_t            pciio_info = pciio_info_get(pconn_vhdl);
 
@@ -1763,7 +1539,7 @@
 }
 
 int
-pciio_dma_enabled(devfs_handle_t pconn_vhdl)
+pciio_dma_enabled(vertex_hdl_t pconn_vhdl)
 {
 	return DEV_FUNC(pconn_vhdl, dma_enabled)(pconn_vhdl);
 }
@@ -1777,7 +1553,7 @@
 
 /*
  * These are complementary Linux interfaces that takes in a pci_dev * as the 
- * first arguement instead of devfs_handle_t.
+ * first arguement instead of vertex_hdl_t.
  */
 iopaddr_t               snia_pciio_dmatrans_addr(struct pci_dev *, device_desc_t, paddr_t, size_t, unsigned);
 pciio_dmamap_t          snia_pciio_dmamap_alloc(struct pci_dev *, device_desc_t, size_t, unsigned);
@@ -1800,7 +1576,7 @@
 	int *count_vchan0,
 	int *count_vchan1)
 {
-	devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
+	vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev);
 
 	return pcibr_rrb_alloc(dev, count_vchan0, count_vchan1);
 }
@@ -1811,7 +1587,7 @@
 	pciio_endian_t device_end,
 	pciio_endian_t desired_end)
 {
-	devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
+	vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev);
 	
 	return DEV_FUNC(dev, endian_set)
 		(dev, device_end, desired_end);
@@ -1825,7 +1601,7 @@
                     unsigned flags)
 {                                       /* defined in dma.h */
 
-    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
+    vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev);
 
     /*
      * If the device is not a PIC, we always want the PCIIO_BYTE_STREAM to be 
@@ -1842,7 +1618,7 @@
                    unsigned flags)
 {                                       /* defined in dma.h */
 
-    devfs_handle_t dev = PCIDEV_VERTEX(pci_dev);
+    vertex_hdl_t dev = PCIDEV_VERTEX(pci_dev);
 
     /*
      * If the device is not a PIC, we always want the PCIIO_BYTE_STREAM to be
diff -Nru a/arch/ia64/sn/io/sn2/pic.c b/arch/ia64/sn/io/sn2/pic.c
--- a/arch/ia64/sn/io/sn2/pic.c	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/sn/io/sn2/pic.c	Wed Jun 18 23:42:08 2003
@@ -27,7 +27,6 @@
 #include <asm/sn/prio.h>
 #include <asm/sn/xtalk/xbow.h>
 #include <asm/sn/ioc3.h>
-#include <asm/sn/eeprom.h>
 #include <asm/sn/io.h>
 #include <asm/sn/sn_private.h>
 
@@ -36,29 +35,16 @@
 
 #define PCI_BUS_NO_1 1
 
-int pic_devflag = D_MP;
+extern int pcibr_attach2(vertex_hdl_t, bridge_t *, vertex_hdl_t, int, pcibr_soft_t *);
+extern void pcibr_driver_reg_callback(vertex_hdl_t, int, int, int);
+extern void pcibr_driver_unreg_callback(vertex_hdl_t, int, int, int);
 
-extern int pcibr_attach2(devfs_handle_t, bridge_t *, devfs_handle_t, int, pcibr_soft_t *);
-extern void pcibr_driver_reg_callback(devfs_handle_t, int, int, int);
-extern void pcibr_driver_unreg_callback(devfs_handle_t, int, int, int);
-
-
-void
-pic_init(void)
-{
-	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_INIT, NULL, "pic_init()\n"));	
-
-	xwidget_driver_register(PIC_WIDGET_PART_NUM_BUS0,
-			    PIC_WIDGET_MFGR_NUM,
-			    "pic_",
-			    0);
-}
 
 /*
  * copy inventory_t from conn_v to peer_conn_v
  */
 int
-pic_bus1_inventory_dup(devfs_handle_t conn_v, devfs_handle_t peer_conn_v)
+pic_bus1_inventory_dup(vertex_hdl_t conn_v, vertex_hdl_t peer_conn_v)
 {
 	inventory_t *pinv, *peer_pinv;
 
@@ -66,7 +52,7 @@
 				(arbitrary_info_t *)&pinv) == GRAPH_SUCCESS)
  {
 		NEW(peer_pinv);
-		bcopy(pinv, peer_pinv, sizeof(inventory_t));
+		bcopy((const char *)pinv, (char *)peer_pinv, sizeof(inventory_t));
 		if (hwgraph_info_add_LBL(peer_conn_v, INFO_LBL_INVENT,
 			    (arbitrary_info_t)peer_pinv) != GRAPH_SUCCESS) {
 			DEL(peer_pinv);
@@ -75,8 +61,7 @@
 		return 1;
 	}
 
-	printk("pic_bus1_inventory_dup: cannot get INFO_LBL_INVENT from 0x%lx\n ",
-								conn_v);
+	printk("pic_bus1_inventory_dup: cannot get INFO_LBL_INVENT from 0x%lx\n ", (uint64_t)conn_v);
 	return 0;
 }
 
@@ -84,13 +69,12 @@
  * copy xwidget_info_t from conn_v to peer_conn_v
  */
 int
-pic_bus1_widget_info_dup(devfs_handle_t conn_v, devfs_handle_t peer_conn_v,
+pic_bus1_widget_info_dup(vertex_hdl_t conn_v, vertex_hdl_t peer_conn_v,
 							cnodeid_t xbow_peer)
 {
 	xwidget_info_t widget_info, peer_widget_info;
 	char peer_path[256];
-	char *p;
-	devfs_handle_t peer_hubv;
+	vertex_hdl_t peer_hubv;
 	hubinfo_t peer_hub_info;
 
 	/* get the peer hub's widgetid */
@@ -126,7 +110,7 @@
 	}
 
 	printk("pic_bus1_widget_info_dup: "
-			"cannot get INFO_LBL_XWIDGET from 0x%lx\n", conn_v);
+			"cannot get INFO_LBL_XWIDGET from 0x%lx\n", (uint64_t)conn_v);
 	return 0;
 }
 
@@ -138,15 +122,15 @@
  * If not successful, return zero and both buses will attach to the
  * vertex passed into pic_attach().
  */
-devfs_handle_t
-pic_bus1_redist(nasid_t nasid, devfs_handle_t conn_v)
+vertex_hdl_t
+pic_bus1_redist(nasid_t nasid, vertex_hdl_t conn_v)
 {
 	cnodeid_t cnode = NASID_TO_COMPACT_NODEID(nasid);
 	cnodeid_t xbow_peer = -1;
 	char pathname[256], peer_path[256], tmpbuf[256];
 	char *p;
 	int rc;
-	devfs_handle_t peer_conn_v;
+	vertex_hdl_t peer_conn_v;
 	int pos;
 	slabid_t slab;
 
@@ -155,7 +139,7 @@
 		/* pcibr widget hw/module/001c11/slab/0/Pbrick/xtalk/12 */
 		/* sprintf(pathname, "%v", conn_v); */
 		xbow_peer = NASID_TO_COMPACT_NODEID(NODEPDA(cnode)->xbow_peer);
-		pos = devfs_generate_path(conn_v, tmpbuf, 256);
+		pos = hwgfs_generate_path(conn_v, tmpbuf, 256);
 		strcpy(pathname, &tmpbuf[pos]);
 		p = pathname + strlen("hw/module/001c01/slab/0/");
 
@@ -170,7 +154,7 @@
 		rc = hwgraph_traverse(hwgraph_root, peer_path, &peer_conn_v);
 		if (GRAPH_SUCCESS == rc)
 			printk("pic_attach: found unexpected vertex: 0x%lx\n",
-								peer_conn_v);
+								(uint64_t)peer_conn_v);
 		else if (GRAPH_NOT_FOUND != rc) {
 			printk("pic_attach: hwgraph_traverse unexpectedly"
 					" returned 0x%x\n", rc);
@@ -208,13 +192,13 @@
 
 
 int
-pic_attach(devfs_handle_t conn_v)
+pic_attach(vertex_hdl_t conn_v)
 {
 	int		rc;
 	bridge_t	*bridge0, *bridge1 = (bridge_t *)0;
-	devfs_handle_t	pcibr_vhdl0, pcibr_vhdl1 = (devfs_handle_t)0;
+	vertex_hdl_t	pcibr_vhdl0, pcibr_vhdl1 = (vertex_hdl_t)0;
 	pcibr_soft_t	bus0_soft, bus1_soft = (pcibr_soft_t)0;
-	devfs_handle_t  conn_v0, conn_v1, peer_conn_v;
+	vertex_hdl_t  conn_v0, conn_v1, peer_conn_v;
 
 	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v, "pic_attach()\n"));
 
@@ -229,11 +213,11 @@
 	conn_v0 = conn_v1 = conn_v;
 
 	/* If dual-ported then split the two PIC buses across both Cbricks */
-	if (peer_conn_v = pic_bus1_redist(NASID_GET(bridge0), conn_v))
+	if ((peer_conn_v = (pic_bus1_redist(NASID_GET(bridge0), conn_v))))
 		conn_v1 = peer_conn_v;
 
 	/*
-	 * Create the vertex for the PCI buses, which week
+	 * Create the vertex for the PCI buses, which we
 	 * will also use to hold the pcibr_soft and
 	 * which will be the "master" vertex for all the
 	 * pciio connection points we will hang off it.
@@ -266,7 +250,6 @@
 	/* save a pointer to the PIC's other bus's soft struct */
         bus0_soft->bs_peers_soft = bus1_soft;
         bus1_soft->bs_peers_soft = bus0_soft;
-        bus0_soft->bs_peers_soft = (pcibr_soft_t)0;
 
 	PCIBR_DEBUG_ALWAYS((PCIBR_DEBUG_ATTACH, conn_v,
 		    "pic_attach: bus0_soft=0x%x, bus1_soft=0x%x\n",
@@ -294,10 +277,8 @@
     (pciio_dmamap_alloc_f *) pcibr_dmamap_alloc,
     (pciio_dmamap_free_f *) pcibr_dmamap_free,
     (pciio_dmamap_addr_f *) pcibr_dmamap_addr,
-    (pciio_dmamap_list_f *) pcibr_dmamap_list,
     (pciio_dmamap_done_f *) pcibr_dmamap_done,
     (pciio_dmatrans_addr_f *) pcibr_dmatrans_addr,
-    (pciio_dmatrans_list_f *) pcibr_dmatrans_list,
     (pciio_dmamap_drain_f *) pcibr_dmamap_drain,
     (pciio_dmaaddr_drain_f *) pcibr_dmaaddr_drain,
     (pciio_dmalist_drain_f *) pcibr_dmalist_drain,
diff -Nru a/arch/ia64/sn/io/sn2/sgi_io_init.c b/arch/ia64/sn/io/sn2/sgi_io_init.c
--- a/arch/ia64/sn/io/sn2/sgi_io_init.c	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,226 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/config.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/io.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/klconfig.h>
-#include <asm/sn/sn_private.h>
-#include <asm/sn/pci/pciba.h>
-#include <linux/smp.h>
-
-extern void mlreset(void);
-extern int init_hcl(void);
-extern void klgraph_hack_init(void);
-extern void hubspc_init(void);
-extern void pciio_init(void);
-extern void pcibr_init(void);
-extern void xtalk_init(void);
-extern void xbow_init(void);
-extern void xbmon_init(void);
-extern void pciiox_init(void);
-extern void pic_init(void);
-extern void usrpci_init(void);
-extern void ioc3_init(void);
-extern void initialize_io(void);
-extern void klhwg_add_all_modules(devfs_handle_t);
-extern void klhwg_add_all_nodes(devfs_handle_t);
-
-void sn_mp_setup(void);
-extern devfs_handle_t hwgraph_root;
-extern void io_module_init(void);
-extern void pci_bus_cvlink_init(void);
-extern void temp_hack(void);
-
-extern int pci_bus_to_hcl_cvlink(void);
-
-/* #define DEBUG_IO_INIT 1 */
-#ifdef DEBUG_IO_INIT
-#define DBG(x...) printk(x)
-#else
-#define DBG(x...)
-#endif /* DEBUG_IO_INIT */
-
-/*
- * per_hub_init
- *
- * 	This code is executed once for each Hub chip.
- */
-static void
-per_hub_init(cnodeid_t cnode)
-{
-	nasid_t		nasid;
-	nodepda_t	*npdap;
-	ii_icmr_u_t	ii_icmr;
-	ii_ibcr_u_t	ii_ibcr;
-
-	nasid = COMPACT_TO_NASID_NODEID(cnode);
-
-	ASSERT(nasid != INVALID_NASID);
-	ASSERT(NASID_TO_COMPACT_NODEID(nasid) == cnode);
-
-	npdap = NODEPDA(cnode);
-
-	REMOTE_HUB_S(nasid, IIO_IWEIM, 0x8000);
-
-	/*
-	 * Set the total number of CRBs that can be used.
-	 */
-	ii_icmr.ii_icmr_regval= 0x0;
-	ii_icmr.ii_icmr_fld_s.i_c_cnt = 0xf;
-	REMOTE_HUB_S(nasid, IIO_ICMR, ii_icmr.ii_icmr_regval);
-
-	/*
-	 * Set the number of CRBs that both of the BTEs combined
-	 * can use minus 1.
-	 */
-	ii_ibcr.ii_ibcr_regval= 0x0;
-	ii_ibcr.ii_ibcr_fld_s.i_count = 0x8;
-	REMOTE_HUB_S(nasid, IIO_IBCR, ii_ibcr.ii_ibcr_regval);
-
-	/*
-	 * Set CRB timeout to be 10ms.
-	 */
-#ifdef BRINGUP2
-	REMOTE_HUB_S(nasid, IIO_ICTP, 0xffffff );
-	REMOTE_HUB_S(nasid, IIO_ICTO, 0xff);
-	//REMOTE_HUB_S(nasid, IIO_IWI, 0x00FF00FF00FFFFFF);
-#endif
-
-	/* Initialize error interrupts for this hub. */
-	hub_error_init(cnode);
-}
-
-/*
- * This routine is responsible for the setup of all the IRIX hwgraph style
- * stuff that's been pulled into linux.  It's called by sn_pci_find_bios which
- * is called just before the generic Linux PCI layer does its probing (by 
- * platform_pci_fixup aka sn_pci_fixup).
- *
- * It is very IMPORTANT that this call is only made by the Master CPU!
- *
- */
-
-void
-sgi_master_io_infr_init(void)
-{
-	int cnode;
-	extern void kdba_io_init();
-
-	/*
-	 * Do any early init stuff .. einit_tbl[] etc.
-	 */
-	init_hcl(); /* Sets up the hwgraph compatibility layer with devfs */
-
-	/*
-	 * initialize the Linux PCI to xwidget vertexes ..
-	 */
-	pci_bus_cvlink_init();
-
-	kdba_io_init();
-
-#ifdef BRINGUP
-	/*
-	 * Hack to provide statically initialzed klgraph entries.
-	 */
-	DBG("--> sgi_master_io_infr_init: calling klgraph_hack_init()\n");
-	klgraph_hack_init();
-#endif /* BRINGUP */
-
-	/*
-	 * This is the Master CPU.  Emulate mlsetup and main.c in Irix.
-	 */
-	mlreset();
-
-	/*
-	 * allowboot() is called by kern/os/main.c in main()
-	 * Emulate allowboot() ...
-	 *   per_cpu_init() - only need per_hub_init()
-	 *   cpu_io_setup() - Nothing to do.
-	 * 
-	 */
-	sn_mp_setup();
-
-	for (cnode = 0; cnode < numnodes; cnode++) {
-		per_hub_init(cnode);
-	}
-
-	/* We can do headless hub cnodes here .. */
-
-	/*
-	 * io_init[] stuff.
-	 *
-	 * Get SGI IO Infrastructure drivers to init and register with 
-	 * each other etc.
-	 */
-
-	hubspc_init();
-	pciio_init();
-	pcibr_init();
-	pic_init();
-	xtalk_init();
-	xbow_init();
-	xbmon_init();
-	pciiox_init();
-	usrpci_init();
-	ioc3_init();
-
-	/*
-	 *
-	 * Our IO Infrastructure drivers are in place .. 
-	 * Initialize the whole IO Infrastructure .. xwidget/device probes.
-	 *
-	 */
-	initialize_io();
-	pci_bus_to_hcl_cvlink();
-
-#ifdef CONFIG_PCIBA
-	DBG("--> sgi_master_io_infr_init: calling pciba_init()\n");
-#ifndef BRINGUP2
- 	pciba_init();
-#endif
-#endif
-}
-
-/*
- * One-time setup for MP SN.
- * Allocate per-node data, slurp prom klconfig information and
- * convert it to hwgraph information.
- */
-void
-sn_mp_setup(void)
-{
-	cpuid_t		cpu;
-
-	for (cpu = 0; cpu < NR_CPUS; cpu++) {
-		/* Skip holes in CPU space */
-		if (cpu_enabled(cpu)) {
-			init_platform_pda(cpu);
-		}
-	}
-
-	/*
-	 * Initialize platform-dependent vertices in the hwgraph:
-	 *	module
-	 *	node
-	 *	cpu
-	 *	memory
-	 *	slot
-	 *	hub
-	 *	router
-	 *	xbow
-	 */
-
-	io_module_init(); /* Use to be called module_init() .. */
-	klhwg_add_all_modules(hwgraph_root);
-	klhwg_add_all_nodes(hwgraph_root);
-}
diff -Nru a/arch/ia64/sn/io/sn2/shub.c b/arch/ia64/sn/io/sn2/shub.c
--- a/arch/ia64/sn/io/sn2/shub.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/sn/io/sn2/shub.c	Wed Jun 18 23:42:07 2003
@@ -97,6 +97,14 @@
 }
 
 static inline void
+shub_mmr_write_iospace(cnodeid_t cnode, shubreg_t reg, uint64_t val)
+{
+	int		   nasid = cnodeid_to_nasid(cnode);
+
+	REMOTE_HUB_S(nasid, reg, val);
+}
+
+static inline void
 shub_mmr_write32(cnodeid_t cnode, shubreg_t reg, uint32_t val)
 {
 	int		   nasid = cnodeid_to_nasid(cnode);
@@ -118,6 +126,14 @@
 	return val;
 }
 
+static inline uint64_t
+shub_mmr_read_iospace(cnodeid_t cnode, shubreg_t reg)
+{
+	int		  nasid = cnodeid_to_nasid(cnode);
+
+	return REMOTE_HUB_L(nasid, reg);
+}
+
 static inline uint32_t
 shub_mmr_read32(cnodeid_t cnode, shubreg_t reg)
 {
@@ -182,11 +198,9 @@
 {
         cnodeid_t       cnode;
         uint64_t        longarg;
-        devfs_handle_t  d;
+        vertex_hdl_t	d;
 	int		nasid;
 
-        if ((d = devfs_get_handle_from_inode(inode)) == NULL)
-                return -ENODEV;
         cnode = (cnodeid_t)hwgraph_fastinfo_get(d);
 
         switch (cmd) {
@@ -231,3 +245,252 @@
 struct file_operations shub_mon_fops = {
 	        ioctl:          shubstats_ioctl,
 };
+
+/*
+ * "linkstatd" kernel thread to export SGI Numalink
+ * stats via /proc/sgi_sn/linkstats
+ */
+static struct s_linkstats {
+	uint64_t	hs_ni_sn_errors[2];
+	uint64_t	hs_ni_cb_errors[2];
+	uint64_t	hs_ni_retry_errors[2];
+	int		hs_ii_up;
+	uint64_t	hs_ii_sn_errors;
+	uint64_t	hs_ii_cb_errors;
+	uint64_t	hs_ii_retry_errors;
+} *sn_linkstats;
+
+static spinlock_t    sn_linkstats_lock;
+static unsigned long sn_linkstats_starttime;
+static unsigned long sn_linkstats_samples;
+static unsigned long sn_linkstats_overflows;
+static unsigned long sn_linkstats_update_msecs;
+
+void
+sn_linkstats_reset(unsigned long msecs)
+{
+	int		    cnode;
+	uint64_t	    iio_wstat;
+	uint64_t	    llp_csr_reg;
+
+	spin_lock(&sn_linkstats_lock);
+	memset(sn_linkstats, 0, numnodes * sizeof(struct s_linkstats));
+	for (cnode=0; cnode < numnodes; cnode++) {
+	    shub_mmr_write(cnode, SH_NI0_LLP_ERR, 0L);
+	    shub_mmr_write(cnode, SH_NI1_LLP_ERR, 0L);
+	    shub_mmr_write_iospace(cnode, IIO_LLP_LOG, 0L);
+
+	    /* zero the II retry counter */
+	    iio_wstat = shub_mmr_read_iospace(cnode, IIO_WSTAT);
+	    iio_wstat &= 0xffffffffff00ffff; /* bits 23:16 */
+	    shub_mmr_write_iospace(cnode, IIO_WSTAT, iio_wstat);
+
+	    /* Check if the II xtalk link is working */
+	    llp_csr_reg = shub_mmr_read_iospace(cnode, IIO_LLP_CSR);
+	    if (llp_csr_reg & IIO_LLP_CSR_IS_UP)
+		sn_linkstats[cnode].hs_ii_up = 1;
+	}
+
+    	sn_linkstats_update_msecs = msecs;
+	sn_linkstats_samples = 0;
+	sn_linkstats_overflows = 0;
+	sn_linkstats_starttime = jiffies;
+	spin_unlock(&sn_linkstats_lock);
+}
+
+int
+linkstatd_thread(void *unused)
+{
+	int		    cnode;
+	int		    overflows;
+	uint64_t	    reg[2];
+	uint64_t	    iio_wstat = 0L;
+	ii_illr_u_t	    illr;
+	struct s_linkstats  *lsp;
+	struct task_struct  *tsk = current;
+
+	daemonize("linkstatd");
+	set_user_nice(tsk, 19);
+	sigfillset(&tsk->blocked);
+	strcpy(tsk->comm, "linkstatd");
+
+	while(1) {
+		set_current_state(TASK_INTERRUPTIBLE);
+		schedule_timeout(sn_linkstats_update_msecs * HZ / 1000);
+
+		spin_lock(&sn_linkstats_lock);
+
+		overflows = 0;
+		for (lsp=sn_linkstats, cnode=0; cnode < numnodes; cnode++, lsp++) {
+			reg[0] = shub_mmr_read(cnode, SH_NI0_LLP_ERR);
+			reg[1] = shub_mmr_read(cnode, SH_NI1_LLP_ERR);
+			if (lsp->hs_ii_up) {
+			    illr = (ii_illr_u_t)shub_mmr_read_iospace(cnode, IIO_LLP_LOG);
+			    iio_wstat = shub_mmr_read_iospace(cnode, IIO_WSTAT);
+			}
+
+			if (!overflows && (
+			    (reg[0] & SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_MASK) == 
+				     SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_MASK ||
+			    (reg[0] & SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_MASK) ==
+			             SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_MASK ||
+			    (reg[1] & SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_MASK) ==
+			             SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_MASK ||
+			    (reg[1] & SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_MASK) ==
+			             SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_MASK ||
+			    (lsp->hs_ii_up && illr.ii_illr_fld_s.i_sn_cnt == IIO_LLP_SN_MAX) ||
+			    (lsp->hs_ii_up && illr.ii_illr_fld_s.i_cb_cnt == IIO_LLP_CB_MAX))) {
+			    overflows = 1;
+			}
+
+#define LINKSTAT_UPDATE(reg, cnt, mask, shift) cnt += (reg & mask) >> shift
+
+			LINKSTAT_UPDATE(reg[0], lsp->hs_ni_sn_errors[0],
+					SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_MASK,
+					SH_NI0_LLP_ERR_RX_SN_ERR_COUNT_SHFT);
+
+			LINKSTAT_UPDATE(reg[1], lsp->hs_ni_sn_errors[1],
+					SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_MASK,
+					SH_NI1_LLP_ERR_RX_SN_ERR_COUNT_SHFT);
+
+			LINKSTAT_UPDATE(reg[0], lsp->hs_ni_cb_errors[0],
+					SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_MASK,
+					SH_NI0_LLP_ERR_RX_CB_ERR_COUNT_SHFT);
+
+			LINKSTAT_UPDATE(reg[1], lsp->hs_ni_cb_errors[1],
+					SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_MASK,
+					SH_NI1_LLP_ERR_RX_CB_ERR_COUNT_SHFT);
+
+			LINKSTAT_UPDATE(reg[0], lsp->hs_ni_retry_errors[0],
+					SH_NI0_LLP_ERR_RETRY_COUNT_MASK,
+					SH_NI0_LLP_ERR_RETRY_COUNT_SHFT);
+
+			LINKSTAT_UPDATE(reg[1], lsp->hs_ni_retry_errors[1],
+					SH_NI1_LLP_ERR_RETRY_COUNT_MASK,
+					SH_NI1_LLP_ERR_RETRY_COUNT_SHFT);
+
+			if (lsp->hs_ii_up) {
+			    /* II sn and cb errors */
+			    lsp->hs_ii_sn_errors += illr.ii_illr_fld_s.i_sn_cnt;
+			    lsp->hs_ii_cb_errors += illr.ii_illr_fld_s.i_cb_cnt;
+			    lsp->hs_ii_retry_errors += (iio_wstat & 0x0000000000ff0000) >> 16;
+
+			    shub_mmr_write(cnode, SH_NI0_LLP_ERR, 0L);
+			    shub_mmr_write(cnode, SH_NI1_LLP_ERR, 0L);
+			    shub_mmr_write_iospace(cnode, IIO_LLP_LOG, 0L);
+
+			    /* zero the II retry counter */
+			    iio_wstat = shub_mmr_read_iospace(cnode, IIO_WSTAT);
+			    iio_wstat &= 0xffffffffff00ffff; /* bits 23:16 */
+			    shub_mmr_write_iospace(cnode, IIO_WSTAT, iio_wstat);
+			}
+		}
+
+		sn_linkstats_samples++;
+		if (overflows)
+		    sn_linkstats_overflows++;
+
+		spin_unlock(&sn_linkstats_lock);
+	}
+}
+
+static char *
+rate_per_minute(uint64_t val, uint64_t secs)
+{
+	static char	buf[16];
+	uint64_t	a=0, b=0, c=0, d=0;
+
+	if (secs) {
+		a = 60 * val / secs;
+		b = 60 * 10 * val / secs - (10 * a);
+		c = 60 * 100 * val / secs - (100 * a) - (10 * b);
+		d = 60 * 1000 * val / secs - (1000 * a) - (100 * b) - (10 * c);
+	}
+	sprintf(buf, "%4lu.%lu%lu%lu", a, b, c, d);
+
+	return buf;
+}
+
+int
+sn_linkstats_get(char *page)
+{
+	int			n = 0;
+	int			cnode;
+	int			nlport;
+	struct s_linkstats	*lsp;
+	nodepda_t		*npda;
+	uint64_t	    	snsum = 0;
+	uint64_t	    	cbsum = 0;
+	uint64_t	    	retrysum = 0;
+	uint64_t	    	snsum_ii = 0;
+	uint64_t	    	cbsum_ii = 0;
+	uint64_t	    	retrysum_ii = 0;
+	uint64_t		secs;
+
+	spin_lock(&sn_linkstats_lock);
+	secs = (jiffies - sn_linkstats_starttime) / HZ;
+
+	n += sprintf(page, "# SGI Numalink stats v1 : %lu samples, %lu o/flows, update %lu msecs\n",
+		sn_linkstats_samples, sn_linkstats_overflows, sn_linkstats_update_msecs);
+
+	n += sprintf(page+n, "%-37s %8s %8s %8s %8s\n",
+		"# Numalink", "sn errs", "cb errs", "cb/min", "retries");
+
+	for (lsp=sn_linkstats, cnode=0; cnode < numnodes; cnode++, lsp++) {
+		npda = NODEPDA(cnode);
+
+		/* two NL links on each SHub */
+		for (nlport=0; nlport < 2; nlport++) {
+			cbsum += lsp->hs_ni_cb_errors[nlport];
+			snsum += lsp->hs_ni_sn_errors[nlport];
+			retrysum += lsp->hs_ni_retry_errors[nlport];
+
+			/* avoid buffer overrun (should be using seq_read API) */
+			if (numnodes > 64)
+				continue;
+
+			n += sprintf(page + n, "/%s/link/%d  %8lu %8lu %8s %8lu\n",
+			    npda->hwg_node_name, nlport+1, lsp->hs_ni_sn_errors[nlport],
+			    lsp->hs_ni_cb_errors[nlport], 
+			    rate_per_minute(lsp->hs_ni_cb_errors[nlport], secs),
+			    lsp->hs_ni_retry_errors[nlport]);
+		}
+
+		/* one II port on each SHub (may not be connected) */
+		if (lsp->hs_ii_up) {
+		    n += sprintf(page + n, "/%s/xtalk   %8lu %8lu %8s %8lu\n",
+			npda->hwg_node_name, lsp->hs_ii_sn_errors,
+			lsp->hs_ii_cb_errors, rate_per_minute(lsp->hs_ii_cb_errors, secs),
+			lsp->hs_ii_retry_errors);
+
+		    snsum_ii += lsp->hs_ii_sn_errors;
+		    cbsum_ii += lsp->hs_ii_cb_errors;
+		    retrysum_ii += lsp->hs_ii_retry_errors;
+		}
+	}
+
+	n += sprintf(page + n, "%-37s %8lu %8lu %8s %8lu\n",
+		"System wide NL totals", snsum, cbsum, 
+		rate_per_minute(cbsum, secs), retrysum);
+
+	n += sprintf(page + n, "%-37s %8lu %8lu %8s %8lu\n",
+		"System wide II totals", snsum_ii, cbsum_ii, 
+		rate_per_minute(cbsum_ii, secs), retrysum_ii);
+
+	spin_unlock(&sn_linkstats_lock);
+
+	return n;
+}
+
+static int __init
+linkstatd_init(void)
+{
+	spin_lock_init(&sn_linkstats_lock);
+	sn_linkstats = kmalloc(numnodes * sizeof(struct s_linkstats), GFP_KERNEL);
+	sn_linkstats_reset(60000UL); /* default 60 second update interval */
+	kernel_thread(linkstatd_thread, NULL, CLONE_FS | CLONE_FILES);
+
+	return 0;                                                                       
+}
+
+__initcall(linkstatd_init);
diff -Nru a/arch/ia64/sn/io/sn2/shub_intr.c b/arch/ia64/sn/io/sn2/shub_intr.c
--- a/arch/ia64/sn/io/sn2/shub_intr.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/sn/io/sn2/shub_intr.c	Wed Jun 18 23:42:07 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #include <linux/types.h>
@@ -30,7 +30,7 @@
 
 /* ARGSUSED */
 void
-hub_intr_init(devfs_handle_t hubv)
+hub_intr_init(vertex_hdl_t hubv)
 {
 }
 
@@ -45,9 +45,9 @@
 }
 
 static hub_intr_t
-do_hub_intr_alloc(devfs_handle_t dev,
+do_hub_intr_alloc(vertex_hdl_t dev,
 		device_desc_t dev_desc,
-		devfs_handle_t owner_dev,
+		vertex_hdl_t owner_dev,
 		int uncond_nothread)
 {
 	cpuid_t		cpu = 0;
@@ -71,7 +71,7 @@
 	cpuphys = cpu_physical_id(cpu);
 	slice = cpu_physical_id_to_slice(cpuphys);
 	nasid = cpu_physical_id_to_nasid(cpuphys);
-	cnode = cpu_to_node_map[cpu];
+	cnode = cpuid_to_cnodeid(cpu);
 
 	if (slice) {
 		xtalk_addr = SH_II_INT1 | ((unsigned long)nasid << 36) | (1UL << 47);
@@ -101,17 +101,17 @@
 }
 
 hub_intr_t
-hub_intr_alloc(devfs_handle_t dev,
+hub_intr_alloc(vertex_hdl_t dev,
 		device_desc_t dev_desc,
-		devfs_handle_t owner_dev)
+		vertex_hdl_t owner_dev)
 {
 	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 0));
 }
 
 hub_intr_t
-hub_intr_alloc_nothd(devfs_handle_t dev,
+hub_intr_alloc_nothd(vertex_hdl_t dev,
 		device_desc_t dev_desc,
-		devfs_handle_t owner_dev)
+		vertex_hdl_t owner_dev)
 {
 	return(do_hub_intr_alloc(dev, dev_desc, owner_dev, 1));
 }
@@ -187,19 +187,4 @@
 	rv = intr_disconnect_level(cpu, bit);
 	ASSERT(rv == 0);
 	intr_hdl->i_flags &= ~HUB_INTR_IS_CONNECTED;
-}
-
-
-/*
- * Return a hwgraph vertex that represents the CPU currently
- * targeted by an interrupt.
- */
-devfs_handle_t
-hub_intr_cpu_get(hub_intr_t intr_hdl)
-{
-	cpuid_t cpuid = intr_hdl->i_cpuid;
-
-	ASSERT(cpuid != CPU_NONE);
-
-	return(cpuid_to_vertex(cpuid));
 }
diff -Nru a/arch/ia64/sn/io/sn2/shuberror.c b/arch/ia64/sn/io/sn2/shuberror.c
--- a/arch/ia64/sn/io/sn2/shuberror.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/sn/io/sn2/shuberror.c	Wed Jun 18 23:42:09 2003
@@ -4,13 +4,14 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000,2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000,2002-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/irq.h>
+#include <asm/io.h>
 #include <asm/irq.h>
 #include <asm/smp.h>
 #include <asm/sn/sgi.h>
@@ -27,28 +28,26 @@
 #include <asm/sn/xtalk/xtalk.h>
 #include <asm/sn/pci/pcibr_private.h>
 #include <asm/sn/intr.h>
+#include <asm/sn/ioerror_handling.h>
 #include <asm/sn/ioerror.h>
 #include <asm/sn/sn2/shubio.h>
 #include <asm/sn/bte.h>
 
 extern void hubni_eint_init(cnodeid_t cnode);
 extern void hubii_eint_init(cnodeid_t cnode);
-extern void hubii_eint_handler (int irq, void *arg, struct pt_regs *ep);
-int hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo);
-int hubiio_prb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo);
-extern void bte_crb_error_handler(devfs_handle_t hub_v, int btenum, int crbnum, ioerror_t *ioe, int bteop);
+extern irqreturn_t hubii_eint_handler (int irq, void *arg, struct pt_regs *ep);
+int hubiio_crb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo);
+int hubiio_prb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo);
+extern void bte_crb_error_handler(vertex_hdl_t hub_v, int btenum, int crbnum, ioerror_t *ioe, int bteop);
+void print_crb_fields(int crb_num, ii_icrb0_a_u_t icrba,
+	ii_icrb0_b_u_t icrbb, ii_icrb0_c_u_t icrbc,
+	ii_icrb0_d_u_t icrbd, ii_icrb0_e_u_t icrbe);
 
 extern int maxcpus;
+extern error_return_code_t error_state_set(vertex_hdl_t v,error_state_t new_state);
 
 #define HUB_ERROR_PERIOD        (120 * HZ)      /* 2 minutes */
 
-#ifdef BUS_INT_WAR
-void sn_add_polled_interrupt(int irq, int interval);
-void sn_delete_polled_interrupt(int irq);
-extern int bus_int_war_ide_irq;
-#endif
-
-
 void
 hub_error_clear(nasid_t nasid)
 {
@@ -74,9 +73,7 @@
         REMOTE_HUB_S(nasid, IIO_IOPRB_0 + (i * sizeof(hubreg_t)), prb.iprb_regval);
     }
 
-    REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, -1);
-    idsr = REMOTE_HUB_L(nasid, IIO_IIDSR);
-    REMOTE_HUB_S(nasid, IIO_IIDSR, (idsr & ~(IIO_IIDSR_SENT_MASK)));
+    REMOTE_HUB_S(nasid, IIO_IECLR, -1);
 
 }
 
@@ -117,7 +114,6 @@
  * Returns	: None.
  */
 
-
 void
 hubii_eint_init(cnodeid_t cnode)
 {
@@ -125,33 +121,41 @@
     ii_iidsr_u_t    	hubio_eint;
     hubinfo_t		hinfo; 
     cpuid_t		intr_cpu;
-    devfs_handle_t 	hub_v;
+    vertex_hdl_t 	hub_v;
     int bit_pos_to_irq(int bit);
+    ii_ilcsr_u_t	ilcsr;
 
 
-    hub_v = (devfs_handle_t)cnodeid_to_vertex(cnode);
+    hub_v = (vertex_hdl_t)cnodeid_to_vertex(cnode);
     ASSERT_ALWAYS(hub_v);
     hubinfo_get(hub_v, &hinfo);
 
     ASSERT(hinfo);
     ASSERT(hinfo->h_cnodeid == cnode);
 
+    ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR);
+    if ((ilcsr.ii_ilcsr_fld_s.i_llp_stat & 0x2) == 0) {
+	/*
+	 * HUB II link is not up.  Disable LLP. Clear old errors.
+	 * Enable interrupts to handle BTE errors.
+	 */
+	ilcsr.ii_ilcsr_fld_s.i_llp_en = 0;
+	REMOTE_HUB_S(hinfo->h_nasid, IIO_ILCSR, ilcsr.ii_ilcsr_regval);
+    }
+
     /* Select a possible interrupt target where there is a free interrupt
      * bit and also reserve the interrupt bit for this IO error interrupt
      */
-    intr_cpu = intr_heuristic(hub_v,0,-1,0,hub_v,
+    intr_cpu = intr_heuristic(hub_v,0,SGI_II_ERROR,0,hub_v,
 			      "HUB IO error interrupt",&bit);
     if (intr_cpu == CPU_NONE) {
 	printk("hubii_eint_init: intr_reserve_level failed, cnode %d", cnode);
 	return;
     }
 	
-    rv = intr_connect_level(intr_cpu, bit, 0, NULL);
-    request_irq(bit + (intr_cpu << 8), hubii_eint_handler, 0, "SN_hub_error", (void *)hub_v);
-    irq_desc(bit + (intr_cpu << 8))->status |= SN2_IRQ_PER_HUB;
-#ifdef BUS_INT_WAR                                              
-    sn_add_polled_interrupt(bit + (intr_cpu << 8), (0.01 * HZ));
-#endif
+    rv = intr_connect_level(intr_cpu, SGI_II_ERROR, 0, NULL);
+    request_irq(SGI_II_ERROR, hubii_eint_handler, SA_SHIRQ, "SN_hub_error", (void *)hub_v);
+    irq_desc(bit)->status |= SN2_IRQ_PER_HUB;
     ASSERT_ALWAYS(rv >= 0);
     hubio_eint.ii_iidsr_regval = 0;
     hubio_eint.ii_iidsr_fld_s.i_enable = 1;
@@ -164,21 +168,32 @@
 
 
 /*ARGSUSED*/
-void
+irqreturn_t
 hubii_eint_handler (int irq, void *arg, struct pt_regs *ep)
 {
-    devfs_handle_t	hub_v;
+    vertex_hdl_t	hub_v;
     hubinfo_t		hinfo; 
     ii_wstat_u_t	wstat;
     hubreg_t		idsr;
+    ii_ilcsr_u_t	ilcsr;
 
 
     /* two levels of casting avoids compiler warning.!! */
-    hub_v = (devfs_handle_t)(long)(arg); 
+    hub_v = (vertex_hdl_t)(long)(arg); 
     ASSERT(hub_v);
 
     hubinfo_get(hub_v, &hinfo);
     
+    idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_ICMR);
+#if 0
+    if (idsr & 0x1) {
+	/* ICMR bit is set .. we are getting into "Spurious Interrupts condition. */
+	printk("Cnode %d II has seen the ICMR condition\n", hinfo->h_cnodeid);
+	printk("***** Please file PV with the above messages *****\n");
+	/* panic("We have to panic to prevent further unknown states ..\n"); */
+    }
+#endif
+	
     /* 
      * Identify the reason for error. 
      */
@@ -218,10 +233,26 @@
 	 * Note: we may never be able to print this, if the II talking
 	 * to Xbow which hosts the console is dead. 
 	 */
-	printk("Hub %d to Xtalk Link failed (II_ECRAZY) Reason: %s", 
-		hinfo->h_cnodeid, reason);
+	ilcsr.ii_ilcsr_regval = REMOTE_HUB_L(hinfo->h_nasid, IIO_ILCSR);
+	if (ilcsr.ii_ilcsr_fld_s.i_llp_en == 1) {	/* Link is enabled */
+	    printk("Hub %d, cnode %d to Xtalk Link failed (II_ECRAZY) Reason: %s", 
+		hinfo->h_nasid, hinfo->h_cnodeid, reason);
+	}
     }
 
+
+    /*
+     * Before processing any interrupt related information, clear all
+     * error indication and reenable interrupts.  This will prevent
+     * lost interrupts due to the interrupt handler scanning past a PRB/CRB
+     * which has not errorred yet and then the PRB/CRB goes into error.
+     * Note, PRB errors are cleared individually.
+     */
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IECLR, 0xff0000);
+    idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_IIDSR) & ~IIO_IIDSR_SENT_MASK;
+    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, idsr);
+
+
     /* 
      * It's a toss as to which one among PRB/CRB to check first. 
      * Current decision is based on the severity of the errors. 
@@ -232,14 +263,8 @@
      */
     (void)hubiio_crb_error_handler(hub_v, hinfo);
     (void)hubiio_prb_error_handler(hub_v, hinfo);
-    /*
-     * If we reach here, it indicates crb/prb handlers successfully
-     * handled the error. So, re-enable II to send more interrupt
-     * and return.
-     */
-    REMOTE_HUB_S(hinfo->h_nasid, IIO_IECLR, 0xffffff);
-    idsr = REMOTE_HUB_L(hinfo->h_nasid, IIO_IIDSR) & ~IIO_IIDSR_SENT_MASK;
-    REMOTE_HUB_S(hinfo->h_nasid, IIO_IIDSR, idsr);
+
+    return IRQ_HANDLED;
 }
 
 /*
@@ -295,6 +320,105 @@
 	"Xtalk Error Packet"
 };
 
+void
+print_crb_fields(int crb_num, ii_icrb0_a_u_t icrba,
+	ii_icrb0_b_u_t icrbb, ii_icrb0_c_u_t icrbc,
+	ii_icrb0_d_u_t icrbd, ii_icrb0_e_u_t icrbe)
+{
+    printk("CRB %d regA\n\t"
+	    "a_iow 0x%x\n\t"
+	    "valid0x%x\n\t"
+	    "Address0x%lx\n\t"
+	    "a_tnum 0x%x\n\t"
+	    "a_sidn 0x%x\n",
+	    crb_num,
+	    icrba.a_iow, 
+	    icrba.a_valid, 
+	    icrba.a_addr, 
+	    icrba.a_tnum, 
+	    icrba.a_sidn);
+    printk("CRB %d regB\n\t"
+	    "b_imsgtype 0x%x\n\t"
+	    "b_imsg 0x%x\n"
+	    "\tb_use_old 0x%x\n\t"
+	    "b_initiator 0x%x\n\t"
+	    "b_exc 0x%x\n"
+	    "\tb_ackcnt 0x%x\n\t"
+	    "b_resp 0x%x\n\t"
+	    "b_ack 0x%x\n"
+	    "\tb_hold 0x%x\n\t"
+	    "b_wb 0x%x\n\t"
+	    "b_intvn 0x%x\n"
+	    "\tb_stall_ib 0x%x\n\t"
+	    "b_stall_int 0x%x\n"
+	    "\tb_stall_bte_0 0x%x\n\t"
+	    "b_stall_bte_1 0x%x\n"
+	    "\tb_error 0x%x\n\t"
+	    "b_lnetuce 0x%x\n\t"
+	    "b_mark 0x%x\n\t"
+	    "b_xerr 0x%x\n",
+	    crb_num,
+	    icrbb.b_imsgtype, 
+	    icrbb.b_imsg, 
+	    icrbb.b_use_old, 
+	    icrbb.b_initiator,
+	    icrbb.b_exc, 
+	    icrbb.b_ackcnt, 
+	    icrbb.b_resp, 
+	    icrbb.b_ack, 
+	    icrbb.b_hold,
+	    icrbb.b_wb, 
+	    icrbb.b_intvn, 
+	    icrbb.b_stall_ib, 
+	    icrbb.b_stall_int,
+	    icrbb.b_stall_bte_0, 
+	    icrbb.b_stall_bte_1, 
+	    icrbb.b_error,
+	    icrbb.b_lnetuce, 
+	    icrbb.b_mark, 
+	    icrbb.b_xerr);
+    printk("CRB %d regC\n\t"
+	    "c_source 0x%x\n\t"
+	    "c_xtsize 0x%x\n\t"
+	    "c_cohtrans 0x%x\n\t"
+	    "c_btenum 0x%x\n\t"
+	    "c_gbr 0x%x\n\t"
+	    "c_doresp 0x%x\n\t"
+	    "c_barrop 0x%x\n\t"
+	    "c_suppl 0x%x\n",
+	    crb_num,
+	    icrbc.c_source,
+	    icrbc.c_xtsize,
+	    icrbc.c_cohtrans,
+	    icrbc.c_btenum,
+	    icrbc.c_gbr,
+	    icrbc.c_doresp,
+	    icrbc.c_barrop,
+	    icrbc.c_suppl);
+    printk("CRB %d regD\n\t"
+	    "d_bteaddr 0x%lx\n\t"
+	    "d_bteop 0x%x\n\t"
+	    "d_pripsc 0x%x\n\t"
+	    "d_pricnt 0x%x\n\t"
+	    "d_sleep 0x%x\n\t",
+	    crb_num,
+	    icrbd.d_bteaddr,
+	    icrbd.d_bteop,
+	    icrbd.d_pripsc,
+	    icrbd.d_pricnt,
+	    icrbd.d_sleep);
+    printk("CRB %d regE\n\t"
+	    "icrbe_timeout 0x%x\n\t"
+	    "icrbe_context 0x%x\n\t"
+	    "icrbe_toutvld 0x%x\n\t"
+	    "icrbe_ctxtvld 0x%x\n\t",
+	    crb_num,
+	    icrbe.icrbe_timeout,
+	    icrbe.icrbe_context,
+	    icrbe.icrbe_toutvld,
+	    icrbe.icrbe_ctxtvld);
+}
+
 /*
  * hubiio_crb_error_handler
  *
@@ -317,7 +441,7 @@
  */
 
 int
-hubiio_crb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo)
+hubiio_crb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo)
 {
 	cnodeid_t	cnode;
 	nasid_t		nasid;
@@ -335,6 +459,9 @@
 	cnode = NASID_TO_COMPACT_NODEID(nasid);
 
 	/*
+	 * XXX - Add locking for any recovery actions
+	 */
+	/*
 	 * Scan through all CRBs in the Hub, and handle the errors
 	 * in any of the CRBs marked.
 	 */
@@ -373,16 +500,11 @@
 			else /* b_initiator bit 2 gives BTE number */
 				bte_num = (icrbb.b_initiator & 0x4) >> 2;
 
-			/* >>> bte_crb_error_handler needs to be 
-			 * broken into two parts.  The first should
-			 * cleanup the CRB.  The second should wait
-			 * until all bte related CRB's are complete
-			 * and then do the error reset.
-			 */
+			hubiio_crb_free(hinfo, i);
+
 			bte_crb_error_handler(hub_v, bte_num,
 					      i, &ioerror,
 					      icrbd.d_bteop);
-			hubiio_crb_free(hinfo, i);
 			num_errors++;
 			continue;
 		}
@@ -430,6 +552,86 @@
 			IOERROR_SETVALUE(&ioerror, tnum, icrba.a_tnum);
 
 		}
+		if (icrbb.b_error) {
+		    /*
+		     * CRB 'i' has some error. Identify the type of error,
+		     * and try to handle it.
+		     *
+		     */
+		    switch(icrbb.b_ecode) {
+			case IIO_ICRB_ECODE_PERR:
+			case IIO_ICRB_ECODE_WERR:
+			case IIO_ICRB_ECODE_AERR:
+			case IIO_ICRB_ECODE_PWERR:
+			case IIO_ICRB_ECODE_TOUT:
+			case IIO_ICRB_ECODE_XTERR:
+			    printk("Shub II CRB %d: error %s on hub cnodeid: %d",
+				    i, hubiio_crb_errors[icrbb.b_ecode], cnode);
+			    /*
+			     * Any sort of write error is mostly due
+			     * bad programming (Note it's not a timeout.)
+			     * So, invoke hub_iio_error_handler with
+			     * appropriate information.
+			     */
+			    IOERROR_SETVALUE(&ioerror,errortype,icrbb.b_ecode);
+
+			    /* Go through the error bit lookup phase */
+			    if (error_state_set(hub_v, ERROR_STATE_LOOKUP) ==
+				    ERROR_RETURN_CODE_CANNOT_SET_STATE)
+				return(IOERROR_UNHANDLED);
+			    rc = hub_ioerror_handler(
+				    hub_v,
+				    DMA_WRITE_ERROR,
+				    MODE_DEVERROR,
+				    &ioerror);
+			    if (rc == IOERROR_HANDLED) {
+				rc = hub_ioerror_handler(
+					hub_v,
+					DMA_WRITE_ERROR,
+					MODE_DEVREENABLE,
+					&ioerror);
+			    }else {
+				printk("Unable to handle %s on hub %d",
+					hubiio_crb_errors[icrbb.b_ecode],
+					cnode);
+				/* panic; */
+			    }
+			    /* Go to Next error */
+			    print_crb_fields(i, icrba, icrbb, icrbc,
+				    icrbd, icrbe);
+			    hubiio_crb_free(hinfo, i);
+			    continue;
+			case IIO_ICRB_ECODE_PRERR:
+			case IIO_ICRB_ECODE_DERR:
+			    printk("Shub II CRB %d: error %s on hub : %d",
+				    i, hubiio_crb_errors[icrbb.b_ecode], cnode);
+			    /* panic */
+			default:
+			    printk("Shub II CRB error (code : %d) on hub : %d",
+				    icrbb.b_ecode, cnode);
+			    /* panic */
+		    }
+		} 
+		/*
+		 * Error is not indicated via the errcode field
+		 * Check other error indications in this register.
+		 */
+		if (icrbb.b_xerr) {
+		    printk("Shub II CRB %d: Xtalk Packet with error bit set to hub %d",
+			    i, cnode);
+		    /* panic */
+		}
+		if (icrbb.b_lnetuce) {
+		    printk("Shub II CRB %d: Uncorrectable data error detected on data "
+			    " from NUMAlink to node %d",
+			    i, cnode);
+		    /* panic */
+		}
+		print_crb_fields(i, icrba, icrbb, icrbc, icrbd, icrbe);
+
+
+
+
 
 		if (icrbb.b_error) {
 		/* 
@@ -488,7 +690,7 @@
 		
 		default:
 			panic("Fatal error (code : %d) on hub : %d",
-				cnode);
+				icrbb.b_ecode, cnode);
 			/*NOTREACHED*/
 
 		}
@@ -568,7 +770,7 @@
  *      Cleanup involes freeing the PRB register
  */
 static void
-hubii_prb_handler(devfs_handle_t hub_v, hubinfo_t hinfo, int wnum)
+hubii_prb_handler(vertex_hdl_t hub_v, hubinfo_t hinfo, int wnum)
 {
         nasid_t         nasid;
 
@@ -576,13 +778,13 @@
         /*
          * Clear error bit by writing to IECLR register.
          */
-        REMOTE_HUB_S(nasid, IIO_IO_ERR_CLR, (1 << wnum));
+        REMOTE_HUB_S(nasid, IIO_IECLR, (1 << wnum));
         /*
          * PIO Write to Widget 'i' got into an error.
          * Invoke hubiio_error_handler with this information.
          */
-        printk( "Hub nasid %d got a PIO Write error from widget %d, cleaning up and continuing",
-                        nasid, wnum);
+        printk( "Hub nasid %d got a PIO Write error from widget %d, "
+				"cleaning up and continuing", nasid, wnum);
         /*
          * XXX
          * It may be necessary to adjust IO PRB counter
@@ -591,7 +793,7 @@
 }
 
 int
-hubiio_prb_error_handler(devfs_handle_t hub_v, hubinfo_t hinfo)
+hubiio_prb_error_handler(vertex_hdl_t hub_v, hubinfo_t hinfo)
 {
         int             wnum;
         nasid_t         nasid;
diff -Nru a/arch/ia64/sn/io/sn2/shubio.c b/arch/ia64/sn/io/sn2/shubio.c
--- a/arch/ia64/sn/io/sn2/shubio.c	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/sn/io/sn2/shubio.c	Wed Jun 18 23:42:08 2003
@@ -30,8 +30,8 @@
 #include <asm/sn/sn2/shubio.h>
 
 
-error_state_t error_state_get(devfs_handle_t v);
-error_return_code_t error_state_set(devfs_handle_t v,error_state_t new_state);
+error_state_t error_state_get(vertex_hdl_t v);
+error_return_code_t error_state_set(vertex_hdl_t v,error_state_t new_state);
 
 
 /*
@@ -42,7 +42,7 @@
 /*ARGSUSED*/
 int
 hub_xp_error_handler(
-	devfs_handle_t 	hub_v, 
+	vertex_hdl_t 	hub_v, 
 	nasid_t		nasid, 
 	int		error_code, 
 	ioerror_mode_t	mode, 
@@ -50,7 +50,7 @@
 {
 	/*REFERENCED*/
 	hubreg_t	iio_imem;
-	devfs_handle_t	xswitch;
+	vertex_hdl_t	xswitch;
 	error_state_t	e_state;
 	cnodeid_t	cnode;
 
@@ -148,7 +148,7 @@
  */
 int
 hub_ioerror_handler(
-	devfs_handle_t 	hub_v, 
+	vertex_hdl_t 	hub_v, 
 	int		error_code,
 	int		mode,
 	struct io_error_s	*ioerror)
@@ -158,6 +158,7 @@
 	int		retval = 0;
 	/*REFERENCED*/
 	iopaddr_t 	p;
+	caddr_t 	cp;
 
 	IOERROR_DUMP("hub_ioerror_handler", error_code, mode, ioerror);
 
@@ -193,14 +194,14 @@
 		 * This is typically true for user mode bus errors while
 		 * accessing I/O space.
 		 */
-		 IOERROR_GETVALUE(p,ioerror,vaddr);
-		 if (p){
+		 IOERROR_GETVALUE(cp,ioerror,vaddr);
+		 if (cp){
 		    /* 
 		     * If neither in small window nor in large window range,
 		     * outright reject it.
 		     */
-		    IOERROR_GETVALUE(p,ioerror,vaddr);
-		    if (NODE_SWIN_ADDR(nasid, (paddr_t)p)){
+		    IOERROR_GETVALUE(cp,ioerror,vaddr);
+		    if (NODE_SWIN_ADDR(nasid, (paddr_t)cp)){
 			iopaddr_t	hubaddr;
 			xwidgetnum_t	widgetnum;
 			iopaddr_t	xtalkaddr;
@@ -216,7 +217,7 @@
 			IOERROR_SETVALUE(ioerror,xtalkaddr,xtalkaddr);
 
 
-		    } else if (NODE_BWIN_ADDR(nasid, (paddr_t)p)){
+		    } else if (NODE_BWIN_ADDR(nasid, (paddr_t)cp)){
 			/* 
 			 * Address corresponds to large window space. 
 			 * Convert it to xtalk address.
@@ -428,11 +429,6 @@
 	return retval;
 }
 
-#define L_BITSMINOR 18
-#define L_MAXMAJ 0x1ff
-#define emajor(x) (int )(((unsigned )(x)>>L_BITSMINOR) & L_MAXMAJ)
-#define dev_is_vertex(dev) (emajor((dev_t)(dev)) == 0)
-
 #define INFO_LBL_ERROR_STATE    "error_state"
 
 #define v_error_state_get(v,s)                                          \
@@ -454,12 +450,12 @@
  *                      current state otherwise
  */
 error_state_t
-error_state_get(devfs_handle_t v)
+error_state_get(vertex_hdl_t v)
 {
         error_state_t   s;
 
         /* Check if we have a valid hwgraph vertex */
-        if (!dev_is_vertex(v))
+        if ( v == (vertex_hdl_t)0 )
                 return(ERROR_STATE_NONE);
 
         /* Get the labelled info hanging off the vertex which corresponds
@@ -479,13 +475,13 @@
  *                      ERROR_RETURN_CODE_SUCCESS otherwise
  */
 error_return_code_t
-error_state_set(devfs_handle_t v,error_state_t new_state)
+error_state_set(vertex_hdl_t v,error_state_t new_state)
 {
         error_state_t   old_state;
         boolean_t       replace = B_TRUE;
 
         /* Check if we have a valid hwgraph vertex */
-        if (!dev_is_vertex(v))
+        if ( v == (vertex_hdl_t)0 )
                 return(ERROR_RETURN_CODE_GENERAL_FAILURE);
 
 
diff -Nru a/arch/ia64/sn/io/sn2/xbow.c b/arch/ia64/sn/io/sn2/xbow.c
--- a/arch/ia64/sn/io/sn2/xbow.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/sn/io/sn2/xbow.c	Wed Jun 18 23:42:07 2003
@@ -11,6 +11,7 @@
 #include <linux/slab.h>
 #include <linux/module.h>
 #include <linux/sched.h>
+#include <linux/interrupt.h>
 #include <asm/sn/sgi.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/sn2/sn_private.h>
@@ -19,7 +20,6 @@
 #include <asm/sn/invent.h>
 #include <asm/sn/hcl.h>
 #include <asm/sn/labelcl.h>
-#include <asm/sn/hack.h>
 #include <asm/sn/pci/bridge.h>
 #include <asm/sn/xtalk/xtalk_private.h>
 #include <asm/sn/simulator.h>
@@ -45,8 +45,6 @@
 #define NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
 #define DEL(ptr)	(kfree(ptr))
 
-int                     xbow_devflag = D_MP;
-
 /*
  * This file supports the Xbow chip.  Main functions: initializtion,
  * error handling, and GBR.
@@ -60,9 +58,9 @@
 typedef struct xbow_soft_s *xbow_soft_t;
 
 struct xbow_soft_s {
-    devfs_handle_t            conn;	/* our connection point */
-    devfs_handle_t            vhdl;	/* xbow's private vertex */
-    devfs_handle_t            busv;	/* the xswitch vertex */
+    vertex_hdl_t            conn;	/* our connection point */
+    vertex_hdl_t            vhdl;	/* xbow's private vertex */
+    vertex_hdl_t            busv;	/* the xswitch vertex */
     xbow_t                 *base;	/* PIO pointer to crossbow chip */
     char                   *name;	/* hwgraph name */
 
@@ -90,36 +88,27 @@
  */
 
 void                    xbow_mlreset(xbow_t *);
-void                    xbow_init(void);
-int                     xbow_attach(devfs_handle_t);
-
-int                     xbow_open(devfs_handle_t *, int, int, cred_t *);
-int                     xbow_close(devfs_handle_t, int, int, cred_t *);
-
-int                     xbow_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint);
-int                     xbow_unmap(devfs_handle_t, vhandl_t *);
-int                     xbow_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *);
+int                     xbow_attach(vertex_hdl_t);
 
 int                     xbow_widget_present(xbow_t *, int);
 static int              xbow_link_alive(xbow_t *, int);
-devfs_handle_t            xbow_widget_lookup(devfs_handle_t, int);
+vertex_hdl_t            xbow_widget_lookup(vertex_hdl_t, int);
 
 void                    xbow_intr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
 
 
 
-void                    xbow_update_perf_counters(devfs_handle_t);
-xbow_perf_link_t       *xbow_get_perf_counters(devfs_handle_t);
-int                     xbow_enable_perf_counter(devfs_handle_t, int, int, int);
-xbow_link_status_t     *xbow_get_llp_status(devfs_handle_t);
-void                    xbow_update_llp_status(devfs_handle_t);
-
-int                     xbow_disable_llp_monitor(devfs_handle_t);
-int                     xbow_enable_llp_monitor(devfs_handle_t);
-int                     xbow_prio_bw_alloc(devfs_handle_t, xwidgetnum_t, xwidgetnum_t,
+void                    xbow_update_perf_counters(vertex_hdl_t);
+xbow_perf_link_t       *xbow_get_perf_counters(vertex_hdl_t);
+int                     xbow_enable_perf_counter(vertex_hdl_t, int, int, int);
+xbow_link_status_t     *xbow_get_llp_status(vertex_hdl_t);
+void                    xbow_update_llp_status(vertex_hdl_t);
+
+int                     xbow_disable_llp_monitor(vertex_hdl_t);
+int                     xbow_enable_llp_monitor(vertex_hdl_t);
+int                     xbow_prio_bw_alloc(vertex_hdl_t, xwidgetnum_t, xwidgetnum_t,
                                 unsigned long long, unsigned long long);
 static void		xbow_setwidint(xtalk_intr_t);
-void                    idbg_xbowregs(int64_t);
 
 xswitch_reset_link_f    xbow_reset_link;
 
@@ -128,32 +117,6 @@
     xbow_reset_link,
 };
 
-/*
- * This is the file operation table for the pcibr driver.
- * As each of the functions are implemented, put the
- * appropriate function name below.
- */
-static int xbow_mmap(struct file * file, struct vm_area_struct * vma);
-struct file_operations xbow_fops = {
-        owner:  THIS_MODULE,
-        llseek: NULL,
-        read: NULL,
-        write: NULL,
-        readdir: NULL,
-        poll: NULL,
-        ioctl: NULL,
-        mmap: xbow_mmap,
-        open: xbow_open,
-        flush: NULL,
-        release: NULL,
-        fsync: NULL,
-        fasync: NULL,
-        lock: NULL,
-        readv: NULL,
-        writev: NULL,
-        sendpage: NULL,
-        get_unmapped_area: NULL
-};
 
 static int
 xbow_mmap(struct file * file, struct vm_area_struct * vma)
@@ -164,12 +127,21 @@
         phys_addr = (unsigned long)file->private_data & ~0xc000000000000000; /* Mask out the Uncache bits */
         vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
         vma->vm_flags |= VM_RESERVED | VM_IO;
-        error = io_remap_page_range(vma, vma->vm_start, phys_addr,
-                                   vma->vm_end - vma->vm_start,
+        error = io_remap_page_range(vma, phys_addr, vma->vm_start,
+                                   vma->vm_end-vma->vm_start,
                                    vma->vm_page_prot);
         return(error);
 }
 
+/*
+ * This is the file operation table for the pcibr driver.
+ * As each of the functions are implemented, put the
+ * appropriate function name below.
+ */
+struct file_operations xbow_fops = {
+        .owner		= THIS_MODULE,
+        .mmap		= xbow_mmap,
+};
 
 /*
  *    xbow_mlreset: called at mlreset time if the
@@ -188,39 +160,6 @@
 {
 }
 
-/*
- *    xbow_init: called with the rest of the device
- *      driver XXX_init routines. This platform *might*
- *      have a Crossbow chip, or even several, but it
- *      might have none. Register with the crosstalk
- *      generic provider so when we encounter the chip
- *      the right magic happens.
- */
-void
-xbow_init(void)
-{
-
-#if DEBUG && ATTACH_DEBUG
-    printk("xbow_init\n");
-#endif
-
-    xwidget_driver_register(PXBOW_WIDGET_PART_NUM,
-			    0, /* XXBOW_WIDGET_MFGR_NUM, */
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-
-
-    xwidget_driver_register(XXBOW_WIDGET_PART_NUM,
-			    0, /* XXBOW_WIDGET_MFGR_NUM, */
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-
-    xwidget_driver_register(XBOW_WIDGET_PART_NUM,
-			    XBOW_WIDGET_MFGR_NUM,
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-}
-
 #ifdef XBRIDGE_REGS_SIM
 /*    xbow_set_simulated_regs: sets xbow regs as needed
  *	for powering through the boot
@@ -257,11 +196,11 @@
 
 /*ARGSUSED */
 int
-xbow_attach(devfs_handle_t conn)
+xbow_attach(vertex_hdl_t conn)
 {
     /*REFERENCED */
-    devfs_handle_t            vhdl;
-    devfs_handle_t            busv;
+    vertex_hdl_t            vhdl;
+    vertex_hdl_t            busv;
     xbow_t                 *xbow;
     xbow_soft_t             soft;
     int                     port;
@@ -322,10 +261,10 @@
      * file ops.
      */
     vhdl = NULL;
-    vhdl = devfs_register(conn, EDGE_LBL_XBOW,
-		DEVFS_FL_AUTO_DEVNUM, 0, 0,
-		S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP,
-		&xbow_fops, (void *)xbow);
+    vhdl = hwgraph_register(conn, EDGE_LBL_XBOW, 0,
+	   0, 0, 0,
+	   S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
+	   (struct file_operations *)&xbow_fops, (void *)xbow);
     if (!vhdl) {
         printk(KERN_WARNING "xbow_attach: Unable to create char device for xbow conn %p\n",
                 (void *)conn);
@@ -393,6 +332,14 @@
       */
      intr_hdl = xtalk_intr_alloc(conn, (device_desc_t)0, vhdl);
      ASSERT(intr_hdl != NULL);
+
+        {
+                int irq = ((hub_intr_t)intr_hdl)->i_bit;
+                int cpu = ((hub_intr_t)intr_hdl)->i_cpuid;
+
+                intr_unreserve_level(cpu, irq);
+                ((hub_intr_t)intr_hdl)->i_bit = SGI_XBOW_ERROR;
+        }
  
      xtalk_intr_connect(intr_hdl,
                         (intr_func_t) xbow_errintr_handler,
@@ -400,19 +347,9 @@
                         (xtalk_intr_setfunc_t) xbow_setwidint,
                         (void *) xbow);
 
-     request_irq(CPU_VECTOR_TO_IRQ(((hub_intr_t)intr_hdl)->i_cpuid,
-			((hub_intr_t)intr_hdl)->i_bit),
-			(intr_func_t)xbow_errintr_handler, 0, "XBOW error",
+     request_irq(SGI_XBOW_ERROR, (void *)xbow_errintr_handler, SA_SHIRQ, "XBOW error",
 			(intr_arg_t) soft);
 
-#ifdef BUS_INT_WAR_NOT_YET
-    {
-	void sn_add_polled_interrupt(int, int);
-        sn_add_polled_interrupt(CPU_VECTOR_TO_IRQ(((hub_intr_t)intr_hdl)->i_cpuid,
-                                ((hub_intr_t)intr_hdl)->i_bit), 5000);
-    }
-#endif
-
  
     /*
      * Enable xbow error interrupts
@@ -482,50 +419,14 @@
     return 0;				/* attach successful */
 }
 
-/*ARGSUSED */
-int
-xbow_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-xbow_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-xbow_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-    devfs_handle_t            vhdl = dev_to_vhdl(dev);
-    xbow_soft_t             soft = xbow_soft_get(vhdl);
-    int                     error;
-
-    ASSERT(soft);
-    len = ctob(btoc(len));
-    /* XXX- this ignores the offset!!! */
-    error = v_mapphys(vt, (void *) soft->base, len);
-    return error;
-}
-
-/*ARGSUSED */
-int
-xbow_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-    return 0;
-}
-
 /* This contains special-case code for grio. There are plans to make
  * this general sometime in the future, but till then this should
  * be good enough.
  */
 xwidgetnum_t
-xbow_widget_num_get(devfs_handle_t dev)
+xbow_widget_num_get(vertex_hdl_t dev)
 {
-	devfs_handle_t	tdev;
+	vertex_hdl_t	tdev;
 	char		devname[MAXDEVNAME];
 	xwidget_info_t	xwidget_info;
 	int		i;
@@ -555,58 +456,6 @@
 	return XWIDGET_NONE;
 }
 
-int
-xbow_ioctl(devfs_handle_t dev,
-	   int cmd,
-	   void *arg,
-	   int flag,
-	   struct cred *cr,
-	   int *rvalp)
-{
-    devfs_handle_t            vhdl;
-    int                     error = 0;
-
-#if defined (DEBUG)
-    int                     rc;
-    devfs_handle_t            conn;
-    struct xwidget_info_s  *xwidget_info;
-    xbow_soft_t             xbow_soft;
-#endif
-    *rvalp = 0;
-
-    vhdl = dev_to_vhdl(dev);
-#if defined (DEBUG)
-    xbow_soft = xbow_soft_get(vhdl);
-    conn = xbow_soft->conn;
-
-    xwidget_info = xwidget_info_get(conn);
-    ASSERT_ALWAYS(xwidget_info != NULL);
-
-    rc = xwidget_hwid_is_xswitch(&xwidget_info->w_hwid);
-    ASSERT_ALWAYS(rc != 0);
-#endif
-    switch (cmd) {
-
-    case XBOWIOC_LLP_ERROR_ENABLE:
-	if ((error = xbow_enable_llp_monitor(vhdl)) != 0)
-	    error = EINVAL;
-
-	break;
-
-    case XBOWIOC_LLP_ERROR_DISABLE:
-
-	if ((error = xbow_disable_llp_monitor(vhdl)) != 0)
-	    error = EINVAL;
-
-	break;
-
-    default:
-	break;
-
-    }
-    return error;
-}
-
 /*
  * xbow_widget_present: See if a device is present
  * on the specified port of this crossbow.
@@ -648,12 +497,12 @@
  *      specified.
  *      If not found, return 0.
  */
-devfs_handle_t
-xbow_widget_lookup(devfs_handle_t vhdl,
+vertex_hdl_t
+xbow_widget_lookup(vertex_hdl_t vhdl,
 		   int widgetnum)
 {
     xswitch_info_t          xswitch_info;
-    devfs_handle_t            conn;
+    vertex_hdl_t            conn;
 
     xswitch_info = xswitch_info_get(vhdl);
     conn = xswitch_info_vhdl_get(xswitch_info, widgetnum);
@@ -713,48 +562,14 @@
 				    XEM_ADD_NVAR("ioe." #n, p);		\
 				}
 
-#ifdef LATER
-static void
-xem_add_ioe(ioerror_t *ioe)
-{
-    union tmp {
-	ushort stmp;
-	unsigned long long lltmp;
-	cpuid_t cputmp;
-	cnodeid_t cntmp;
-	iopaddr_t iotmp;
-	caddr_t catmp;
-	paddr_t patmp;
-    } tmp;
-
-    XEM_ADD_IOEF(tmp.stmp, errortype);
-    XEM_ADD_IOEF(tmp.stmp, widgetnum);
-    XEM_ADD_IOEF(tmp.stmp, widgetdev);
-    XEM_ADD_IOEF(tmp.cputmp, srccpu);
-    XEM_ADD_IOEF(tmp.cntmp, srcnode);
-    XEM_ADD_IOEF(tmp.cntmp, errnode);
-    XEM_ADD_IOEF(tmp.iotmp, sysioaddr);
-    XEM_ADD_IOEF(tmp.iotmp, xtalkaddr);
-    XEM_ADD_IOEF(tmp.iotmp, busspace);
-    XEM_ADD_IOEF(tmp.iotmp, busaddr);
-    XEM_ADD_IOEF(tmp.catmp, vaddr);
-    XEM_ADD_IOEF(tmp.patmp, memaddr);
-    XEM_ADD_IOEF(tmp.catmp, epc);
-    XEM_ADD_IOEF(tmp.catmp, ef);
-    XEM_ADD_IOEF(tmp.stmp, tnum);
-}
-
-#define XEM_ADD_IOE()   (xem_add_ioe(ioe))
-#endif	/* LATER */
-
-int                     xbow_xmit_retry_errors = 0;
+int                     xbow_xmit_retry_errors;
 
 int
 xbow_xmit_retry_error(xbow_soft_t soft,
 		      int port)
 {
     xswitch_info_t          info;
-    devfs_handle_t            vhdl;
+    vertex_hdl_t            vhdl;
     widget_cfg_t           *wid;
     widgetreg_t             id;
     int                     part;
@@ -904,7 +719,7 @@
 		    link_pend &= ~XB_STAT_XMT_RTRY_ERR;
 		}
 		if (link_pend) {
-		    devfs_handle_t	xwidget_vhdl;
+		    vertex_hdl_t	xwidget_vhdl;
 		    char		*xwidget_name;
 		    
 		    /* Get the widget name corresponding to the current
@@ -956,12 +771,6 @@
 			XEM_ADD_VAR(link_status);
 			XEM_ADD_VAR(link_aux_status);
 
-#ifdef LATER
-			if (dump_ioe) {
-			    XEM_ADD_IOE();
-			    dump_ioe = 0;
-			}
-#endif
 #if !DEBUG
 		    }
 #endif
@@ -1026,8 +835,8 @@
 
     xbow_soft_t             soft = (xbow_soft_t) einfo;
     int                     port;
-    devfs_handle_t          conn;
-    devfs_handle_t          busv;
+    vertex_hdl_t          conn;
+    vertex_hdl_t          busv;
 
     xbow_t                 *xbow = soft->base;
     xbowreg_t               wid_stat;
@@ -1279,7 +1088,7 @@
 }
 
 void
-xbow_update_perf_counters(devfs_handle_t vhdl)
+xbow_update_perf_counters(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     xbow_perf_t            *xbow_perf = xbow_soft->xbow_perfcnt;
@@ -1307,7 +1116,7 @@
 }
 
 xbow_perf_link_t       *
-xbow_get_perf_counters(devfs_handle_t vhdl)
+xbow_get_perf_counters(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     xbow_perf_link_t       *xbow_perf_link = xbow_soft->xbow_perflink;
@@ -1316,7 +1125,7 @@
 }
 
 int
-xbow_enable_perf_counter(devfs_handle_t vhdl, int link, int mode, int counter)
+xbow_enable_perf_counter(vertex_hdl_t vhdl, int link, int mode, int counter)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     xbow_perf_t            *xbow_perf = xbow_soft->xbow_perfcnt;
@@ -1370,7 +1179,7 @@
 }
 
 xbow_link_status_t     *
-xbow_get_llp_status(devfs_handle_t vhdl)
+xbow_get_llp_status(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     xbow_link_status_t     *xbow_llp_status = xbow_soft->xbow_link_status;
@@ -1379,7 +1188,7 @@
 }
 
 void
-xbow_update_llp_status(devfs_handle_t vhdl)
+xbow_update_llp_status(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     xbow_link_status_t     *xbow_llp_status = xbow_soft->xbow_link_status;
@@ -1387,7 +1196,7 @@
     xbwX_stat_t             lnk_sts;
     xbow_aux_link_status_t  aux_sts;
     int                     link;
-    devfs_handle_t	    xwidget_vhdl;
+    vertex_hdl_t	    xwidget_vhdl;
     char		   *xwidget_name;	
 
     xbow = (xbow_t *) xbow_soft->base;
@@ -1421,7 +1230,7 @@
 }
 
 int
-xbow_disable_llp_monitor(devfs_handle_t vhdl)
+xbow_disable_llp_monitor(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
     int                     port;
@@ -1436,7 +1245,7 @@
 }
 
 int
-xbow_enable_llp_monitor(devfs_handle_t vhdl)
+xbow_enable_llp_monitor(vertex_hdl_t vhdl)
 {
     xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
 
@@ -1446,7 +1255,7 @@
 
 
 int
-xbow_reset_link(devfs_handle_t xconn_vhdl)
+xbow_reset_link(vertex_hdl_t xconn_vhdl)
 {
     xwidget_info_t          widget_info;
     xwidgetnum_t            port;
@@ -1469,7 +1278,7 @@
     xbow = XBOW_K1PTR;
 #else
     {
-	devfs_handle_t            xbow_vhdl;
+	vertex_hdl_t            xbow_vhdl;
 	xbow_soft_t             xbow_soft;
 
 	hwgraph_traverse(xconn_vhdl, ".master/xtalk/0/xbow", &xbow_vhdl);
@@ -1502,46 +1311,6 @@
     return 0;
 }
 
-/*
- * Dump xbow registers.
- * input parameter is either a pointer to
- * the xbow chip or the vertex handle for
- * an xbow vertex.
- */
-void
-idbg_xbowregs(int64_t regs)
-{
-    xbow_t                 *xbow;
-    int                     i;
-    xb_linkregs_t          *link;
-
-    xbow = (xbow_t *) regs;
-
-#ifdef LATER
-    qprintf("Printing xbow registers starting at 0x%x\n", xbow);
-    qprintf("wid %x status %x erruppr %x errlower %x control %x timeout %x\n",
-	    xbow->xb_wid_id, xbow->xb_wid_stat, xbow->xb_wid_err_upper,
-	    xbow->xb_wid_err_lower, xbow->xb_wid_control,
-	    xbow->xb_wid_req_timeout);
-    qprintf("intr uppr %x lower %x errcmd %x llp ctrl %x arb_reload %x\n",
-	    xbow->xb_wid_int_upper, xbow->xb_wid_int_lower,
-	    xbow->xb_wid_err_cmdword, xbow->xb_wid_llp,
-	    xbow->xb_wid_arb_reload);
-#endif
-
-    for (i = 8; i <= 0xf; i++) {
-	link = &xbow->xb_link(i);
-#ifdef LATER
-	qprintf("Link %d registers\n", i);
-	qprintf("\tctrl %x stat %x arbuppr %x arblowr %x auxstat %x\n",
-		link->link_control, link->link_status,
-		link->link_arb_upper, link->link_arb_lower,
-		link->link_aux_status);
-#endif
-    }
-}
-
-
 #define XBOW_ARB_RELOAD_TICKS		25
 					/* granularity: 4 MB/s, max: 124 MB/s */
 #define GRANULARITY			((100 * 1000000) / XBOW_ARB_RELOAD_TICKS)
@@ -1601,7 +1370,7 @@
  * If bandwidth allocation is successful, return success else return failure.
  */
 int
-xbow_prio_bw_alloc(devfs_handle_t vhdl,
+xbow_prio_bw_alloc(vertex_hdl_t vhdl,
 		xwidgetnum_t src_wid,
 		xwidgetnum_t dest_wid,
 		unsigned long long old_alloc_bw,
diff -Nru a/arch/ia64/sn/io/sn2/xtalk.c b/arch/ia64/sn/io/sn2/xtalk.c
--- a/arch/ia64/sn/io/sn2/xtalk.c	Wed Jun 18 23:42:05 2003
+++ b/arch/ia64/sn/io/sn2/xtalk.c	Wed Jun 18 23:42:05 2003
@@ -37,8 +37,6 @@
 
 char                    widget_info_fingerprint[] = "widget_info";
 
-cdl_p                   xtalk_registry = NULL;
-
 #define	DEV_FUNC(dev,func)	hub_##func
 #define	CAST_PIOMAP(x)		((hub_piomap_t)(x))
 #define	CAST_DMAMAP(x)		((hub_dmamap_t)(x))
@@ -47,71 +45,70 @@
 /* =====================================================================
  *            Function Table of Contents
  */
-xtalk_piomap_t          xtalk_piomap_alloc(devfs_handle_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned);
+xtalk_piomap_t          xtalk_piomap_alloc(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned);
 void                    xtalk_piomap_free(xtalk_piomap_t);
 caddr_t                 xtalk_piomap_addr(xtalk_piomap_t, iopaddr_t, size_t);
 void                    xtalk_piomap_done(xtalk_piomap_t);
-caddr_t                 xtalk_piotrans_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, unsigned);
-caddr_t                 xtalk_pio_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned);
+caddr_t                 xtalk_piotrans_addr(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, unsigned);
+caddr_t                 xtalk_pio_addr(vertex_hdl_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned);
 void                    xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *);
 caddr_t                 xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
 static caddr_t          null_xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
-xtalk_dmamap_t          xtalk_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
+xtalk_dmamap_t          xtalk_dmamap_alloc(vertex_hdl_t, device_desc_t, size_t, unsigned);
 void                    xtalk_dmamap_free(xtalk_dmamap_t);
 iopaddr_t               xtalk_dmamap_addr(xtalk_dmamap_t, paddr_t, size_t);
 alenlist_t              xtalk_dmamap_list(xtalk_dmamap_t, alenlist_t, unsigned);
 void                    xtalk_dmamap_done(xtalk_dmamap_t);
-iopaddr_t               xtalk_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              xtalk_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
+iopaddr_t               xtalk_dmatrans_addr(vertex_hdl_t, device_desc_t, paddr_t, size_t, unsigned);
+alenlist_t              xtalk_dmatrans_list(vertex_hdl_t, device_desc_t, alenlist_t, unsigned);
 void			xtalk_dmamap_drain(xtalk_dmamap_t);
-void			xtalk_dmaaddr_drain(devfs_handle_t, iopaddr_t, size_t);
-void			xtalk_dmalist_drain(devfs_handle_t, alenlist_t);
-xtalk_intr_t            xtalk_intr_alloc(devfs_handle_t, device_desc_t, devfs_handle_t);
-xtalk_intr_t            xtalk_intr_alloc_nothd(devfs_handle_t, device_desc_t, devfs_handle_t);
+void			xtalk_dmaaddr_drain(vertex_hdl_t, iopaddr_t, size_t);
+void			xtalk_dmalist_drain(vertex_hdl_t, alenlist_t);
+xtalk_intr_t            xtalk_intr_alloc(vertex_hdl_t, device_desc_t, vertex_hdl_t);
+xtalk_intr_t            xtalk_intr_alloc_nothd(vertex_hdl_t, device_desc_t, vertex_hdl_t);
 void                    xtalk_intr_free(xtalk_intr_t);
 int                     xtalk_intr_connect(xtalk_intr_t, intr_func_t, intr_arg_t, xtalk_intr_setfunc_t, void *);
 void                    xtalk_intr_disconnect(xtalk_intr_t);
-devfs_handle_t            xtalk_intr_cpu_get(xtalk_intr_t);
-int                     xtalk_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *);
-int                     xtalk_error_devenable(devfs_handle_t, int, int);
-void                    xtalk_provider_startup(devfs_handle_t);
-void                    xtalk_provider_shutdown(devfs_handle_t);
-devfs_handle_t            xtalk_intr_dev_get(xtalk_intr_t);
+vertex_hdl_t            xtalk_intr_cpu_get(xtalk_intr_t);
+int                     xtalk_error_handler(vertex_hdl_t, int, ioerror_mode_t, ioerror_t *);
+int                     xtalk_error_devenable(vertex_hdl_t, int, int);
+void                    xtalk_provider_startup(vertex_hdl_t);
+void                    xtalk_provider_shutdown(vertex_hdl_t);
+vertex_hdl_t            xtalk_intr_dev_get(xtalk_intr_t);
 xwidgetnum_t            xtalk_intr_target_get(xtalk_intr_t);
 xtalk_intr_vector_t     xtalk_intr_vector_get(xtalk_intr_t);
 iopaddr_t               xtalk_intr_addr_get(struct xtalk_intr_s *);
 void                   *xtalk_intr_sfarg_get(xtalk_intr_t);
-devfs_handle_t            xtalk_pio_dev_get(xtalk_piomap_t);
+vertex_hdl_t            xtalk_pio_dev_get(xtalk_piomap_t);
 xwidgetnum_t            xtalk_pio_target_get(xtalk_piomap_t);
 iopaddr_t               xtalk_pio_xtalk_addr_get(xtalk_piomap_t);
 ulong                   xtalk_pio_mapsz_get(xtalk_piomap_t);
 caddr_t                 xtalk_pio_kvaddr_get(xtalk_piomap_t);
-devfs_handle_t            xtalk_dma_dev_get(xtalk_dmamap_t);
+vertex_hdl_t            xtalk_dma_dev_get(xtalk_dmamap_t);
 xwidgetnum_t            xtalk_dma_target_get(xtalk_dmamap_t);
-xwidget_info_t          xwidget_info_chk(devfs_handle_t);
-xwidget_info_t          xwidget_info_get(devfs_handle_t);
-void                    xwidget_info_set(devfs_handle_t, xwidget_info_t);
-devfs_handle_t            xwidget_info_dev_get(xwidget_info_t);
+xwidget_info_t          xwidget_info_chk(vertex_hdl_t);
+xwidget_info_t          xwidget_info_get(vertex_hdl_t);
+void                    xwidget_info_set(vertex_hdl_t, xwidget_info_t);
+vertex_hdl_t            xwidget_info_dev_get(xwidget_info_t);
 xwidgetnum_t            xwidget_info_id_get(xwidget_info_t);
-devfs_handle_t            xwidget_info_master_get(xwidget_info_t);
+vertex_hdl_t            xwidget_info_master_get(xwidget_info_t);
 xwidgetnum_t            xwidget_info_masterid_get(xwidget_info_t);
 xwidget_part_num_t      xwidget_info_part_num_get(xwidget_info_t);
 xwidget_mfg_num_t       xwidget_info_mfg_num_get(xwidget_info_t);
 char 			*xwidget_info_name_get(xwidget_info_t);
-void                    xtalk_init(void);
-void                    xtalk_provider_register(devfs_handle_t, xtalk_provider_t *);
-void                    xtalk_provider_unregister(devfs_handle_t);
-xtalk_provider_t       *xtalk_provider_fns_get(devfs_handle_t);
+void                    xtalk_provider_register(vertex_hdl_t, xtalk_provider_t *);
+void                    xtalk_provider_unregister(vertex_hdl_t);
+xtalk_provider_t       *xtalk_provider_fns_get(vertex_hdl_t);
 int                     xwidget_driver_register(xwidget_part_num_t, 
 						xwidget_mfg_num_t, 
 						char *, unsigned);
 void                    xwidget_driver_unregister(char *);
-int                     xwidget_register(xwidget_hwid_t, devfs_handle_t, 
-					 xwidgetnum_t, devfs_handle_t, 
-					 xwidgetnum_t, async_attach_t);
-int			xwidget_unregister(devfs_handle_t);
-void                    xwidget_reset(devfs_handle_t);
-char			*xwidget_name_get(devfs_handle_t);
+int                     xwidget_register(xwidget_hwid_t, vertex_hdl_t, 
+					 xwidgetnum_t, vertex_hdl_t, 
+					 xwidgetnum_t);
+int			xwidget_unregister(vertex_hdl_t);
+void                    xwidget_reset(vertex_hdl_t);
+char			*xwidget_name_get(vertex_hdl_t);
 #if !defined(DEV_FUNC)
 /*
  * There is more than one possible provider
@@ -126,7 +123,7 @@
 #define	CAST_INTR(x)		((xtalk_intr_t)(x))
 
 static xtalk_provider_t *
-xwidget_to_provider_fns(devfs_handle_t xconn)
+xwidget_to_provider_fns(vertex_hdl_t xconn)
 {
     xwidget_info_t          widget_info;
     xtalk_provider_t       *provider_fns;
@@ -159,7 +156,7 @@
  */
 
 xtalk_piomap_t
-xtalk_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
+xtalk_piomap_alloc(vertex_hdl_t dev,	/* set up mapping for this device */
 		   device_desc_t dev_desc,	/* device descriptor */
 		   iopaddr_t xtalk_addr,	/* map for this xtalk_addr range */
 		   size_t byte_count,
@@ -198,7 +195,7 @@
 
 
 caddr_t
-xtalk_piotrans_addr(devfs_handle_t dev,	/* translate for this device */
+xtalk_piotrans_addr(vertex_hdl_t dev,	/* translate for this device */
 		    device_desc_t dev_desc,	/* device descriptor */
 		    iopaddr_t xtalk_addr,	/* Crosstalk address */
 		    size_t byte_count,	/* map this many bytes */
@@ -209,7 +206,7 @@
 }
 
 caddr_t
-xtalk_pio_addr(devfs_handle_t dev,	/* translate for this device */
+xtalk_pio_addr(vertex_hdl_t dev,	/* translate for this device */
 	       device_desc_t dev_desc,	/* device descriptor */
 	       iopaddr_t addr,		/* starting address (or offset in window) */
 	       size_t byte_count,	/* map this many bytes */
@@ -326,7 +323,7 @@
  */
 
 xtalk_dmamap_t
-xtalk_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */
+xtalk_dmamap_alloc(vertex_hdl_t dev,	/* set up mappings for this device */
 		   device_desc_t dev_desc,	/* device descriptor */
 		   size_t byte_count_max,	/* max size of a mapping */
 		   unsigned flags)
@@ -373,7 +370,7 @@
 
 
 iopaddr_t
-xtalk_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */
+xtalk_dmatrans_addr(vertex_hdl_t dev,	/* translate for this device */
 		    device_desc_t dev_desc,	/* device descriptor */
 		    paddr_t paddr,	/* system physical address */
 		    size_t byte_count,	/* length */
@@ -385,7 +382,7 @@
 
 
 alenlist_t
-xtalk_dmatrans_list(devfs_handle_t dev,	/* translate for this device */
+xtalk_dmatrans_list(vertex_hdl_t dev,	/* translate for this device */
 		    device_desc_t dev_desc,	/* device descriptor */
 		    alenlist_t palenlist,	/* system address/length list */
 		    unsigned flags)
@@ -402,14 +399,14 @@
 }
 
 void
-xtalk_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
+xtalk_dmaaddr_drain(vertex_hdl_t dev, paddr_t addr, size_t size)
 {
     DEV_FUNC(dev, dmaaddr_drain)
 	(dev, addr, size);
 }
 
 void
-xtalk_dmalist_drain(devfs_handle_t dev, alenlist_t list)
+xtalk_dmalist_drain(vertex_hdl_t dev, alenlist_t list)
 {
     DEV_FUNC(dev, dmalist_drain)
 	(dev, list);
@@ -426,9 +423,9 @@
  * Return resource handle in intr_hdl.
  */
 xtalk_intr_t
-xtalk_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */
+xtalk_intr_alloc(vertex_hdl_t dev,	/* which Crosstalk device */
 		 device_desc_t dev_desc,	/* device descriptor */
-		 devfs_handle_t owner_dev)
+		 vertex_hdl_t owner_dev)
 {				/* owner of this interrupt */
     return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc)
 	(dev, dev_desc, owner_dev);
@@ -440,9 +437,9 @@
  * Return resource handle in intr_hdl.
  */
 xtalk_intr_t
-xtalk_intr_alloc_nothd(devfs_handle_t dev,	/* which Crosstalk device */
+xtalk_intr_alloc_nothd(vertex_hdl_t dev,	/* which Crosstalk device */
 		 	device_desc_t dev_desc,	/* device descriptor */
-		 	devfs_handle_t owner_dev)	/* owner of this interrupt */
+		 	vertex_hdl_t owner_dev)	/* owner of this interrupt */
 {
     return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc_nothd)
 	(dev, dev_desc, owner_dev);
@@ -492,11 +489,10 @@
  * Return a hwgraph vertex that represents the CPU currently
  * targeted by an interrupt.
  */
-devfs_handle_t
+vertex_hdl_t
 xtalk_intr_cpu_get(xtalk_intr_t intr_hdl)
 {
-    return INTR_FUNC(intr_hdl, intr_cpu_get)
-	(CAST_INTR(intr_hdl));
+      return (vertex_hdl_t)0;
 }
 
 
@@ -526,7 +522,7 @@
  */
 int
 xtalk_error_handler(
-		       devfs_handle_t xconn,
+		       vertex_hdl_t xconn,
 		       int error_code,
 		       ioerror_mode_t mode,
 		       ioerror_t *ioerror)
@@ -555,7 +551,7 @@
 #if defined(SUPPORT_PRINTING_V_FORMAT)
     printk(KERN_WARNING "Xbow at %v encountered Fatal error", xconn);
 #else
-    printk(KERN_WARNING "Xbow at 0x%p encountered Fatal error", xconn);
+    printk(KERN_WARNING "Xbow at 0x%p encountered Fatal error", (void *)xconn);
 #endif
     ioerror_dump("xtalk", error_code, mode, ioerror);
 
@@ -563,7 +559,7 @@
 }
 
 int
-xtalk_error_devenable(devfs_handle_t xconn_vhdl, int devnum, int error_code)
+xtalk_error_devenable(vertex_hdl_t xconn_vhdl, int devnum, int error_code)
 {
     return DEV_FUNC(xconn_vhdl, error_devenable) (xconn_vhdl, devnum, error_code);
 }
@@ -577,7 +573,7 @@
  * Startup a crosstalk provider
  */
 void
-xtalk_provider_startup(devfs_handle_t xtalk_provider)
+xtalk_provider_startup(vertex_hdl_t xtalk_provider)
 {
     DEV_FUNC(xtalk_provider, provider_startup)
 	(xtalk_provider);
@@ -588,7 +584,7 @@
  * Shutdown a crosstalk provider
  */
 void
-xtalk_provider_shutdown(devfs_handle_t xtalk_provider)
+xtalk_provider_shutdown(vertex_hdl_t xtalk_provider)
 {
     DEV_FUNC(xtalk_provider, provider_shutdown)
 	(xtalk_provider);
@@ -598,22 +594,22 @@
  * Enable a device on a xtalk widget 
  */
 void
-xtalk_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum)
+xtalk_widgetdev_enable(vertex_hdl_t xconn_vhdl, int devnum)
 {
-    DEV_FUNC(xconn_vhdl, widgetdev_enable) (xconn_vhdl, devnum);
+	return;
 }
 
 /* 
  * Shutdown a device on a xtalk widget 
  */
 void
-xtalk_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum)
+xtalk_widgetdev_shutdown(vertex_hdl_t xconn_vhdl, int devnum)
 {
-    DEV_FUNC(xconn_vhdl, widgetdev_shutdown) (xconn_vhdl, devnum);
+	return;
 }
 
 int
-xtalk_dma_enabled(devfs_handle_t xconn_vhdl)
+xtalk_dma_enabled(vertex_hdl_t xconn_vhdl)
 {
     return DEV_FUNC(xconn_vhdl, dma_enabled) (xconn_vhdl);
 }
@@ -623,7 +619,7 @@
  */
 
 /****** Generic crosstalk interrupt interfaces ******/
-devfs_handle_t
+vertex_hdl_t
 xtalk_intr_dev_get(xtalk_intr_t xtalk_intr)
 {
     return (xtalk_intr->xi_dev);
@@ -654,7 +650,7 @@
 }
 
 /****** Generic crosstalk pio interfaces ******/
-devfs_handle_t
+vertex_hdl_t
 xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap)
 {
     return (xtalk_piomap->xp_dev);
@@ -686,7 +682,7 @@
 
 
 /****** Generic crosstalk dma interfaces ******/
-devfs_handle_t
+vertex_hdl_t
 xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap)
 {
     return (xtalk_dmamap->xd_dev);
@@ -707,7 +703,7 @@
  * if not, return NULL.
  */
 xwidget_info_t
-xwidget_info_chk(devfs_handle_t xwidget)
+xwidget_info_chk(vertex_hdl_t xwidget)
 {
     arbitrary_info_t        ainfo = 0;
 
@@ -717,28 +713,18 @@
 
 
 xwidget_info_t
-xwidget_info_get(devfs_handle_t xwidget)
+xwidget_info_get(vertex_hdl_t xwidget)
 {
     xwidget_info_t          widget_info;
 
     widget_info = (xwidget_info_t)
 	hwgraph_fastinfo_get(xwidget);
 
-#ifdef	LATER
-    if ((widget_info != NULL) &&
-	(widget_info->w_fingerprint != widget_info_fingerprint))
-#ifdef SUPPORT_PRINTING_V_FORMAT
-	PRINT_PANIC("%v bad xwidget_info", xwidget);
-#else
-	PRINT_PANIC("%x bad xwidget_info", xwidget);
-#endif
-#endif	/* LATER */
-
     return (widget_info);
 }
 
 void
-xwidget_info_set(devfs_handle_t xwidget, xwidget_info_t widget_info)
+xwidget_info_set(vertex_hdl_t xwidget, xwidget_info_t widget_info)
 {
     if (widget_info != NULL)
 	widget_info->w_fingerprint = widget_info_fingerprint;
@@ -753,11 +739,11 @@
 			 (arbitrary_info_t) widget_info);
 }
 
-devfs_handle_t
+vertex_hdl_t
 xwidget_info_dev_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_dev_get: null xwidget_info");
     return (xwidget_info->w_vertex);
 }
 
@@ -765,16 +751,16 @@
 xwidget_info_id_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_id_get: null xwidget_info");
     return (xwidget_info->w_id);
 }
 
 
-devfs_handle_t
+vertex_hdl_t
 xwidget_info_master_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_master_get: null xwidget_info");
     return (xwidget_info->w_master);
 }
 
@@ -782,7 +768,7 @@
 xwidget_info_masterid_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_masterid_get: null xwidget_info");
     return (xwidget_info->w_masterid);
 }
 
@@ -790,7 +776,7 @@
 xwidget_info_part_num_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_part_num_get: null xwidget_info");
     return (xwidget_info->w_hwid.part_num);
 }
 
@@ -798,7 +784,7 @@
 xwidget_info_mfg_num_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget_info");
+	panic("xwidget_info_mfg_num_get: null xwidget_info");
     return (xwidget_info->w_hwid.mfg_num);
 }
 /* Extract the widget name from the widget information
@@ -808,49 +794,16 @@
 xwidget_info_name_get(xwidget_info_t xwidget_info)
 {
     if (xwidget_info == NULL)
-	panic("null xwidget info");
+	panic("xwidget_info_name_get: null xwidget_info");
     return(xwidget_info->w_name);
 }
 /****** Generic crosstalk initialization interfaces ******/
 
 /*
- * One-time initialization needed for systems that support crosstalk.
- */
-void
-xtalk_init(void)
-{
-    cdl_p                   cp;
-
-#if DEBUG && ATTACH_DEBUG
-    printf("xtalk_init\n");
-#endif
-    /* Allocate the registry.
-     * We might already have one.
-     * If we don't, go get one.
-     * MPness: someone might have
-     * set one up for us while we
-     * were not looking; use an atomic
-     * compare-and-swap to commit to
-     * using the new registry if and
-     * only if nobody else did first.
-     * If someone did get there first,
-     * toss the one we allocated back
-     * into the pool.
-     */
-    if (xtalk_registry == NULL) {
-	cp = cdl_new(EDGE_LBL_XIO, "part", "mfgr");
-	if (!compare_and_swap_ptr((void **) &xtalk_registry, NULL, (void *) cp)) {
-	    cdl_del(cp);
-	}
-    }
-    ASSERT(xtalk_registry != NULL);
-}
-
-/*
  * Associate a set of xtalk_provider functions with a vertex.
  */
 void
-xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns)
+xtalk_provider_register(vertex_hdl_t provider, xtalk_provider_t *xtalk_fns)
 {
     hwgraph_fastinfo_set(provider, (arbitrary_info_t) xtalk_fns);
 }
@@ -859,7 +812,7 @@
  * Disassociate a set of xtalk_provider functions with a vertex.
  */
 void
-xtalk_provider_unregister(devfs_handle_t provider)
+xtalk_provider_unregister(vertex_hdl_t provider)
 {
     hwgraph_fastinfo_set(provider, (arbitrary_info_t)NULL);
 }
@@ -869,50 +822,19 @@
  * provider.
  */
 xtalk_provider_t       *
-xtalk_provider_fns_get(devfs_handle_t provider)
+xtalk_provider_fns_get(vertex_hdl_t provider)
 {
     return ((xtalk_provider_t *) hwgraph_fastinfo_get(provider));
 }
 
 /*
- * Announce a driver for a particular crosstalk part.
- * Returns 0 on success or -1 on failure.  Failure occurs if the
- * specified hardware already has a driver.
- */
-/*ARGSUSED4 */
-int
-xwidget_driver_register(xwidget_part_num_t part_num,
-			xwidget_mfg_num_t mfg_num,
-			char *driver_prefix,
-			unsigned flags)
-{
-    /* a driver's init routine could call
-     * xwidget_driver_register before the
-     * system calls xtalk_init; so, we
-     * make the call here.
-     */
-    if (xtalk_registry == NULL)
-	xtalk_init();
-
-    return cdl_add_driver(xtalk_registry,
-			  part_num, mfg_num,
-			  driver_prefix, flags, NULL);
-}
-
-/*
  * Inform xtalk infrastructure that a driver is no longer available for
  * handling any widgets.
  */
 void
 xwidget_driver_unregister(char *driver_prefix)
 {
-    /* before a driver calls unregister,
-     * it must have called registger; so we
-     * can assume we have a registry here.
-     */
-    ASSERT(xtalk_registry != NULL);
-
-    cdl_del_driver(xtalk_registry, driver_prefix, NULL);
+	return;
 }
 
 /*
@@ -923,9 +845,6 @@
 xtalk_iterate(char *driver_prefix,
 	      xtalk_iter_f *func)
 {
-    ASSERT(xtalk_registry != NULL);
-
-    cdl_iterate(xtalk_registry, driver_prefix, (cdl_iter_f *)func);
 }
 
 /*
@@ -939,11 +858,10 @@
  */
 int
 xwidget_register(xwidget_hwid_t hwid,		/* widget's hardware ID */
-		 devfs_handle_t 	widget,		/* widget to initialize */
+		 vertex_hdl_t 	widget,		/* widget to initialize */
 		 xwidgetnum_t 	id,		/* widget's target id (0..f) */
-		 devfs_handle_t 	master,		/* widget's master vertex */
-		 xwidgetnum_t 	targetid,	/* master's target id (9/a) */
-		 async_attach_t aa)
+		 vertex_hdl_t 	master,		/* widget's master vertex */
+		 xwidgetnum_t 	targetid)	/* master's target id (9/a) */
 {			
     xwidget_info_t          widget_info;
     char		    *s,devnm[MAXDEVNAME];
@@ -972,21 +890,11 @@
 
     device_master_set(widget, master);
 
-    /* All the driver init routines (including
-     * xtalk_init) are called before we get into
-     * attaching devices, so we can assume we
-     * have a registry here.
-     */
-    ASSERT(xtalk_registry != NULL);
-
     /* 
      * Add pointer to async attach info -- tear down will be done when
      * the particular descendant is done with the info.
      */
-    if (aa)
-	    async_attach_add_info(widget, aa);
-
-    return cdl_add_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
+    return cdl_add_connpt(hwid->part_num, hwid->mfg_num,
                           widget, 0);
 }
 
@@ -995,7 +903,7 @@
  *	Unregister the xtalk device and detach all its hwgraph namespace.
  */
 int
-xwidget_unregister(devfs_handle_t widget)
+xwidget_unregister(vertex_hdl_t widget)
 {
     xwidget_info_t	widget_info;
     xwidget_hwid_t	hwid;
@@ -1011,9 +919,6 @@
     
     hwid = &(widget_info->w_hwid);
 
-    cdl_del_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
-                   widget, 0);
-
     /* Clean out the xwidget information */
     (void)kfree(widget_info->w_name);
     BZERO((void *)widget_info, sizeof(widget_info));
@@ -1023,7 +928,7 @@
 }
 
 void
-xwidget_error_register(devfs_handle_t xwidget,
+xwidget_error_register(vertex_hdl_t xwidget,
 		       error_handler_f *efunc,
 		       error_handler_arg_t einfo)
 {
@@ -1039,37 +944,23 @@
  * Issue a link reset to a widget.
  */
 void
-xwidget_reset(devfs_handle_t xwidget)
+xwidget_reset(vertex_hdl_t xwidget)
 {
     xswitch_reset_link(xwidget);
-
 }
 
 
 void
-xwidget_gfx_reset(devfs_handle_t xwidget)
+xwidget_gfx_reset(vertex_hdl_t xwidget)
 {
-    xwidget_info_t info;
-
-    xswitch_reset_link(xwidget);
-    info = xwidget_info_get(xwidget);
-#ifdef LATER
-    ASSERT_ALWAYS(info != NULL);
-#endif
-
-    /*
-     * Enable this for other architectures once we add widget_reset to the
-     * xtalk provider interface.
-     */
-    DEV_FUNC(xtalk_provider, widget_reset)
-	(xwidget_info_master_get(info), xwidget_info_id_get(info));
+	return;
 }
 
 #define ANON_XWIDGET_NAME	"No Name"	/* Default Widget Name */
 
 /* Get the canonical hwgraph  name of xtalk widget */
 char *
-xwidget_name_get(devfs_handle_t xwidget_vhdl)
+xwidget_name_get(vertex_hdl_t xwidget_vhdl)
 {
 	xwidget_info_t  info;
 
diff -Nru a/arch/ia64/sn/io/stubs.c b/arch/ia64/sn/io/stubs.c
--- a/arch/ia64/sn/io/stubs.c	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,140 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/ctype.h>
-#include <linux/mmzone.h>
-#include <linux/slab.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/ioerror_handling.h>
-#include <asm/sn/pci/pciio.h>
-#include <asm/sn/slotnum.h>
-#include <asm/sn/vector.h>
-#include <asm/sn/nic.h>
-
-/******
- ****** hack defines ......
- ******/
-
-int pcibr_prefetch_enable_rev, pcibr_wg_enable_rev;
-int default_intr_pri;
-int force_fire_and_forget = 1;
-int ignore_conveyor_override = 0;
-
-devfs_handle_t dummy_vrtx;	/* Needed for cpuid_to_vertex() in hack.h */
-
-
-/* ARGSUSED */
-void hub_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum)
-        {FIXME("hub_widgetdev_enable");}
-
-/* ARGSUSED */
-void hub_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum)
-        {FIXME("hub_widgetdev_shutdown");}
-
-/* ARGSUSED */
-void hub_widget_reset(devfs_handle_t hubv, xwidgetnum_t widget)
-        {FIXME("hub_widget_reset");}
-
-boolean_t
-is_sys_critical_vertex(devfs_handle_t x)
-{
-	FIXME("is_sys_critical_vertex : returns 0");
-	return(0);
-}
-
-void *
-snia_kmem_zone_alloc(register struct zone *zone, int flags)
-{
-	FIXME("snia_kmem_zone_alloc : return null");
-	return((void *)0);
-}
-
-void
-snia_kmem_zone_free(register struct zone *zone, void *ptr)
-{
-	FIXME("snia_kmem_zone_free : no-op");
-}
-
-struct zone *
-snia_kmem_zone_init(register int size, char *zone_name)
-{
-	FIXME("snia_kmem_zone_free : returns NULL");
-	return((struct zone *)0);
-}
-
-int
-compare_and_swap_ptr(void **location, void *old_ptr, void *new_ptr)
-{
-	FIXME("compare_and_swap_ptr : NOT ATOMIC");
-	if (*location == old_ptr) {
-		*location = new_ptr;
-		return(1);
-	}
-	else
-		return(0);
-}
-
-/* For ml/SN/SN1/slots.c */
-/* ARGSUSED */
-slotid_t get_widget_slotnum(int xbow, int widget)
-        {FIXME("get_widget_slotnum"); return (unsigned char)NULL;}
-
-/* For router */
-int
-router_init(cnodeid_t cnode,int writeid, void *npda_rip)
-        {FIXME("router_init"); return(0);}
-
-/* From io/ioerror_handling.c */
-error_return_code_t
-sys_critical_graph_vertex_add(devfs_handle_t parent, devfs_handle_t child)
-	{FIXME("sys_critical_graph_vertex_add"); return(0);}
-
-/* From io/ioc3.c */
-devfs_handle_t
-ioc3_console_vhdl_get(void)
-	{FIXME("ioc3_console_vhdl_get"); return( (devfs_handle_t)-1);}
-
-void
-nic_vmc_check(devfs_handle_t vhdl, char *nicinfo)
-{
-
-	FIXME("nic_vmc_check\n");
-
-}
-
-char *
-nic_vertex_info_get(devfs_handle_t v)
-{
-	FIXME("nic_vertex_info_get\n");
-	return(NULL);
-}
-
-int
-vector_read_node(net_vec_t dest, nasid_t nasid,
-             int write_id, int address,
-             uint64_t *value)
-{
-	FIXME("vector_read_node\n");
-	return(0);
-}
-
-int
-vector_write_node(net_vec_t dest, nasid_t nasid,
-              int write_id, int address,
-              uint64_t value)
-{
-	FIXME("vector_write_node\n");
-	return(0);
-}
diff -Nru a/arch/ia64/sn/io/xbow.c b/arch/ia64/sn/io/xbow.c
--- a/arch/ia64/sn/io/xbow.c	Wed Jun 18 23:42:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1325 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/sched.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/hack.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/xtalk/xtalk_private.h>
-#include <asm/sn/simulator.h>
-
-/* #define DEBUG		1 */
-/* #define XBOW_DEBUG	1 */
-
-
-/*
- * Files needed to get the device driver entry points
- */
-
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/xtalk/xwidget.h>
-
-#include <asm/sn/prio.h>
-#include <asm/sn/hcl_util.h>
-
-
-#define NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define DEL(ptr)	(kfree(ptr))
-
-int                     xbow_devflag = D_MP;
-
-/*
- * This file supports the Xbow chip.  Main functions: initializtion,
- * error handling, and GBR.
- */
-
-/*
- * each vertex corresponding to an xbow chip
- * has a "fastinfo" pointer pointing at one
- * of these things.
- */
-typedef struct xbow_soft_s *xbow_soft_t;
-
-struct xbow_soft_s {
-    devfs_handle_t            conn;	/* our connection point */
-    devfs_handle_t            vhdl;	/* xbow's private vertex */
-    devfs_handle_t            busv;	/* the xswitch vertex */
-    xbow_t                 *base;	/* PIO pointer to crossbow chip */
-    char                   *name;	/* hwgraph name */
-
-    xbow_perf_t             xbow_perfcnt[XBOW_PERF_COUNTERS];
-    xbow_perf_link_t        xbow_perflink[MAX_XBOW_PORTS];
-    xbow_link_status_t      xbow_link_status[MAX_XBOW_PORTS];
-    spinlock_t              xbow_perf_lock;
-    int                     link_monitor;
-    widget_cfg_t	   *wpio[MAX_XBOW_PORTS];	/* cached PIO pointer */
-
-    /* Bandwidth allocation state. Bandwidth values are for the
-     * destination port since contention happens there.
-     * Implicit mapping from xbow ports (8..f) -> (0..7) array indices.
-     */
-    spinlock_t		    xbow_bw_alloc_lock;		/* bw allocation lock */
-    unsigned long long	    bw_hiwm[MAX_XBOW_PORTS];	/* hiwater mark values */
-    unsigned long long      bw_cur_used[MAX_XBOW_PORTS]; /* bw used currently */
-};
-
-#define xbow_soft_set(v,i)	hwgraph_fastinfo_set((v), (arbitrary_info_t)(i))
-#define xbow_soft_get(v)	((xbow_soft_t)hwgraph_fastinfo_get((v)))
-
-/*
- * Function Table of Contents
- */
-
-void                    xbow_mlreset(xbow_t *);
-void                    xbow_init(void);
-int                     xbow_attach(devfs_handle_t);
-
-int                     xbow_open(devfs_handle_t *, int, int, cred_t *);
-int                     xbow_close(devfs_handle_t, int, int, cred_t *);
-
-int                     xbow_map(devfs_handle_t, vhandl_t *, off_t, size_t, uint);
-int                     xbow_unmap(devfs_handle_t, vhandl_t *);
-int                     xbow_ioctl(devfs_handle_t, int, void *, int, struct cred *, int *);
-
-int                     xbow_widget_present(xbow_t *, int);
-static int              xbow_link_alive(xbow_t *, int);
-devfs_handle_t            xbow_widget_lookup(devfs_handle_t, int);
-
-#ifdef LATER
-static void             xbow_setwidint(xtalk_intr_t);
-static void             xbow_errintr_handler(intr_arg_t);
-#endif
-void                    xbow_intr_preset(void *, int, xwidgetnum_t, iopaddr_t, xtalk_intr_vector_t);
-
-
-
-void                    xbow_update_perf_counters(devfs_handle_t);
-xbow_perf_link_t       *xbow_get_perf_counters(devfs_handle_t);
-int                     xbow_enable_perf_counter(devfs_handle_t, int, int, int);
-xbow_link_status_t     *xbow_get_llp_status(devfs_handle_t);
-void                    xbow_update_llp_status(devfs_handle_t);
-
-int                     xbow_disable_llp_monitor(devfs_handle_t);
-int                     xbow_enable_llp_monitor(devfs_handle_t);
-int                     xbow_prio_bw_alloc(devfs_handle_t, xwidgetnum_t, xwidgetnum_t,
-                                unsigned long long, unsigned long long);
-
-xswitch_reset_link_f    xbow_reset_link;
-
-void                    idbg_xbowregs(int64_t);
-
-xswitch_provider_t      xbow_provider =
-{
-    xbow_reset_link,
-};
-
-/*
- *    xbow_mlreset: called at mlreset time if the
- *      platform specific code determines that there is
- *      a crossbow in a critical path that must be
- *      functional before the driver would normally get
- *      the device properly set up.
- *
- *      what do we need to do, that the boot prom can
- *      not be counted on to have already done, that is
- *      generic across all platforms using crossbows?
- */
-/*ARGSUSED */
-void
-xbow_mlreset(xbow_t * xbow)
-{
-}
-
-/*
- *    xbow_init: called with the rest of the device
- *      driver XXX_init routines. This platform *might*
- *      have a Crossbow chip, or even several, but it
- *      might have none. Register with the crosstalk
- *      generic provider so when we encounter the chip
- *      the right magic happens.
- */
-void
-xbow_init(void)
-{
-
-#if DEBUG && ATTACH_DEBUG
-    printf("xbow_init\n");
-#endif
-
-    xwidget_driver_register(XXBOW_WIDGET_PART_NUM,
-			    0, /* XXBOW_WIDGET_MFGR_NUM, */
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-
-    xwidget_driver_register(XBOW_WIDGET_PART_NUM,
-			    XBOW_WIDGET_MFGR_NUM,
-			    "xbow_",
-			    CDL_PRI_HI);	/* attach before friends */
-}
-
-#ifdef XBRIDGE_REGS_SIM
-/*    xbow_set_simulated_regs: sets xbow regs as needed
- *	for powering through the boot
- */
-void
-xbow_set_simulated_regs(xbow_t *xbow, int port)
-{
-    /*
-     * turn on link
-     */
-    xbow->xb_link(port).link_status = (1<<31);
-    /*
-     * and give it a live widget too
-     */
-    xbow->xb_link(port).link_aux_status = XB_AUX_STAT_PRESENT;
-    /*
-     * zero the link control reg
-     */
-    xbow->xb_link(port).link_control = 0x0;
-}
-#endif /* XBRIDGE_REGS_SIM */
-
-/*
- *    xbow_attach: the crosstalk provider has
- *      determined that there is a crossbow widget
- *      present, and has handed us the connection
- *      point for that vertex.
- *
- *      We not only add our own vertex, but add
- *      some "xtalk switch" data to the switch
- *      vertex (at the connect point's parent) if
- *      it does not have any.
- */
-
-/*ARGSUSED */
-int
-xbow_attach(devfs_handle_t conn)
-{
-    /*REFERENCED */
-    devfs_handle_t            vhdl;
-    devfs_handle_t            busv;
-    xbow_t                 *xbow;
-    xbow_soft_t             soft;
-    int                     port;
-    xswitch_info_t          info;
-#ifdef LATER
-    xtalk_intr_t            intr_hdl;
-    device_desc_t           dev_desc;
-#endif
-    char                    devnm[MAXDEVNAME], *s;
-    xbowreg_t               id;
-    int                     rev;
-    int			    i;
-    int			    xbow_num;
-	
-#if DEBUG && ATTACH_DEBUG
-#if defined(SUPPORT_PRINTING_V_FORMAT
-    printk("%v: xbow_attach\n", conn);
-#else
-    printk("0x%x: xbow_attach\n", conn);
-#endif
-#endif
-
-    /*
-     * Get a PIO pointer to the base of the crossbow
-     * chip.
-     */
-#ifdef XBRIDGE_REGS_SIM
-    printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: allocating %ld bytes for xbow_s\n", sizeof(xbow_t));
-    xbow = (xbow_t *) kmalloc(sizeof(xbow_t), GFP_KERNEL);
-    /*
-     * turn on ports e and f like in a real live ibrick
-     */
-    xbow_set_simulated_regs(xbow, 0xe);
-    xbow_set_simulated_regs(xbow, 0xf);
-#else
-    xbow = (xbow_t *) xtalk_piotrans_addr(conn, 0, 0, sizeof(xbow_t), 0);
-#endif /* XBRIDGE_REGS_SIM */
-
-    /*
-     * Locate the "switch" vertex: it is the parent
-     * of our connection point.
-     */
-    busv = hwgraph_connectpt_get(conn);
-#if DEBUG && ATTACH_DEBUG
-    printk("xbow_attach: Bus Vertex 0x%p, conn 0x%p, xbow register 0x%p wid= 0x%x\n", busv, conn, xbow, *(volatile u32 *)xbow);
-#endif
-
-    ASSERT(busv != GRAPH_VERTEX_NONE);
-
-    /*
-     * Create our private vertex, and connect our
-     * driver information to it. This makes it possible
-     * for diagnostic drivers to open the crossbow
-     * vertex for access to registers.
-     */
-
-    /*
-     * We need to teach xbow drivers to provide the right set of
-     * file ops.
-     */
-    vhdl = NULL;
-    vhdl = hwgraph_register(conn, EDGE_LBL_XBOW,
-                        0, DEVFS_FL_AUTO_DEVNUM,
-                        0, 0,
-                        S_IFCHR | S_IRUSR | S_IWUSR | S_IRGRP, 0, 0,
-                        /* &hcl_fops */ (void *)&vhdl, NULL);
-    if (!vhdl) {
-        printk(KERN_WARNING "xbow_attach: Unable to create char device for xbow conn %p\n",
-                (void *)conn);
-    }
-
-    /*
-     * Allocate the soft state structure and attach
-     * it to the xbow's vertex
-     */
-    NEW(soft);
-    soft->conn = conn;
-    soft->vhdl = vhdl;
-    soft->busv = busv;
-    soft->base = xbow;
-    /* does the universe really need another macro?  */
-    /* xbow_soft_set(vhdl, (arbitrary_info_t) soft); */
-    hwgraph_fastinfo_set(vhdl, (arbitrary_info_t) soft);
-
-#define XBOW_NUM_SUFFIX_FORMAT	"[xbow# %d]"
-
-    /* Add xbow number as a suffix to the hwgraph name of the xbow.
-     * This is helpful while looking at the error/warning messages.
-     */
-    xbow_num = 0;
-
-    /*
-     * get the name of this xbow vertex and keep the info.
-     * This is needed during errors and interrupts, but as
-     * long as we have it, we can use it elsewhere.
-     */
-    s = dev_to_name(vhdl, devnm, MAXDEVNAME);
-    soft->name = kmalloc(strlen(s) + strlen(XBOW_NUM_SUFFIX_FORMAT) + 1, 
-			    GFP_KERNEL);
-    sprintf(soft->name,"%s"XBOW_NUM_SUFFIX_FORMAT, s,xbow_num);
-
-#ifdef XBRIDGE_REGS_SIM
-    /* my o200/ibrick has id=0x2d002049, but XXBOW_WIDGET_PART_NUM is defined
-     * as 0xd000, so I'm using that for the partnum bitfield.
-     */
-    printk("xbow_attach: XBRIDGE_REGS_SIM FIXME: need xb_wid_id value!!\n");
-    id = 0x2d000049;
-#else
-    id = xbow->xb_wid_id;
-#endif /* XBRIDGE_REGS_SIM */
-    rev = XWIDGET_PART_REV_NUM(id);
-
-    /*
-     * Print the revision if DEBUG, or SHOW_REVS and kdebug,
-     * or the xbow is downrev.
-     *
-     * If xbow is downrev, make it a WARNING that the
-     * Crossbow is DOWNREV: these chips are not good
-     * to have around, and the operator should be told.
-     */
-#ifdef	LATER
-#if !DEBUG
-    if (
-#if SHOW_REVS
-	   (kdebug) ||
-#endif	/* SHOW_REVS */
-	   (rev < XBOW_REV_1_1))
-#endif	/* !DEBUG  */
-	printk("%sCrossbow ASIC: rev %s (code=%d) at %s%s",
-		(rev < XBOW_REV_1_1) ? "DOWNREV " : "",
-		(rev == XBOW_REV_1_0) ? "1.0" :
-		(rev == XBOW_REV_1_1) ? "1.1" :
-		(rev == XBOW_REV_1_2) ? "1.2" :
-		(rev == XBOW_REV_1_3) ? "1.3" :
-		(rev == XBOW_REV_2_0) ? "2.0" :
-		(rev == XXBOW_PART_REV_1_0) ? "Xbridge 1.0" :
-		(rev == XXBOW_PART_REV_2_0) ? "Xbridge 2.0" :
-		"unknown",
-		rev, soft->name,
-		(rev < XBOW_REV_1_1) ? "" : "\n");
-#endif	/* LATER */
-    mutex_spinlock_init(&soft->xbow_perf_lock);
-    soft->xbow_perfcnt[0].xp_perf_reg = &xbow->xb_perf_ctr_a;
-    soft->xbow_perfcnt[1].xp_perf_reg = &xbow->xb_perf_ctr_b;
-
-    /* Initialization for GBR bw allocation */
-    mutex_spinlock_init(&soft->xbow_bw_alloc_lock);
-
-#define	XBOW_8_BIT_PORT_BW_MAX		(400 * 1000 * 1000)	/* 400 MB/s */
-#define XBOW_16_BIT_PORT_BW_MAX		(800 * 1000 * 1000)	/* 800 MB/s */
-
-    /* Set bandwidth hiwatermark and current values */
-    for (i = 0; i < MAX_XBOW_PORTS; i++) {
-	soft->bw_hiwm[i] = XBOW_16_BIT_PORT_BW_MAX;	/* for now */
-	soft->bw_cur_used[i] = 0;
-    }
-
-    /*
-     * Enable xbow error interrupts
-     */
-    xbow->xb_wid_control = (XB_WID_CTRL_REG_ACC_IE | XB_WID_CTRL_XTALK_IE);
-
-    /*
-     * take a census of the widgets present,
-     * leaving notes at the switch vertex.
-     */
-    info = xswitch_info_new(busv);
-
-    for (port = MAX_PORT_NUM - MAX_XBOW_PORTS;
-	 port < MAX_PORT_NUM; ++port) {
-	if (!xbow_link_alive(xbow, port)) {
-#if DEBUG && XBOW_DEBUG
-	    printk(KERN_INFO "0x%p link %d is not alive\n",
-		    busv, port);
-#endif
-	    continue;
-	}
-	if (!xbow_widget_present(xbow, port)) {
-#if DEBUG && XBOW_DEBUG
-	    printk(KERN_INFO "0x%p link %d is alive but no widget is present\n", busv, port);
-#endif
-	    continue;
-	}
-#if DEBUG && XBOW_DEBUG
-	printk(KERN_INFO "0x%p link %d has a widget\n",
-		busv, port);
-#endif
-
-	xswitch_info_link_is_ok(info, port);
-	/*
-	 * Turn some error interrupts on
-	 * and turn others off. The PROM has
-	 * some things turned on we don't
-	 * want to see (bandwidth allocation
-	 * errors for instance); so if it
-	 * is not listed here, it is not on.
-	 */
-	xbow->xb_link(port).link_control =
-	    ( (xbow->xb_link(port).link_control
-	/*
-	 * Turn off these bits; they are non-fatal,
-	 * but we might want to save some statistics
-	 * on the frequency of these errors.
-	 * XXX FIXME XXX
-	 */
-	    & ~XB_CTRL_RCV_CNT_OFLOW_IE
-	    & ~XB_CTRL_XMT_CNT_OFLOW_IE
-	    & ~XB_CTRL_BNDWDTH_ALLOC_IE
-	    & ~XB_CTRL_RCV_IE)
-	/*
-	 * These are the ones we want to turn on.
-	 */
-	    | (XB_CTRL_ILLEGAL_DST_IE
-	    | XB_CTRL_OALLOC_IBUF_IE
-	    | XB_CTRL_XMT_MAX_RTRY_IE
-	    | XB_CTRL_MAXREQ_TOUT_IE
-	    | XB_CTRL_XMT_RTRY_IE
-	    | XB_CTRL_SRC_TOUT_IE) );
-    }
-
-    xswitch_provider_register(busv, &xbow_provider);
-
-    return 0;				/* attach successful */
-}
-
-/*ARGSUSED */
-int
-xbow_open(devfs_handle_t *devp, int oflag, int otyp, cred_t *credp)
-{
-    return 0;
-
-}
-
-/*ARGSUSED */
-int
-xbow_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp)
-{
-    return 0;
-}
-
-/*ARGSUSED */
-int
-xbow_map(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot)
-{
-    devfs_handle_t            vhdl = dev_to_vhdl(dev);
-    xbow_soft_t             soft = xbow_soft_get(vhdl);
-    int                     error;
-
-    ASSERT(soft);
-    len = ctob(btoc(len));
-    /* XXX- this ignores the offset!!! */
-    error = v_mapphys(vt, (void *) soft->base, len);
-    return error;
-}
-
-/*ARGSUSED */
-int
-xbow_unmap(devfs_handle_t dev, vhandl_t *vt)
-{
-    return 0;
-}
-
-/* This contains special-case code for grio. There are plans to make
- * this general sometime in the future, but till then this should
- * be good enough.
- */
-xwidgetnum_t
-xbow_widget_num_get(devfs_handle_t dev)
-{
-	devfs_handle_t	tdev;
-	char		devname[MAXDEVNAME];
-	xwidget_info_t	xwidget_info;
-	int		i;
-
-	vertex_to_name(dev, devname, MAXDEVNAME);
-
-	/* If this is a pci controller vertex, traverse up using
-	 * the ".." links to get to the widget.
-	 */
-	if (strstr(devname, EDGE_LBL_PCI) &&
-			strstr(devname, EDGE_LBL_CONTROLLER)) {
-		tdev = dev;
-		for (i=0; i< 2; i++) {
-			if (hwgraph_edge_get(tdev,
-				HWGRAPH_EDGELBL_DOTDOT, &tdev) !=
-					GRAPH_SUCCESS)
-				return XWIDGET_NONE;
-		}
-
-		if ((xwidget_info = xwidget_info_chk(tdev)) != NULL) {
-			return (xwidget_info_id_get(xwidget_info));
-		} else {
-			return XWIDGET_NONE;
-		}
-	}
-
-	return XWIDGET_NONE;
-}
-
-int
-xbow_ioctl(devfs_handle_t dev,
-	   int cmd,
-	   void *arg,
-	   int flag,
-	   struct cred *cr,
-	   int *rvalp)
-{
-    devfs_handle_t            vhdl;
-    int                     error = 0;
-
-#if defined (DEBUG)
-    int                     rc;
-    devfs_handle_t            conn;
-    struct xwidget_info_s  *xwidget_info;
-    xbow_soft_t             xbow_soft;
-#endif
-    *rvalp = 0;
-
-    vhdl = dev_to_vhdl(dev);
-#if defined (DEBUG)
-    xbow_soft = xbow_soft_get(vhdl);
-    conn = xbow_soft->conn;
-
-    xwidget_info = xwidget_info_get(conn);
-    ASSERT_ALWAYS(xwidget_info != NULL);
-
-    rc = xwidget_hwid_is_xswitch(&xwidget_info->w_hwid);
-    ASSERT_ALWAYS(rc != 0);
-#endif
-    switch (cmd) {
-#ifdef LATER
-    case XBOWIOC_PERF_ENABLE:
-    case XBOWIOC_PERF_DISABLE:
-	{
-	    struct xbow_perfarg_t   xbow_perf_en;
-
-	    if (!_CAP_CRABLE(cr, CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-	    if ((flag & FWRITE) == 0) {
-		error = EBADF;
-		break;
-	    }
-	    if (COPYIN(arg, &xbow_perf_en, sizeof(xbow_perf_en))) {
-		error = EFAULT;
-		break;
-	    }
-	    if (error = xbow_enable_perf_counter(vhdl,
-						 xbow_perf_en.link,
-						 (cmd == XBOWIOC_PERF_DISABLE) ? 0 : xbow_perf_en.mode,
-						 xbow_perf_en.counter)) {
-		error = EINVAL;
-		break;
-	    }
-	    break;
-	}
-#endif
-
-#ifdef LATER
-    case XBOWIOC_PERF_GET:
-	{
-	    xbow_perf_link_t       *xbow_perf_cnt;
-
-	    if ((flag & FREAD) == 0) {
-		error = EBADF;
-		break;
-	    }
-	    xbow_perf_cnt = xbow_get_perf_counters(vhdl);
-	    ASSERT_ALWAYS(xbow_perf_cnt != NULL);
-
-	    if (COPYOUT((void *) xbow_perf_cnt, (void *) arg,
-			MAX_XBOW_PORTS * sizeof(xbow_perf_link_t))) {
-		error = EFAULT;
-		break;
-	    }
-	    break;
-	}
-#endif
-
-    case XBOWIOC_LLP_ERROR_ENABLE:
-	if ((error = xbow_enable_llp_monitor(vhdl)) != 0)
-	    error = EINVAL;
-
-	break;
-
-    case XBOWIOC_LLP_ERROR_DISABLE:
-
-	if ((error = xbow_disable_llp_monitor(vhdl)) != 0)
-	    error = EINVAL;
-
-	break;
-
-#ifdef LATER
-    case XBOWIOC_LLP_ERROR_GET:
-	{
-	    xbow_link_status_t     *xbow_llp_status;
-
-	    if ((flag & FREAD) == 0) {
-		error = EBADF;
-		break;
-	    }
-	    xbow_llp_status = xbow_get_llp_status(vhdl);
-	    ASSERT_ALWAYS(xbow_llp_status != NULL);
-
-	    if (COPYOUT((void *) xbow_llp_status, (void *) arg,
-			MAX_XBOW_PORTS * sizeof(xbow_link_status_t))) {
-		error = EFAULT;
-		break;
-	    }
-	    break;
-	}
-#endif
-
-#ifdef LATER
-    case GIOCSETBW:
-	{
-	    grio_ioctl_info_t info;
-	    xwidgetnum_t src_widgetnum, dest_widgetnum;
-
-	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
-		error = EFAULT;
-		break;
-	    }
-#ifdef GRIO_DEBUG
-	    printf("xbow:: prev_vhdl: %d next_vhdl: %d reqbw: %lld\n",
-			info.prev_vhdl, info.next_vhdl, info.reqbw);
-#endif /* GRIO_DEBUG */
-
-	    src_widgetnum = xbow_widget_num_get(info.prev_vhdl);
-	    dest_widgetnum = xbow_widget_num_get(info.next_vhdl);
-
-	    /* Bandwidth allocation is bi-directional. Since bandwidth
-	     * reservations have already been done at an earlier stage,
-	     * we cannot fail here for lack of bandwidth.
-	     */
-	    xbow_prio_bw_alloc(dev, src_widgetnum, dest_widgetnum,
-			0, info.reqbw);
-	    xbow_prio_bw_alloc(dev, dest_widgetnum, src_widgetnum,
-			0, info.reqbw);
-
-	    break;
-	}
-
-    case GIOCRELEASEBW:
-	{
-	    grio_ioctl_info_t info;
-	    xwidgetnum_t src_widgetnum, dest_widgetnum;
-
-	    if (!cap_able(CAP_DEVICE_MGT)) {
-		error = EPERM;
-		break;
-	    }
-
-	    if (COPYIN(arg, &info, sizeof(grio_ioctl_info_t))) {
-		error = EFAULT;
-		break;
-	    }
-#ifdef GRIO_DEBUG
-	    printf("xbow:: prev_vhdl: %d next_vhdl: %d reqbw: %lld\n",
-			info.prev_vhdl, info.next_vhdl, info.reqbw);
-#endif /* GRIO_DEBUG */
-
-	    src_widgetnum = xbow_widget_num_get(info.prev_vhdl);
-	    dest_widgetnum = xbow_widget_num_get(info.next_vhdl);
-
-	    /* Bandwidth reservation is bi-directional. Hence, remove
-	     * bandwidth reservations for both directions.
-	     */
-	    xbow_prio_bw_alloc(dev, src_widgetnum, dest_widgetnum,
-			info.reqbw, (-1 * info.reqbw));
-	    xbow_prio_bw_alloc(dev, dest_widgetnum, src_widgetnum,
-			info.reqbw, (-1 * info.reqbw));
-
-	    break;
-	}
-#endif
-
-    default:
-	break;
-
-    }
-    return error;
-}
-
-/*
- * xbow_widget_present: See if a device is present
- * on the specified port of this crossbow.
- */
-int
-xbow_widget_present(xbow_t * xbow, int port)
-{
-	if ( IS_RUNNING_ON_SIMULATOR() ) {
-		if ( (port == 14) || (port == 15) ) {
-			return 1;
-		}
-		else {
-			return 0;
-		}
-	}
-	else {
-		return xbow->xb_link(port).link_aux_status & XB_AUX_STAT_PRESENT;
-	}
-}
-
-static int
-xbow_link_alive(xbow_t * xbow, int port)
-{
-    xbwX_stat_t             xbow_linkstat;
-
-    xbow_linkstat.linkstatus = xbow->xb_link(port).link_status;
-    return (xbow_linkstat.link_alive);
-}
-
-/*
- * xbow_widget_lookup
- *      Lookup the edges connected to the xbow specified, and
- *      retrieve the handle corresponding to the widgetnum
- *      specified.
- *      If not found, return 0.
- */
-devfs_handle_t
-xbow_widget_lookup(devfs_handle_t vhdl,
-		   int widgetnum)
-{
-    xswitch_info_t          xswitch_info;
-    devfs_handle_t            conn;
-
-    xswitch_info = xswitch_info_get(vhdl);
-    conn = xswitch_info_vhdl_get(xswitch_info, widgetnum);
-    return conn;
-}
-
-/*
- * xbow_setwidint: called when xtalk
- * is establishing or migrating our
- * interrupt service.
- */
-#ifdef LATER
-static void
-xbow_setwidint(xtalk_intr_t intr)
-{
-    xwidgetnum_t            targ = xtalk_intr_target_get(intr);
-    iopaddr_t               addr = xtalk_intr_addr_get(intr);
-    xtalk_intr_vector_t     vect = xtalk_intr_vector_get(intr);
-    xbow_t                 *xbow = (xbow_t *) xtalk_intr_sfarg_get(intr);
-
-    xbow_intr_preset((void *) xbow, 0, targ, addr, vect);
-}
-#endif	/* LATER */
-
-/*
- * xbow_intr_preset: called during mlreset time
- * if the platform specific code needs to route
- * an xbow interrupt before the xtalk infrastructure
- * is available for use.
- *
- * Also called from xbow_setwidint, so we don't
- * replicate the guts of the routine.
- *
- * XXX- probably should be renamed xbow_wid_intr_set or
- * something to reduce confusion.
- */
-/*ARGSUSED3 */
-void
-xbow_intr_preset(void *which_widget,
-		 int which_widget_intr,
-		 xwidgetnum_t targ,
-		 iopaddr_t addr,
-		 xtalk_intr_vector_t vect)
-{
-    xbow_t                 *xbow = (xbow_t *) which_widget;
-
-    xbow->xb_wid_int_upper = ((0xFF000000 & (vect << 24)) |
-			      (0x000F0000 & (targ << 16)) |
-			      XTALK_ADDR_TO_UPPER(addr));
-    xbow->xb_wid_int_lower = XTALK_ADDR_TO_LOWER(addr);
-}
-
-#define	XEM_ADD_STR(s)		printk("%s", (s))
-#define	XEM_ADD_NVAR(n,v)	printk("\t%20s: 0x%x\n", (n), (v))
-#define	XEM_ADD_VAR(v)		XEM_ADD_NVAR(#v,(v))
-#define XEM_ADD_IOEF(n) 	if (IOERROR_FIELDVALID(ioe,n))		    \
-				    XEM_ADD_NVAR("ioe." #n,		    \
-						 IOERROR_GETVALUE(ioe,n))
-
-#ifdef LATER
-static void
-xem_add_ioe(ioerror_t *ioe)
-{
-    XEM_ADD_IOEF(errortype);
-    XEM_ADD_IOEF(widgetnum);
-    XEM_ADD_IOEF(widgetdev);
-    XEM_ADD_IOEF(srccpu);
-    XEM_ADD_IOEF(srcnode);
-    XEM_ADD_IOEF(errnode);
-    XEM_ADD_IOEF(sysioaddr);
-    XEM_ADD_IOEF(xtalkaddr);
-    XEM_ADD_IOEF(busspace);
-    XEM_ADD_IOEF(busaddr);
-    XEM_ADD_IOEF(vaddr);
-    XEM_ADD_IOEF(memaddr);
-    XEM_ADD_IOEF(epc);
-    XEM_ADD_IOEF(ef);
-}
-
-#define XEM_ADD_IOE()	(xem_add_ioe(ioe))
-#endif	/* LATER */
-
-int                     xbow_xmit_retry_errors = 0;
-
-int
-xbow_xmit_retry_error(xbow_soft_t soft,
-		      int port)
-{
-    xswitch_info_t          info;
-    devfs_handle_t            vhdl;
-    widget_cfg_t           *wid;
-    widgetreg_t             id;
-    int                     part;
-    int                     mfgr;
-
-    wid = soft->wpio[port - BASE_XBOW_PORT];
-    if (wid == NULL) {
-	/* If we can't track down a PIO
-	 * pointer to our widget yet,
-	 * leave our caller knowing that
-	 * we are interested in this
-	 * interrupt if it occurs in
-	 * the future.
-	 */
-	info = xswitch_info_get(soft->busv);
-	if (!info)
-	    return 1;
-	vhdl = xswitch_info_vhdl_get(info, port);
-	if (vhdl == GRAPH_VERTEX_NONE)
-	    return 1;
-	wid = (widget_cfg_t *) xtalk_piotrans_addr
-	    (vhdl, 0, 0, sizeof *wid, 0);
-	if (!wid)
-	    return 1;
-	soft->wpio[port - BASE_XBOW_PORT] = wid;
-    }
-    id = wid->w_id;
-    part = XWIDGET_PART_NUM(id);
-    mfgr = XWIDGET_MFG_NUM(id);
-
-    /* If this thing is not a Bridge,
-     * do not activate the WAR, and
-     * tell our caller we do not need
-     * to be called again.
-     */
-    if ((part != BRIDGE_WIDGET_PART_NUM) ||
-	(mfgr != BRIDGE_WIDGET_MFGR_NUM)) {
-		/* FIXME: add Xbridge to the WAR.
-		 * Shouldn't hurt anything.  Later need to
-		 * check if we can remove this.
-                 */
-    		if ((part != XBRIDGE_WIDGET_PART_NUM) ||
-		    (mfgr != XBRIDGE_WIDGET_MFGR_NUM))
-			return 0;
-    }
-
-    /* count how many times we
-     * have picked up after
-     * LLP Transmit problems.
-     */
-    xbow_xmit_retry_errors++;
-
-    /* rewrite the control register
-     * to fix things up.
-     */
-    wid->w_control = wid->w_control;
-    wid->w_control;
-
-    return 1;
-}
-
-void
-xbow_update_perf_counters(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_perf_t            *xbow_perf = xbow_soft->xbow_perfcnt;
-    xbow_perf_link_t       *xbow_plink = xbow_soft->xbow_perflink;
-    xbow_perfcount_t        perf_reg;
-    unsigned long           s;
-    int                     link, i;
-
-    for (i = 0; i < XBOW_PERF_COUNTERS; i++, xbow_perf++) {
-	if (xbow_perf->xp_mode == XBOW_MONITOR_NONE)
-	    continue;
-
-	s = mutex_spinlock(&xbow_soft->xbow_perf_lock);
-
-	perf_reg.xb_counter_val = *(xbowreg_t *) xbow_perf->xp_perf_reg;
-
-	link = perf_reg.xb_perf.link_select;
-
-	(xbow_plink + link)->xlp_cumulative[xbow_perf->xp_curmode] +=
-	    ((perf_reg.xb_perf.count - xbow_perf->xp_current) & XBOW_COUNTER_MASK);
-	xbow_perf->xp_current = perf_reg.xb_perf.count;
-
-	mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-    }
-    /* Do port /mode multiplexing here */
-
-#ifdef LATER
-    (void) timeout(xbow_update_perf_counters,
-		   (void *) (__psunsigned_t) vhdl, XBOW_PERF_TIMEOUT);
-#endif
-
-}
-
-xbow_perf_link_t       *
-xbow_get_perf_counters(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_perf_link_t       *xbow_perf_link = xbow_soft->xbow_perflink;
-
-    return xbow_perf_link;
-}
-
-int
-xbow_enable_perf_counter(devfs_handle_t vhdl, int link, int mode, int counter)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_perf_t            *xbow_perf = xbow_soft->xbow_perfcnt;
-    xbow_linkctrl_t         xbow_link_ctrl;
-    xbow_t                 *xbow = xbow_soft->base;
-    xbow_perfcount_t        perf_reg;
-    unsigned long           s;
-    int                     i;
-
-    link -= BASE_XBOW_PORT;
-    if ((link < 0) || (link >= MAX_XBOW_PORTS))
-	return -1;
-
-    if ((mode < XBOW_MONITOR_NONE) || (mode > XBOW_MONITOR_DEST_LINK))
-	return -1;
-
-    if ((counter < 0) || (counter >= XBOW_PERF_COUNTERS))
-	return -1;
-
-    s = mutex_spinlock(&xbow_soft->xbow_perf_lock);
-
-    if ((xbow_perf + counter)->xp_mode && mode) {
-	mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-	return -1;
-    }
-    for (i = 0; i < XBOW_PERF_COUNTERS; i++) {
-	if (i == counter)
-	    continue;
-	if (((xbow_perf + i)->xp_link == link) &&
-	    ((xbow_perf + i)->xp_mode)) {
-	    mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-	    return -1;
-	}
-    }
-    xbow_perf += counter;
-
-    xbow_perf->xp_curlink = xbow_perf->xp_link = link;
-    xbow_perf->xp_curmode = xbow_perf->xp_mode = mode;
-
-    xbow_link_ctrl.xbl_ctrlword = xbow->xb_link_raw[link].link_control;
-    xbow_link_ctrl.xb_linkcontrol.perf_mode = mode;
-    xbow->xb_link_raw[link].link_control = xbow_link_ctrl.xbl_ctrlword;
-
-    perf_reg.xb_counter_val = *(xbowreg_t *) xbow_perf->xp_perf_reg;
-    perf_reg.xb_perf.link_select = link;
-    *(xbowreg_t *) xbow_perf->xp_perf_reg = perf_reg.xb_counter_val;
-    xbow_perf->xp_current = perf_reg.xb_perf.count;
-
-#ifdef LATER
-    (void) timeout(xbow_update_perf_counters,
-		   (void *) (__psunsigned_t) vhdl, XBOW_PERF_TIMEOUT);
-#endif
-
-    mutex_spinunlock(&xbow_soft->xbow_perf_lock, s);
-
-    return 0;
-}
-
-xbow_link_status_t     *
-xbow_get_llp_status(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_link_status_t     *xbow_llp_status = xbow_soft->xbow_link_status;
-
-    return xbow_llp_status;
-}
-
-void
-xbow_update_llp_status(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    xbow_link_status_t     *xbow_llp_status = xbow_soft->xbow_link_status;
-    xbow_t                 *xbow;
-    xbwX_stat_t             lnk_sts;
-    xbow_aux_link_status_t  aux_sts;
-    int                     link;
-    devfs_handle_t	    xwidget_vhdl;
-    char		   *xwidget_name;	
-
-    xbow = (xbow_t *) xbow_soft->base;
-    for (link = 0; link < MAX_XBOW_PORTS; link++, xbow_llp_status++) {
-	/* Get the widget name corresponding the current link.
-	 * Note : 0 <= link < MAX_XBOW_PORTS(8).
-	 * 	  BASE_XBOW_PORT(0x8) <= xwidget number < MAX_PORT_NUM (0x10)
-	 */
-	xwidget_vhdl = xbow_widget_lookup(xbow_soft->busv,link+BASE_XBOW_PORT);
-	xwidget_name = xwidget_name_get(xwidget_vhdl);
-	aux_sts.aux_linkstatus
-	    = xbow->xb_link_raw[link].link_aux_status;
-	lnk_sts.linkstatus = xbow->xb_link_raw[link].link_status_clr;
-
-	if (lnk_sts.link_alive == 0)
-	    continue;
-
-	xbow_llp_status->rx_err_count +=
-	    aux_sts.xb_aux_linkstatus.rx_err_cnt;
-
-	xbow_llp_status->tx_retry_count +=
-	    aux_sts.xb_aux_linkstatus.tx_retry_cnt;
-
-	if (lnk_sts.linkstatus & ~(XB_STAT_RCV_ERR | XB_STAT_XMT_RTRY_ERR | XB_STAT_LINKALIVE)) {
-#ifdef	LATER
-	    printk(KERN_WARNING  "link %d[%s]: bad status 0x%x\n",
-		    link, xwidget_name, lnk_sts.linkstatus);
-#endif
-	}
-    }
-#ifdef LATER
-    if (xbow_soft->link_monitor)
-	(void) timeout(xbow_update_llp_status,
-		       (void *) (__psunsigned_t) vhdl, XBOW_STATS_TIMEOUT);
-#endif
-}
-
-int
-xbow_disable_llp_monitor(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-    int                     port;
-
-    for (port = 0; port < MAX_XBOW_PORTS; port++) {
-	xbow_soft->xbow_link_status[port].rx_err_count = 0;
-	xbow_soft->xbow_link_status[port].tx_retry_count = 0;
-    }
-
-    xbow_soft->link_monitor = 0;
-    return 0;
-}
-
-int
-xbow_enable_llp_monitor(devfs_handle_t vhdl)
-{
-    xbow_soft_t             xbow_soft = xbow_soft_get(vhdl);
-
-#ifdef LATER
-    (void) timeout(xbow_update_llp_status,
-		   (void *) (__psunsigned_t) vhdl, XBOW_STATS_TIMEOUT);
-#endif
-    xbow_soft->link_monitor = 1;
-    return 0;
-}
-
-
-int
-xbow_reset_link(devfs_handle_t xconn_vhdl)
-{
-    xwidget_info_t          widget_info;
-    xwidgetnum_t            port;
-    xbow_t                 *xbow;
-    xbowreg_t               ctrl;
-    xbwX_stat_t             stat;
-    unsigned                itick;
-    unsigned                dtick;
-    static int              ticks_per_ms = 0;
-
-    if (!ticks_per_ms) {
-	itick = get_timestamp();
-	us_delay(1000);
-	ticks_per_ms = get_timestamp() - itick;
-    }
-    widget_info = xwidget_info_get(xconn_vhdl);
-    port = xwidget_info_id_get(widget_info);
-
-#ifdef XBOW_K1PTR			/* defined if we only have one xbow ... */
-    xbow = XBOW_K1PTR;
-#else
-    {
-	devfs_handle_t            xbow_vhdl;
-	xbow_soft_t             xbow_soft;
-
-	hwgraph_traverse(xconn_vhdl, ".master/xtalk/0/xbow", &xbow_vhdl);
-	xbow_soft = xbow_soft_get(xbow_vhdl);
-	xbow = xbow_soft->base;
-    }
-#endif
-
-    /*
-     * This requires three PIOs (reset the link, check for the
-     * reset, restore the control register for the link) plus
-     * 10us to wait for the reset. We allow up to 1ms for the
-     * widget to come out of reset before giving up and
-     * returning a failure.
-     */
-    ctrl = xbow->xb_link(port).link_control;
-    xbow->xb_link(port).link_reset = 0;
-    itick = get_timestamp();
-    while (1) {
-	stat.linkstatus = xbow->xb_link(port).link_status;
-	if (stat.link_alive)
-	    break;
-	dtick = get_timestamp() - itick;
-	if (dtick > ticks_per_ms) {
-	    return -1;			/* never came out of reset */
-	}
-	DELAY(2);			/* don't beat on link_status */
-    }
-    xbow->xb_link(port).link_control = ctrl;
-    return 0;
-}
-
-/*
- * Dump xbow registers.
- * input parameter is either a pointer to
- * the xbow chip or the vertex handle for
- * an xbow vertex.
- */
-void
-idbg_xbowregs(int64_t regs)
-{
-    xbow_t                 *xbow;
-    int                     i;
-    xb_linkregs_t          *link;
-
-#ifdef LATER
-    if (dev_is_vertex((devfs_handle_t) regs)) {
-	devfs_handle_t            vhdl = (devfs_handle_t) regs;
-	xbow_soft_t             soft = xbow_soft_get(vhdl);
-
-	xbow = soft->base;
-    } else
-#endif
-    {
-	xbow = (xbow_t *) regs;
-    }
-
-#ifdef LATER
-    qprintf("Printing xbow registers starting at 0x%x\n", xbow);
-    qprintf("wid %x status %x erruppr %x errlower %x control %x timeout %x\n",
-	    xbow->xb_wid_id, xbow->xb_wid_stat, xbow->xb_wid_err_upper,
-	    xbow->xb_wid_err_lower, xbow->xb_wid_control,
-	    xbow->xb_wid_req_timeout);
-    qprintf("intr uppr %x lower %x errcmd %x llp ctrl %x arb_reload %x\n",
-	    xbow->xb_wid_int_upper, xbow->xb_wid_int_lower,
-	    xbow->xb_wid_err_cmdword, xbow->xb_wid_llp,
-	    xbow->xb_wid_arb_reload);
-#endif
-
-    for (i = 8; i <= 0xf; i++) {
-	link = &xbow->xb_link(i);
-#ifdef LATER
-	qprintf("Link %d registers\n", i);
-	qprintf("\tctrl %x stat %x arbuppr %x arblowr %x auxstat %x\n",
-		link->link_control, link->link_status,
-		link->link_arb_upper, link->link_arb_lower,
-		link->link_aux_status);
-#endif
-    }
-}
-
-
-#define XBOW_ARB_RELOAD_TICKS		25
-					/* granularity: 4 MB/s, max: 124 MB/s */
-#define GRANULARITY			((100 * 1000000) / XBOW_ARB_RELOAD_TICKS)
-
-#define XBOW_BYTES_TO_GBR(BYTES_per_s)	(int) (BYTES_per_s / GRANULARITY)
-
-#define XBOW_GBR_TO_BYTES(cnt)		(bandwidth_t) ((cnt) * GRANULARITY)
-
-#define CEILING_BYTES_TO_GBR(gbr, bytes_per_sec)	\
-			((XBOW_GBR_TO_BYTES(gbr) < bytes_per_sec) ? gbr+1 : gbr)
-
-#define XBOW_ARB_GBR_MAX		31
-
-#define ABS(x)				((x > 0) ? (x) : (-1 * x))
-					/* absolute value */
-
-int
-xbow_bytes_to_gbr(bandwidth_t old_bytes_per_sec, bandwidth_t bytes_per_sec)
-{
-    int                     gbr_granted;
-    int                     new_total_gbr;
-    int                     change_gbr;
-    bandwidth_t             new_total_bw;
-
-#ifdef GRIO_DEBUG
-    printf("xbow_bytes_to_gbr: old_bytes_per_sec %lld bytes_per_sec %lld\n",
-		old_bytes_per_sec, bytes_per_sec);
-#endif	/* GRIO_DEBUG */
-
-    gbr_granted = CEILING_BYTES_TO_GBR((XBOW_BYTES_TO_GBR(old_bytes_per_sec)),
-			old_bytes_per_sec);
-    new_total_bw = old_bytes_per_sec + bytes_per_sec;
-    new_total_gbr = CEILING_BYTES_TO_GBR((XBOW_BYTES_TO_GBR(new_total_bw)),
-			new_total_bw);
-
-    change_gbr = new_total_gbr - gbr_granted;
-
-#ifdef GRIO_DEBUG
-    printf("xbow_bytes_to_gbr: gbr_granted %d new_total_gbr %d change_gbr %d\n",
-		gbr_granted, new_total_gbr, change_gbr);
-#endif	/* GRIO_DEBUG */
-
-    return (change_gbr);
-}
-
-/* Conversion from GBR to bytes */
-bandwidth_t
-xbow_gbr_to_bytes(int gbr)
-{
-    return (XBOW_GBR_TO_BYTES(gbr));
-}
-
-/* Given the vhdl for the desired xbow, the src and dest. widget ids
- * and the req_bw value, this xbow driver entry point accesses the
- * xbow registers and allocates the desired bandwidth if available.
- *
- * If bandwidth allocation is successful, return success else return failure.
- */
-int
-xbow_prio_bw_alloc(devfs_handle_t vhdl,
-		xwidgetnum_t src_wid,
-		xwidgetnum_t dest_wid,
-		unsigned long long old_alloc_bw,
-		unsigned long long req_bw)
-{
-    xbow_soft_t             soft = xbow_soft_get(vhdl);
-    volatile xbowreg_t     *xreg;
-    xbowreg_t               mask;
-    unsigned long           s;
-    int                     error = 0;
-    bandwidth_t             old_bw_BYTES, req_bw_BYTES;
-    xbowreg_t               old_xreg;
-    int                     old_bw_GBR, req_bw_GBR, new_bw_GBR;
-
-#ifdef GRIO_DEBUG
-    printf("xbow_prio_bw_alloc: vhdl %d src_wid %d dest_wid %d req_bw %lld\n",
-		(int) vhdl, (int) src_wid, (int) dest_wid, req_bw);
-#endif
-
-    ASSERT(XBOW_WIDGET_IS_VALID(src_wid));
-    ASSERT(XBOW_WIDGET_IS_VALID(dest_wid));
-
-    s = mutex_spinlock(&soft->xbow_bw_alloc_lock);
-
-    /* Get pointer to the correct register */
-    xreg = XBOW_PRIO_ARBREG_PTR(soft->base, dest_wid, src_wid);
-
-    /* Get mask for GBR count value */
-    mask = XB_ARB_GBR_MSK << XB_ARB_GBR_SHFT(src_wid);
-
-    req_bw_GBR = xbow_bytes_to_gbr(old_alloc_bw, req_bw);
-    req_bw_BYTES = (req_bw_GBR < 0) ? (-1 * xbow_gbr_to_bytes(ABS(req_bw_GBR)))
-		: xbow_gbr_to_bytes(req_bw_GBR);
-
-#ifdef GRIO_DEBUG
-    printf("req_bw %lld req_bw_BYTES %lld req_bw_GBR %d\n",
-		req_bw, req_bw_BYTES, req_bw_GBR);
-#endif	/* GRIO_DEBUG */
-
-    old_bw_BYTES = soft->bw_cur_used[(int) dest_wid - MAX_XBOW_PORTS];
-    old_xreg = *xreg;
-    old_bw_GBR = (((*xreg) & mask) >> XB_ARB_GBR_SHFT(src_wid));
-
-#ifdef GRIO_DEBUG
-    ASSERT(XBOW_BYTES_TO_GBR(old_bw_BYTES) == old_bw_GBR);
-
-    printf("old_bw_BYTES %lld old_bw_GBR %d\n", old_bw_BYTES, old_bw_GBR);
-
-    printf("req_bw_BYTES %lld old_bw_BYTES %lld soft->bw_hiwm %lld\n",
-		req_bw_BYTES, old_bw_BYTES,
-		soft->bw_hiwm[(int) dest_wid - MAX_XBOW_PORTS]);
-	   
-#endif				/* GRIO_DEBUG */
-
-    /* Accept the request only if we don't exceed the destination
-     * port HIWATER_MARK *AND* the max. link GBR arbitration count
-     */
-    if (((old_bw_BYTES + req_bw_BYTES) <=
-		soft->bw_hiwm[(int) dest_wid - MAX_XBOW_PORTS]) &&
-		(req_bw_GBR + old_bw_GBR <= XBOW_ARB_GBR_MAX)) {
-
-	new_bw_GBR = (old_bw_GBR + req_bw_GBR);
-
-	/* Set this in the xbow link register */
-	*xreg = (old_xreg & ~mask) | \
-	    (new_bw_GBR << XB_ARB_GBR_SHFT(src_wid) & mask);
-
-	soft->bw_cur_used[(int) dest_wid - MAX_XBOW_PORTS] =
-			xbow_gbr_to_bytes(new_bw_GBR);
-    } else {
-	error = 1;
-    }
-
-    mutex_spinunlock(&soft->xbow_bw_alloc_lock, s);
-
-    return (error);
-}
diff -Nru a/arch/ia64/sn/io/xswitch.c b/arch/ia64/sn/io/xswitch.c
--- a/arch/ia64/sn/io/xswitch.c	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/sn/io/xswitch.c	Wed Jun 18 23:42:06 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/types.h>
@@ -23,8 +23,6 @@
 #define	NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
 #define	DEL(ptr)	(kfree(ptr))
 
-int                     xswitch_devflag = D_MP;
-
 /*
  * This file provides generic support for Crosstalk
  * Switches, in a way that insulates crosstalk providers
@@ -45,9 +43,9 @@
 #define	DEV_FUNC(dev,func)	xwidget_to_provider_fns(dev)->func
 
 static xswitch_provider_t *
-xwidget_to_provider_fns(devfs_handle_t xconn)
+xwidget_to_provider_fns(vertex_hdl_t xconn)
 {
-    devfs_handle_t            busv;
+    vertex_hdl_t            busv;
     xswitch_info_t          xswitch_info;
     xswitch_provider_t      provider_fns;
 
@@ -75,27 +73,18 @@
 struct xswitch_info_s {
     char                   *fingerprint;
     unsigned                census;
-    devfs_handle_t            vhdl[XSWITCH_CENSUS_PORTS];
-    devfs_handle_t            master_vhdl[XSWITCH_CENSUS_PORTS];
+    vertex_hdl_t            vhdl[XSWITCH_CENSUS_PORTS];
+    vertex_hdl_t            master_vhdl[XSWITCH_CENSUS_PORTS];
     xswitch_provider_t     *xswitch_fns;
 };
 
 xswitch_info_t
-xswitch_info_get(devfs_handle_t xwidget)
+xswitch_info_get(vertex_hdl_t xwidget)
 {
     xswitch_info_t          xswitch_info;
 
     xswitch_info = (xswitch_info_t)
 	hwgraph_fastinfo_get(xwidget);
-#ifdef	LATER
-    if ((xswitch_info != NULL) &&
-	(xswitch_info->fingerprint != xswitch_info_fingerprint))
-#ifdef SUPPORT_PRINTING_V_FORMAT
-	PRINT_PANIC("%v xswitch_info_get bad fingerprint", xwidget);
-#else
-	PRINT_PANIC("%x xswitch_info_get bad fingerprint", xwidget);
-#endif
-#endif	/* LATER */
 
     return (xswitch_info);
 }
@@ -103,7 +92,7 @@
 void
 xswitch_info_vhdl_set(xswitch_info_t xswitch_info,
 		      xwidgetnum_t port,
-		      devfs_handle_t xwidget)
+		      vertex_hdl_t xwidget)
 {
 #if XSWITCH_CENSUS_PORT_MIN
     if (port < XSWITCH_CENSUS_PORT_MIN)
@@ -115,15 +104,10 @@
     xswitch_info->vhdl[port - XSWITCH_CENSUS_PORT_MIN] = xwidget;
 }
 
-devfs_handle_t
+vertex_hdl_t
 xswitch_info_vhdl_get(xswitch_info_t xswitch_info,
 		      xwidgetnum_t port)
 {
-#ifdef	LATER
-    if (xswitch_info == NULL)
-	PRINT_PANIC("xswitch_info_vhdl_get: null xswitch_info");
-#endif
-
 #if XSWITCH_CENSUS_PORT_MIN
     if (port < XSWITCH_CENSUS_PORT_MIN)
 	return GRAPH_VERTEX_NONE;
@@ -142,7 +126,7 @@
 void
 xswitch_info_master_assignment_set(xswitch_info_t xswitch_info,
 				   xwidgetnum_t port,
-				   devfs_handle_t master_vhdl)
+				   vertex_hdl_t master_vhdl)
 {
 #if XSWITCH_CENSUS_PORT_MIN
     if (port < XSWITCH_CENSUS_PORT_MIN)
@@ -154,7 +138,7 @@
     xswitch_info->master_vhdl[port - XSWITCH_CENSUS_PORT_MIN] = master_vhdl;
 }
 
-devfs_handle_t
+vertex_hdl_t
 xswitch_info_master_assignment_get(xswitch_info_t xswitch_info,
 				   xwidgetnum_t port)
 {
@@ -169,14 +153,14 @@
 }
 
 void
-xswitch_info_set(devfs_handle_t xwidget, xswitch_info_t xswitch_info)
+xswitch_info_set(vertex_hdl_t xwidget, xswitch_info_t xswitch_info)
 {
     xswitch_info->fingerprint = xswitch_info_fingerprint;
     hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) xswitch_info);
 }
 
 xswitch_info_t
-xswitch_info_new(devfs_handle_t xwidget)
+xswitch_info_new(vertex_hdl_t xwidget)
 {
     xswitch_info_t          xswitch_info;
 
@@ -202,7 +186,7 @@
 }
 
 void
-xswitch_provider_register(devfs_handle_t busv,
+xswitch_provider_register(vertex_hdl_t busv,
 			  xswitch_provider_t * xswitch_fns)
 {
     xswitch_info_t          xswitch_info = xswitch_info_get(busv);
@@ -232,35 +216,8 @@
 }
 
 int
-xswitch_reset_link(devfs_handle_t xconn_vhdl)
+xswitch_reset_link(vertex_hdl_t xconn_vhdl)
 {
     return DEV_FUNC(xconn_vhdl, reset_link)
 	(xconn_vhdl);
-}
-
-/* Given a vertex handle to the xswitch get its logical
- * id.
- */
-int
-xswitch_id_get(devfs_handle_t	xconn_vhdl)
-{
-    arbitrary_info_t 	xbow_num;
-    graph_error_t	rv;
-
-    rv = hwgraph_info_get_LBL(xconn_vhdl,INFO_LBL_XSWITCH_ID,&xbow_num);
-    ASSERT(rv == GRAPH_SUCCESS);
-    return(xbow_num);
-}
-
-/* Given a vertex handle to the xswitch set its logical
- * id.
- */
-void
-xswitch_id_set(devfs_handle_t	xconn_vhdl,int xbow_num)
-{
-    graph_error_t	rv;
-
-    rv = hwgraph_info_add_LBL(xconn_vhdl,INFO_LBL_XSWITCH_ID,
-			      (arbitrary_info_t)xbow_num);
-    ASSERT(rv == GRAPH_SUCCESS);
 }
diff -Nru a/arch/ia64/sn/io/xtalk.c b/arch/ia64/sn/io/xtalk.c
--- a/arch/ia64/sn/io/xtalk.c	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1024 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/io.h>
-#include <asm/sn/iograph.h>
-#include <asm/sn/invent.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/labelcl.h>
-#include <asm/sn/hcl_util.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/xtalk/xswitch.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/xtalk/xtalk_private.h>
-
-/*
- * Implement crosstalk provider operations.  The xtalk* layer provides a
- * platform-independent interface for crosstalk devices.  This layer
- * switches among the possible implementations of a crosstalk adapter.
- *
- * On platforms with only one possible xtalk provider, macros can be
- * set up at the top that cause the table lookups and indirections to
- * completely disappear.
- */
-
-#define	NEW(ptr)	(ptr = kmalloc(sizeof (*(ptr)), GFP_KERNEL))
-#define	DEL(ptr)	(kfree(ptr))
-
-char                    widget_info_fingerprint[] = "widget_info";
-
-cdl_p                   xtalk_registry = NULL;
-
-#define	DEV_FUNC(dev,func)	hub_##func
-#define	CAST_PIOMAP(x)		((hub_piomap_t)(x))
-#define	CAST_DMAMAP(x)		((hub_dmamap_t)(x))
-#define	CAST_INTR(x)		((hub_intr_t)(x))
-
-/* =====================================================================
- *            Function Table of Contents
- */
-xtalk_piomap_t          xtalk_piomap_alloc(devfs_handle_t, device_desc_t, iopaddr_t, size_t, size_t, unsigned);
-void                    xtalk_piomap_free(xtalk_piomap_t);
-caddr_t                 xtalk_piomap_addr(xtalk_piomap_t, iopaddr_t, size_t);
-void                    xtalk_piomap_done(xtalk_piomap_t);
-caddr_t                 xtalk_piotrans_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, unsigned);
-caddr_t                 xtalk_pio_addr(devfs_handle_t, device_desc_t, iopaddr_t, size_t, xtalk_piomap_t *, unsigned);
-void                    xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *);
-caddr_t                 xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
-static caddr_t          null_xtalk_early_piotrans_addr(xwidget_part_num_t, xwidget_mfg_num_t, int, iopaddr_t, size_t, unsigned);
-xtalk_dmamap_t          xtalk_dmamap_alloc(devfs_handle_t, device_desc_t, size_t, unsigned);
-void                    xtalk_dmamap_free(xtalk_dmamap_t);
-iopaddr_t               xtalk_dmamap_addr(xtalk_dmamap_t, paddr_t, size_t);
-alenlist_t              xtalk_dmamap_list(xtalk_dmamap_t, alenlist_t, unsigned);
-void                    xtalk_dmamap_done(xtalk_dmamap_t);
-iopaddr_t               xtalk_dmatrans_addr(devfs_handle_t, device_desc_t, paddr_t, size_t, unsigned);
-alenlist_t              xtalk_dmatrans_list(devfs_handle_t, device_desc_t, alenlist_t, unsigned);
-void			xtalk_dmamap_drain(xtalk_dmamap_t);
-void			xtalk_dmaaddr_drain(devfs_handle_t, iopaddr_t, size_t);
-void			xtalk_dmalist_drain(devfs_handle_t, alenlist_t);
-xtalk_intr_t            xtalk_intr_alloc(devfs_handle_t, device_desc_t, devfs_handle_t);
-xtalk_intr_t            xtalk_intr_alloc_nothd(devfs_handle_t, device_desc_t, devfs_handle_t);
-void                    xtalk_intr_free(xtalk_intr_t);
-int                     xtalk_intr_connect(xtalk_intr_t, xtalk_intr_setfunc_t, void *);
-void                    xtalk_intr_disconnect(xtalk_intr_t);
-devfs_handle_t            xtalk_intr_cpu_get(xtalk_intr_t);
-int                     xtalk_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *);
-int                     xtalk_error_devenable(devfs_handle_t, int, int);
-void                    xtalk_provider_startup(devfs_handle_t);
-void                    xtalk_provider_shutdown(devfs_handle_t);
-devfs_handle_t            xtalk_intr_dev_get(xtalk_intr_t);
-xwidgetnum_t            xtalk_intr_target_get(xtalk_intr_t);
-xtalk_intr_vector_t     xtalk_intr_vector_get(xtalk_intr_t);
-iopaddr_t               xtalk_intr_addr_get(struct xtalk_intr_s *);
-void                   *xtalk_intr_sfarg_get(xtalk_intr_t);
-devfs_handle_t            xtalk_pio_dev_get(xtalk_piomap_t);
-xwidgetnum_t            xtalk_pio_target_get(xtalk_piomap_t);
-iopaddr_t               xtalk_pio_xtalk_addr_get(xtalk_piomap_t);
-ulong                   xtalk_pio_mapsz_get(xtalk_piomap_t);
-caddr_t                 xtalk_pio_kvaddr_get(xtalk_piomap_t);
-devfs_handle_t            xtalk_dma_dev_get(xtalk_dmamap_t);
-xwidgetnum_t            xtalk_dma_target_get(xtalk_dmamap_t);
-xwidget_info_t          xwidget_info_chk(devfs_handle_t);
-xwidget_info_t          xwidget_info_get(devfs_handle_t);
-void                    xwidget_info_set(devfs_handle_t, xwidget_info_t);
-devfs_handle_t            xwidget_info_dev_get(xwidget_info_t);
-xwidgetnum_t            xwidget_info_id_get(xwidget_info_t);
-devfs_handle_t            xwidget_info_master_get(xwidget_info_t);
-xwidgetnum_t            xwidget_info_masterid_get(xwidget_info_t);
-xwidget_part_num_t      xwidget_info_part_num_get(xwidget_info_t);
-xwidget_mfg_num_t       xwidget_info_mfg_num_get(xwidget_info_t);
-char 			*xwidget_info_name_get(xwidget_info_t);
-void                    xtalk_init(void);
-void                    xtalk_provider_register(devfs_handle_t, xtalk_provider_t *);
-void                    xtalk_provider_unregister(devfs_handle_t);
-xtalk_provider_t       *xtalk_provider_fns_get(devfs_handle_t);
-int                     xwidget_driver_register(xwidget_part_num_t, 
-						xwidget_mfg_num_t, 
-						char *, unsigned);
-void                    xwidget_driver_unregister(char *);
-int                     xwidget_register(xwidget_hwid_t, devfs_handle_t, 
-					 xwidgetnum_t, devfs_handle_t, 
-					 xwidgetnum_t, async_attach_t);
-int			xwidget_unregister(devfs_handle_t);
-void                    xwidget_reset(devfs_handle_t);
-char			*xwidget_name_get(devfs_handle_t);
-#if !defined(DEV_FUNC)
-/*
- * There is more than one possible provider
- * for this platform. We need to examine the
- * master vertex of the current vertex for
- * a provider function structure, and indirect
- * through the appropriately named member.
- */
-#define	DEV_FUNC(dev,func)	xwidget_to_provider_fns(dev)->func
-#define	CAST_PIOMAP(x)		((xtalk_piomap_t)(x))
-#define	CAST_DMAMAP(x)		((xtalk_dmamap_t)(x))
-#define	CAST_INTR(x)		((xtalk_intr_t)(x))
-
-static xtalk_provider_t *
-xwidget_to_provider_fns(devfs_handle_t xconn)
-{
-    xwidget_info_t          widget_info;
-    xtalk_provider_t       *provider_fns;
-
-    widget_info = xwidget_info_get(xconn);
-    ASSERT(widget_info != NULL);
-
-    provider_fns = xwidget_info_pops_get(widget_info);
-    ASSERT(provider_fns != NULL);
-
-    return (provider_fns);
-}
-#endif
-
-/*
- * Many functions are not passed their vertex
- * information directly; rather, they must
- * dive through a resource map. These macros
- * are available to coordinate this detail.
- */
-#define	PIOMAP_FUNC(map,func)	DEV_FUNC(map->xp_dev,func)
-#define	DMAMAP_FUNC(map,func)	DEV_FUNC(map->xd_dev,func)
-#define	INTR_FUNC(intr,func)	DEV_FUNC(intr_hdl->xi_dev,func)
-
-/* =====================================================================
- *                    PIO MANAGEMENT
- *
- *      For mapping system virtual address space to
- *      xtalk space on a specified widget
- */
-
-xtalk_piomap_t
-xtalk_piomap_alloc(devfs_handle_t dev,	/* set up mapping for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   iopaddr_t xtalk_addr,	/* map for this xtalk_addr range */
-		   size_t byte_count,
-		   size_t byte_count_max,	/* maximum size of a mapping */
-		   unsigned flags)
-{				/* defined in sys/pio.h */
-    return (xtalk_piomap_t) DEV_FUNC(dev, piomap_alloc)
-	(dev, dev_desc, xtalk_addr, byte_count, byte_count_max, flags);
-}
-
-
-void
-xtalk_piomap_free(xtalk_piomap_t xtalk_piomap)
-{
-    PIOMAP_FUNC(xtalk_piomap, piomap_free)
-	(CAST_PIOMAP(xtalk_piomap));
-}
-
-
-caddr_t
-xtalk_piomap_addr(xtalk_piomap_t xtalk_piomap,	/* mapping resources */
-		  iopaddr_t xtalk_addr,		/* map for this xtalk address */
-		  size_t byte_count)
-{				/* map this many bytes */
-    return PIOMAP_FUNC(xtalk_piomap, piomap_addr)
-	(CAST_PIOMAP(xtalk_piomap), xtalk_addr, byte_count);
-}
-
-
-void
-xtalk_piomap_done(xtalk_piomap_t xtalk_piomap)
-{
-    PIOMAP_FUNC(xtalk_piomap, piomap_done)
-	(CAST_PIOMAP(xtalk_piomap));
-}
-
-
-caddr_t
-xtalk_piotrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    iopaddr_t xtalk_addr,	/* Crosstalk address */
-		    size_t byte_count,	/* map this many bytes */
-		    unsigned flags)
-{				/* (currently unused) */
-    return DEV_FUNC(dev, piotrans_addr)
-	(dev, dev_desc, xtalk_addr, byte_count, flags);
-}
-
-caddr_t
-xtalk_pio_addr(devfs_handle_t dev,	/* translate for this device */
-	       device_desc_t dev_desc,	/* device descriptor */
-	       iopaddr_t addr,		/* starting address (or offset in window) */
-	       size_t byte_count,	/* map this many bytes */
-	       xtalk_piomap_t *mapp,	/* where to return the map pointer */
-	       unsigned flags)
-{					/* PIO flags */
-    xtalk_piomap_t          map = 0;
-    caddr_t                 res;
-
-    if (mapp)
-	*mapp = 0;			/* record "no map used" */
-
-    res = xtalk_piotrans_addr
-	(dev, dev_desc, addr, byte_count, flags);
-    if (res)
-	return res;			/* xtalk_piotrans worked */
-
-    map = xtalk_piomap_alloc
-	(dev, dev_desc, addr, byte_count, byte_count, flags);
-    if (!map)
-	return res;			/* xtalk_piomap_alloc failed */
-
-    res = xtalk_piomap_addr
-	(map, addr, byte_count);
-    if (!res) {
-	xtalk_piomap_free(map);
-	return res;			/* xtalk_piomap_addr failed */
-    }
-    if (mapp)
-	*mapp = map;			/* pass back map used */
-
-    return res;				/* xtalk_piomap_addr succeeded */
-}
-
-/* =====================================================================
- *            EARLY PIOTRANS SUPPORT
- *
- *      There are places where drivers (mgras, for instance)
- *      need to get PIO translations before the infrastructure
- *      is extended to them (setting up textports, for
- *      instance). These drivers should call
- *      xtalk_early_piotrans_addr with their xtalk ID
- *      information, a sequence number (so we can use the second
- *      mgras for instance), and the usual piotrans parameters.
- *
- *      Machine specific code should provide an implementation
- *      of early_piotrans_addr, and present a pointer to this
- *      function to xtalk_set_early_piotrans_addr so it can be
- *      used by clients without the clients having to know what
- *      platform or what xtalk provider is in use.
- */
-
-static xtalk_early_piotrans_addr_f null_xtalk_early_piotrans_addr;
-
-xtalk_early_piotrans_addr_f *impl_early_piotrans_addr = null_xtalk_early_piotrans_addr;
-
-/* xtalk_set_early_piotrans_addr:
- * specify the early_piotrans_addr implementation function.
- */
-void
-xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *impl)
-{
-    impl_early_piotrans_addr = impl;
-}
-
-/* xtalk_early_piotrans_addr:
- * figure out a PIO address for the "nth" crosstalk widget that
- * matches the specified part and mfgr number. Returns NULL if
- * there is no such widget, or if the requested mapping can not
- * be constructed.
- * Limitations on which crosstalk slots (and busses) are
- * checked, and definitions of the ordering of the search across
- * the crosstalk slots, are defined by the platform.
- */
-caddr_t
-xtalk_early_piotrans_addr(xwidget_part_num_t part_num,
-			  xwidget_mfg_num_t mfg_num,
-			  int which,
-			  iopaddr_t xtalk_addr,
-			  size_t byte_count,
-			  unsigned flags)
-{
-    return impl_early_piotrans_addr
-	(part_num, mfg_num, which, xtalk_addr, byte_count, flags);
-}
-
-/* null_xtalk_early_piotrans_addr:
- * used as the early_piotrans_addr implementation until and
- * unless a real implementation is provided. In DEBUG kernels,
- * we want to know who is calling before the implementation is
- * registered; in non-DEBUG kernels, return NULL representing
- * lack of mapping support.
- */
-/*ARGSUSED */
-static caddr_t
-null_xtalk_early_piotrans_addr(xwidget_part_num_t part_num,
-			       xwidget_mfg_num_t mfg_num,
-			       int which,
-			       iopaddr_t xtalk_addr,
-			       size_t byte_count,
-			       unsigned flags)
-{
-#if DEBUG
-    PRINT_PANIC("null_xtalk_early_piotrans_addr");
-#endif
-    return NULL;
-}
-
-/* =====================================================================
- *                    DMA MANAGEMENT
- *
- *      For mapping from crosstalk space to system
- *      physical space.
- */
-
-xtalk_dmamap_t
-xtalk_dmamap_alloc(devfs_handle_t dev,	/* set up mappings for this device */
-		   device_desc_t dev_desc,	/* device descriptor */
-		   size_t byte_count_max,	/* max size of a mapping */
-		   unsigned flags)
-{				/* defined in dma.h */
-    return (xtalk_dmamap_t) DEV_FUNC(dev, dmamap_alloc)
-	(dev, dev_desc, byte_count_max, flags);
-}
-
-
-void
-xtalk_dmamap_free(xtalk_dmamap_t xtalk_dmamap)
-{
-    DMAMAP_FUNC(xtalk_dmamap, dmamap_free)
-	(CAST_DMAMAP(xtalk_dmamap));
-}
-
-
-iopaddr_t
-xtalk_dmamap_addr(xtalk_dmamap_t xtalk_dmamap,	/* use these mapping resources */
-		  paddr_t paddr,	/* map for this address */
-		  size_t byte_count)
-{				/* map this many bytes */
-    return DMAMAP_FUNC(xtalk_dmamap, dmamap_addr)
-	(CAST_DMAMAP(xtalk_dmamap), paddr, byte_count);
-}
-
-
-alenlist_t
-xtalk_dmamap_list(xtalk_dmamap_t xtalk_dmamap,	/* use these mapping resources */
-		  alenlist_t alenlist,	/* map this Address/Length List */
-		  unsigned flags)
-{
-    return DMAMAP_FUNC(xtalk_dmamap, dmamap_list)
-	(CAST_DMAMAP(xtalk_dmamap), alenlist, flags);
-}
-
-
-void
-xtalk_dmamap_done(xtalk_dmamap_t xtalk_dmamap)
-{
-    DMAMAP_FUNC(xtalk_dmamap, dmamap_done)
-	(CAST_DMAMAP(xtalk_dmamap));
-}
-
-
-iopaddr_t
-xtalk_dmatrans_addr(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    paddr_t paddr,	/* system physical address */
-		    size_t byte_count,	/* length */
-		    unsigned flags)
-{				/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_addr)
-	(dev, dev_desc, paddr, byte_count, flags);
-}
-
-
-alenlist_t
-xtalk_dmatrans_list(devfs_handle_t dev,	/* translate for this device */
-		    device_desc_t dev_desc,	/* device descriptor */
-		    alenlist_t palenlist,	/* system address/length list */
-		    unsigned flags)
-{				/* defined in dma.h */
-    return DEV_FUNC(dev, dmatrans_list)
-	(dev, dev_desc, palenlist, flags);
-}
-
-void
-xtalk_dmamap_drain(xtalk_dmamap_t map)
-{
-    DMAMAP_FUNC(map, dmamap_drain)
-	(CAST_DMAMAP(map));
-}
-
-void
-xtalk_dmaaddr_drain(devfs_handle_t dev, paddr_t addr, size_t size)
-{
-    DEV_FUNC(dev, dmaaddr_drain)
-	(dev, addr, size);
-}
-
-void
-xtalk_dmalist_drain(devfs_handle_t dev, alenlist_t list)
-{
-    DEV_FUNC(dev, dmalist_drain)
-	(dev, list);
-}
-
-/* =====================================================================
- *                    INTERRUPT MANAGEMENT
- *
- *      Allow crosstalk devices to establish interrupts
- */
-
-/*
- * Allocate resources required for an interrupt as specified in intr_desc.
- * Return resource handle in intr_hdl.
- */
-xtalk_intr_t
-xtalk_intr_alloc(devfs_handle_t dev,	/* which Crosstalk device */
-		 device_desc_t dev_desc,	/* device descriptor */
-		 devfs_handle_t owner_dev)
-{				/* owner of this interrupt */
-    return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc)
-	(dev, dev_desc, owner_dev);
-}
-
-/*
- * Allocate resources required for an interrupt as specified in dev_desc.
- * Unconditionally setup resources to be non-threaded.
- * Return resource handle in intr_hdl.
- */
-xtalk_intr_t
-xtalk_intr_alloc_nothd(devfs_handle_t dev,	/* which Crosstalk device */
-		 	device_desc_t dev_desc,	/* device descriptor */
-		 	devfs_handle_t owner_dev)	/* owner of this interrupt */
-{
-    return (xtalk_intr_t) DEV_FUNC(dev, intr_alloc_nothd)
-	(dev, dev_desc, owner_dev);
-}
-
-/*
- * Free resources consumed by intr_alloc.
- */
-void
-xtalk_intr_free(xtalk_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_free)
-	(CAST_INTR(intr_hdl));
-}
-
-
-/*
- * Associate resources allocated with a previous xtalk_intr_alloc call with the
- * described handler, arg, name, etc.
- *
- * Returns 0 on success, returns <0 on failure.
- */
-int
-xtalk_intr_connect(xtalk_intr_t intr_hdl,	/* xtalk intr resource handle */
-		   xtalk_intr_setfunc_t setfunc,	/* func to set intr hw */
-		   void *setfunc_arg)	/* arg to setfunc */
-{
-    return INTR_FUNC(intr_hdl, intr_connect)
-	(CAST_INTR(intr_hdl), setfunc, setfunc_arg);
-}
-
-
-/*
- * Disassociate handler with the specified interrupt.
- */
-void
-xtalk_intr_disconnect(xtalk_intr_t intr_hdl)
-{
-    INTR_FUNC(intr_hdl, intr_disconnect)
-	(CAST_INTR(intr_hdl));
-}
-
-
-/*
- * Return a hwgraph vertex that represents the CPU currently
- * targeted by an interrupt.
- */
-devfs_handle_t
-xtalk_intr_cpu_get(xtalk_intr_t intr_hdl)
-{
-    return INTR_FUNC(intr_hdl, intr_cpu_get)
-	(CAST_INTR(intr_hdl));
-}
-
-
-/* =====================================================================
- *                    CONFIGURATION MANAGEMENT
- */
-
-/*
- * Startup a crosstalk provider
- */
-void
-xtalk_provider_startup(devfs_handle_t xtalk_provider)
-{
-    DEV_FUNC(xtalk_provider, provider_startup)
-	(xtalk_provider);
-}
-
-
-/*
- * Shutdown a crosstalk provider
- */
-void
-xtalk_provider_shutdown(devfs_handle_t xtalk_provider)
-{
-    DEV_FUNC(xtalk_provider, provider_shutdown)
-	(xtalk_provider);
-}
-
-/* 
- * Enable a device on a xtalk widget 
- */
-void
-xtalk_widgetdev_enable(devfs_handle_t xconn_vhdl, int devnum)
-{
-    DEV_FUNC(xconn_vhdl, widgetdev_enable) (xconn_vhdl, devnum);
-}
-
-/* 
- * Shutdown a device on a xtalk widget 
- */
-void
-xtalk_widgetdev_shutdown(devfs_handle_t xconn_vhdl, int devnum)
-{
-    DEV_FUNC(xconn_vhdl, widgetdev_shutdown) (xconn_vhdl, devnum);
-}
-
-int
-xtalk_dma_enabled(devfs_handle_t xconn_vhdl)
-{
-    return DEV_FUNC(xconn_vhdl, dma_enabled) (xconn_vhdl);
-}
-/*
- * Generic crosstalk functions, for use with all crosstalk providers
- * and all crosstalk devices.
- */
-
-/****** Generic crosstalk interrupt interfaces ******/
-devfs_handle_t
-xtalk_intr_dev_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_dev);
-}
-
-xwidgetnum_t
-xtalk_intr_target_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_target);
-}
-
-xtalk_intr_vector_t
-xtalk_intr_vector_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_vector);
-}
-
-iopaddr_t
-xtalk_intr_addr_get(struct xtalk_intr_s *xtalk_intr)
-{
-    return (xtalk_intr->xi_addr);
-}
-
-void                   *
-xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr)
-{
-    return (xtalk_intr->xi_sfarg);
-}
-
-/****** Generic crosstalk pio interfaces ******/
-devfs_handle_t
-xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_dev);
-}
-
-xwidgetnum_t
-xtalk_pio_target_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_target);
-}
-
-iopaddr_t
-xtalk_pio_xtalk_addr_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_xtalk_addr);
-}
-
-ulong
-xtalk_pio_mapsz_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_mapsz);
-}
-
-caddr_t
-xtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap)
-{
-    return (xtalk_piomap->xp_kvaddr);
-}
-
-
-/****** Generic crosstalk dma interfaces ******/
-devfs_handle_t
-xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap)
-{
-    return (xtalk_dmamap->xd_dev);
-}
-
-xwidgetnum_t
-xtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap)
-{
-    return (xtalk_dmamap->xd_target);
-}
-
-
-/****** Generic crosstalk widget information interfaces ******/
-
-/* xwidget_info_chk:
- * check to see if this vertex is a widget;
- * if so, return its widget_info (if any).
- * if not, return NULL.
- */
-xwidget_info_t
-xwidget_info_chk(devfs_handle_t xwidget)
-{
-    arbitrary_info_t        ainfo = 0;
-
-    hwgraph_info_get_LBL(xwidget, INFO_LBL_XWIDGET, &ainfo);
-    return (xwidget_info_t) ainfo;
-}
-
-
-xwidget_info_t
-xwidget_info_get(devfs_handle_t xwidget)
-{
-    xwidget_info_t          widget_info;
-
-    widget_info = (xwidget_info_t)
-	hwgraph_fastinfo_get(xwidget);
-
-#ifdef	LATER
-    if ((widget_info != NULL) &&
-	(widget_info->w_fingerprint != widget_info_fingerprint))
-#ifdef SUPPORT_PRINTING_V_FORMAT
-	PRINT_PANIC("%v bad xwidget_info", xwidget);
-#else
-	PRINT_PANIC("%x bad xwidget_info", xwidget);
-#endif
-#endif	/* LATER */
-
-    return (widget_info);
-}
-
-void
-xwidget_info_set(devfs_handle_t xwidget, xwidget_info_t widget_info)
-{
-    if (widget_info != NULL)
-	widget_info->w_fingerprint = widget_info_fingerprint;
-
-    hwgraph_fastinfo_set(xwidget, (arbitrary_info_t) widget_info);
-
-    /* Also, mark this vertex as an xwidget,
-     * and use the widget_info, so xwidget_info_chk
-     * can work (and be fairly efficient).
-     */
-    hwgraph_info_add_LBL(xwidget, INFO_LBL_XWIDGET,
-			 (arbitrary_info_t) widget_info);
-}
-
-devfs_handle_t
-xwidget_info_dev_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_vertex);
-}
-
-xwidgetnum_t
-xwidget_info_id_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_id);
-}
-
-
-devfs_handle_t
-xwidget_info_master_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_master);
-}
-
-xwidgetnum_t
-xwidget_info_masterid_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_masterid);
-}
-
-xwidget_part_num_t
-xwidget_info_part_num_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_hwid.part_num);
-}
-
-xwidget_mfg_num_t
-xwidget_info_mfg_num_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget_info");
-    return (xwidget_info->w_hwid.mfg_num);
-}
-/* Extract the widget name from the widget information
- * for the xtalk widget.
- */
-char *
-xwidget_info_name_get(xwidget_info_t xwidget_info)
-{
-    if (xwidget_info == NULL)
-	panic("null xwidget info");
-    return(xwidget_info->w_name);
-}
-/****** Generic crosstalk initialization interfaces ******/
-
-/*
- * One-time initialization needed for systems that support crosstalk.
- */
-void
-xtalk_init(void)
-{
-    cdl_p                   cp;
-
-#if DEBUG && ATTACH_DEBUG
-    printf("xtalk_init\n");
-#endif
-    /* Allocate the registry.
-     * We might already have one.
-     * If we don't, go get one.
-     * MPness: someone might have
-     * set one up for us while we
-     * were not looking; use an atomic
-     * compare-and-swap to commit to
-     * using the new registry if and
-     * only if nobody else did first.
-     * If someone did get there first,
-     * toss the one we allocated back
-     * into the pool.
-     */
-    if (xtalk_registry == NULL) {
-	cp = cdl_new(EDGE_LBL_XIO, "part", "mfgr");
-	if (!compare_and_swap_ptr((void **) &xtalk_registry, NULL, (void *) cp)) {
-	    cdl_del(cp);
-	}
-    }
-    ASSERT(xtalk_registry != NULL);
-}
-
-/*
- * Associate a set of xtalk_provider functions with a vertex.
- */
-void
-xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns)
-{
-    hwgraph_fastinfo_set(provider, (arbitrary_info_t) xtalk_fns);
-}
-
-/*
- * Disassociate a set of xtalk_provider functions with a vertex.
- */
-void
-xtalk_provider_unregister(devfs_handle_t provider)
-{
-    hwgraph_fastinfo_set(provider, (arbitrary_info_t)NULL);
-}
-
-/*
- * Obtain a pointer to the xtalk_provider functions for a specified Crosstalk
- * provider.
- */
-xtalk_provider_t       *
-xtalk_provider_fns_get(devfs_handle_t provider)
-{
-    return ((xtalk_provider_t *) hwgraph_fastinfo_get(provider));
-}
-
-/*
- * Announce a driver for a particular crosstalk part.
- * Returns 0 on success or -1 on failure.  Failure occurs if the
- * specified hardware already has a driver.
- */
-/*ARGSUSED4 */
-int
-xwidget_driver_register(xwidget_part_num_t part_num,
-			xwidget_mfg_num_t mfg_num,
-			char *driver_prefix,
-			unsigned flags)
-{
-    /* a driver's init routine could call
-     * xwidget_driver_register before the
-     * system calls xtalk_init; so, we
-     * make the call here.
-     */
-    if (xtalk_registry == NULL)
-	xtalk_init();
-
-    return cdl_add_driver(xtalk_registry,
-			  part_num, mfg_num,
-			  driver_prefix, flags, NULL);
-}
-
-/*
- * Inform xtalk infrastructure that a driver is no longer available for
- * handling any widgets.
- */
-void
-xwidget_driver_unregister(char *driver_prefix)
-{
-    /* before a driver calls unregister,
-     * it must have called registger; so we
-     * can assume we have a registry here.
-     */
-    ASSERT(xtalk_registry != NULL);
-
-    cdl_del_driver(xtalk_registry, driver_prefix, NULL);
-}
-
-/*
- * Call some function with each vertex that
- * might be one of this driver's attach points.
- */
-void
-xtalk_iterate(char *driver_prefix,
-	      xtalk_iter_f *func)
-{
-    ASSERT(xtalk_registry != NULL);
-
-    cdl_iterate(xtalk_registry, driver_prefix, (cdl_iter_f *)func);
-}
-
-/*
- * xwidget_register:
- *	Register a xtalk device (xwidget) by doing the following.
- *      -allocate and initialize xwidget_info data
- *      -allocate a hwgraph vertex with name based on widget number (id)
- *      -look up the widget's initialization function and call it,
- *      or remember the vertex for later initialization.
- *
- */
-int
-xwidget_register(xwidget_hwid_t hwid,		/* widget's hardware ID */
-		 devfs_handle_t 	widget,		/* widget to initialize */
-		 xwidgetnum_t 	id,		/* widget's target id (0..f) */
-		 devfs_handle_t 	master,		/* widget's master vertex */
-		 xwidgetnum_t 	targetid,	/* master's target id (9/a) */
-		 async_attach_t aa)
-{			
-    xwidget_info_t          widget_info;
-    char		    *s,devnm[MAXDEVNAME];
-
-    /* Allocate widget_info and associate it with widget vertex */
-    NEW(widget_info);
-
-    /* Initialize widget_info */
-    widget_info->w_vertex = widget;
-    widget_info->w_id = id;
-    widget_info->w_master = master;
-    widget_info->w_masterid = targetid;
-    widget_info->w_hwid = *hwid;	/* structure copy */
-    widget_info->w_efunc = 0;
-    widget_info->w_einfo = 0;
-    /*
-     * get the name of this xwidget vertex and keep the info.
-     * This is needed during errors and interrupts, but as
-     * long as we have it, we can use it elsewhere.
-     */
-    s = dev_to_name(widget,devnm,MAXDEVNAME);
-    widget_info->w_name = kmalloc(strlen(s) + 1, GFP_KERNEL);
-    strcpy(widget_info->w_name,s);
-    
-    xwidget_info_set(widget, widget_info);
-
-    device_master_set(widget, master);
-
-    /* All the driver init routines (including
-     * xtalk_init) are called before we get into
-     * attaching devices, so we can assume we
-     * have a registry here.
-     */
-    ASSERT(xtalk_registry != NULL);
-
-    /* 
-     * Add pointer to async attach info -- tear down will be done when
-     * the particular descendant is done with the info.
-     */
-    if (aa)
-	    async_attach_add_info(widget, aa);
-
-    return cdl_add_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
-                          widget, 0);
-}
-
-/*
- * xwidget_unregister :
- *	Unregister the xtalk device and detach all its hwgraph namespace.
- */
-int
-xwidget_unregister(devfs_handle_t widget)
-{
-    xwidget_info_t	widget_info;
-    xwidget_hwid_t	hwid;
-
-    /* Make sure that we have valid widget information initialized */
-    if (!(widget_info = xwidget_info_get(widget)))
-	return(1);
-
-    /* Remove the inventory information associated
-     * with the widget.
-     */
-    hwgraph_inventory_remove(widget, -1, -1, -1, -1, -1);
-    
-    hwid = &(widget_info->w_hwid);
-
-    cdl_del_connpt(xtalk_registry, hwid->part_num, hwid->mfg_num,
-                   widget, 0);
-
-    /* Clean out the xwidget information */
-    (void)kfree(widget_info->w_name);
-    BZERO((void *)widget_info, sizeof(widget_info));
-    DEL(widget_info);
-    
-    return(0);
-}
-
-/*
- * Issue a link reset to a widget.
- */
-void
-xwidget_reset(devfs_handle_t xwidget)
-{
-    xswitch_reset_link(xwidget);
-
-}
-
-
-void
-xwidget_gfx_reset(devfs_handle_t xwidget)
-{
-    xwidget_info_t info;
-
-    xswitch_reset_link(xwidget);
-    info = xwidget_info_get(xwidget);
-#ifdef LATER
-    ASSERT_ALWAYS(info != NULL);
-#endif
-
-    /*
-     * Enable this for other architectures once we add widget_reset to the
-     * xtalk provider interface.
-     */
-    DEV_FUNC(xtalk_provider, widget_reset)
-	(xwidget_info_master_get(info), xwidget_info_id_get(info));
-}
-
-#define ANON_XWIDGET_NAME	"No Name"	/* Default Widget Name */
-
-/* Get the canonical hwgraph  name of xtalk widget */
-char *
-xwidget_name_get(devfs_handle_t xwidget_vhdl)
-{
-	xwidget_info_t  info;
-
-	/* If we have a bogus widget handle then return
-	 * a default anonymous widget name.
-	 */
-	if (xwidget_vhdl == GRAPH_VERTEX_NONE)
-	    return(ANON_XWIDGET_NAME);
-	/* Read the widget name stored in the widget info
-	 * for the widget setup during widget initialization.
-	 */
-	info = xwidget_info_get(xwidget_vhdl);
-	ASSERT(info != NULL);
-	return(xwidget_info_name_get(info));
-}
-
-/*
- * xtalk_device_shutdown
- *	Disable  the specified xtalk widget and clean out all the software
- *	state associated with it.
- */
-int
-xtalk_device_shutdown(devfs_handle_t xbus_vhdl, xwidgetnum_t widget)
-{
-	devfs_handle_t	widget_vhdl;
-	char		edge_name[8];
-
-	sprintf(edge_name, "%d", widget);
-	if (hwgraph_traverse(xbus_vhdl, edge_name, &widget_vhdl) 
-	    != GRAPH_SUCCESS)
-		return(1);
-
-	xwidget_unregister(widget_vhdl);
-	
-	return(0);
-}
diff -Nru a/arch/ia64/sn/kernel/Makefile b/arch/ia64/sn/kernel/Makefile
--- a/arch/ia64/sn/kernel/Makefile	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/sn/kernel/Makefile	Wed Jun 18 23:42:06 2003
@@ -9,11 +9,7 @@
 
 EXTRA_CFLAGS := -DLITTLE_ENDIAN
 
-obj-y				:= probe.o setup.o sn_asm.o sv.o bte.o iomv.o \
-				   irq.o mca.o
+obj-y				:= probe.o setup.o sv.o bte.o irq.o mca.o sn2/
 
-obj-$(CONFIG_IA64_SGI_SN2)      += sn2/
-obj-$(CONFIG_IA64_SGI_AUTOTEST) += llsc4.o misctest.o
 obj-$(CONFIG_IA64_GENERIC)      += machvec.o
 obj-$(CONFIG_MODULES)           += sn_ksyms.o
-obj-$(CONFIG_IA64_SGI_SN_BRT)	+= bte_regr_test.o
diff -Nru a/arch/ia64/sn/kernel/bte.c b/arch/ia64/sn/kernel/bte.c
--- a/arch/ia64/sn/kernel/bte.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/sn/kernel/bte.c	Wed Jun 18 23:42:07 2003
@@ -1,7 +1,7 @@
 /*
  *
  *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -38,124 +38,160 @@
 #include <asm/sn/arch.h>
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/pda.h>
-#ifdef CONFIG_IA64_SGI_SN2
 #include <asm/sn/sn2/shubio.h>
-#endif
 #include <asm/nodedata.h>
 
 #include <linux/bootmem.h>
 #include <linux/string.h>
 #include <linux/sched.h>
 
-#include <asm/sn/bte_copy.h>
+#include <asm/sn/bte.h>
 
-int bte_offsets[] = { IIO_IBLS0, IIO_IBLS1 };
+#ifndef L1_CACHE_MASK
+#define L1_CACHE_MASK (L1_CACHE_BYTES - 1)
+#endif
 
 /*
- * bte_init_node(nodepda, cnode)
+ * The base address of for each set of bte registers.
+ */
+static int bte_offsets[] = { IIO_IBLS0, IIO_IBLS1 };
+
+
+/************************************************************************
+ * Block Transfer Engine copy related functions.
  *
- * Initialize the nodepda structure with BTE base addresses and
- * spinlocks.
+ ***********************************************************************/
+
+
+/*
+ * bte_copy(src, dest, len, mode, notification)
+ *
+ * Use the block transfer engine to move kernel memory from src to dest
+ * using the assigned mode.
+ *
+ * Paramaters:
+ *   src - physical address of the transfer source.
+ *   dest - physical address of the transfer destination.
+ *   len - number of bytes to transfer from source to dest.
+ *   mode - hardware defined.  See reference information
+ *          for IBCT0/1 in the SHUB Programmers Reference
+ *   notification - kernel virtual address of the notification cache
+ *                  line.  If NULL, the default is used and
+ *                  the bte_copy is synchronous.
  *
- * NOTE: The kernel parameter btetest will cause the initialization
- * code to reserve blocks of physically contiguous memory to be
- * used by the bte test module.
+ * NOTE:  This function requires src, dest, and len to
+ * be cacheline aligned.
  */
-void
-bte_init_node(nodepda_t * mynodepda, cnodeid_t cnode)
+bte_result_t
+bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification)
 {
-	int i;
+	int bte_to_use;
+	u64 transfer_size;
+	struct bteinfo_s *bte;
+	bte_result_t bte_status;
+	unsigned long irq_flags;
 
 
-	/*
-	 * Indicate that all the block transfer engines on this node
-	 * are available.
-	 */
-	for (i = 0; i < BTES_PER_NODE; i++) {
-#ifdef CONFIG_IA64_SGI_SN2
-		/* >>> Don't know why the 0x1800000L is here.  Robin */
-		mynodepda->bte_if[i].bte_base_addr =
-		    (char *)LOCAL_MMR_ADDR(bte_offsets[i] | 0x1800000L);
+	BTE_PRINTK(("bte_copy(0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%p)\n",
+		    src, dest, len, mode, notification));
 
-#elif CONFIG_IA64_SGI_SN1
-		mynodepda->bte_if[i].bte_base_addr =
-		    (char *)LOCAL_HUB_ADDR(bte_offsets[i]);
-#else
-#error BTE Not defined for this hardware platform.
-#endif
+	if (len == 0) {
+		return BTE_SUCCESS;
+	}
 
-		/*
-		 * Initialize the notification and spinlock
-		 * so the first transfer can occur.
-		 */
-		mynodepda->bte_if[i].most_rcnt_na =
-		    &(mynodepda->bte_if[i].notify);
-		mynodepda->bte_if[i].notify = 0L;
-#ifdef CONFIG_IA64_SGI_BTE_LOCKING
-		spin_lock_init(&mynodepda->bte_if[i].spinlock);
-#endif				/* CONFIG_IA64_SGI_BTE_LOCKING */
+	ASSERT(!((len & L1_CACHE_MASK) ||
+		 (src & L1_CACHE_MASK) || (dest & L1_CACHE_MASK)));
+	ASSERT(len < ((BTE_LEN_MASK + 1) << L1_CACHE_SHIFT));
+
+	do {
+		local_irq_save(irq_flags);
+
+		bte_to_use = 0;
+		/* Attempt to lock one of the BTE interfaces. */
+		while ((bte_to_use < BTES_PER_NODE) &&
+		       BTE_LOCK_IF_AVAIL(bte_to_use)) {
+			bte_to_use++;
+		}
 
-		mynodepda->bte_if[i].bte_test_buf =
-			alloc_bootmem_node(NODE_DATA(cnode), BTE_MAX_XFER);
+		if (bte_to_use < BTES_PER_NODE) {
+			break;
+		}
+
+		local_irq_restore(irq_flags);
+
+		if (!(mode & BTE_WACQUIRE)) {
+			return BTEFAIL_NOTAVAIL;
+		}
+
+		/* Wait until a bte is available. */
+		udelay(10);
+	} while (1);
+
+	bte = pda->cpu_bte_if[bte_to_use];
+	BTE_PRINTKV(("Got a lock on bte %d\n", bte_to_use));
+
+
+	if (notification == NULL) {
+		/* User does not want to be notified. */
+		bte->most_rcnt_na = &bte->notify;
+	} else {
+		bte->most_rcnt_na = notification;
 	}
 
-}
+	/* Calculate the number of cache lines to transfer. */
+	transfer_size = ((len >> L1_CACHE_SHIFT) & BTE_LEN_MASK);
 
+	/* Initialize the notification to a known value. */
+	*bte->most_rcnt_na = -1L;
 
-/*
- * bte_reset_nasid(nasid_t)
- *
- * Does a soft reset of the BTEs on the specified nasid.
- * This is followed by a one-line transfer from each of the
- * virtual interfaces.
- */
-void
-bte_reset_nasid(nasid_t n)
-{
-	ii_ibcr_u_t	ibcr;
+	/* Set the status reg busy bit and transfer length */
+	BTE_PRINTKV(("IBLS - HUB_S(0x%p, 0x%lx)\n",
+		     BTEREG_LNSTAT_ADDR, IBLS_BUSY | transfer_size));
+	HUB_S(BTEREG_LNSTAT_ADDR, (IBLS_BUSY | transfer_size));
+
+	/* Set the source and destination registers */
+	BTE_PRINTKV(("IBSA - HUB_S(0x%p, 0x%lx)\n", BTEREG_SRC_ADDR,
+		     (TO_PHYS(src))));
+	HUB_S(BTEREG_SRC_ADDR, (TO_PHYS(src)));
+	BTE_PRINTKV(("IBDA - HUB_S(0x%p, 0x%lx)\n", BTEREG_DEST_ADDR,
+		     (TO_PHYS(dest))));
+	HUB_S(BTEREG_DEST_ADDR, (TO_PHYS(dest)));
+
+	/* Set the notification register */
+	BTE_PRINTKV(("IBNA - HUB_S(0x%p, 0x%lx)\n", BTEREG_NOTIF_ADDR,
+		     (TO_PHYS(ia64_tpa((unsigned long)bte->most_rcnt_na)))));
+	HUB_S(BTEREG_NOTIF_ADDR, (TO_PHYS(ia64_tpa((unsigned long)bte->most_rcnt_na))));
 
-	ibcr.ii_ibcr_regval  = REMOTE_HUB_L(n, IIO_IBCR);
-	ibcr.ii_ibcr_fld_s.i_soft_reset = 1;
-	REMOTE_HUB_S(n, IIO_IBCR, ibcr.ii_ibcr_regval);
-
-	/* One line transfer on virtual interface 0 */
-	REMOTE_HUB_S(n, IIO_IBLS_0, IBLS_BUSY | 1);
-	REMOTE_HUB_S(n, IIO_IBSA_0, TO_PHYS(__pa(&nodepda->bte_cleanup)));
-	REMOTE_HUB_S(n, IIO_IBDA_0,
-		     TO_PHYS(__pa(&nodepda->bte_cleanup[4*L1_CACHE_BYTES])));
-	REMOTE_HUB_S(n, IIO_IBNA_0,
-		     TO_PHYS(__pa(&nodepda->bte_cleanup[4*L1_CACHE_BYTES])));
-	REMOTE_HUB_S(n, IIO_IBCT_0, BTE_NOTIFY);
-	while (REMOTE_HUB_L(n, IIO_IBLS0)) {
-		/* >>> Need some way out in case of hang... */
+
+	/* Initiate the transfer */
+	BTE_PRINTK(("IBCT - HUB_S(0x%p, 0x%lx)\n", BTEREG_CTRL_ADDR,
+		     BTE_VALID_MODE(mode)));
+	HUB_S(BTEREG_CTRL_ADDR, BTE_VALID_MODE(mode));
+
+	spin_unlock_irqrestore(&bte->spinlock, irq_flags);
+
+
+	if (notification != NULL) {
+		return BTE_SUCCESS;
 	}
 
-	/* One line transfer on virtual interface 1 */
-	REMOTE_HUB_S(n, IIO_IBLS_1, IBLS_BUSY | 1);
-	REMOTE_HUB_S(n, IIO_IBSA_1, TO_PHYS(__pa(nodepda->bte_cleanup)));
-	REMOTE_HUB_S(n, IIO_IBDA_1,
-		     TO_PHYS(__pa(nodepda->bte_cleanup[4 * L1_CACHE_BYTES])));
-	REMOTE_HUB_S(n, IIO_IBNA_1,
-		     TO_PHYS(__pa(nodepda->bte_cleanup[5 * L1_CACHE_BYTES])));
-	REMOTE_HUB_S(n, IIO_IBCT_1, BTE_NOTIFY);
-	while (REMOTE_HUB_L(n, IIO_IBLS1)) {
-		/* >>> Need some way out in case of hang... */
+	while (*bte->most_rcnt_na == -1UL) {
 	}
-}
 
 
-/*
- * bte_init_cpu()
- *
- * Initialize the cpupda structure with pointers to the
- * nodepda bte blocks.
- *
- */
-void
-bte_init_cpu(void)
-{
-	pda->cpu_bte_if[0] = &(nodepda->bte_if[1]);
-	pda->cpu_bte_if[1] = &(nodepda->bte_if[0]);
+	BTE_PRINTKV((" Delay Done.  IBLS = 0x%lx, most_rcnt_na = 0x%lx\n",
+				HUB_L(BTEREG_LNSTAT_ADDR), *bte->most_rcnt_na));
+
+	if (*bte->most_rcnt_na & IBLS_ERROR) {
+		bte_status = *bte->most_rcnt_na & ~IBLS_ERROR;
+		*bte->most_rcnt_na = 0L;
+	} else {
+		bte_status = BTE_SUCCESS;
+	}
+	BTE_PRINTK(("Returning status is 0x%lx and most_rcnt_na is 0x%lx\n",
+				HUB_L(BTEREG_LNSTAT_ADDR), *bte->most_rcnt_na));
+
+	return bte_status;
 }
 
 
@@ -192,15 +228,11 @@
 	char *bteBlock;
 
 	if (len == 0) {
-		return (BTE_SUCCESS);
+		return BTE_SUCCESS;
 	}
 
-#ifdef CONFIG_IA64_SGI_BTE_LOCKING
-#error bte_unaligned_copy() assumes single BTE selection in bte_copy().
-#else
 	/* temporary buffer used during unaligned transfers */
-	bteBlock = pda->cpu_bte_if[0]->bte_test_buf;
-#endif
+	bteBlock = pda->cpu_bte_if[0]->scratch_buf;
 
 	headBcopySrcOffset = src & L1_CACHE_MASK;
 	destFirstCacheOffset = dest & L1_CACHE_MASK;
@@ -265,15 +297,15 @@
 				headBteLen += footBteLen;
 			} else if (footBcopyLen > 0) {
 				rv = bte_copy(footBteSource,
-					      __pa(bteBlock),
+					      ia64_tpa((unsigned long)bteBlock),
 					      footBteLen, mode, NULL);
 				if (rv != BTE_SUCCESS) {
-					return (rv);
+					return rv;
 				}
 
 
 				memcpy(__va(footBcopyDest),
-				       (char *)bteBlock, footBcopyLen);
+				       (char *) bteBlock, footBcopyLen);
 			}
 		} else {
 			footBcopyLen = 0;
@@ -288,7 +320,7 @@
 				      (len - headBcopyLen -
 				       footBcopyLen), mode, NULL);
 			if (rv != BTE_SUCCESS) {
-				return (rv);
+				return rv;
 			}
 
 		}
@@ -315,14 +347,93 @@
 
 	if (headBcopyLen > 0) {
 		rv = bte_copy(headBteSource,
-			      __pa(bteBlock), headBteLen, mode, NULL);
+			      ia64_tpa((unsigned long)bteBlock), headBteLen, mode, NULL);
 		if (rv != BTE_SUCCESS) {
-			return (rv);
+			return rv;
 		}
 
-		memcpy(__va(headBcopyDest), ((char *)bteBlock +
+		memcpy(__va(headBcopyDest), ((char *) bteBlock +
 					     headBcopySrcOffset),
 		       headBcopyLen);
 	}
-	return (BTE_SUCCESS);
+	return BTE_SUCCESS;
+}
+
+
+/************************************************************************
+ * Block Transfer Engine initialization functions.
+ *
+ ***********************************************************************/
+
+
+/*
+ * bte_init_node(nodepda, cnode)
+ *
+ * Initialize the nodepda structure with BTE base addresses and
+ * spinlocks.
+ */
+void
+bte_init_node(nodepda_t * mynodepda, cnodeid_t cnode)
+{
+	int i;
+
+
+	/*
+	 * Indicate that all the block transfer engines on this node
+	 * are available.
+	 */
+
+	/*
+	 * Allocate one bte_recover_t structure per node.  It holds
+	 * the recovery lock for node.  All the bte interface structures
+	 * will point at this one bte_recover structure to get the lock.
+	 */
+	spin_lock_init(&mynodepda->bte_recovery_lock);
+	init_timer(&mynodepda->bte_recovery_timer);
+	mynodepda->bte_recovery_timer.function = bte_error_handler;
+	mynodepda->bte_recovery_timer.data = (unsigned long) mynodepda;
+
+	for (i = 0; i < BTES_PER_NODE; i++) {
+		/* >>> Don't know why the 0x1800000L is here.  Robin */
+		mynodepda->bte_if[i].bte_base_addr =
+		    (char *) LOCAL_MMR_ADDR(bte_offsets[i] | 0x1800000L);
+
+		/*
+		 * Initialize the notification and spinlock
+		 * so the first transfer can occur.
+		 */
+		mynodepda->bte_if[i].most_rcnt_na =
+		    &(mynodepda->bte_if[i].notify);
+		mynodepda->bte_if[i].notify = 0L;
+		spin_lock_init(&mynodepda->bte_if[i].spinlock);
+
+		mynodepda->bte_if[i].scratch_buf =
+		    alloc_bootmem_node(NODE_DATA(cnode), BTE_MAX_XFER);
+		mynodepda->bte_if[i].bte_cnode = cnode;
+		mynodepda->bte_if[i].bte_error_count = 0;
+		mynodepda->bte_if[i].bte_num = i;
+		mynodepda->bte_if[i].cleanup_active = 0;
+		mynodepda->bte_if[i].bh_error = 0;
+	}
+
+}
+
+/*
+ * bte_init_cpu()
+ *
+ * Initialize the cpupda structure with pointers to the
+ * nodepda bte blocks.
+ *
+ */
+void
+bte_init_cpu(void)
+{
+	/* Called by setup.c as each cpu is being added to the nodepda */
+	if (local_node_data->active_cpu_count & 0x1) {
+		pda->cpu_bte_if[0] = &(nodepda->bte_if[0]);
+		pda->cpu_bte_if[1] = &(nodepda->bte_if[1]);
+	} else {
+		pda->cpu_bte_if[0] = &(nodepda->bte_if[1]);
+		pda->cpu_bte_if[1] = &(nodepda->bte_if[0]);
+	}
 }
diff -Nru a/arch/ia64/sn/kernel/idle.c b/arch/ia64/sn/kernel/idle.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/kernel/idle.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,36 @@
+/*
+ * 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) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
+ */
+
+#include <linux/config.h>
+#include <asm/sn/leds.h>
+#include <asm/sn/simulator.h>
+
+void snidle(int state) {
+	if (state) {
+		if (pda.idle_flag == 0) {
+			/* 
+			 * Turn the activity LED off.
+			 */
+			set_led_bits(0, LED_CPU_ACTIVITY);
+		}
+
+#ifdef CONFIG_IA64_SGI_SN_SIM
+		if (IS_RUNNING_ON_SIMULATOR())
+			SIMULATOR_SLEEP();
+#endif
+
+		pda.idle_flag = 1;
+	} else {
+		/* 
+		 * Turn the activity LED on.
+		 */
+		set_led_bits(LED_CPU_ACTIVITY, LED_CPU_ACTIVITY);
+
+		pda.idle_flag = 0;
+	}
+}
diff -Nru a/arch/ia64/sn/kernel/iomv.c b/arch/ia64/sn/kernel/iomv.c
--- a/arch/ia64/sn/kernel/iomv.c	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,115 +0,0 @@
-/* 
- * 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) 2000-2003 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <asm/io.h>
-#include <linux/module.h>
-
-extern void * sn_io_addr(unsigned long port); /* defined in sn[12]/iomv.c */
-
-/**
- * sn_inb - read a byte from a port
- * @port: port to read from
- *
- * Reads a byte from @port and returns it to the caller.
- */
-unsigned int
-sn_inb (unsigned long port)
-{
-	volatile unsigned char *addr = sn_io_addr(port);
-	unsigned char ret;
-
-	ret = *addr;
-	__ia64_mf_a();
-	return ret;
-}
-
-/**
- * sn_inw - read a word from a port
- * @port: port to read from
- *
- * Reads a word from @port and returns it to the caller.
- */
-unsigned int
-sn_inw (unsigned long port)
-{
-	volatile unsigned short *addr = sn_io_addr(port);
-	unsigned short ret;
-
-	ret = *addr;
-	__ia64_mf_a();
-	return ret;
-}
-
-/**
- * sn_inl - read a word from a port
- * @port: port to read from
- *
- * Reads a word from @port and returns it to the caller.
- */
-unsigned int
-sn_inl (unsigned long port)
-{
-	volatile unsigned int *addr = sn_io_addr(port);
-	unsigned int ret;
-
-	ret = *addr;
-	__ia64_mf_a();
-	return ret;
-}
-
-/**
- * sn_outb - write a byte to a port
- * @port: port to write to
- * @val: value to write
- *
- * Writes @val to @port.
- */
-void
-sn_outb (unsigned char val, unsigned long port)
-{
-	volatile unsigned char *addr = sn_io_addr(port);
-
-	*addr = val;
-}
-
-/**
- * sn_outw - write a word to a port
- * @port: port to write to
- * @val: value to write
- *
- * Writes @val to @port.
- */
-void
-sn_outw (unsigned short val, unsigned long port)
-{
-	volatile unsigned short *addr = sn_io_addr(port);
-
-	*addr = val;
-}
-
-/**
- * sn_outl - write a word to a port
- * @port: port to write to
- * @val: value to write
- *
- * Writes @val to @port.
- */
-void
-sn_outl (unsigned int val, unsigned long port)
-{
-	volatile unsigned int *addr = sn_io_addr(port);
-
-	*addr = val;
-}
-
-EXPORT_SYMBOL(sn_inb);
-EXPORT_SYMBOL(sn_inw);
-EXPORT_SYMBOL(sn_inl);
-EXPORT_SYMBOL(sn_outb);
-EXPORT_SYMBOL(sn_outw);
-EXPORT_SYMBOL(sn_outl);
diff -Nru a/arch/ia64/sn/kernel/irq.c b/arch/ia64/sn/kernel/irq.c
--- a/arch/ia64/sn/kernel/irq.c	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/sn/kernel/irq.c	Wed Jun 18 23:42:06 2003
@@ -1,7 +1,7 @@
 /*
- * Platform dependent support for SGI SN1
+ * Platform dependent support for SGI SN
  *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -32,12 +32,12 @@
  * http://oss.sgi.com/projects/GenInfo/NoticeExplan
  */
 
-#include <linux/config.h>
 #include <linux/init.h>
 #include <linux/sched.h>
 #include <asm/current.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/slab.h>
 #include <asm/page.h>
 #include <asm/pgtable.h>
 #include <asm/sn/sgi.h>
@@ -49,19 +49,25 @@
 #include <asm/sn/pci/bridge.h>
 #include <asm/sn/pci/pciio.h>
 #include <asm/sn/pci/pciio_private.h>
-#ifdef ajmtestintr
 #include <asm/sn/pci/pcibr.h>
 #include <asm/sn/pci/pcibr_private.h>
-#endif /* ajmtestintr */
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/io.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/addrs.h>
 #include <asm/sn/driver.h>
 #include <asm/sn/arch.h>
-#include <asm/sn/nodepda.h>
+#include <asm/sn/pda.h>
+#include <asm/processor.h>
+#include <asm/system.h>
+#include <asm/bitops.h>
 
 int irq_to_bit_pos(int irq);
+static void force_interrupt(int irq);
+extern void pcibr_force_interrupt(pcibr_intr_t intr);
+extern int sn_force_interrupt_flag;
+
+
 
 static unsigned int
 sn_startup_irq(unsigned int irq)
@@ -87,49 +93,11 @@
 static void
 sn_ack_irq(unsigned int irq)
 {
-#ifdef CONFIG_IA64_SGI_SN1
-	int bit = -1;
-	unsigned long long intpend_val;
-	int subnode;
-#endif
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long event_occurred, mask = 0;
-#endif
 	int nasid;
 
 	irq = irq & 0xff;
 	nasid = smp_physical_node_id();
-#ifdef CONFIG_IA64_SGI_SN1
-	subnode = cpuid_to_subnode(smp_processor_id());
-	if (irq == SGI_UART_IRQ) {
-		intpend_val = REMOTE_HUB_PI_L(nasid, subnode, PI_INT_PEND0);
-		if (intpend_val & (1L<<GFX_INTR_A) ) {
-			bit = GFX_INTR_A;
-			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-		}
-		if ( intpend_val & (1L<<GFX_INTR_B) ) {
-			bit = GFX_INTR_B;
-			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-		}
-		if (intpend_val & (1L<<PG_MIG_INTR) ) {
-			bit = PG_MIG_INTR;
-			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-		}
-		if (intpend_val & (1L<<CC_PEND_A)) {
-			bit = CC_PEND_A;
-			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-		}
-		if (intpend_val & (1L<<CC_PEND_B)) {
-			bit = CC_PEND_B;
-			REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-		}
-		return;
-	}
-	bit = irq_to_bit_pos(irq);
-	REMOTE_HUB_PI_CLR_INTR(nasid, subnode, bit);
-#endif
-
-#ifdef CONFIG_IA64_SGI_SN2
 	event_occurred = HUB_L( (unsigned long *)GLOBAL_MMR_ADDR(nasid,SH_EVENT_OCCURRED) );
 	if (event_occurred & SH_EVENT_OCCURRED_UART_INT_MASK) {
 		mask |= (1 << SH_EVENT_OCCURRED_UART_INT_SHFT);
@@ -144,34 +112,18 @@
 		mask |= (1 << SH_EVENT_OCCURRED_II_INT1_SHFT);
 	}
 	HUB_S((unsigned long *)GLOBAL_MMR_ADDR(nasid, SH_EVENT_OCCURRED_ALIAS), mask );
-#endif
+	__set_bit(irq, (volatile void *)pda->sn_in_service_ivecs);
 }
 
 static void
 sn_end_irq(unsigned int irq)
 {
-#ifdef CONFIG_IA64_SGI_SN1
-	unsigned long long intpend_val, mask = 0x70L;
-	int subnode;
-#endif
 	int nasid;
-#ifdef CONFIG_IA64_SGI_SN2
+	int ivec;
 	unsigned long event_occurred;
-#endif
 
-	irq = irq & 0xff;
-#ifdef CONFIG_IA64_SGI_SN1
-	if (irq == SGI_UART_IRQ) {
-		nasid = smp_physical_node_id();
-		subnode = cpuid_to_subnode(smp_processor_id());
-		intpend_val = REMOTE_HUB_PI_L(nasid, subnode, PI_INT_PEND0);
-		if (intpend_val & mask) {
-			platform_send_ipi(smp_processor_id(), SGI_UART_IRQ, IA64_IPI_DM_INT, 0);
-		}
-	}
-#endif
-#ifdef CONFIG_IA64_SGI_SN2
-	if (irq == SGI_UART_VECTOR) {
+	ivec = irq & 0xff;
+	if (ivec == SGI_UART_VECTOR) {
 		nasid = smp_physical_node_id();
 		event_occurred = HUB_L( (unsigned long *)GLOBAL_MMR_ADDR(nasid,SH_EVENT_OCCURRED) );
 		// If the UART bit is set here, we may have received an interrupt from the
@@ -181,8 +133,9 @@
 				platform_send_ipi(smp_processor_id(), SGI_UART_VECTOR, IA64_IPI_DM_INT, 0);
 		}
 	}
-#endif
-
+	__clear_bit(ivec, (volatile void *)pda->sn_in_service_ivecs);
+	if (sn_force_interrupt_flag)
+		force_interrupt(irq);
 }
 
 static void
@@ -191,7 +144,7 @@
 }
 
 
-struct hw_interrupt_type irq_type_iosapic_level = {
+struct hw_interrupt_type irq_type_sn = {
 	"SN hub",
 	sn_startup_irq,
 	sn_shutdown_irq,
@@ -203,29 +156,17 @@
 };
 
 
-#define irq_type_sn irq_type_iosapic_level
-struct irq_desc *_sn_irq_desc[NR_CPUS];
-
 struct irq_desc *
 sn_irq_desc(unsigned int irq) {
-	int cpu = irq >> 8;
 
-	irq = irq & 0xff;
+	irq = SN_IVEC_FROM_IRQ(irq);
 
-	return(_sn_irq_desc[cpu] + irq);
+	return(_irq_desc + irq);
 }
 
 u8
 sn_irq_to_vector(u8 irq) {
-	return(irq & 0xff);
-}
-
-int gsi_to_vector(u32 irq) {
-	return irq & 0xff;
-}
-
-int gsi_to_irq(u32 irq) {
-	return irq & 0xff;
+	return(irq);
 }
 
 unsigned int
@@ -233,47 +174,24 @@
 	return (CPU_VECTOR_TO_IRQ(smp_processor_id(), vector));
 }
 
-void *kmalloc(size_t, int);
-
 void
 sn_irq_init (void)
 {
 	int i;
 	irq_desc_t *base_desc = _irq_desc;
 
-	for (i=IA64_FIRST_DEVICE_VECTOR; i<NR_IVECS; i++) {
+	for (i=IA64_FIRST_DEVICE_VECTOR; i<NR_IRQS; i++) {
 		if (base_desc[i].handler == &no_irq_type) {
 			base_desc[i].handler = &irq_type_sn;
 		}
 	}
 }
 
-void
-sn_init_irq_desc(void) {
-	int i;
-	irq_desc_t *base_desc = _irq_desc, *p;
-
-	for (i=0; i < NR_CPUS; i++) {
-		p =  page_address(alloc_pages_node(local_nodeid, GFP_KERNEL,
-			get_order(sizeof(struct irq_desc) * NR_IVECS) ) );
-		ASSERT(p);
-		memcpy(p, base_desc, sizeof(struct irq_desc) * NR_IVECS);
-		_sn_irq_desc[i] = p;
-	}
-}
-
-
 int
 bit_pos_to_irq(int bit) {
 #define BIT_TO_IRQ 64
 	if (bit > 118) bit = 118;
 
-#ifdef CONFIG_IA64_SGI_SN1
-	if (bit >= GFX_INTR_A && bit <= CC_PEND_B) {
-		return SGI_UART_IRQ;
-	}
-#endif
-
         return bit + BIT_TO_IRQ;
 }
 
@@ -285,53 +203,181 @@
         return bit;
 }
 
-#ifdef ajmtestintr
-
-#include <linux/timer.h>
-struct timer_list intr_test_timer = TIMER_INITIALIZER(NULL, 0, 0);
-int intr_test_icount[NR_IRQS];
-struct intr_test_reg_struct {
-	pcibr_soft_t pcibr_soft;
-	int slot;
+struct pcibr_intr_list_t {
+	struct pcibr_intr_list_t *next;
+	pcibr_intr_t intr;
 };
-struct intr_test_reg_struct intr_test_registered[NR_IRQS];
+
+static struct pcibr_intr_list_t **pcibr_intr_list;
+
+void
+register_pcibr_intr(int irq, pcibr_intr_t intr) {
+	struct pcibr_intr_list_t *p = kmalloc(sizeof(struct pcibr_intr_list_t), GFP_KERNEL);
+	struct pcibr_intr_list_t *list;
+	int cpu = SN_CPU_FROM_IRQ(irq);
+
+	if (pcibr_intr_list == NULL) {
+		pcibr_intr_list = kmalloc(sizeof(struct pcibr_intr_list_t *) * NR_IRQS, GFP_KERNEL);
+		if (pcibr_intr_list == NULL) panic("Could not allocate memory for pcibr_intr_list\n");
+		memset( (void *)pcibr_intr_list, 0, sizeof(struct pcibr_intr_list_t *) * NR_IRQS);
+	}
+	if (pdacpu(cpu)->sn_last_irq < irq) {
+		pdacpu(cpu)->sn_last_irq = irq;
+	}
+	if (pdacpu(cpu)->sn_first_irq > irq) pdacpu(cpu)->sn_first_irq = irq;
+	if (!p) panic("Could not allocate memory for pcibr_intr_list_t\n");
+	if ((list = pcibr_intr_list[irq])) {
+		while (list->next) list = list->next;
+		list->next = p;
+		p->next = NULL;
+		p->intr = intr;
+	} else {
+		pcibr_intr_list[irq] = p;
+		p->next = NULL;
+		p->intr = intr;
+	}
+}
 
 void
-intr_test_handle_timer(unsigned long data) {
+force_polled_int(void) {
 	int i;
-	bridge_t	*bridge;
+	struct pcibr_intr_list_t *p;
 
-	for (i=0;i<NR_IRQS;i++) {
-		if (intr_test_registered[i].pcibr_soft) {
-			pcibr_soft_t pcibr_soft = intr_test_registered[i].pcibr_soft;
-			xtalk_intr_t intr = pcibr_soft->bs_intr[intr_test_registered[i].slot].bsi_xtalk_intr;
-			/* send interrupt */
-			bridge = pcibr_soft->bs_base;
-			bridge->b_force_always[intr_test_registered[i].slot].intr = 1;
+	for (i=0; i<NR_IRQS;i++) {
+		p = pcibr_intr_list[i];
+		while (p) {
+			if (p->intr){
+				pcibr_force_interrupt(p->intr);
+			}
+			p = p->next;
 		}
 	}
-	del_timer(&intr_test_timer);
-	intr_test_timer.expires = jiffies + HZ/100;
-	add_timer(&intr_test_timer);
 }
 
-void
-intr_test_set_timer(void) {
-	intr_test_timer.expires = jiffies + HZ/100;
-	intr_test_timer.function = intr_test_handle_timer;
-	add_timer(&intr_test_timer);
+static void
+force_interrupt(int irq) {
+	struct pcibr_intr_list_t *p = pcibr_intr_list[irq];
+
+	while (p) {
+		if (p->intr) {
+			pcibr_force_interrupt(p->intr);
+		}
+		p = p->next;
+	}
+}
+
+/*
+Check for lost interrupts.  If the PIC int_status reg. says that
+an interrupt has been sent, but not handled, and the interrupt
+is not pending in either the cpu irr regs or in the soft irr regs,
+and the interrupt is not in service, then the interrupt may have
+been lost.  Force an interrupt on that pin.  It is possible that
+the interrupt is in flight, so we may generate a spurious interrupt,
+but we should never miss a real lost interrupt.
+*/
+
+static void
+sn_check_intr(int irq, pcibr_intr_t intr) {
+	unsigned long regval;
+	int irr_reg_num;
+	int irr_bit;
+	unsigned long irr_reg;
+
+
+	regval = intr->bi_soft->bs_base->p_int_status_64;
+	irr_reg_num = irq_to_vector(irq) / 64;
+	irr_bit = irq_to_vector(irq) % 64;
+	switch (irr_reg_num) {
+		case 0:
+			irr_reg = ia64_get_irr0();
+			break;
+		case 1:
+			irr_reg = ia64_get_irr1();
+			break;
+		case 2:
+			irr_reg = ia64_get_irr2();
+			break;
+		case 3:
+			irr_reg = ia64_get_irr3();
+			break;
+	}
+	if (!test_bit(irr_bit, &irr_reg) ) {
+		if (!test_bit(irq, pda->sn_soft_irr) ) {
+			if (!test_bit(irq, pda->sn_in_service_ivecs) ) {
+				regval &= 0xff;
+				if (intr->bi_ibits & regval & intr->bi_last_intr) {
+					regval &= ~(intr->bi_ibits & regval);
+					pcibr_force_interrupt(intr);
+				}
+			}
+		}
+	}
+	intr->bi_last_intr = regval;
 }
 
 void
-intr_test_register_irq(int irq, pcibr_soft_t pcibr_soft, int slot) {
-	irq = irq & 0xff;
-	intr_test_registered[irq].pcibr_soft = pcibr_soft;
-	intr_test_registered[irq].slot = slot;
+sn_lb_int_war_check(void) {
+	int i;
+
+	if (pda->sn_first_irq == 0) return;
+	for (i=pda->sn_first_irq;
+		i <= pda->sn_last_irq; i++) {
+			struct pcibr_intr_list_t *p = pcibr_intr_list[i];
+			if (p == NULL) {
+				continue;
+			}
+			while (p) {
+				sn_check_intr(i, p->intr);
+				p = p->next;
+			}
+	}
+}
+
+static inline int
+sn_get_next_bit(void) {
+	int i;
+	int bit;
+
+	for (i = 3; i >= 0; i--) {
+		if (pda->sn_soft_irr[i] != 0) {
+			bit = (i * 64) +  __ffs(pda->sn_soft_irr[i]);
+			__change_bit(bit, (volatile void *)pda->sn_soft_irr);
+			return(bit);
+		}
+	}
+	return IA64_SPURIOUS_INT_VECTOR;
 }
 
 void
-intr_test_handle_intr(int irq, void *junk, struct pt_regs *morejunk) {
-	intr_test_icount[irq]++;
-	printk("RECEIVED %d INTERRUPTS ON IRQ %d\n",intr_test_icount[irq], irq);
+sn_set_tpr(int vector) {
+	if (vector > IA64_LAST_DEVICE_VECTOR || vector < IA64_FIRST_DEVICE_VECTOR) {
+		ia64_set_tpr(vector);
+	} else {
+		ia64_set_tpr(IA64_LAST_DEVICE_VECTOR);
+	}
+}
+
+static inline void
+sn_get_all_ivr(void) {
+	int vector;
+
+	vector = ia64_get_ivr();
+	while (vector != IA64_SPURIOUS_INT_VECTOR) {
+		__set_bit(vector, (volatile void *)pda->sn_soft_irr);
+		ia64_eoi();
+		if (vector > IA64_LAST_DEVICE_VECTOR) return;
+		vector = ia64_get_ivr();
+	}
+}
+	
+int
+sn_get_ivr(void) {
+	int vector;
+
+	vector = sn_get_next_bit();
+	if (vector == IA64_SPURIOUS_INT_VECTOR) {
+		sn_get_all_ivr();
+		vector = sn_get_next_bit();
+	}
+	return vector;
 }
-#endif /* ajmtestintr */
diff -Nru a/arch/ia64/sn/kernel/llsc4.c b/arch/ia64/sn/kernel/llsc4.c
--- a/arch/ia64/sn/kernel/llsc4.c	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1044 +0,0 @@
-/* 
- *
- * 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) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/config.h>
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/init.h>
-#include <linux/interrupt.h>
-#include <linux/smp.h>
-#include <linux/kernel_stat.h>
-#include <linux/mm.h>
-#include <linux/delay.h>
-#include <linux/string.h>
-#include <linux/efi.h>
-#include <asm/page.h>
-#include <linux/threads.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/leds.h>
-
-#include "llsc4.h"
-
-
-#ifdef STANDALONE
-#include "lock.h"
-#endif
-
-#ifdef INTTEST
-static int	inttest=0;
-#endif
-
-#ifdef IA64_SEMFIX_INSN
-#undef IA64_SEMFIX_INSN
-#endif
-#ifdef IA64_SEMFIX
-#undef IA64_SEMFIX
-#endif
-# define IA64_SEMFIX_INSN
-# define IA64_SEMFIX    ""
-
-#define NOLOCK		0xdead
-#define BGUARD(linei)	(0xbbbb0000 | (linei));
-#define EGUARD(linei)	(0xeeee0000 | (linei));
-#define GUARDLINE(v)	((v)&0xffff)
-
-/*
- * Test parameter table for AUTOTEST
- */
-typedef struct {
-	int	passes;
-	int	linecount;
-	int	linepad;
-} autotest_table_t;
-
-autotest_table_t autotest_table[] = {
-	{50000000,	2,	0x2b4		},
-	{50000000,	16,	0,		},
-	{50000000,	16,	4,		},
-	{50000000,	128,	0x44		},
-	{50000000,	128,	0x84		},
-	{50000000,	128,	0x200		},
-	{50000000,	128,	0x204		},
-	{50000000,	128,	0x2b4		},
-	{50000000,	2,	8*MB+0x2b4	},
-	{50000000,	16,	8*MB+0		},
-	{50000000,	16,	8*MB+4		},
-	{50000000,	128,	8*MB+0x44	},
-	{50000000,	128,	8*MB+0x84	},
-	{50000000,	128,	8*MB+0x200	},
-	{50000000,	128,	8*MB+0x204	},
-	{50000000,	128,	8*MB+0x2b4	},
-	{0}};
-
-/*
- * Array of virtual addresses available for test purposes.
- */
-
-typedef struct {
-	long	vstart;
-	long	vend;
-	long	nextaddr;
-	long	nextinit;
-	int	wrapcount;
-} memmap_t;
-
-#define MAPCHUNKS		128
-memmap_t 	memmap[MAPCHUNKS];
-int		memmapx=0;
-
-typedef struct {
-	void	*addr;
-	long	data[16];
-	long	data_fc[16];
-} capture_line_t;
-
-typedef struct {
-	int	size;
-	void	*blockaddr;
-	void	*shadaddr;
-	long	blockdata[48];
-	long	shaddata[48];
-	long	blockdata_fc[48];
-	long	shaddata_fc[48];
-	long	synerr;
-} capture_t;
-
-/*
- * PORTING NOTE: revisit this statement. On hardware we put mbase at 0 and
- * the rest of the tables have to start at 1MB to skip PROM tables.
- */
-#define THREADPRIVATESZ()	((sizeof(threadprivate_t)+511)/512*512)
-#define THREADPRIVATE(t)	((threadprivate_t*)(((long)mbase)+4096+t*THREADPRIVATESZ()))
-
-#define k_capture		mbase->sk_capture
-#define k_go			mbase->sk_go
-#define k_linecount		mbase->sk_linecount
-#define k_passes		mbase->sk_passes
-#define k_napticks		mbase->sk_napticks
-#define k_stop_on_error		mbase->sk_stop_on_error
-#define k_verbose		mbase->sk_verbose
-#define k_threadprivate		mbase->sk_threadprivate
-#define k_blocks		mbase->sk_blocks
-#define k_iter_msg		mbase->sk_iter_msg
-#define k_vv			mbase->sk_vv
-#define k_linepad		mbase->sk_linepad
-#define k_options		mbase->sk_options
-#define k_testnumber		mbase->sk_testnumber
-#define k_currentpass		mbase->sk_currentpass
-
-static long		blocks[MAX_LINECOUNT];		/* addresses of data blocks */
-static control_t	*mbase;
-static vint		initialized=0;
-
-static unsigned int ran_conf_llsc(int);
-static int  rerr(capture_t *, char *, void *, void *, int, int, int, int, int, int);
-static void dumpline(void *, char *, char *, void *, void *, int);
-static int  checkstop(int, int, uint);
-static void spin(int);
-static void capturedata(capture_t *, uint, void *, void *, int);
-static int  randn(uint max, uint *seed);
-static uint zrandom (uint *zranseed);
-static int  set_lock(uint *, uint);
-static int  clr_lock(uint *, uint);
-static void Speedo(void);
-
-int autotest_enabled=0;
-static int llsctest_number=-1;
-static int errstop_enabled=0;
-static int fail_enabled=0;
-static int l4_opt=0;
-static int selective_trigger=0;
-static int dump_block_addrs_opt=0;
-static lock_t errlock=NOLOCK;
-static private_t init_private[LLSC_MAXCPUS];
-
-static int __init autotest_enable(char *str)
-{
-        autotest_enabled = 1;
-	return 1;
-}
-static int __init set_llscblkadr(char *str)
-{
-	dump_block_addrs_opt = 1;
-	return 1;
-}
-static int __init set_llscselt(char *str)
-{
-	selective_trigger = 1;
-	return 1;
-}
-static int __init set_llsctest(char *str)
-{
-        llsctest_number = simple_strtol(str, &str, 10);
-	if (llsctest_number < 0 || llsctest_number > 15)
-		llsctest_number = -1;
-	return 1;
-}
-static int __init set_llscerrstop(char *str)
-{
-        errstop_enabled = 1;
-	return 1;
-}
-static int __init set_llscfail(char *str)
-{
-        fail_enabled = 8;
-	return 1;
-}
-static int __init set_llscl4(char *str)
-{
-        l4_opt = 1;
-	return 1;
-}
-
-static void print_params(void)
-{
-	printk ("********* Enter AUTOTEST facility on master cpu *************\n");
-	printk ("  Test options:\n");
-	printk ("     llsctest=<n>\t%d\tTest number to run (all = -1)\n", llsctest_number);
-	printk ("     llscerrstop \t%s\tStop on error\n", errstop_enabled ? "on" : "off");
-	printk ("     llscfail    \t%s\tForce a failure to test the trigger & error messages\n", fail_enabled ? "on" : "off");
-	printk ("     llscselt    \t%s\tSelective triger on failures\n", selective_trigger ? "on" : "off");
-	printk ("     llscblkadr  \t%s\tDump data block addresses\n", dump_block_addrs_opt ? "on" : "off");
-	printk ("     llscl4      \t%s\tRun only tests that evict from L4\n", l4_opt ? "on" : "off");
-	printk ("  SEMFIX: %s\n", IA64_SEMFIX);
-	printk ("\n");
-}
-__setup("autotest", autotest_enable);
-__setup("llsctest=", set_llsctest);
-__setup("llscerrstop", set_llscerrstop);
-__setup("llscfail", set_llscfail);
-__setup("llscselt", set_llscselt);
-__setup("llscblkadr", set_llscblkadr);
-__setup("llscl4", set_llscl4);
-
-
-
-static inline int
-set_lock(uint *lock, uint id)
-{
-	uint	old;
-	old = cmpxchg_acq(lock, NOLOCK, id);
-	return (old == NOLOCK);
-}
-
-static inline int
-clr_lock(uint *lock, uint id)
-{
-	uint	old;
-	old = cmpxchg_rel(lock, id, NOLOCK);
-	return (old == id);
-}
-
-static inline void
-init_lock(uint *lock)
-{
-	*lock = NOLOCK;
-}
-
-/*------------------------------------------------------------------------+
-| Routine  :  ran_conf_llsc - ll/sc shared data test                      |
-| Description: This test checks the coherency of shared data              |
-+------------------------------------------------------------------------*/
-static unsigned int
-ran_conf_llsc(int thread)
-{
-	private_t	pval;
-	share_t		sval, sval2;
-	uint		vv, linei, slinei, sharei, pass;
-	long		t;
-	lock_t		lockpat;
-	share_t		*sharecopy;
-	long		verbose, napticks, passes, linecount, lcount;
-	dataline_t	*linep, *slinep;
-	int		s, seed;
-	threadprivate_t	*tp;
-	uint		iter_msg, iter_msg_i=0;
-	int		vv_mask;
-	int		correct_errors;
-	int		errs=0;
-	int		stillbad;
-	capture_t	capdata;
-	private_t	*privp;
-	share_t		*sharep;
-
-
-	linecount = k_linecount;
-	napticks = k_napticks;
-	verbose = k_verbose;
-	passes = k_passes;
-	iter_msg = k_iter_msg;
-	seed = (thread + 1) * 647;
-	tp = THREADPRIVATE(thread);
-	vv_mask = (k_vv>>((thread%16)*4)) & 0xf;
-	correct_errors = k_options&0xff;
-
-	memset (&capdata, 0, sizeof(capdata));
-	for (linei=0; linei<linecount; linei++)
-		tp->private[linei] = thread;	
-
-	for (pass = 1; passes == 0 || pass < passes; pass++) {
-		lockpat = (pass & 0x0fffffff) + (thread <<28);
-		if (lockpat == NOLOCK)
-			continue;
-		tp->threadpasses = pass;
-		if (checkstop(thread, pass, lockpat))
-			return 0;
-		iter_msg_i++;
-		if (iter_msg && iter_msg_i > iter_msg) {
-			printk("Thread %d, Pass %d\n", thread, pass);
-			iter_msg_i = 0;
-		}
-		lcount = 0;
-
-		/*
-		 * Select line to perform operations on.
-		 */
-		linei = randn(linecount, &seed);
-		sharei = randn(2, &seed);
-		slinei = (linei + (linecount/2))%linecount;		/* I don't like this - fix later */
-
-		linep = (dataline_t *)blocks[linei];
-		slinep = (dataline_t *)blocks[slinei];
-		if (sharei == 0)
-			sharecopy = &slinep->share0;
-		else
-			sharecopy = &slinep->share1;
-
-
-		vv = randn(4, &seed);
-		if ((vv_mask & (1<<vv)) == 0)
-			continue;
-
-		if (napticks) {
-			t = randn(napticks, &seed);
-			udelay(t);
-		}
-		privp = &linep->private[thread];
-		sharep = &linep->share[sharei];
-		
-		switch(vv) {
-		case 0:
-			/* Read and verify private count on line. */
-			pval = *privp;
-			if (verbose)
-				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, tp->private[linei]);
-			if (pval != tp->private[linei]) {
-				capturedata(&capdata, pass, privp, NULL, sizeof(*privp));
-				stillbad = (*privp != tp->private[linei]);
-				if (rerr(&capdata, "Private count", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) {
-					return 1;
-				}
-				if (correct_errors) {
-					tp->private[linei] = *privp;
-				}
-				errs++;
-			}
-			break;
-
-		case 1:
-			/* Read, verify, and increment private count on line. */
-			pval = *privp;
-			if (verbose)
-				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, tp->private[linei]);
-			if (pval != tp->private[linei]) {
-				capturedata(&capdata, pass, privp, NULL, sizeof(*privp));
-				stillbad = (*privp != tp->private[linei]);
-				if (rerr(&capdata, "Private count & inc", linep, slinep, thread, pass, linei, tp->private[linei], pval, stillbad)) {
-					return 1;
-				}
-				errs++;
-			}
-			pval = (pval==255) ? 0 : pval+1;
-			*privp = pval;
-			tp->private[linei] = pval;
-			break;
-
-		case 2:
-			/* Lock line, read and verify shared data. */
-			if (verbose)
-				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, *sharecopy);
-			lcount = 0;
-			while (LOCK(sharei) != 1) {
-				if (checkstop(thread, pass, lockpat))
-					return 0;
-				if (lcount++>1000000) {
-					capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t));
-					stillbad = (GETLOCK(sharei) != 0);
-					rerr(&capdata, "Shared data lock", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad);
-					return 1;
-				}
-				if ((lcount&0x3fff) == 0)
-					udelay(1000);
-			}
-
-			sval = *sharep;
-			sval2 = *sharecopy;
-			if (pass > 12 && thread == 0 && fail_enabled == 1)
-				sval++;
-			if (sval != sval2) {
-				capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy));
-				stillbad = (*sharep != *sharecopy);
-				if (!stillbad && *sharep != sval && *sharecopy == sval2)
-					stillbad = 2;
-				if (rerr(&capdata, "Shared data", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) {
-					return 1;
-				}
-				if (correct_errors)
-					*sharep = *sharecopy;
-				errs++;
-			}
-
-
-			if ( (s=UNLOCK(sharei)) != 1) {
-				capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4);
-				stillbad = (GETLOCK(sharei) != lockpat);
-				if (rerr(&capdata, "Shared data unlock", linep, slinep, thread, pass, linei, lockpat, GETLOCK(sharei), stillbad))
-					return 1;
-				if (correct_errors)
-					ZEROLOCK(sharei);	
-				errs++;
-			}
-			break;
-
-		case 3:
-			/* Lock line, read and verify shared data, modify shared data. */
-			if (verbose)
-				printk("Line:%3d, Thread:%d:%d. Val: %x\n", linei, thread, vv, *sharecopy);
-			lcount = 0;
-			while (LOCK(sharei) != 1) {
-				if (checkstop(thread, pass, lockpat))
-					return 0;
-				if (lcount++>1000000) {
-					capturedata(&capdata, pass, LOCKADDR(sharei), NULL, sizeof(lock_t));
-					stillbad = (GETLOCK(sharei) != 0);
-					rerr(&capdata, "Shared data lock & inc", linep, slinep, thread, pass, linei, 0, GETLOCK(sharei), stillbad);
-					return 1;
-				}
-				if ((lcount&0x3fff) == 0)
-					udelay(1000);
-			}
-			sval = *sharep;
-			sval2 = *sharecopy;
-			if (sval != sval2) {
-				capturedata(&capdata, pass, sharep, sharecopy, sizeof(*sharecopy));
-				stillbad = (*sharep != *sharecopy);
-				if (!stillbad && *sharep != sval && *sharecopy == sval2)
-					stillbad = 2;
-				if (rerr(&capdata, "Shared data & inc", linep, slinep, thread, pass, linei, sval2, sval, stillbad)) {
-					return 1;
-				}
-				errs++;
-			}
-
-			*sharep = lockpat;
-			*sharecopy = lockpat;
-
-
-			if ( (s=UNLOCK(sharei)) != 1) {
-				capturedata(&capdata, pass, LOCKADDR(sharei), NULL, 4);
-				stillbad = (GETLOCK(sharei) != lockpat);
-				if (rerr(&capdata, "Shared data & inc unlock", linep, slinep, thread, pass, linei, thread, GETLOCK(sharei), stillbad))
-					return 1;
-				if (correct_errors)
-					ZEROLOCK(sharei);	
-				errs++;
-			}
-			break;
-		}
-	}
-
-	return (errs > 0);
-}
-
-static void
-trigger_la(long val)
-{
-	long	*p;
-
-	p = (long*)0xc0000a0001000020L; /* PI_CPU_NUM */
-	*p = val;
-}
-
-static long
-getsynerr(void)
-{
-	long	err, *errp;
-
-	errp = (long*)0xc0000e0000000340L;	/* SYN_ERR */
-	err = *errp;
-	if (err)
-		*errp = -1L;
-	return (err & ~0x60);
-}
-
-static int
-rerr(capture_t *cap, char *msg, void *lp, void *slp, int thread, int pass, int badlinei, int exp, int found, int stillbad)
-{
-	int		cpu, i, linei;
-	long 		synerr;
-	int		selt;
-
-
-	selt = selective_trigger && stillbad > 1 && 
-			memcmp(cap->blockdata, cap->blockdata_fc, 128) != 0 &&
-			memcmp(cap->shaddata, cap->shaddata_fc, 128) == 0;
-	if (selt) {
-		trigger_la(pass);
-	} else if (selective_trigger) {
-		k_go = ST_STOP;
-		return k_stop_on_error;;
-	}
-
-	spin(1);
-	i = 100;
-	while (i && set_lock(&errlock, 1) != 1) {
-		spin(1);
-		i--;
-	}
-	printk ("\nDataError!: %-20s, test %ld, thread %d, line:%d, pass %d (0x%x), time %ld expected:%x, found:%x\n",
-	    msg, k_testnumber, thread, badlinei, pass, pass, jiffies, exp, found);
-
-	dumpline (lp, "Corrupted data", "D ", cap->blockaddr, cap->blockdata, cap->size);
-#ifdef ZZZ
-	if (memcmp(cap->blockdata, cap->blockdata_fc, 128))
-		dumpline (lp, "Corrupted data", "DF", cap->blockaddr, cap->blockdata_fc, cap->size);
-#endif
-
-	if (cap->shadaddr) {
-		dumpline (slp, "Shadow    data", "S ", cap->shadaddr, cap->shaddata, cap->size);
-#ifdef ZZZ
-		if (memcmp(cap->shaddata, cap->shaddata_fc, 128))
-			dumpline (slp, "Shadow    data", "SF", cap->shadaddr, cap->shaddata_fc, cap->size);
-#endif
-	}
-	
-	printk("Threadpasses: ");
-	for (cpu=0,i=0; cpu<LLSC_MAXCPUS; cpu++)
-		if (k_threadprivate[cpu]->threadpasses) {
-			if (i && (i%8) == 0)
-				printk("\n            : ");
-			printk("  %d:0x%x", cpu, k_threadprivate[cpu]->threadpasses);
-			i++;
-		}
-	printk("\n");
-	
-	for (linei=0; linei<k_linecount; linei++) {
-		int		slinei, g1linei, g2linei, g1err, g2err, sh0err, sh1err;
-		dataline_t	*linep, *slinep;
-
-		slinei = (linei + (k_linecount/2))%k_linecount;
-		linep = (dataline_t *)blocks[linei];
-		slinep = (dataline_t *)blocks[slinei];
-
-		g1linei = GUARDLINE(linep->guard1);
-		g2linei = GUARDLINE(linep->guard2);
-		g1err = (g1linei != linei);
-		g2err = (g2linei != linei);
-		sh0err = (linep->share[0] != slinep->share0);
-		sh1err = (linep->share[1] != slinep->share1);
-
-		if (g1err || g2err || sh0err || sh1err) {
-			printk("Line 0x%lx (%03d), %sG1 0x%lx (%03d), %sG2 0x%lx (%03d), %sSH0 %08x (%08x), %sSH1 %08x (%08x)\n",
-				blocks[linei], linei, 
-				g1err ? "*" : " ", blocks[g1linei], g1linei,
-				g2err ? "*" : " ", blocks[g2linei], g2linei,
-				sh0err ? "*" : " ", linep->share[0], slinep->share0,
-				sh1err ? "*" : " ", linep->share[1], slinep->share1);
-
-
-		}
-	}
-
-	printk("\nData was %sfixed by flushcache\n", (stillbad == 1 ? "**** NOT **** " : " "));
-	synerr = getsynerr();
-	if (synerr)
-		printk("SYNERR: Thread %d, Synerr: 0x%lx\n", thread, synerr);
-	spin(2);
-	printk("\n\n");
-	clr_lock(&errlock, 1);
-
-	if (errstop_enabled) {
-		local_irq_disable();
-		while(1);
-	}
-	return k_stop_on_error;
-}
-
-
-static void
-dumpline(void *lp, char *str1, char *str2, void *addr, void *data, int size)
-{
-	long *p;
-	int i, off;
-
-	printk("%s at 0x%lx, size %d, block starts at 0x%lx\n", str1, (long)addr, size, (long)lp);
-	p = (long*) data;
-	for (i=0; i<48; i++, p++) {
-		if (i%8 == 0) printk("%2s", i==16 ? str2 : "  ");
-		printk(" %016lx", *p);
-		if ((i&7)==7) printk("\n");
-	}
-	printk("   ");
-	off = (((long)addr) ^ size) & 63L;
-	for (i=0; i<off+size; i++) {
-		printk("%s", (i>=off) ? "--" : "  ");
-		if ((i%8) == 7)
-			printk(" ");
-	}
-
-	off = ((long)addr) & 127;
-	printk(" (line %d)\n", 2+off/64+1);
-}
-
-
-static int
-randn(uint max, uint *seedp)
-{
-	if (max == 1)
-		return(0);
-	else
-		return((int)(zrandom(seedp)>>10) % max);
-}
-
-
-static int
-checkstop(int thread, int pass, uint lockpat)
-{
-	long	synerr;
-
-	if (k_go == ST_RUN)
-		return 0;
-	if (k_go == ST_STOP)
-		return 1;
-
-	if (errstop_enabled) {
-		local_irq_disable();
-		while(1);
-	}
-	synerr = getsynerr();
-	spin(2);
-	if (k_go == ST_STOP)
-		return 1;
-	if (synerr)
-		printk("SYNERR: Thread %d, Synerr: 0x%lx\n", thread, synerr);
-	return 1;
-}
-
-
-static void
-spin(int j)
-{
-	udelay(j * 500000);
-}
-
-static void
-capturedata(capture_t *cap, uint pass, void *blockaddr, void *shadaddr, int size)
-{
-
-	if (!selective_trigger)
-		trigger_la (pass);
-
-	memcpy (cap->blockdata, CACHEALIGN(blockaddr)-128, 3*128);
-	if (shadaddr) 
-		memcpy (cap->shaddata, CACHEALIGN(shadaddr)-128, 3*128);
-
-	if (k_stop_on_error) {
-		k_go = ST_ERRSTOP;
-	}
-
- 	cap->size = size;
-	cap->blockaddr = blockaddr;
-	cap->shadaddr = shadaddr;
-
-	asm volatile ("fc %0" :: "r"(blockaddr) : "memory");
-	ia64_sync_i();
-	ia64_srlz_d();
-	memcpy (cap->blockdata_fc, CACHEALIGN(blockaddr)-128, 3*128);
-
-	if (shadaddr) {
-		asm volatile ("fc %0" :: "r"(shadaddr) : "memory");
-		ia64_sync_i();
-		ia64_srlz_d();
-		memcpy (cap->shaddata_fc, CACHEALIGN(shadaddr)-128, 3*128);
-	}
-}
-
-int             zranmult = 0x48c27395;
-
-static uint  
-zrandom (uint *seedp)
-{
-        *seedp = (*seedp * zranmult) & 0x7fffffff;
-        return (*seedp);
-}
-
-
-void
-set_autotest_params(void)
-{
-	static int	testnumber=-1;
-
-	if (llsctest_number >= 0) {
-		testnumber = llsctest_number;
-	} else {
-		testnumber++;
-		if (autotest_table[testnumber].passes == 0) {
-			testnumber = 0;
-			dump_block_addrs_opt = 0;
-		}
-	}
-	if (testnumber == 0 && l4_opt) testnumber = 9;
-
-	k_passes = autotest_table[testnumber].passes;
-	k_linepad = autotest_table[testnumber].linepad;
-	k_linecount = autotest_table[testnumber].linecount;
-	k_testnumber = testnumber;
-
-	if (IS_RUNNING_ON_SIMULATOR()) {
-		printk ("llsc start test %ld\n", k_testnumber);
-		k_passes = 1000;
-	}
-}
-
-
-static void
-set_leds(int errs)
-{
-	unsigned char	leds=0;
-
-	/*
-	 * Leds are:
-	 * 	ppppeee-  
-	 *   where
-	 *      pppp = test number
-	 *       eee = error count but top bit is stick
-	 */
-
-	leds =  ((errs&7)<<1) | ((k_testnumber&15)<<4) | (errs ? 0x08 : 0);
-	set_led_bits(leds, LED_MASK_AUTOTEST);
-}
-
-static void
-setup_block_addresses(void)
-{
-	int			i, stride, memmapi;
-	dataline_t		*dp;
-	long			*ip, *ipe;
-
-
-	stride = k_linepad + sizeof(dataline_t);
-	memmapi = 0;
-	for (i=0; i<memmapx; i++) {
-		memmap[i].nextaddr = memmap[i].vstart;
-		memmap[i].nextinit = memmap[i].vstart;
-		memmap[i].wrapcount = 0;
-	}
-
-	for (i=0; i<k_linecount; i++) {
-		blocks[i] = memmap[memmapi].nextaddr;
-		dp = (dataline_t*)blocks[i];
-		memmap[memmapi].nextaddr += (stride & 0xffff);
-		if (memmap[memmapi].nextaddr + sizeof(dataline_t) >= memmap[memmapi].vend) {
-			memmap[memmapi].wrapcount++;
-			memmap[memmapi].nextaddr = memmap[memmapi].vstart + 
-					memmap[memmapi].wrapcount * sizeof(dataline_t);
-		}
-
-		ip = (long*)((memmap[memmapi].nextinit+7)&~7);
-		ipe = (long*)(memmap[memmapi].nextaddr+2*sizeof(dataline_t)+8);
-		while(ip <= ipe && ip < ((long*)memmap[memmapi].vend-8))
-			*ip++ = (long)ip;
-		memmap[memmapi].nextinit = (long) ipe;
-		dp->guard1 = BGUARD(i);
-		dp->guard2 = EGUARD(i);
-		dp->lock[0] = dp->lock[1] = NOLOCK;
-		dp->share[0] = dp->share0 = 0x1111;
-		dp->share[1] = dp->share1 = 0x2222;
-		memcpy(dp->private, init_private, LLSC_MAXCPUS*sizeof(private_t));
-
-
-		if (stride > 16384) {
-			memmapi++;
-			if (memmapi == memmapx)
-				memmapi = 0;
-		}
-	}
-
-}
-
-static void
-dump_block_addrs(void)
-{
-	int	i;
-
-	printk("LLSC TestNumber %ld\n", k_testnumber);
-
-	for (i=0; i<k_linecount; i++) {
-		printk("  %lx", blocks[i]);
-		if (i%4 == 3)
-			printk("\n");
-	}
-	printk("\n");
-}
-
-
-static void
-set_thread_state(int cpuid, int state)
-{
-	if (k_threadprivate[cpuid]->threadstate == TS_KILLED) {
-		set_led_bits(LED_MASK_AUTOTEST, LED_MASK_AUTOTEST);
-		while(1);
-	}
-	k_threadprivate[cpuid]->threadstate = state;
-}
-
-#define MINBLK	(16*1024*1024)
-static int
-build_mem_map(unsigned long start, unsigned long end, void *arg)
-{
-	long	lstart, lend;
-	long	align = 8*MB;
-
-	printk ("LLSC memmap: start 0x%lx, end 0x%lx, (0x%lx - 0x%lx)\n", 
-		start, end, (long) virt_to_page(start), (long) virt_to_page(end-PAGE_SIZE));
-
-	if (memmapx >= MAPCHUNKS || (end-start) < MINBLK)
-		return 0;
-
-	/*
-	 * Start in the middle of the range & find the first non-free page in both directions
-	 * from the midpoint. This is likely to be the bigest free block.
-	 */
-	lend = lstart = start + (end-start)/2;
-	while (lend < end && !PageReserved(virt_to_page(lend)) && virt_to_page(lend)->count.counter == 0)
-		lend += PAGE_SIZE;
-	lend -= PAGE_SIZE;
-
-	while (lstart >= start && !PageReserved(virt_to_page(lstart)) && virt_to_page(lstart)->count.counter == 0)
-		lstart -= PAGE_SIZE;
-	lstart += PAGE_SIZE;
-
-	lstart = (lstart + align -1) /align * align;
-	end = end / align * align;
-	if (lstart >= end)
-		return 0;
-	printk ("     memmap: start 0x%lx, end 0x%lx\n", lstart, end);
-
-	memmap[memmapx].vstart = lstart;
-	memmap[memmapx].vend = end;
-	memmapx++;
-	return 0;
-}
-
-void int_test(void);
-
-int
-llsc_main (int cpuid)
-{
-	int		i, cpu, is_master, repeatcnt=0;
-	unsigned int	preverr=0, errs=0, pass=0;
-	int		automode=0;
-
-#ifdef INTTEST
-	if (inttest)
-		int_test();
-#endif
-
-	if (!autotest_enabled)
-		return 0;
-
-#ifdef CONFIG_SMP
-	is_master = !smp_processor_id();
-#else
-	is_master = 1;
-#endif
-
-
-	if (is_master) {
-		mbase = (control_t*) __get_free_pages(GFP_KERNEL, get_order(4096+THREADPRIVATESZ()*LLSC_MAXCPUS));
-		printk("LLSC: mbase 0x%lx\n", (long)mbase);
-		print_params();
-		if(!IS_RUNNING_ON_SIMULATOR())
-			spin(10);
-		k_currentpass = 0;
-		k_go = ST_IDLE;
-		k_passes = DEF_PASSES;
-		k_napticks = DEF_NAPTICKS;
-		k_stop_on_error = DEF_STOP_ON_ERROR;
-		k_verbose = DEF_VERBOSE;
-		k_linecount = DEF_LINECOUNT;
-		k_iter_msg = DEF_ITER_MSG;
-		k_vv = DEF_VV;
-		k_linepad = DEF_LINEPAD;
-		k_blocks = (void*)blocks;
-		efi_memmap_walk(build_mem_map, 0);
-	
-#ifdef CONFIG_IA64_SGI_AUTOTEST
-		automode = 1;
-#endif
-
-		for (i=0; i<LLSC_MAXCPUS; i++) {
-			k_threadprivate[i] = THREADPRIVATE(i);
-			memset(k_threadprivate[i], 0, sizeof(*k_threadprivate[i]));
-			init_private[i] = i;
-		}
-		mb();
-		initialized = 1;
-	} else {
-		while (initialized == 0)
-			udelay(100);
-	}
-
-loop:
-	if (is_master) {
-		if (automode) {
-			if (!preverr || repeatcnt++ > 5) {
-				set_autotest_params();
-				repeatcnt = 0;
-			}
-		} else {
-			while (k_go == ST_IDLE);
-		}
-
-		k_go = ST_INIT;
-		if (k_linecount > MAX_LINECOUNT) k_linecount = MAX_LINECOUNT;
-		k_linecount = k_linecount & ~1;
-		setup_block_addresses();
-		if (!preverr && dump_block_addrs_opt)
-			dump_block_addrs();
-
-		k_currentpass = pass++;
-		k_go = ST_RUN;
-		if (fail_enabled)
-			fail_enabled--;
-
-	} else {
-		while (k_go != ST_RUN || k_currentpass != pass);
-		pass++;
-	}
-
-
-	set_leds(errs);
-	set_thread_state(cpuid, TS_RUNNING);
-
-	errs += ran_conf_llsc(cpuid);
-	preverr = (k_go == ST_ERRSTOP);
-
-	set_leds(errs);
-	set_thread_state(cpuid, TS_STOPPED);
-
-	if (is_master) {
-		Speedo();
-		for (i=0, cpu=0; cpu<LLSC_MAXCPUS; cpu++) {
-			while (k_threadprivate[cpu]->threadstate == TS_RUNNING) {
-				i++;
-				if (i == 10000) { 
-					k_go = ST_STOP;
-					printk ("  llsc master stopping test number %ld\n", k_testnumber);
-				}
-				if (i > 100000) {
-					k_threadprivate[cpu]->threadstate = TS_KILLED;
-					printk ("  llsc: master killing cpuid %d, running test number %ld\n", 
-							cpu, k_testnumber);
-				}
-				udelay(1000);
-			}
-		}
-	}
-
-	goto loop;
-}
-
-
-static void
-Speedo(void)
-{
-	static int i = 0;
-
-	switch (++i%4) {
-	case 0:
-		printk("|\b");
-		break;
-	case 1:
-		printk("\\\b");
-		break;
-	case 2:
-		printk("-\b");
-		break;
-	case 3:
-		printk("/\b");
-		break;
-	}
-}
-
-#ifdef INTTEST
-
-/* ======================================================================================================== 
- *
- * Some test code to verify that interrupts work
- *
- * Add the following to the arch/ia64/kernel/smp.c after the comment "Reschedule callback"
- * 		if (zzzprint_resched) printk("  cpu %d got interrupt\n", smp_processor_id());
- *
- * Enable the code in arch/ia64/sn/sn1/smp.c to print sending IPIs.
- *
- */
-
-static int __init set_inttest(char *str)
-{
-        inttest = 1;
-	autotest_enabled = 1;
-
-	return 1;
-}	
-
-__setup("inttest=", set_inttest);
-
-int	zzzprint_resched=0;
-
-void
-int_test() {
-	int			mycpu, cpu;
-	static volatile int	control_cpu=0;
-
-	mycpu = smp_processor_id();
-	zzzprint_resched = 2;
-
-	printk("Testing cross interrupts\n");
-	
-	while (control_cpu != smp_num_cpus) {
-		if (mycpu == cpu_logical_map(control_cpu)) {
-			for (cpu=0; cpu<smp_num_cpus; cpu++) {
-				printk("Sending interrupt from %d to %d\n", mycpu, cpu_logical_map(cpu));
-				udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
-				smp_send_reschedule(cpu_logical_map(cpu));
-				udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
-				smp_send_reschedule(cpu_logical_map(cpu));
-				udelay(IS_RUNNING_ON_SIMULATOR ? 10000 : 400000);
-			}
-			control_cpu++;
-		}
-	}
-
-	zzzprint_resched = 1;
-
-	if (mycpu == cpu_logical_map(smp_num_cpus-1)) {
-		printk("\nTight loop of cpu %d sending ints to cpu 0 (every 100 us)\n", mycpu);
-		udelay(IS_RUNNING_ON_SIMULATOR ? 1000 : 1000000);
-		__cli();
-		while (1) {
-			smp_send_reschedule(0);
-			udelay(100);
-		}
-
-	}
-
-	while(1);
-}
-#endif
diff -Nru a/arch/ia64/sn/kernel/llsc4.h b/arch/ia64/sn/kernel/llsc4.h
--- a/arch/ia64/sn/kernel/llsc4.h	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,107 +0,0 @@
-/* 
- *
- * 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) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifdef STANDALONE
-#include "lock.h"
-#endif
-
-
-#define DEF_NAPTICKS		0
-#define DEF_PASSES		0
-#define DEF_AUTO_PASSES		1000000
-#define DEF_STOP_ON_ERROR	1
-#define DEF_VERBOSE		0
-#define DEF_LINECOUNT		2
-#define DEF_ITER_MSG		0
-#define DEF_VV			0xffffffff
-#define DEF_LINEPAD		0x234
-
-
-
-#define LLSC_MAXCPUS		64
-#define CACHELINE		64
-#define MAX_LINECOUNT		1024
-#define K			1024
-#define	MB			(K*K)
-
-
-#define	uint 		unsigned int
-#define	ushort		unsigned short
-#define	uchar		unsigned char
-#define vint		volatile int
-#define vlong		volatile long
-
-#define LOCKADDR(i)	&linep->lock[(i)]
-#define LOCK(i)		set_lock(LOCKADDR(i), lockpat)
-#define UNLOCK(i)	clr_lock(LOCKADDR(i), lockpat)
-#define GETLOCK(i)	*LOCKADDR(i)
-#define ZEROLOCK(i)	init_lock(LOCKADDR(i))
-
-#define CACHEALIGN(a)	((char*)((long)(a) & ~127L))
-
-typedef uint		guard_t;
-typedef uint		lock_t;
-typedef uint		share_t;
-typedef uchar		private_t;
-
-typedef struct {
-	guard_t		guard1;
-	lock_t		lock[2];
-	share_t		share[2];
-	private_t	private[LLSC_MAXCPUS];
-	share_t		share0;
-	share_t		share1;
-	guard_t		guard2;
-} dataline_t ;
-
-
-#define LINEPAD			k_linepad
-#define LINESTRIDE		(((sizeof(dataline_t)+CACHELINE-1)/CACHELINE)*CACHELINE + LINEPAD)
-
-
-typedef struct {
-	vint		threadstate;
-	uint		threadpasses;
-	private_t	private[MAX_LINECOUNT];
-} threadprivate_t;
-
-typedef struct {
-	vlong		sk_go;		/* 0=idle, 1=init, 2=run */
-	long		sk_linecount;
-	long		sk_passes;
-	long		sk_napticks;
-	long		sk_stop_on_error;
-	long		sk_verbose;
-	long		sk_iter_msg;
-	long		sk_vv;
-	long		sk_linepad;
-	long		sk_options;
-	long		sk_testnumber;
-	vlong		sk_currentpass;
-	void 		*sk_blocks;
-	threadprivate_t	*sk_threadprivate[LLSC_MAXCPUS];
-} control_t;
-
-/* Run state (k_go) constants */
-#define ST_IDLE		0
-#define ST_INIT		1
-#define ST_RUN		2
-#define ST_STOP		3
-#define ST_ERRSTOP	4
-
-
-/* Threadstate constants */
-#define TS_STOPPED	0
-#define	TS_RUNNING	1
-#define TS_KILLED	2
-
-
-
-int llsc_main (int cpuid);
-
diff -Nru a/arch/ia64/sn/kernel/machvec.c b/arch/ia64/sn/kernel/machvec.c
--- a/arch/ia64/sn/kernel/machvec.c	Wed Jun 18 23:42:07 2003
+++ b/arch/ia64/sn/kernel/machvec.c	Wed Jun 18 23:42:07 2003
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -30,32 +30,5 @@
  * http://oss.sgi.com/projects/GenInfo/NoticeExplan
  */
 
-#include <linux/config.h>
-
-#ifdef CONFIG_IA64_SGI_SN1
-#define MACHVEC_PLATFORM_NAME		sn1
-#define MACHVEC_PLATFORM_HEADER		<asm/machvec_sn1.h>
-#else CONFIG_IA64_SGI_SN1
-#define MACHVEC_PLATFORM_NAME		sn2
-#define MACHVEC_PLATFORM_HEADER		<asm/machvec_sn2.h>
-#else
-#error "unknown platform"
-#endif
-
+#define MACHVEC_PLATFORM_NAME	sn2
 #include <asm/machvec_init.h>
-#include <asm/io.h>
-#include <linux/pci.h>
-void*
-sn_mk_io_addr_MACRO
-
-dma_addr_t
-sn_pci_map_single_MACRO
-
-int
-sn_pci_map_sg_MACRO
-
-unsigned long
-sn_virt_to_phys_MACRO
-
-void *
-sn_phys_to_virt_MACRO
diff -Nru a/arch/ia64/sn/kernel/mca.c b/arch/ia64/sn/kernel/mca.c
--- a/arch/ia64/sn/kernel/mca.c	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/sn/kernel/mca.c	Wed Jun 18 23:42:06 2003
@@ -2,7 +2,7 @@
  * File:	mca.c
  * Purpose:	SN specific MCA code.
  *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -34,247 +34,101 @@
  */
 
 #include <linux/types.h>
-#include <linux/init.h>
-#include <linux/jiffies.h>
-#include <linux/threads.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/smp_lock.h>
-#include <linux/acpi.h>
-#ifdef CONFIG_KDB
-#include <linux/kdb.h>
-#endif
-
-#include <asm/machvec.h>
-#include <asm/page.h>
-#include <asm/ptrace.h>
-#include <asm/system.h>
+#include <linux/kernel.h>
+#include <linux/timer.h>
+#include <asm/mca.h>
 #include <asm/sal.h>
 #include <asm/sn/sn_sal.h>
-#include <asm/mca.h>
-#include <asm/sn/mca.h>
 
-#include <asm/irq.h>
-#include <asm/hw_irq.h>
-#include <asm/smp.h>
-#include <asm/sn/sn_cpuid.h>
-
-static char *shub_mmr_names[] = {
-	"sh_event_occurred",
-	"sh_first_error",
-	"sh_event_overflow",
-
-/* PI */
-	"sh_pi_first_error",
-	"sh_pi_error_summary",
-	"sh_pi_error_overflow",
-
-/* PI HW */
-	"sh_pi_error_detail_1",
-	"sh_pi_error_detail_2",
-	"sh_pi_hw_time_stamp",
-
-/* PI UCE */
-	"sh_pi_uncorrected_detail_1",
-	"sh_pi_uncorrected_detail_2",
-	"sh_pi_uncorrected_detail_3",
-	"sh_pi_uncorrected_detail_4",
-	"sh_pi_uncor_time_stamp",
-
-/* PI CE */
-	"sh_pi_corrected_detail_1",
-	"sh_pi_corrected_detail_2",
-	"sh_pi_corrected_detail_3",
-	"sh_pi_corrected_detail_4",
-	"sh_pi_cor_time_stamp",
-
-/* MD */
-	"sh_mem_error_summary",
-	"sh_mem_error_overflow",
-/* MD HW */
-	"sh_misc_err_hdr_upper",
-	"sh_misc_err_hdr_lower",
-	"sh_md_dqlp_mmr_xperr_val",
-	"sh_md_dqlp_mmr_yperr_val",
-	"sh_md_dqrp_mmr_xperr_val",
-	"sh_md_dqrp_mmr_yperr_val",
-	"sh_md_hw_time_stamp",
-
-/* MD UCE */
-	"sh_dir_uc_err_hdr_lower",
-	"sh_dir_uc_err_hdr_upper",
-	"sh_md_dqlp_mmr_xuerr1",
-	"sh_md_dqlp_mmr_xuerr2",
-	"sh_md_dqlp_mmr_yuerr1",
-	"sh_md_dqlp_mmr_yuerr2",
-	"sh_md_dqrp_mmr_xuerr1",
-	"sh_md_dqrp_mmr_xuerr2",
-	"sh_md_dqrp_mmr_yuerr1",
-	"sh_md_dqrp_mmr_yuerr2",
-	"sh_md_uncor_time_stamp",
-
-/* MD CE */
-	"sh_dir_cor_err_hdr_lower",
-	"sh_dir_cor_err_hdr_upper",
-	"sh_md_dqlp_mmr_xcerr1",
-	"sh_md_dqlp_mmr_xcerr2",
-	"sh_md_dqlp_mmr_ycerr1",
-	"sh_md_dqlp_mmr_ycerr2",
-	"sh_md_dqrp_mmr_xcerr1",
-	"sh_md_dqrp_mmr_xcerr2",
-	"sh_md_dqrp_mmr_ycerr1",
-	"sh_md_dqrp_mmr_ycerr2",
-	"sh_md_cor_time_stamp",
-
-/* MD CE, UCE */
-	"sh_md_dqls_mmr_xamopw_err",
-	"sh_md_dqrs_mmr_yamopw_err",
-
-/* XN */
-	"sh_xn_error_summary",
-	"sh_xn_first_error",
-	"sh_xn_error_overflow",
-
-/* XN HW */
-	"sh_xniilb_error_summary",
-	"sh_xniilb_first_error",
-	"sh_xniilb_error_overflow",
-	"sh_xniilb_error_detail_1",
-	"sh_xniilb_error_detail_2",
-	"sh_xniilb_error_detail_3",
-
-	"sh_ni0_error_summary_1",
-	"sh_ni0_first_error_1",
-	"sh_ni0_error_overflow_1",
-
-	"sh_ni0_error_summary_2",
-	"sh_ni0_first_error_2",
-	"sh_ni0_error_overflow_2",
-	"sh_ni0_error_detail_1",
-	"sh_ni0_error_detail_2",
-	"sh_ni0_error_detail_3",
-
-	"sh_ni1_error_summary_1",
-	"sh_ni1_first_error_1",
-	"sh_ni1_error_overflow_1",
-
-	"sh_ni1_error_summary_2",
-	"sh_ni1_first_error_2",
-	"sh_ni1_error_overflow_2",
-
-	"sh_ni1_error_detail_1",
-	"sh_ni1_error_detail_2",
-	"sh_ni1_error_detail_3",
-
-	"sh_xn_hw_time_stamp",
-
-/* XN HW & UCE & SBE */
-	"sh_xnpi_error_summary",
-	"sh_xnpi_first_error",
-	"sh_xnpi_error_overflow",
-	"sh_xnpi_error_detail_1",
-
-	"sh_xnmd_error_summary",
-	"sh_xnmd_first_error",
-	"sh_xnmd_error_overflow",
-	"sh_xnmd_ecc_err_report",
-	"sh_xnmd_error_detail_1",
-
-/* XN UCE */
-	"sh_xn_uncorrected_detail_1",
-	"sh_xn_uncorrected_detail_2",
-	"sh_xn_uncorrected_detail_3",
-	"sh_xn_uncorrected_detail_4",
-	"sh_xn_uncor_time_stamp",
-
-/* XN CE */
-	"sh_xn_corrected_detail_1",
-	"sh_xn_corrected_detail_2",
-	"sh_xn_corrected_detail_3",
-	"sh_xn_corrected_detail_4",
-	"sh_xn_cor_time_stamp",
-
-/* LB HW */
-	"sh_lb_error_summary",
-	"sh_lb_first_error",
-	"sh_lb_error_overflow",
-	"sh_lb_error_detail_1",
-	"sh_lb_error_detail_2",
-	"sh_lb_error_detail_3",
-	"sh_lb_error_detail_4",
-	"sh_lb_error_detail_5",
-	"sh_junk_error_status",
-};
 
-void 
-sal_log_plat_print(int header_len, int sect_len, u8 *p_data, prfunc_t prfunc) 
+
+/*
+ * Interval for calling SAL to poll for errors that do NOT cause error
+ * interrupts. SAL will raise a CPEI if any errors are present that
+ * need to be logged.
+ */
+#define CPEI_INTERVAL	(5*HZ)
+
+
+struct timer_list sn_cpei_timer;
+void sn_init_cpei_timer(void);
+
+
+/*
+ * print_hook
+ *
+ * This function is the callback routine that SAL calls to log error
+ * info for platform errors. 
+ */
+static int
+print_hook(const char *fmt, ...)
 {
-	sal_log_plat_info_t *sh_info = (sal_log_plat_info_t *) p_data;
-	u64 *mmr_val = (u64 *)&(sh_info->shub_state);
-	char **mmr_name = shub_mmr_names;
-	int mmr_count = sizeof(sal_log_shub_state_t)>>3;
-
-	while(mmr_count) {
-		if(*mmr_val) {
-			prfunc("%-40s: %#016lx\n",*mmr_name, *mmr_val);
-		}
-		mmr_name++;
-		mmr_val++;
-		mmr_count--;
-	}
+	static int	newline=1;
+	char		buf[400], *p;
+	va_list		args;
+	int		len=0;
 
-}
 
-void
-sn_cpei_handler(int irq, void *devid, struct pt_regs *regs) {
+	va_start(args, fmt);
+	if (newline) {
+		strcpy(buf, "+ ");
+		len += 2;
+	}
+	len += vsnprintf(buf+len, sizeof(buf)-len, fmt, args);
 
-        struct ia64_sal_retval isrv;
-// this function's sole purpose is to call SAL when we receive
-// a CE interrupt from SHUB or when the timer routine decides
-// we need to call SAL to check for CEs.
+	/* Prefix each line with "+ " to be consistent with mca.c. */
+	p = buf;
+	while ((p=strchr(p, '\n')) && *++p != '\0') {
+		memmove(p+2, p, 1+strlen(p));
+		strncpy(p, "+ ", 2);
+		len += 2;
+	}
+	newline = (p != 0);
 
-        // CALL SAL_LOG_CE
-        SAL_CALL(isrv, SN_SAL_LOG_CE, irq, 0, 0, 0, 0, 0, 0);
+	va_end(args);
+	printk("%s", buf);
+	return len;
 }
 
-#include <linux/timer.h>
 
-#define CPEI_INTERVAL   (HZ/100)
-struct timer_list sn_cpei_timer = TIMER_INITIALIZER(NULL, 0, 0);
-void sn_init_cpei_timer(void);
 
+/*
+ * ia64_sn2_platform_plat_specific_err_print
+ *
+ * Called by the MCA handler to log platform-specific errors.
+ */
 void
-sn_cpei_timer_handler(unsigned long dummy) {
-        sn_cpei_handler(-1, NULL, NULL);
-        del_timer(&sn_cpei_timer);
-        sn_cpei_timer.expires = jiffies + CPEI_INTERVAL;
-        add_timer(&sn_cpei_timer);
+ia64_sn2_platform_plat_specific_err_print(int header_len, int sect_len, u8 *p_data, prfunc_t prfunc)
+{
+	ia64_sn_plat_specific_err_print(print_hook, p_data - sect_len);
 }
 
-void
-sn_init_cpei_timer() {
-        sn_cpei_timer.expires = jiffies + CPEI_INTERVAL;
-        sn_cpei_timer.function = sn_cpei_timer_handler;
-        add_timer(&sn_cpei_timer);
-}
 
-#ifdef ajmtestceintr
 
-struct timer_list sn_ce_timer;
+static void
+sn_cpei_handler(int irq, void *devid, struct pt_regs *regs)
+{
+	/*
+	 * this function's sole purpose is to call SAL when we receive
+	 * a CE interrupt from SHUB or when the timer routine decides
+	 * we need to call SAL to check for CEs.
+	 */
+
+	/* CALL SAL_LOG_CE */
 
-void
-sn_ce_timer_handler(long dummy) {
-        unsigned long *pi_ce_error_inject_reg = 0xc00000092fffff00;
+	ia64_sn_plat_cpei_handler();
+}
 
-        *pi_ce_error_inject_reg = 0x0000000000000100;
-        del_timer(&sn_ce_timer);
-        sn_ce_timer.expires = jiffies + CPEI_INTERVAL;
-        add_timer(&sn_ce_timer);
+
+static void
+sn_cpei_timer_handler(unsigned long dummy) {
+	sn_cpei_handler(-1, NULL, NULL);
+	mod_timer(&sn_cpei_timer, jiffies + CPEI_INTERVAL);
 }
 
-sn_init_ce_timer() {
-        sn_ce_timer.expires = jiffies + CPEI_INTERVAL;
-        sn_ce_timer.function = sn_ce_timer_handler;
-        add_timer(&sn_ce_timer);
+void
+sn_init_cpei_timer() {
+	sn_cpei_timer.expires = jiffies + CPEI_INTERVAL;
+        sn_cpei_timer.function = sn_cpei_timer_handler;
+        add_timer(&sn_cpei_timer);
 }
-#endif /* ajmtestceintr */
diff -Nru a/arch/ia64/sn/kernel/misctest.c b/arch/ia64/sn/kernel/misctest.c
--- a/arch/ia64/sn/kernel/misctest.c	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,371 +0,0 @@
-/* 
- *
- * 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) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/kernel.h>
-#include <linux/init.h>
-#include <linux/delay.h>
-#include <linux/interrupt.h>
-#include <asm/sn/sn_sal.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/processor.h>
-#include <asm/pgtable.h>
-#include <asm/page.h>
-#include <asm/timex.h>
-#include <asm/io.h>
-#include <asm/irq.h>
-#include <asm/sn/intr.h>
-#include <asm/hw_irq.h>
-#include <asm/sn/leds.h>
-
-extern	int autotest_enabled;
-long	mcatest=0, debug0, debug1, debug2, debug3;
-
-#define HDELAY(t)	(IS_RUNNING_ON_SIMULATOR() ? udelay(1) : udelay(t))
-
-/* 
- * mcatest
- *	mactest contains a decimal number (RPTT) where
- *		R - flag, if non zero, run forever
- *
- *		P - identifies when to run the test
- *		    0 execute test at cpu 0 early init
- *		    1 execute test at cpu 0 idle
- *		    2 execute test at last (highest numbered) cpu idle
- *		    3 execute test on all cpus at idle
- *
- *		TT- identifies test to run
- *		    01 = MCA via dup TLB dropin
- *		    02 = MCA via garbage address
- *		    03 = lfetch via garbage address
- *		    05 = INIT self
- *		    06 = INIT other cpu
- *		    07 = INIT non-existent cpu
- *		    10 = IPI stress test. Target cpu 0
- *		    11 = IPI stress test. Target all cpus
- *		    12 = TLB stress test
- *		    13 = Park cpu (spinloop)
- *		    14 = One shot TLB test with tlb spinlock
- *		    15 = One shot TLB test
- *		    16 = One shot TLB test sync'ed with RTC
- *		    20 = set led to the cpuid & spin.
- *		    21 = Try mixed cache/uncached refs & see what happens
- *		    22 = Call SAL reboot
- *		    23 = Call PAL halt
- */
-static int __init set_mcatest(char *str)
-{
-	int	val;
-	get_option(&str, &val);
-	mcatest = val;
-	return 1;
-}
-__setup("mcatest=", set_mcatest);
-
-static int __init set_debug0(char *str)
-{
-	int	val;
-	get_option(&str, &val);
-	debug0 = val;
-	return 1;
-}
-__setup("debug0=", set_debug0);
-
-static int __init set_debug1(char *str)
-{
-	int	val;
-	get_option(&str, &val);
-	debug1 = val;
-	return 1;
-}
-__setup("debug1=", set_debug1);
-
-static int __init set_debug2(char *str)
-{
-	int	val;
-	get_option(&str, &val);
-	debug2 = val;
-	return 1;
-}
-__setup("debug2=", set_debug2);
-
-static int __init set_debug3(char *str)
-{
-	int	val;
-	get_option(&str, &val);
-	debug3 = val;
-	return 1;
-}
-__setup("debug3=", set_debug3);
-
-static volatile int	go;
-
-static void
-do_sync(int pos) {
-	if (pos != 3)
-		return;
-	else if (smp_processor_id() == 0)
-		go = 1;
-	else
-		while (!go);
-}
-
-static void
-sgi_mcatest_bkpt(void)
-{
-}
-
-
-/*
- * Optional test
- *	pos - 0 called from early init
- *	pos - called when cpu about to go idle (fully initialized
- */
-void
-sgi_mcatest(int pos)
-{
-	long	spos, test, repeat;
-	int	cpu, curcpu, i, n;
-
-	//if (IS_RUNNING_ON_SIMULATOR()) mcatest=1323;
-	repeat = mcatest/1000;
-	spos = (mcatest/100)%10;
-	test = mcatest % 100;
-	curcpu = smp_processor_id();
-
-	if ( mcatest == 0 || !((pos == 0 && spos == 0) ||
-		(pos == 1 && spos == 3) ||
-	        (pos == 1 && spos == 1 && curcpu == 0) ||
-	        (pos == 1 && spos == 2 && curcpu == smp_num_cpus-1)))
-		return;
-	     
-again:
-	if (test == 1 || test == 2 || test == 3) {
-		void zzzmca(int);
-		printk("CPU %d: About to cause unexpected MCA\n", curcpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		zzzmca(test-1);
-	
-		HDELAY(100000);
-	}
-
-	if (test == 4) {
-		long    result, adrs[] = {0xe0021000009821e0UL, 0xc0003f3000000000UL, 0xc0000081101c0000UL, 0xc00000180e021004UL,  0xc00000180e022004UL, 0xc00000180e023004UL };
-		long    size[] = {1,2,4,8};
-		int     r, i, j, k;
-
-		for (k=0; k<2; k++) {
-			for (i=0; i<6; i++) {
-				for (j=0; j<4; j++) {
-					printk("Probing 0x%lx, size %ld\n", adrs[i], size[j]);
-					result = -1;
-					r = ia64_sn_probe_io_slot (adrs[i], size[j], &result);
-					printk("    status %d, val 0x%lx\n", r, result);
-					udelay(100000);
-				}
-			}
-		}
-
-	}
-
-	if (test == 5) {
-		cpu =  curcpu;
-		printk("CPU %d: About to send INIT to self (cpu %d)\n", curcpu, cpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		platform_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0);
-		
-		HDELAY(100000);
-		printk("CPU %d: Returned from INIT\n", curcpu);
-	}
-
-	if (test == 6) {
-		cpu =  curcpu ^ 1;
-		printk("CPU %d: About to send INIT to other cpu (cpu %d)\n", curcpu, cpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		platform_send_ipi(cpu, 0, IA64_IPI_DM_INIT, 0);
-
-		HDELAY(100000);
-		printk("CPU %d: Done\n", curcpu);
-	}
-
-	if (test == 7) {
-		printk("CPU %d: About to send INIT to non-existent cpu\n", curcpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		sn_send_IPI_phys(0xffff, 0, IA64_IPI_DM_INIT);
-
-		HDELAY(100000);
-		printk("CPU %d: Done\n", curcpu);
-	}
-
-	if (test == 10) {
-		n = IS_RUNNING_ON_SIMULATOR() ? 10 : 10000000;
-		cpu = 0;
-		printk("CPU %d: IPI stress test. Target cpu 0\n", curcpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		for (i=0; i<n; i++)
-			platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0);
-
-		HDELAY(100000);
-		printk("CPU %d: Done\n", curcpu);
-	}
-
-	if (test == 11) {
-		n = IS_RUNNING_ON_SIMULATOR() ? 100 : 10000000;
-		printk("CPU %d: IPI stress test. Target all cpus\n", curcpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		for (i=0; i<n; i++)
-			for (cpu=0; cpu<smp_num_cpus; cpu++)
-				if (smp_num_cpus > 2 && cpu != curcpu)
-					platform_send_ipi(cpu, IA64_IPI_RESCHEDULE, IA64_IPI_DM_INT, 0);
-
-		HDELAY(100000);
-		printk("CPU %d: Done\n", curcpu);
-	}
-
-	if (test == 12) {
-		long adr = 0xe002200000000000UL;
-		n = IS_RUNNING_ON_SIMULATOR() ? 1000 : 100000;
-		printk("CPU %d: TLB flush stress test\n", curcpu);
-		HDELAY(100000);
-		sgi_mcatest_bkpt();
-		do_sync(spos);
-
-		for (i=0; i<n; i++)
-			platform_global_tlb_purge(adr, adr+25*PAGE_SIZE, 14);
-
-		HDELAY(100000);
-		printk("CPU %d: Done\n", curcpu);
-	}
-	
-	if (test == 13) {
-		printk("CPU %d: Park cpu in spinloop\n", curcpu);
-		while(1);
-	}
-	if (test == 14 || test == 15 || test == 16 || test == 17) {
-		long adr = 0xe002200000000000UL;
-		static int inited=0;
-		if (inited == 0) {
-			if (debug0 == 0) debug0 = 1;
-			repeat = 1;
-			do_sync(spos);
-			if (curcpu >= smp_num_cpus-2) {
-				printk("Parking cpu %d\n", curcpu);
-				local_irq_disable();
-				while(1);
-			} else {
-				printk("Waiting cpu %d\n", curcpu);
-				HDELAY(1000000);
-			}
-			HDELAY(1000000);
-			inited = 1;
-		}
-		if (test == 16 || test == 17) {
-			unsigned long t, shift, mask;
-			mask =  (smp_num_cpus > 16) ? 0x1f : 0xf;
-			shift = 25-debug1;
-			do {
-				t = get_cycles();
-				if (IS_RUNNING_ON_SIMULATOR())
-					t = (t>>8);
-				else
-					t = (t>>shift);
-				t = t & mask;
-			} while (t == curcpu);
-			do {
-				t = get_cycles();
-				if (IS_RUNNING_ON_SIMULATOR())
-					t = (t>>8);
-				else
-					t = (t>>shift);
-				t = t & mask;
-			} while (t != curcpu);
-		}
-		if(debug3) printk("CPU %d: One TLB start\n", curcpu);
-		if (test != 17) platform_global_tlb_purge(adr, adr+PAGE_SIZE*debug0, 14);
-		if(debug3) printk("CPU %d: One TLB flush done\n", curcpu);
-	}
-	if (test == 20) {
-		local_irq_disable();
-		set_led_bits(smp_processor_id(), 0xff);
-		while(1);
-	}
-	if (test == 21) {
-		extern long ia64_mca_stack[];
-		int		i, n;
-		volatile long	*p, *up;
-		p = (volatile long*)__imva(ia64_mca_stack);
-		up = (volatile long*)(__pa(p) | __IA64_UNCACHED_OFFSET);
-
-		if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ get data in cache\n");
-		for (n=0, i=0; i<100; i++)
-			n += *(p+i);
-		if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ Make uncached refs to same data\n");
-		for (n=0, i=0; i<100; i++)
-			n += *(up+i);
-		if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ dirty the data via cached refs\n");
-		for (n=0, i=0; i<100; i++)
-			*(p+i) = i;
-		if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ Make uncached refs to same data\n");
-		for (n=0, i=0; i<100; i++)
-			n += *(up+i);
-		if(!IS_RUNNING_ON_SIMULATOR()) printk("ZZZ Flushing cache\n");
-		for (n=0, i=0; i<100; i++)
-			ia64_fc((void*)(p+i));
-		printk("ZZZ done\n");
-	}
-	if (test == 21) {
-		int i;
-		volatile long tb, t[10];
-		for (i=0; i<10; i++) {
-			tb = debug3+ia64_get_itc();
-			sgi_mcatest_bkpt();
-			t[i] = ia64_get_itc() - tb;
-		}
-		for (i=0; i<10; i++) {
-			printk("ZZZ NULL  0x%lx\n", t[i]);
-		}
-		for (i=0; i<10; i++) {
-			tb = debug3+ia64_get_itc();
-			ia64_pal_call_static(PAL_MC_DRAIN, 0, 0, 0, 0);
-			t[i] = ia64_get_itc() - tb;
-		}
-		for (i=0; i<10; i++) {
-			printk("ZZZ DRAIN 0x%lx\n", t[i]);
-		}
-	}
-	if (test == 22) {
-		extern void machine_restart(char*);
-		printk("ZZZ machine_restart\n");
-		machine_restart(0);
-	}
-	if (test == 23) {
-		printk("ZZZ ia64_pal_halt_light\n");
-		ia64_pal_halt_light();
-	}
-	if (repeat)
-		goto again;
-
-}
diff -Nru a/arch/ia64/sn/kernel/probe.c b/arch/ia64/sn/kernel/probe.c
--- a/arch/ia64/sn/kernel/probe.c	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/sn/kernel/probe.c	Wed Jun 18 23:42:06 2003
@@ -1,7 +1,7 @@
 /*
  * Platform dependent support for IO probing.
  *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
diff -Nru a/arch/ia64/sn/kernel/setup.c b/arch/ia64/sn/kernel/setup.c
--- a/arch/ia64/sn/kernel/setup.c	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/sn/kernel/setup.c	Wed Jun 18 23:42:06 2003
@@ -1,5 +1,5 @@
 /*
- * Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1999,2001-2003 Silicon Graphics, Inc. All rights reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -69,23 +69,26 @@
 #include <asm/sn/bte.h>
 #include <asm/sn/clksupport.h>
 #include <asm/sn/sn_sal.h>
-
-#ifdef CONFIG_IA64_SGI_SN2
 #include <asm/sn/sn2/shub.h>
-#endif
 
 DEFINE_PER_CPU(struct pda_s, pda_percpu);
 
+#define pxm_to_nasid(pxm) ((pxm)<<1)
+
 extern void bte_init_node (nodepda_t *, cnodeid_t);
 extern void bte_init_cpu (void);
+extern void sn_timer_init (void);
+extern void (*ia64_mark_idle)(int);
+void snidle(int);
 
 unsigned long sn_rtc_cycles_per_second;   
-unsigned long sn_rtc_usec_per_cyc;
 
 partid_t sn_partid = -1;
 char sn_system_serial_number_string[128];
 u64 sn_partition_serial_number;
 
+short physical_node_map[MAX_PHYSNODE_ID];
+
 /*
  * This is the address of the RRegs in the HSpace of the global
  * master.  It is used by a hack in serial.c (serial_[in|out],
@@ -94,21 +97,14 @@
  * early_printk won't try to access the UART before
  * master_node_bedrock_address is properly calculated.
  */
-u64 master_node_bedrock_address = 0UL;
+u64 master_node_bedrock_address;
 
 static void sn_init_pdas(char **);
 
-extern struct irq_desc *_sn_irq_desc[];
-
-#if defined(CONFIG_IA64_SGI_SN1)
-extern synergy_da_t	*Synergy_da_indr[];
-#endif
 
 static nodepda_t	*nodepdaindr[MAX_COMPACT_NODES];
 
-#ifdef CONFIG_IA64_SGI_SN2
-irqpda_t		*irqpdaindr[NR_CPUS];
-#endif /* CONFIG_IA64_SGI_SN2 */
+irqpda_t		*irqpdaindr;
 
 
 /*
@@ -135,29 +131,19 @@
  * running in the simulator.  Note that passing zeroes in DRIVE_INFO
  * is sufficient (the IDE driver will autodetect the drive geometry).
  */
+#ifdef CONFIG_IA64_GENERIC
+extern char drive_info[4*16];
+#else
 char drive_info[4*16];
-
-/**
- * sn_map_nr - return the mem_map entry for a given kernel address
- * @addr: kernel address to query
- *
- * Finds the mem_map entry for the kernel address given.  Used by
- * virt_to_page() (asm-ia64/page.h), among other things.
- */
-unsigned long
-sn_map_nr (unsigned long addr)
-{
-	return BANK_MAP_NR(addr);
-}
+#endif
 
 /**
  * early_sn_setup - early setup routine for SN platforms
  *
  * Sets up an initial console to aid debugging.  Intended primarily
- * for bringup, it's only called if %BRINGUP and %CONFIG_IA64_EARLY_PRINTK
- * are turned on.  See start_kernel() in init/main.c.
+ * for bringup.  See start_kernel() in init/main.c.
  */
-#if defined(CONFIG_IA64_EARLY_PRINTK)
+#if defined(CONFIG_IA64_EARLY_PRINTK) || defined(CONFIG_IA64_SGI_SN_SIM)
 
 void __init
 early_sn_setup(void)
@@ -195,21 +181,48 @@
 	}
 
 	if ( IS_RUNNING_ON_SIMULATOR() ) {
-#if defined(CONFIG_IA64_SGI_SN1)
-		master_node_bedrock_address = (u64)REMOTE_HSPEC_ADDR(get_nasid(), 0);
-#else
 		master_node_bedrock_address = (u64)REMOTE_HUB(get_nasid(), SH_JUNK_BUS_UART0);
-#endif
 		printk(KERN_DEBUG "early_sn_setup: setting master_node_bedrock_address to 0x%lx\n", master_node_bedrock_address);
 	}
 }
-#endif /* CONFIG_IA64_SGI_SN1 */
+#endif /* CONFIG_IA64_EARLY_PRINTK */
 
 #ifdef CONFIG_IA64_MCA
 extern int platform_intr_list[];
 #endif
 
 extern nasid_t master_nasid;
+static int shub_1_1_found __initdata;
+
+
+/*
+ * sn_check_for_wars
+ *
+ * Set flag for enabling shub specific wars
+ */
+
+static inline int __init
+is_shub_1_1(int nasid)
+{
+	unsigned long id;
+	int	rev;
+
+	id = REMOTE_HUB_L(nasid, SH_SHUB_ID);
+	rev =  (id & SH_SHUB_ID_REVISION_MASK) >> SH_SHUB_ID_REVISION_SHFT;
+	return rev <= 2;
+}
+
+static void __init
+sn_check_for_wars(void)
+{
+	int	cnode;
+
+	for (cnode=0; cnode< numnodes; cnode++)
+		if (is_shub_1_1(cnodeid_to_nasid(cnode)))
+			shub_1_1_found = 1;
+}
+
+
 
 /**
  * sn_setup - SN platform setup routine
@@ -223,8 +236,18 @@
 sn_setup(char **cmdline_p)
 {
 	long status, ticks_per_sec, drift;
-	int i;
+	int pxm;
 	int major = sn_sal_rev_major(), minor = sn_sal_rev_minor();
+	extern void io_sh_swapper(int, int);
+	extern nasid_t get_master_baseio_nasid(void);
+	extern void sn_cpu_init(void);
+
+	MAX_DMA_ADDRESS = PAGE_OFFSET + MAX_PHYS_MEMORY;
+
+	memset(physical_node_map, -1, sizeof(physical_node_map));
+	for (pxm=0; pxm<MAX_PXM_DOMAINS; pxm++)
+		if (pxm_to_nid_map[pxm] != -1)
+			physical_node_map[pxm_to_nasid(pxm)] = pxm_to_nid_map[pxm];
 
 	printk("SGI SAL version %x.%02x\n", major, minor);
 
@@ -237,23 +260,13 @@
 		       "%x.%02x\n", SN_SAL_MIN_MAJOR, SN_SAL_MIN_MINOR);
 		panic("PROM version too old\n");
 	}
-#ifdef CONFIG_PCI
-#ifdef CONFIG_IA64_SGI_SN2
-	{
-		extern void io_sh_swapper(int, int);
-		io_sh_swapper(get_nasid(), 0);
-	}
-#endif
+
+	io_sh_swapper(get_nasid(), 0);
 
 	master_nasid = get_nasid();
 	(void)get_console_nasid();
-#ifndef CONFIG_IA64_SGI_SN1
-	{
-		extern nasid_t get_master_baseio_nasid(void);
-		(void)get_master_baseio_nasid();
-	}
-#endif
-#endif /* CONFIG_PCI */
+	(void)get_master_baseio_nasid();
+
 	status = ia64_sal_freq_base(SAL_FREQ_BASE_REALTIME_CLOCK, &ticks_per_sec, &drift);
 	if (status != 0 || ticks_per_sec < 100000) {
 		printk(KERN_WARNING "unable to determine platform RTC clock frequency, guessing.\n");
@@ -263,26 +276,12 @@
 	else
 		sn_rtc_cycles_per_second = ticks_per_sec;
 
-#ifdef CONFIG_IA64_SGI_SN1
-	/* PROM has wrong value on SN1 */
-	sn_rtc_cycles_per_second = 990177;
-#endif
-	sn_rtc_usec_per_cyc = ((1000000000UL<<IA64_NSEC_PER_CYC_SHIFT)
-			       + sn_rtc_cycles_per_second/2) / sn_rtc_cycles_per_second;
-		
-	for (i=0;i<NR_CPUS;i++)
-		_sn_irq_desc[i] = _irq_desc;
-
 	platform_intr_list[ACPI_INTERRUPT_CPEI] = IA64_PCE_VECTOR;
 
 
 	if ( IS_RUNNING_ON_SIMULATOR() )
 	{
-#ifdef CONFIG_IA64_SGI_SN2
 		master_node_bedrock_address = (u64)REMOTE_HUB(get_nasid(), SH_JUNK_BUS_UART0);
-#else
-		master_node_bedrock_address = (u64)REMOTE_HSPEC_ADDR(get_nasid(), 0);
-#endif
 		printk(KERN_DEBUG "sn_setup: setting master_node_bedrock_address to 0x%lx\n",
 		       master_node_bedrock_address);
 	}
@@ -292,6 +291,10 @@
 	 */
 	sn_init_pdas(cmdline_p);
 
+	/*
+	 * Check for WARs.
+	 */
+	sn_check_for_wars();
 
 	/* 
 	 * For the bootcpu, we do this here. All other cpus will make the
@@ -305,10 +308,9 @@
 #endif
 	screen_info = sn_screen_info;
 
-	/*
-	 * Turn off "floating-point assist fault" warnings by default.
-	 */
-	current->thread.flags |= IA64_THREAD_FPEMU_NOPRINT;
+	sn_timer_init();
+
+	ia64_mark_idle = &snidle;
 }
 
 /**
@@ -325,22 +327,19 @@
 	 * Make sure that the PDA fits entirely in the same page as the 
 	 * cpu_data area.
 	 */
-	if ( (((unsigned long)pda & ~PAGE_MASK) + sizeof(pda_t)) > PAGE_SIZE)
+	if ((((unsigned long)pda & (~PAGE_MASK)) + sizeof(pda_t)) > PAGE_SIZE)
 		panic("overflow of cpu_data page");
 
+	memset(pda->cnodeid_to_nasid_table, -1, sizeof(pda->cnodeid_to_nasid_table));
+	for (cnode=0; cnode<numnodes; cnode++)
+		pda->cnodeid_to_nasid_table[cnode] = pxm_to_nasid(nid_to_pxm_map[cnode]);
+
         /*
          * Allocate & initalize the nodepda for each node.
          */
         for (cnode=0; cnode < numnodes; cnode++) {
 		nodepdaindr[cnode] = alloc_bootmem_node(NODE_DATA(cnode), sizeof(nodepda_t));
 		memset(nodepdaindr[cnode], 0, sizeof(nodepda_t));
-
-#if defined(CONFIG_IA64_SGI_SN1)
-		Synergy_da_indr[cnode * 2] = (synergy_da_t *) alloc_bootmem_node(NODE_DATA(cnode), sizeof(synergy_da_t));
-		Synergy_da_indr[cnode * 2 + 1] = (synergy_da_t *) alloc_bootmem_node(NODE_DATA(cnode), sizeof(synergy_da_t));
-		memset(Synergy_da_indr[cnode * 2], 0, sizeof(synergy_da_t));
-		memset(Synergy_da_indr[cnode * 2 + 1], 0, sizeof(synergy_da_t));
-#endif
         }
 
 	/*
@@ -349,7 +348,7 @@
         for (cnode=0; cnode < numnodes; cnode++)
 		memcpy(nodepdaindr[cnode]->pernode_pdaindr, nodepdaindr, sizeof(nodepdaindr));
 
-#ifdef CONFIG_PCI
+
 	/*
 	 * Set up IO related platform-dependent nodepda fields.
 	 * The following routine actually sets up the hubinfo struct
@@ -359,7 +358,6 @@
 		init_platform_nodepda(nodepdaindr[cnode], cnode);
 		bte_init_node (nodepdaindr[cnode], cnode);
 	}
-#endif
 }
 
 /**
@@ -374,7 +372,11 @@
 void __init
 sn_cpu_init(void)
 {
-	int cpuid, cpuphyid, nasid, nodeid, slice;
+	int	cpuid;
+	int	cpuphyid;
+	int	nasid;
+	int	slice;
+	int	cnode, i;
 
 	/*
 	 * The boot cpu makes this call again after platform initialization is
@@ -386,14 +388,43 @@
 	cpuid = smp_processor_id();
 	cpuphyid = ((ia64_get_lid() >> 16) & 0xffff);
 	nasid = cpu_physical_id_to_nasid(cpuphyid);
-	nodeid = cpu_to_node_map[cpuphyid];
+	cnode = nasid_to_cnodeid(nasid);
 	slice = cpu_physical_id_to_slice(cpuphyid);
 
-	memset(pda, 0, sizeof(pda_t));
-	pda->p_nodepda = nodepdaindr[nodeid];
+	printk("CPU %d: nasid %d, slice %d, cnode %d\n",
+			smp_processor_id(), nasid, slice, cnode);
+
+	memset(pda, 0, sizeof(pda));
+	pda->p_nodepda = nodepdaindr[cnode];
+	pda->led_address = (typeof(pda->led_address)) (LED0 + (slice<<LED_CPU_SHIFT));
+	pda->led_state = LED_ALWAYS_SET;
 	pda->hb_count = HZ/2;
 	pda->hb_state = 0;
 	pda->idle_flag = 0;
+	pda->shub_1_1_found = shub_1_1_found;
+	
+	memset(pda->cnodeid_to_nasid_table, -1, sizeof(pda->cnodeid_to_nasid_table));
+	for (i=0; i<numnodes; i++)
+		pda->cnodeid_to_nasid_table[i] = pxm_to_nasid(nid_to_pxm_map[i]);
+
+	if (local_node_data->active_cpu_count == 1)
+		nodepda->node_first_cpu = cpuid;
+
+
+
+	/*
+	 * We must use different memory allocators for first cpu (bootmem 
+	 * allocator) than for the other cpus (regular allocator).
+	 */
+	if (cpuid == 0)
+		irqpdaindr = alloc_bootmem_node(NODE_DATA(cpuid_to_cnodeid(cpuid)),sizeof(irqpda_t));
+
+	memset(irqpdaindr, 0, sizeof(irqpda_t));
+	irqpdaindr->irq_flags[SGI_PCIBR_ERROR] = SN2_IRQ_SHARED;
+	irqpdaindr->irq_flags[SGI_PCIBR_ERROR] |= SN2_IRQ_RESERVED;
+	irqpdaindr->irq_flags[SGI_II_ERROR] = SN2_IRQ_SHARED;
+	irqpdaindr->irq_flags[SGI_II_ERROR] |= SN2_IRQ_RESERVED;
+
 	pda->pio_write_status_addr = (volatile unsigned long *)
 			LOCAL_MMR_ADDR((slice < 2 ? SH_PIO_WRITE_STATUS_0 : SH_PIO_WRITE_STATUS_1 ) );
 	pda->mem_write_status_addr = (volatile u64 *)
@@ -401,89 +432,25 @@
 
 	if (nodepda->node_first_cpu == cpuid) {
 		int	buddy_nasid;
-		buddy_nasid = cnodeid_to_nasid(local_nodeid == numnodes - 1 ? 0 : local_nodeid + 1);
+		buddy_nasid = cnodeid_to_nasid(numa_node_id() == numnodes-1 ? 0 : numa_node_id()+ 1);
 		pda->pio_shub_war_cam_addr = (volatile unsigned long*)GLOBAL_MMR_ADDR(nasid, SH_PI_CAM_CONTROL);
 	}
 
 	bte_init_cpu();
 }
 
-#ifdef II_PRTE_TLB_WAR
-long iiprt_lock[16*64] __cacheline_aligned; /* allow for NASIDs up to 64 */
-#endif
-
-#ifdef BUS_INT_WAR
-
-#include <asm/hw_irq.h>
-#include <asm/sn/pda.h>
-
-void ia64_handle_irq (ia64_vector vector, struct pt_regs *regs);
-
-static spinlock_t irq_lock = SPIN_LOCK_UNLOCKED;
-
-#define IRQCPU(irq)	((irq)>>8)
-
-void
-sn_add_polled_interrupt(int irq, int interval)
+void snidle(int idleness)
 {
-	unsigned long flags, irq_cnt;
-	sn_poll_entry_t	*irq_list;
-
-	irq_list = pdacpu(IRQCPU(irq)).pda_poll_entries;;
-
-	spin_lock_irqsave(&irq_lock, flags);
-	irq_cnt = pdacpu(IRQCPU(irq)).pda_poll_entry_count;
-	irq_list[irq_cnt].irq = irq;
-	irq_list[irq_cnt].interval = interval;
-	irq_list[irq_cnt].tick = interval;
-	pdacpu(IRQCPU(irq)).pda_poll_entry_count++;
-	spin_unlock_irqrestore(&irq_lock, flags);
-
-
-}
-
-void
-sn_delete_polled_interrupt(int irq)
-{
-	unsigned long flags, i, irq_cnt;
-	sn_poll_entry_t	*irq_list;
-
-	irq_list = pdacpu(IRQCPU(irq)).pda_poll_entries;
-
-	spin_lock_irqsave(&irq_lock, flags);
-	irq_cnt = pdacpu(IRQCPU(irq)).pda_poll_entry_count;
-	for (i=0; i<irq_cnt; i++) {
-		if (irq_list[i].irq == irq) {
-			irq_list[i] = irq_list[irq_cnt-1];
-			pdacpu(IRQCPU(irq)).pda_poll_entry_count--;
-			break;
+	if (!idleness) {
+		if (pda->idle_flag == 0) {
+			set_led_bits(0, LED_CPU_ACTIVITY);
 		}
-	}
-	spin_unlock_irqrestore(&irq_lock, flags);
-}
 
-void
-sn_irq_poll(int cpu, int reason) 
-{
-	unsigned long flags, i;
-	sn_poll_entry_t	*irq_list;
-
-
-	ia64_handle_irq(IA64_IPI_VECTOR, 0);
-
-	if (reason == 0)
-		return;
-
-	irq_list = pda->pda_poll_entries;
-
-	for (i=0; i<pda->pda_poll_entry_count; i++, irq_list++) {
-		if (--irq_list->tick <= 0) {
-			irq_list->tick = irq_list->interval;
-			local_irq_save(flags);
-			ia64_handle_irq(irq_to_vector(irq_list->irq), 0);
-			local_irq_restore(flags);
-		}
+		pda->idle_flag = 1;
 	}
-}	
+	else {
+		set_led_bits(LED_CPU_ACTIVITY, LED_CPU_ACTIVITY);
 
-#endif
+		pda->idle_flag = 0;
+	}
+}
diff -Nru a/arch/ia64/sn/kernel/sn1/Makefile b/arch/ia64/sn/kernel/sn1/Makefile
--- a/arch/ia64/sn/kernel/sn1/Makefile	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,45 +0,0 @@
-#
-# arch/ia64/sn/kernel/sn1/Makefile
-#
-# Copyright (C) 1999,2001-2002 Silicon Graphics, Inc. All rights reserved.
-#
-# This program is free software; you can redistribute it and/or modify it 
-# under the terms of version 2 of the GNU General Public License 
-# as published by the Free Software Foundation.
-# 
-# This program is distributed in the hope that it would be useful, but 
-# WITHOUT ANY WARRANTY; without even the implied warranty of 
-# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
-# 
-# Further, this software is distributed without any warranty that it is 
-# free of the rightful claim of any third person regarding infringement 
-# or the like.  Any license provided herein, whether implied or 
-# otherwise, applies only to this software file.  Patent licenses, if 
-# any, provided herein do not apply to combinations of this program with 
-# other software, or any other product whatsoever.
-# 
-# You should have received a copy of the GNU General Public 
-# License along with this program; if not, write the Free Software 
-# Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
-# 
-# Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
-# Mountain View, CA  94043, or:
-# 
-# http://www.sgi.com 
-# 
-# For further information regarding this notice, see: 
-# 
-# http://oss.sgi.com/projects/GenInfo/NoticeExplan
-#
-
-
-EXTRA_CFLAGS    := -DLITTLE_ENDIAN
-
-.S.s:
-	$(CPP) $(AFLAGS) $(AFLAGS_KERNEL) -o $*.s $<
-.S.o:
-	$(CC) $(AFLAGS) $(AFLAGS_KERNEL) -c -o $*.o $<
-
-O_TARGET        = sn1.o
-
-obj-y          = cache.o error.o iomv.o synergy.o sn1_smp.o
diff -Nru a/arch/ia64/sn/kernel/sn1/cache.c b/arch/ia64/sn/kernel/sn1/cache.c
--- a/arch/ia64/sn/kernel/sn1/cache.c	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,81 +0,0 @@
-/*
- * 
- * 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) 2001-2002 Silicon Graphics, Inc. All rights reserved.
- *
- */
-
-#include <linux/kernel.h>
-#include <asm/pgalloc.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn1/synergy.h>
-#include <asm/delay.h>
-
-#ifndef MB
-#define	MB	(1024*1024)
-#endif
-
-/*
- * Lock for protecting SYN_TAG_DISABLE_WAY.
- * Consider making this a per-FSB lock. 
- */
-static spinlock_t flush_lock = SPIN_LOCK_UNLOCKED;
-
-/**
- * sn_flush_all_caches - flush a range of addresses from all caches (incl. L4)
- * @flush_addr: identity mapped region 7 address to start flushing
- * @bytes: number of bytes to flush
- *
- * Flush a range of addresses from all caches including L4.  All addresses 
- * fully or partially contained within @flush_addr to @flush_addr + @bytes 
- * are flushed from the all caches.
- */
-void
-sn_flush_all_caches(long flush_addr, long bytes)
-{
-	ulong 	addr, baddr, eaddr, bitbucket;
-	int	way, alias;
-
-	/*
-	 * Because of the way synergy implements "fc", this flushes the
-	 * data from all caches on all cpus & L4's on OTHER FSBs. It also
-	 * flushes both cpus on the local FSB. It does NOT flush it from 
-	 * the local FSB.
-	 */
-	flush_icache_range(flush_addr, flush_addr+bytes);
-
-	/*
-	 * Memory DIMMs are a minimum of 256MB and start on 256MB
-	 * boundaries. Convert the start address to an address
-	 * that is between +0MB & +128 of the same DIMM. 
-	 * Then add 8MB to skip the uncached MinState areas if the address
-	 * is on the master node.
-	 */
-	if (bytes > SYNERGY_L4_BYTES_PER_WAY)
-		bytes = SYNERGY_L4_BYTES_PER_WAY;
-	baddr = TO_NODE(smp_physical_node_id(), PAGE_OFFSET + (flush_addr & (128*MB-1)) + 8*MB); 
-	eaddr = (baddr+bytes+SYNERGY_BLOCK_SIZE-1) & ~(SYNERGY_BLOCK_SIZE-1);
-	baddr = baddr & ~(SYNERGY_BLOCK_SIZE-1);
-
-	/*
-	 * Now flush the local synergy.
-	 */
-	spin_lock(&flush_lock);
-	for(way=0; way<SYNERGY_L4_WAYS; way++) {
-		WRITE_LOCAL_SYNERGY_REG(SYN_TAG_DISABLE_WAY, 0xffL ^ (1L<<way));
-		mb();
-		for(alias=0; alias < 9; alias++)
-			for(addr=baddr; addr<eaddr; addr+=SYNERGY_BLOCK_SIZE)
-				bitbucket = *(volatile ulong *)(addr+alias*8*MB);
-		mb();
-	}
-	WRITE_LOCAL_SYNERGY_REG(SYN_TAG_DISABLE_WAY, 0);
-	spin_unlock(&flush_lock);
-
-}
-
-
diff -Nru a/arch/ia64/sn/kernel/sn1/error.c b/arch/ia64/sn/kernel/sn1/error.c
--- a/arch/ia64/sn/kernel/sn1/error.c	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,187 +0,0 @@
-/*
- * SN1 Platform specific error Support
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-
-#include <asm/ptrace.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/smp.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn1/bedrock.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/addrs.h>
-
-/**
- * snia_error_intr_handler - handle SN specific error interrupts
- * @irq: error interrupt received
- * @devid: device causing the interrupt
- * @pt_regs: saved register state
- *
- * This routine is called when certain interrupts occur on SN systems.
- * It will either recover from the situations that caused the interrupt
- * or panic.
- */
-void
-snia_error_intr_handler(int irq, void *devid, struct pt_regs *pt_regs)
-{
-	unsigned long long intpend_val;
-	unsigned long long bit;
-
-	switch (irq) {
-	case SGI_UART_IRQ:
-		/*
-		 * This isn't really an error interrupt.  We're just
-		 * here because we have to do something with them.
-		 * This is probably wrong, and this code will be
-		 * removed.
-		 */
-		intpend_val = LOCAL_HUB_L(PI_INT_PEND0);
-		if ( (bit = ~(1L<<GFX_INTR_A)) ==
-			(intpend_val & ~(1L<<GFX_INTR_A)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<GFX_INTR_B)) ==
-			(intpend_val & ~(1L<<GFX_INTR_B)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<PG_MIG_INTR)) ==
-			(intpend_val & ~(1L<<PG_MIG_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<UART_INTR)) ==
-			(intpend_val & ~(1L<<UART_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<CC_PEND_A)) ==
-			(intpend_val & ~(1L<<CC_PEND_A)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		if ( (bit = ~(1L<<CC_PEND_B)) ==
-			(intpend_val & ~(1L<<CC_PEND_B)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			return;
-		}
-		printk("Received SGI_UART_IRQ (65), but no intpend0 bits were set???\n");
-		return;
-	case SGI_HUB_ERROR_IRQ:
-		/*
-		 * These are mostly error interrupts of various
-		 * sorts.  We need to do more than panic here, but
-		 * what the heck, this is bring up.
-		 */
-		intpend_val = LOCAL_HUB_L(PI_INT_PEND1);
-		
-		if ( (bit = ~(1L<<XB_ERROR)) ==
-			(intpend_val & ~(1L<<XB_ERROR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED XB_ERROR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<LB_ERROR)) ==
-			(intpend_val & ~(1L<<LB_ERROR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED LB_ERROR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<NACK_INT_A)) ==
-			(intpend_val & ~(1L<<NACK_INT_A)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED NACK_INT_A on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<NACK_INT_B)) ==
-			(intpend_val & ~(1L<<NACK_INT_B)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED NACK_INT_B on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<CLK_ERR_INTR)) ==
-			(intpend_val & ~(1L<<CLK_ERR_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED CLK_ERR_INTR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<COR_ERR_INTR_A)) ==
-			(intpend_val & ~(1L<<COR_ERR_INTR_A)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED COR_ERR_INTR_A on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<COR_ERR_INTR_B)) ==
-			(intpend_val & ~(1L<<COR_ERR_INTR_B)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED COR_ERR_INTR_B on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<MD_COR_ERR_INTR)) ==
-			(intpend_val & ~(1L<<MD_COR_ERR_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED MD_COR_ERR_INTR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<NI_ERROR_INTR)) ==
-			(intpend_val & ~(1L<<NI_ERROR_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED NI_ERROR_INTR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		if ( (bit = ~(1L<<MSC_PANIC_INTR)) ==
-			(intpend_val & ~(1L<<MSC_PANIC_INTR)) ) {
-			LOCAL_HUB_CLR_INTR(bit);
-			panic("RECEIVED MSC_PANIC_INTR on cpu %d, cnode %d\n",
-				smp_processor_id(), 
-				cpuid_to_cnodeid(smp_processor_id()));
-		}
-		printk("Received SGI_XB_ERROR_IRQ (182) but no intpend1 bits are set???\n");
-		return;
-	default:
-		printk("Received invalid irq in snia_error_intr_handler()\n");
-	}
-}
diff -Nru a/arch/ia64/sn/kernel/sn1/iomv.c b/arch/ia64/sn/kernel/sn1/iomv.c
--- a/arch/ia64/sn/kernel/sn1/iomv.c	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,65 +0,0 @@
-/* 
- * 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) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/pci.h>
-#include <asm/io.h>
-#include <asm/sn/simulator.h>
-#include <asm/delay.h>
-#include <asm/sn/pda.h>
-
-/**
- * sn_io_addr - convert an in/out port to an i/o address
- * @port: port to convert
- *
- * Legacy in/out instructions are converted to ld/st instructions
- * on IA64.  This routine will convert a port number into a valid 
- * SN i/o address.  Used by sn_in*() and sn_out*().
- */
-void *
-sn_io_addr(unsigned long port)
-{
-	if (!IS_RUNNING_ON_SIMULATOR()) {
-		return( (void *)  (port | __IA64_UNCACHED_OFFSET));
-	} else {
-		unsigned long io_base;
-		unsigned long addr;
- 
-		/*
- 		 * word align port, but need more than 10 bits
- 		 * for accessing registers in bedrock local block
- 		 * (so we don't do port&0xfff)
- 		 */
-		if ((port >= 0x1f0 && port <= 0x1f7) ||
-			port == 0x3f6 || port == 0x3f7) {
-			io_base = __IA64_UNCACHED_OFFSET | 0x00000FFFFC000000;
-			addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
-		} else {
-			addr = __ia64_get_io_port_base() | ((port >> 2) << 2);
-		}
-		return(void *) addr;
-	}
-}
-
-/**
- * sn1_mmiob - I/O space memory barrier
- *
- * Acts as a memory mapped I/O barrier for platforms that queue writes to 
- * I/O space.  This ensures that subsequent writes to I/O space arrive after
- * all previous writes.  For most ia64 platforms, this is a simple
- * 'mf.a' instruction.  For other platforms, mmiob() may have to read
- * a chipset register to ensure ordering.
- *
- * On SN1, we wait for the PIO_WRITE_STATUS Bedrock register to clear.
- */
-void
-sn1_mmiob (void)
-{
-	(volatile unsigned long) (*pda.bedrock_rev_id);
-	while (!(volatile unsigned long) (*pda.pio_write_status_addr))
-		udelay(5);
-}
diff -Nru a/arch/ia64/sn/kernel/sn1/sn1_smp.c b/arch/ia64/sn/kernel/sn1/sn1_smp.c
--- a/arch/ia64/sn/kernel/sn1/sn1_smp.c	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,476 +0,0 @@
-/*
- * SN1 Platform specific SMP Support
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/config.h>
-#include <linux/init.h>
-#include <linux/kernel.h>
-#include <linux/spinlock.h>
-#include <linux/threads.h>
-#include <linux/sched.h>
-#include <linux/smp.h>
-#include <linux/interrupt.h>
-#include <linux/irq.h>
-#include <linux/mmzone.h>
-
-#include <asm/processor.h>
-#include <asm/irq.h>
-#include <asm/sal.h>
-#include <asm/system.h>
-#include <asm/io.h>
-#include <asm/smp.h>
-#include <asm/hw_irq.h>
-#include <asm/current.h>
-#include <asm/delay.h>
-#include <asm/sn/sn_cpuid.h>
-
-/*
- * The following structure is used to pass params thru smp_call_function
- * to other cpus for flushing TLB ranges.
- */
-typedef struct {
-	union {
-		struct {
-			unsigned long	start;
-			unsigned long	end;
-			unsigned long	nbits;
-			unsigned int	rid;
-			atomic_t	unfinished_count;
-		} ptc;
-		char pad[SMP_CACHE_BYTES];
-	};
-} ptc_params_t;
-
-#define NUMPTC	512
-
-static ptc_params_t	ptcParamArray[NUMPTC] __attribute__((__aligned__(128)));
-
-/* use separate cache lines on ptcParamsNextByCpu to avoid false sharing */
-static ptc_params_t	*ptcParamsNextByCpu[NR_CPUS*16] __attribute__((__aligned__(128)));
-static volatile ptc_params_t	*ptcParamsEmpty __cacheline_aligned;
-
-/*REFERENCED*/
-static spinlock_t ptcParamsLock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
-
-static int ptcInit = 0;
-#ifdef PTCDEBUG
-static int ptcParamsAllBusy = 0;		/* debugging/statistics */
-static int ptcCountBacklog = 0;
-static int ptcBacklog[NUMPTC+1];
-static char ptcParamsCounts[NR_CPUS][NUMPTC] __attribute__((__aligned__(128)));
-static char ptcParamsResults[NR_CPUS][NUMPTC] __attribute__((__aligned__(128)));
-#endif
-
-/*
- * Make smp_send_flush_tlbsmp_send_flush_tlb() a weak reference,
- * so that we get a clean compile with the ia64 patch without the
- * actual SN1 specific code in arch/ia64/kernel/smp.c.
- */
-extern void smp_send_flush_tlb (void) __attribute((weak));
-
-/*
- * The following table/struct is for remembering PTC coherency domains. It
- * is also used to translate sapicid into cpuids. We don't want to start 
- * cpus unless we know their cache domain.
- */
-#ifdef PTC_NOTYET
-sn_sapicid_info_t	sn_sapicid_info[NR_CPUS];
-#endif
-
-/**
- * sn1_ptc_l_range - purge local translation cache
- * @start: start of virtual address range
- * @end: end of virtual address range
- * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
- *
- * Purges the range specified from the local processor's translation cache
- * (as opposed to the translation registers).  Note that more than the specified
- * range *may* be cleared from the cache by some processors.
- *
- * This is probably not good enough, but I don't want to try to make it better 
- * until I get some statistics on a running system. At a minimum, we should only 
- * send IPIs to 1 processor in each TLB domain & have it issue a ptc.g on it's 
- * own FSB. Also, we only have to serialize per FSB, not globally.
- *
- * More likely, we will have to do some work to reduce the frequency of calls to
- * this routine.
- */
-static inline void
-sn1_ptc_l_range(unsigned long start, unsigned long end, unsigned long nbits)
-{
-	do {
-		__asm__ __volatile__ ("ptc.l %0,%1" :: "r"(start), "r"(nbits<<2) : "memory");
-		start += (1UL << nbits);
-	} while (start < end);
-	ia64_srlz_d();
-}
-
-/**
- * sn1_received_flush_tlb - cpu tlb flush routine
- *
- * Flushes the TLB of a given processor.
- */
-void
-sn1_received_flush_tlb(void)
-{
-	unsigned long	start, end, nbits;
-	unsigned int	rid, saved_rid;
-	int		cpu = smp_processor_id();
-	int		result;
-	ptc_params_t	*ptcParams;
-
-	ptcParams = ptcParamsNextByCpu[cpu*16];
-	if (ptcParams == ptcParamsEmpty)
-		return;
-
-	do {
-		start = ptcParams->ptc.start;
-		saved_rid = (unsigned int) ia64_get_rr(start);
-		end = ptcParams->ptc.end;
-		nbits = ptcParams->ptc.nbits;
-		rid = ptcParams->ptc.rid;
-
-		if (saved_rid != rid) {
-			ia64_set_rr(start, (unsigned long)rid);
-			ia64_srlz_d();
-		}
-
-		sn1_ptc_l_range(start, end, nbits);
-
-		if (saved_rid != rid) 
-			ia64_set_rr(start, (unsigned long)saved_rid);
-
-		ia64_srlz_i();
-
-		result = atomic_dec(&ptcParams->ptc.unfinished_count);
-#ifdef PTCDEBUG
-		{
-		    int i = ptcParams-&ptcParamArray[0];
-		    ptcParamsResults[cpu][i] = (char) result;
-		    ptcParamsCounts[cpu][i]++;
-		}
-#endif /* PTCDEBUG */
-
-		if (++ptcParams == &ptcParamArray[NUMPTC])
-			ptcParams = &ptcParamArray[0];
-
-	} while (ptcParams != ptcParamsEmpty);
-
-	ptcParamsNextByCpu[cpu*16] = ptcParams;
-}
-
-/**
- * sn1_global_tlb_purge - flush a translation cache range on all processors
- * @start: start of virtual address range to flush
- * @end: end of virtual address range
- * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
- *
- * Flushes the translation cache of all processors from @start to @end.
- */
-void
-sn1_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
-{
-	ptc_params_t	*params;
-	ptc_params_t	*next;
-	unsigned long	irqflags;
-#ifdef PTCDEBUG
-	ptc_params_t	*nextnext;
-	int		backlog = 0;
-#endif
-
-	if (smp_num_cpus == 1) {
-		sn1_ptc_l_range(start, end, nbits);
-		return;
-	}
-
-	if (in_interrupt()) {
-		/*
-		 *  If at interrupt level and cannot get spinlock, 
-		 *  then do something useful by flushing own tlbflush queue
-		 *  so as to avoid a possible deadlock.
-		 */
-		while (!spin_trylock(&ptcParamsLock)) {
-			local_irq_save(irqflags);
-			sn1_received_flush_tlb();
-			local_irq_restore(irqflags);
-			udelay(10);	/* take it easier on the bus */	
-		}
-	} else {
-		spin_lock(&ptcParamsLock);
-	}
-
-	if (!ptcInit) {
-		int cpu;
-		ptcInit = 1;
-		memset(ptcParamArray, 0, sizeof(ptcParamArray));
-		ptcParamsEmpty = &ptcParamArray[0];
-		for (cpu=0; cpu<NR_CPUS; cpu++)
-			ptcParamsNextByCpu[cpu*16] = &ptcParamArray[0];
-
-#ifdef PTCDEBUG
-		memset(ptcBacklog, 0, sizeof(ptcBacklog));
-		memset(ptcParamsCounts, 0, sizeof(ptcParamsCounts));
-		memset(ptcParamsResults, 0, sizeof(ptcParamsResults));
-#endif	/* PTCDEBUG */
-	}
-
-	params = (ptc_params_t *) ptcParamsEmpty;
-	next = (ptc_params_t *) ptcParamsEmpty + 1;
-	if (next == &ptcParamArray[NUMPTC])
-		next = &ptcParamArray[0];
-
-#ifdef PTCDEBUG
-	nextnext = next + 1;
-	if (nextnext == &ptcParamArray[NUMPTC])
-		nextnext = &ptcParamArray[0];
-
-	if (ptcCountBacklog) {
-		/* quick count of backlog */
-		ptc_params_t *ptr;
-
-		/* check the current pointer to the beginning */
-		ptr = params;
-		while(--ptr >= &ptcParamArray[0]) {
-			if (atomic_read(&ptr->ptc.unfinished_count) == 0)
-				break;
-			++backlog;
-		}
-
-		if (backlog) {
-			/* check the end of the array */
-			ptr = &ptcParamArray[NUMPTC];
-			while (--ptr > params) {
-				if (atomic_read(&ptr->ptc.unfinished_count) == 0)
-					break;
-				++backlog;
-			}
-		}
-		ptcBacklog[backlog]++;
-	}
-#endif	/* PTCDEBUG */
-
-	/* wait for the next entry to clear...should be rare */
-	if (atomic_read(&next->ptc.unfinished_count) > 0) {
-#ifdef PTCDEBUG
-		ptcParamsAllBusy++;
-
-		if (atomic_read(&nextnext->ptc.unfinished_count) == 0) {
-		    if (atomic_read(&next->ptc.unfinished_count) > 0) {
-			panic("\nnonzero next zero nextnext %lx %lx\n",
-			    (long)next, (long)nextnext);
-		    }
-		}
-#endif
-
-		/* it could be this cpu that is behind */
-		local_irq_save(irqflags);
-		sn1_received_flush_tlb();
-		local_irq_restore(irqflags);
-
-		/* now we know it's not this cpu, so just wait */
-		while (atomic_read(&next->ptc.unfinished_count) > 0) {
-			barrier();
-		}
-	}
-
-	params->ptc.start = start;
-	params->ptc.end = end;
-	params->ptc.nbits = nbits;
-	params->ptc.rid = (unsigned int) ia64_get_rr(start);
-	atomic_set(&params->ptc.unfinished_count, smp_num_cpus);
-
-	/* The atomic_set above can hit memory *after* the update
-	 * to ptcParamsEmpty below, which opens a timing window
-	 * that other cpus can squeeze into!
-	 */
-	mb();
-
-	/* everything is ready to process:
-	 *	-- global lock is held
-	 *	-- new entry + 1 is free
-	 *	-- new entry is set up
-	 * so now:
-	 *	-- update the global next pointer
-	 *	-- unlock the global lock
-	 *	-- send IPI to notify other cpus
-	 *	-- process the data ourselves
-	 */
-	ptcParamsEmpty = next;
-	spin_unlock(&ptcParamsLock);
-	smp_send_flush_tlb();
-
-	local_irq_save(irqflags);
-	sn1_received_flush_tlb();
-	local_irq_restore(irqflags);
-
-	/* Currently we don't think global TLB purges need to be atomic.
-	 * All CPUs get sent IPIs, so if they haven't done the purge,
-	 * they're busy with interrupts that are at the IPI level, which is
-	 * priority 15.  We're asserting that any code at that level
-	 * shouldn't be using user TLB entries.  To change this to wait
-	 * for all the flushes to complete, enable the following code.
-	 */
-#if defined(SN1_SYNCHRONOUS_GLOBAL_TLB_PURGE) || defined(BUS_INT_WAR)
-	/* this code is not tested */
-	/* wait for the flush to complete */
-	while (atomic_read(&params->ptc.unfinished_count) > 0)
-		barrier();
-#endif
-}
-
-/**
- * sn_send_IPI_phys - send an IPI to a Nasid and slice
- * @physid: physical cpuid to receive the interrupt.
- * @vector: command to send
- * @delivery_mode: delivery mechanism
- *
- * Sends an IPI (interprocessor interrupt) to the processor specified by
- * @physid
- *
- * @delivery_mode can be one of the following
- *
- * %IA64_IPI_DM_INT - pend an interrupt
- * %IA64_IPI_DM_PMI - pend a PMI
- * %IA64_IPI_DM_NMI - pend an NMI
- * %IA64_IPI_DM_INIT - pend an INIT interrupt
- */
-void
-sn_send_IPI_phys(long physid, int vector, int delivery_mode)
-{
-	long		*p;
-	long		nasid, slice;
-
-	static int 	off[4] = {0x1800080, 0x1800088, 0x1a00080, 0x1a00088};
-
-#ifdef BUS_INT_WAR
-	if (vector != ap_wakeup_vector) {
-		return;
-	}
-#endif
-
-	nasid = cpu_physical_id_to_nasid(physid);
-        slice = cpu_physical_id_to_slice(physid);
-
-	p = (long*)(0xc0000a0000000000LL | (nasid<<33) | off[slice]);
-
-	mb();
-	*p = (delivery_mode << 8) | (vector & 0xff);
-}
-
-
-/**
- * sn1_send_IPI - send an IPI to a processor
- * @cpuid: target of the IPI
- * @vector: command to send
- * @delivery_mode: delivery mechanism
- * @redirect: redirect the IPI?
- *
- * Sends an IPI (interprocessor interrupt) to the processor specified by
- * @cpuid.  @delivery_mode can be one of the following
- *
- * %IA64_IPI_DM_INT - pend an interrupt
- * %IA64_IPI_DM_PMI - pend a PMI
- * %IA64_IPI_DM_NMI - pend an NMI
- * %IA64_IPI_DM_INIT - pend an INIT interrupt
- */
-void
-sn1_send_IPI(int cpuid, int vector, int delivery_mode, int redirect)
-{
-	long		physid;
-
-	physid = cpu_physical_id(cpuid);
-
-	sn_send_IPI_phys(physid, vector, delivery_mode);
-}
-#ifdef CONFIG_SMP
-
-#ifdef PTC_NOTYET
-static void __init
-process_sal_ptc_domain_info(ia64_sal_ptc_domain_info_t *di, int domain)
-{
-	ia64_sal_ptc_domain_proc_entry_t	*pe;
-	int 					i, sapicid, cpuid;
-
-	pe = __va(di->proc_list);
-	for (i=0; i<di->proc_count; i++, pe++) {
-		sapicid = id_eid_to_sapicid(pe->id, pe->eid);
-		cpuid = cpu_logical_id(sapicid);
-		sn_sapicid_info[cpuid].domain = domain;
-		sn_sapicid_info[cpuid].sapicid = sapicid;
-	}
-}
-
-
-static void __init
-process_sal_desc_ptc(ia64_sal_desc_ptc_t *ptc)
-{
-	ia64_sal_ptc_domain_info_t	*di;
-	int i;
-
-	di = __va(ptc->domain_info);
-	for (i=0; i<ptc->num_domains; i++, di++) {
-		process_sal_ptc_domain_info(di, i);	
-	}
-}
-#endif /* PTC_NOTYET */
-
-/**
- * init_sn1_smp_config - setup PTC domains per processor
- */
-void __init
-init_sn1_smp_config(void)
-{
-	if (!ia64_ptc_domain_info)  {
-		printk("SMP: Can't find PTC domain info. Forcing UP mode\n");
-		smp_num_cpus = 1;
-		return;
-	}
-
-#ifdef PTC_NOTYET
-	memset (sn_sapicid_info, -1, sizeof(sn_sapicid_info));
-	process_sal_desc_ptc(ia64_ptc_domain_info);
-#endif
-}
-
-#else /* CONFIG_SMP */
-
-void __init
-init_sn1_smp_config(void)
-{
-
-#ifdef PTC_NOTYET
-	sn_sapicid_info[0].sapicid = hard_smp_processor_id();
-#endif
-}
-
-#endif /* CONFIG_SMP */
diff -Nru a/arch/ia64/sn/kernel/sn1/synergy.c b/arch/ia64/sn/kernel/sn1/synergy.c
--- a/arch/ia64/sn/kernel/sn1/synergy.c	Wed Jun 18 23:42:09 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,533 +0,0 @@
-/*
- * SN1 Platform specific synergy Support
- *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/kernel.h>
-#include <linux/sched.h>
-#include <linux/mm.h>
-#include <linux/spinlock.h>
-#include <linux/proc_fs.h>
-
-#include <asm/ptrace.h>
-#include <linux/devfs_fs_kernel.h>
-#include <asm/smp.h>
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn1/bedrock.h>
-#include <asm/sn/intr.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/nodepda.h>
-#include <asm/sn/sn1/synergy.h>
-#include <asm/sn/sndrv.h>
-
-int bit_pos_to_irq(int bit);
-void setclear_mask_b(int irq, int cpuid, int set);
-void setclear_mask_a(int irq, int cpuid, int set);
-void * kmalloc(size_t size, int flags);
-
-static int synergy_perf_initialized = 0;
-
-void
-synergy_intr_alloc(int bit, int cpuid) {
-	return;
-}
-
-int
-synergy_intr_connect(int bit, 
-		int cpuid)
-{
-	int irq;
-	unsigned is_b;
-
-	irq = bit_pos_to_irq(bit);
-
-	is_b = (cpuid_to_slice(cpuid)) & 1;
-	if (is_b) {
-		setclear_mask_b(irq,cpuid,1);
-		setclear_mask_a(irq,cpuid, 0);
-	} else {
-		setclear_mask_a(irq, cpuid, 1);
-		setclear_mask_b(irq, cpuid, 0);
-	}
-	return 0;
-}
-void
-setclear_mask_a(int irq, int cpuid, int set)
-{
-	int synergy;
-	int nasid;
-	int reg_num;
-	unsigned long mask;
-	unsigned long addr;
-	unsigned long reg;
-	unsigned long val;
-	int my_cnode, my_synergy;
-	int target_cnode, target_synergy;
-
-        /*
-         * Perform some idiot checks ..
-         */
-        if ( (irq < 0) || (irq > 255) ||
-                (cpuid < 0) || (cpuid > 512) ) {
-                printk("clear_mask_a: Invalid parameter irq %d cpuid %d\n", irq, cpuid);
-		return;
-	}
-
-	target_cnode = cpuid_to_cnodeid(cpuid);
-	target_synergy = cpuid_to_synergy(cpuid);
-	my_cnode = cpuid_to_cnodeid(smp_processor_id());
-	my_synergy = cpuid_to_synergy(smp_processor_id());
-
-	reg_num = irq / 64;
-	mask = 1;
-	mask <<= (irq % 64);
-	switch (reg_num) {
-		case 0: 
-			reg = VEC_MASK0A;
-			addr = VEC_MASK0A_ADDR;
-			break;
-		case 1: 
-			reg = VEC_MASK1A;
-			addr = VEC_MASK1A_ADDR;
-			break;
-		case 2: 
-			reg = VEC_MASK2A;
-			addr = VEC_MASK2A_ADDR;
-			break;
-		case 3: 
-			reg = VEC_MASK3A;
-			addr = VEC_MASK3A_ADDR;
-			break;
-		default:
-			reg = addr = 0;
-			break;
-	}
-	if (my_cnode == target_cnode && my_synergy == target_synergy) {
-		// local synergy
-		val = READ_LOCAL_SYNERGY_REG(addr);
-		if (set) {
-			val |= mask;
-		} else {
-			val &= ~mask;
-		}
-		WRITE_LOCAL_SYNERGY_REG(addr, val);
-		val = READ_LOCAL_SYNERGY_REG(addr);
-	} else { /* remote synergy */
-		synergy = cpuid_to_synergy(cpuid);
-		nasid = cpuid_to_nasid(cpuid);
-		val = REMOTE_SYNERGY_LOAD(nasid, synergy, reg);
-		if (set) {
-			val |= mask;
-		} else {
-			val &= ~mask;
-		}
-		REMOTE_SYNERGY_STORE(nasid, synergy, reg, val);
-	}
-}
-
-void
-setclear_mask_b(int irq, int cpuid, int set)
-{
-	int synergy;
-	int nasid;
-	int reg_num;
-	unsigned long mask;
-	unsigned long addr;
-	unsigned long reg;
-	unsigned long val;
-	int my_cnode, my_synergy;
-	int target_cnode, target_synergy;
-
-	/*
-	 * Perform some idiot checks ..
-	 */
-	if ( (irq < 0) || (irq > 255) ||
-		(cpuid < 0) || (cpuid > 512) ) {
-		printk("clear_mask_b: Invalid parameter irq %d cpuid %d\n", irq, cpuid);
-		return;
-	}
-
-	target_cnode = cpuid_to_cnodeid(cpuid);
-	target_synergy = cpuid_to_synergy(cpuid);
-	my_cnode = cpuid_to_cnodeid(smp_processor_id());
-	my_synergy = cpuid_to_synergy(smp_processor_id());
-
-	reg_num = irq / 64;
-	mask = 1;
-	mask <<= (irq % 64);
-	switch (reg_num) {
-		case 0: 
-			reg = VEC_MASK0B;
-			addr = VEC_MASK0B_ADDR;
-			break;
-		case 1: 
-			reg = VEC_MASK1B;
-			addr = VEC_MASK1B_ADDR;
-			break;
-		case 2: 
-			reg = VEC_MASK2B;
-			addr = VEC_MASK2B_ADDR;
-			break;
-		case 3: 
-			reg = VEC_MASK3B;
-			addr = VEC_MASK3B_ADDR;
-			break;
-		default:
-			reg = addr = 0;
-			break;
-	}
-	if (my_cnode == target_cnode && my_synergy == target_synergy) {
-		// local synergy
-		val = READ_LOCAL_SYNERGY_REG(addr);
-		if (set) {
-			val |= mask;
-		} else {
-			val &= ~mask;
-		}
-		WRITE_LOCAL_SYNERGY_REG(addr, val);
-		val = READ_LOCAL_SYNERGY_REG(addr);
-	} else { /* remote synergy */
-		synergy = cpuid_to_synergy(cpuid);
-		nasid = cpuid_to_nasid(cpuid);
-		val = REMOTE_SYNERGY_LOAD(nasid, synergy, reg);
-		if (set) {
-			val |= mask;
-		} else {
-			val &= ~mask;
-		}
-		REMOTE_SYNERGY_STORE(nasid, synergy, reg, val);
-	}
-}
-
-/*
- * Synergy perf stats. Multiplexed via timer_interrupt.
- */
-
-static int
-synergy_perf_append(uint64_t modesel)
-{
-	int		cnode;
-	nodepda_t       *npdap;
-	synergy_perf_t	*p;
-	int		checked = 0;
-	int		err = 0;
-	unsigned long	flags;
-
-	/* bit 45 is enable */
-	modesel |= (1UL << 45);
-
-	for (cnode=0; cnode < numnodes; cnode++) {
-		/* for each node, insert a new synergy_perf entry */
-		if ((npdap = NODEPDA(cnode)) == NULL) {
-			printk("synergy_perf_append: cnode=%d NODEPDA(cnode)==NULL, nodepda=%p\n", cnode, (void *)nodepda);
-			continue;
-		}
-
-		if (npdap->synergy_perf_enabled) {
-			/* user must disable counting to append new events */
-			err = -EBUSY;
-			break;
-		}
-
-		if (!checked && npdap->synergy_perf_data != NULL) {
-			checked = 1;
-			for (p = npdap->synergy_perf_first; ;) {
-				if (p->modesel == modesel)
-					return 0; /* event already registered */
-				if ((p = p->next) == npdap->synergy_perf_first)
-					break;
-			}
-		}
-
-		/* XX use kmem_alloc_node() when it is implemented */
-		p = (synergy_perf_t *)kmalloc(sizeof(synergy_perf_t), GFP_KERNEL);
-		if ((((uint64_t)p) & 7UL) != 0)
-			BUG(); /* bad alignment */
-		if (p == NULL) {
-			err = -ENOMEM;
-			break;
-		}
-		else {
-			memset(p, 0, sizeof(synergy_perf_t));
-			p->modesel = modesel;
-
-			spin_lock_irqsave(&npdap->synergy_perf_lock, flags);
-			if (npdap->synergy_perf_data == NULL) {
-				/* circular list */
-				p->next = p;
-				npdap->synergy_perf_first = p;
-				npdap->synergy_perf_data = p;
-			}
-			else {
-				p->next = npdap->synergy_perf_data->next;
-				npdap->synergy_perf_data->next = p;
-			}
-			spin_unlock_irqrestore(&npdap->synergy_perf_lock, flags);
-		}
-	}
-
-	return err;
-}
-
-static void
-synergy_perf_set_freq(int freq)
-{
-	int		cnode;
-	nodepda_t	*npdap;
-
-	for (cnode=0; cnode < numnodes; cnode++) {
-		if ((npdap = NODEPDA(cnode)) != NULL)
-			npdap->synergy_perf_freq = freq;
-	}
-}
-
-static void
-synergy_perf_set_enable(int enable)
-{
-	int		cnode;
-	nodepda_t	*npdap;
-
-	for (cnode=0; cnode < numnodes; cnode++) {
-		if ((npdap = NODEPDA(cnode)) != NULL)
-			npdap->synergy_perf_enabled = enable;
-	}
-	printk("NOTICE: synergy perf counting %sabled on all nodes\n", enable ? "en" : "dis");
-}
-
-static int
-synergy_perf_size(nodepda_t *npdap)
-{
-	synergy_perf_t	*p;
-	int		n;
-
-	if (npdap->synergy_perf_enabled == 0) {
-		/* no stats to return */
-		return 0;
-	}
-
-	spin_lock_irq(&npdap->synergy_perf_lock);
-	for (n=0, p = npdap->synergy_perf_first; p;) {
-		n++;
-		p = p->next;
-		if (p == npdap->synergy_perf_first)
-			break;
-	}
-	spin_unlock_irq(&npdap->synergy_perf_lock);
-
-	/* bytes == n pairs of {event,counter} */
-	return n * 2 * sizeof(uint64_t);
-}
-
-static int
-synergy_perf_ioctl(struct inode *inode, struct file *file,
-        unsigned int cmd, unsigned long arg)
-{
-	int             cnode;
-	nodepda_t       *npdap;
-	synergy_perf_t	*p;
-	int		intarg;
-	int		fsb;
-	uint64_t	longarg;
-	uint64_t	*stats;
-	int		n;
-	devfs_handle_t	d;
-	arbitrary_info_t info;
-	
-	if ((d = devfs_get_handle_from_inode(inode)) == NULL)
-		return -ENODEV;
-	info = hwgraph_fastinfo_get(d);
-
-	cnode = SYNERGY_PERF_INFO_CNODE(info);
-	fsb = SYNERGY_PERF_INFO_FSB(info);
-	npdap = NODEPDA(cnode);
-
-	switch (cmd) {
-	case SNDRV_GET_SYNERGY_VERSION:
-		/* return int, version of data structure for SNDRV_GET_SYNERGYINFO */
-		intarg = 1; /* version 1 */
-		if (copy_to_user((void *)arg, &intarg, sizeof(intarg)))
-		    return -EFAULT;
-		break;
-
-	case SNDRV_GET_INFOSIZE:
-		/* return int, sizeof buf needed for SYNERGY_PERF_GET_STATS */
-		intarg = synergy_perf_size(npdap);
-		if (copy_to_user((void *)arg, &intarg, sizeof(intarg)))
-		    return -EFAULT;
-		break;
-
-	case SNDRV_GET_SYNERGYINFO:
-		/* return array of event/value pairs, this node only */
-		if ((intarg = synergy_perf_size(npdap)) <= 0)
-			return -ENODATA;
-		if ((stats = (uint64_t *)kmalloc(intarg, GFP_KERNEL)) == NULL)
-			return -ENOMEM;
-		spin_lock_irq(&npdap->synergy_perf_lock);
-		for (n=0, p = npdap->synergy_perf_first; p;) {
-			stats[n++] = p->modesel;
-			if (p->intervals > 0)
-			    stats[n++] = p->counts[fsb] * p->total_intervals / p->intervals;
-			else
-			    stats[n++] = 0;
-			p = p->next;
-			if (p == npdap->synergy_perf_first)
-				break;
-		}
-		spin_unlock_irq(&npdap->synergy_perf_lock);
-
-		if (copy_to_user((void *)arg, stats, intarg)) {
-		    kfree(stats);
-		    return -EFAULT;
-		}
-
-		kfree(stats);
-		break;
-
-	case SNDRV_SYNERGY_APPEND:
-		/* reads 64bit event, append synergy perf event to all nodes  */
-		if (copy_from_user(&longarg, (void *)arg, sizeof(longarg)))
-		    return -EFAULT;
-		return synergy_perf_append(longarg);
-		break;
-
-	case SNDRV_GET_SYNERGY_STATUS:
-		/* return int, 1 if enabled else 0 */
-		intarg = npdap->synergy_perf_enabled;
-		if (copy_to_user((void *)arg, &intarg, sizeof(intarg)))
-		    return -EFAULT;
-		break;
-
-	case SNDRV_SYNERGY_ENABLE:
-		/* read int, if true enable counting else disable */
-		if (copy_from_user(&intarg, (void *)arg, sizeof(intarg)))
-		    return -EFAULT;
-		synergy_perf_set_enable(intarg);
-		break;
-
-	case SNDRV_SYNERGY_FREQ:
-		/* read int, set jiffies per update */ 
-		if (copy_from_user(&intarg, (void *)arg, sizeof(intarg)))
-		    return -EFAULT;
-		if (intarg < 0 || intarg >= HZ)
-			return -EINVAL;
-		synergy_perf_set_freq(intarg);
-		break;
-
-	default:
-		printk("Warning: invalid ioctl %d on synergy mon for cnode=%d fsb=%d\n", cmd, cnode, fsb);
-		return -EINVAL;
-	}
-	return(0);
-}
-
-struct file_operations synergy_mon_fops = {
-        .ioctl		= synergy_perf_ioctl,
-};
-
-void
-synergy_perf_update(int cpu)
-{
-	nasid_t		nasid;
-	cnodeid_t       cnode;
-	struct nodepda_s *npdap;
-
-	/*
-	 * synergy_perf_initialized is set by synergy_perf_init()
-	 * which is called last thing by sn_mp_setup(), i.e. well
-	 * after nodepda has been initialized.
-	 */
-	if (!synergy_perf_initialized)
-		return;
-
-	cnode = cpuid_to_cnodeid(cpu);
-	npdap = NODEPDA(cnode);
-
-	if (npdap == NULL || cnode < 0 || cnode >= numnodes)
-		/* this should not happen: still in early io init */
-		return;
-
-#if 0
-	/* use this to check nodepda initialization */
-	if (((uint64_t)npdap) & 0x7) {
-		printk("\nERROR on cpu %d : cnode=%d, npdap == %p, not aligned\n", cpu, cnode, npdap);
-		BUG();
-	}
-#endif
-
-	if (npdap->synergy_perf_enabled == 0 || npdap->synergy_perf_data == NULL) {
-		/* Not enabled, or no events to monitor */
-		return;
-	}
-
-	if (npdap->synergy_inactive_intervals++ % npdap->synergy_perf_freq != 0) {
-		/* don't multiplex on every timer interrupt */
-		return;
-	}
-
-	/*
-	 * Read registers for last interval and increment counters.
-	 * Hold the per-node synergy_perf_lock so concurrent readers get
-	 * consistent values.
-	 */
-	spin_lock_irq(&npdap->synergy_perf_lock);
-
-	nasid = cpuid_to_nasid(cpu);
-	npdap->synergy_active_intervals++;
-	npdap->synergy_perf_data->intervals++;
-	npdap->synergy_perf_data->total_intervals = npdap->synergy_active_intervals;
-
-	npdap->synergy_perf_data->counts[0] += 0xffffffffffUL &
-		REMOTE_SYNERGY_LOAD(nasid, 0, PERF_CNTR0_A);
-
-	npdap->synergy_perf_data->counts[1] += 0xffffffffffUL &
-		REMOTE_SYNERGY_LOAD(nasid, 1, PERF_CNTR0_B);
-
-	/* skip to next in circular list */
-	npdap->synergy_perf_data = npdap->synergy_perf_data->next;
-
-	spin_unlock_irq(&npdap->synergy_perf_lock);
-
-	/* set the counter 0 selection modes for both A and B */
-	REMOTE_SYNERGY_STORE(nasid, 0, PERF_CNTL0_A, npdap->synergy_perf_data->modesel);
-	REMOTE_SYNERGY_STORE(nasid, 1, PERF_CNTL0_B, npdap->synergy_perf_data->modesel);
-
-	/* and reset the counter registers to zero */
-	REMOTE_SYNERGY_STORE(nasid, 0, PERF_CNTR0_A, 0UL);
-	REMOTE_SYNERGY_STORE(nasid, 1, PERF_CNTR0_B, 0UL);
-}
-
-void
-synergy_perf_init(void)
-{
-	printk("synergy_perf_init(), counting is initially disabled\n");
-	synergy_perf_initialized++;
-}
diff -Nru a/arch/ia64/sn/kernel/sn2/Makefile b/arch/ia64/sn/kernel/sn2/Makefile
--- a/arch/ia64/sn/kernel/sn2/Makefile	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/sn/kernel/sn2/Makefile	Wed Jun 18 23:42:09 2003
@@ -11,4 +11,5 @@
 
 EXTRA_CFLAGS := -DLITTLE_ENDIAN
 
-obj-y += cache.o iomv.o ptc_deadlock.o sn2_smp.o sn_proc_fs.o
+obj-y += cache.o io.o ptc_deadlock.o sn2_smp.o sn_proc_fs.o \
+	 prominfo_proc.o timer.o
diff -Nru a/arch/ia64/sn/kernel/sn2/cache.c b/arch/ia64/sn/kernel/sn2/cache.c
--- a/arch/ia64/sn/kernel/sn2/cache.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/sn/kernel/sn2/cache.c	Wed Jun 18 23:42:09 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  * 
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2001-2003 Silicon Graphics, Inc. All rights reserved.
  *
  */
 
@@ -24,6 +24,5 @@
 sn_flush_all_caches(long flush_addr, long bytes)
 {
 	flush_icache_range(flush_addr, flush_addr+bytes);
+	mb();
 }
-
-
diff -Nru a/arch/ia64/sn/kernel/sn2/io.c b/arch/ia64/sn/kernel/sn2/io.c
--- a/arch/ia64/sn/kernel/sn2/io.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/sn/kernel/sn2/io.c	Wed Jun 18 23:42:09 2003
@@ -9,13 +9,8 @@
  * we wrap the inlines from asm/ia64/sn/sn2/io.h here.
  */
 
-#include <linux/config.h>
-#include <linux/types.h>
-
 #include <asm/sn/sn2/io.h>
 
-#ifdef CONFIG_IA64_GENERIC
-
 unsigned int
 sn_inb (unsigned long port)
 {
@@ -73,7 +68,7 @@
 unsigned long
 sn_readq (void *addr)
 {
-	return __sn_readq (addr)
+	return __sn_readq (addr);
 }
 
 
@@ -94,5 +89,3 @@
 asm ("__sn_readw = sn_readw");
 asm ("__sn_readl = sn_readl");
 asm ("__sn_readq = sn_readq");
-
-#endif /* CONFIG_IA64_GENERIC */
diff -Nru a/arch/ia64/sn/kernel/sn2/iomv.c b/arch/ia64/sn/kernel/sn2/iomv.c
--- a/arch/ia64/sn/kernel/sn2/iomv.c	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,71 +0,0 @@
-/* 
- * 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) 2000-2003 Silicon Graphics, Inc. All rights reserved.
- */
-
-#include <linux/pci.h>
-#include <linux/module.h>
-#include <asm/io.h>
-#include <asm/delay.h>
-#include <asm/sn/simulator.h>
-#include <asm/sn/pda.h>
-#include <asm/sn/sn_cpuid.h>
-
-/**
- * sn_io_addr - convert an in/out port to an i/o address
- * @port: port to convert
- *
- * Legacy in/out instructions are converted to ld/st instructions
- * on IA64.  This routine will convert a port number into a valid 
- * SN i/o address.  Used by sn_in*() and sn_out*().
- */
-void *
-sn_io_addr(unsigned long port)
-{
-	if (!IS_RUNNING_ON_SIMULATOR()) {
-		return( (void *)  (port | __IA64_UNCACHED_OFFSET));
-	} else {
-		unsigned long io_base;
-		unsigned long addr;
- 
-		/*
- 		 * word align port, but need more than 10 bits
- 		 * for accessing registers in bedrock local block
- 		 * (so we don't do port&0xfff)
- 		 */
-		if ((port >= 0x1f0 && port <= 0x1f7) ||
-			port == 0x3f6 || port == 0x3f7) {
-			io_base = (0xc000000fcc000000 | ((unsigned long)get_nasid() << 38));
-			addr = io_base | ((port >> 2) << 12) | (port & 0xfff);
-		} else {
-			addr = __ia64_get_io_port_base() | ((port >> 2) << 2);
-		}
-		return(void *) addr;
-	}
-}
-
-EXPORT_SYMBOL(sn_io_addr);
-
-/**
- * sn_mmiob - I/O space memory barrier
- *
- * Acts as a memory mapped I/O barrier for platforms that queue writes to 
- * I/O space.  This ensures that subsequent writes to I/O space arrive after
- * all previous writes.  For most ia64 platforms, this is a simple
- * 'mf.a' instruction.  For other platforms, mmiob() may have to read
- * a chipset register to ensure ordering.
- *
- * On SN2, we wait for the PIO_WRITE_STATUS SHub register to clear.
- * See PV 871084 for details about the WAR about zero value.
- *
- */
-void
-sn_mmiob (void)
-{
-	while ((((volatile unsigned long) (*pda.pio_write_status_addr)) & SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK) != 
-				SH_PIO_WRITE_STATUS_0_PENDING_WRITE_COUNT_MASK)
-		udelay(1);
-}
diff -Nru a/arch/ia64/sn/kernel/sn2/prominfo_proc.c b/arch/ia64/sn/kernel/sn2/prominfo_proc.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/kernel/sn2/prominfo_proc.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,361 @@
+/*
+ * 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) 1999,2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
+ *
+ * Module to export the system's Firmware Interface Tables, including
+ * PROM revision numbers, in /proc
+ */
+#include <linux/config.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/proc_fs.h>
+#include <asm/io.h>
+#include <asm/sn/simulator.h>
+
+/* to lookup nasids */
+#include <asm/sn/sn_cpuid.h>
+
+MODULE_DESCRIPTION("PROM version reporting for /proc");
+MODULE_AUTHOR("Chad Talbott");
+MODULE_LICENSE("GPL");
+
+#undef DEBUG_PROMINFO
+
+#define TRACE_PROMINFO
+
+#if defined(DEBUG_PROMINFO)
+#  define DPRINTK(x...) printk(KERN_DEBUG x)
+#else
+#  define DPRINTK(x...)
+#endif
+
+#if defined(TRACE_PROMINFO) && defined(DEBUG_PROMINFO)
+#  if defined(__GNUC__)
+#    define TRACE()	printk(KERN_DEBUG "%s:%d:%s\n", \
+			       __FILE__, __LINE__, __FUNCTION__)
+#  else
+#    define TRACE()	printk(KERN_DEBUG "%s:%d\n", __LINE__, __FILE__)
+#  endif
+#else
+#  define TRACE()
+#endif
+
+/* Sub-regions determined by bits in Node Offset */
+#define	LB_PROM_SPACE		0x0000000700000000ul /* Local LB PROM */
+
+#define FIT_SIGNATURE		0x2020205f5449465ful
+/* Standard Intel FIT entry types */
+#define FIT_ENTRY_FIT_HEADER	0x00	/* FIT header entry */
+#define FIT_ENTRY_PAL_B		0x01	/* PAL_B entry */
+/* Entries 0x02 through 0x0D reserved by Intel */
+#define FIT_ENTRY_PAL_A_PROC	0x0E	/* Processor-specific PAL_A entry */
+#define FIT_ENTRY_PAL_A		0x0F	/* PAL_A entry, same as... */
+#define FIT_ENTRY_PAL_A_GEN	0x0F	/* ...Generic PAL_A entry */
+#define FIT_ENTRY_UNUSED	0x7F	/* Unused (reserved by Intel?) */
+/* OEM-defined entries range from 0x10 to 0x7E. */
+#define FIT_ENTRY_SAL_A		0x10	/* SAL_A entry */
+#define FIT_ENTRY_SAL_B		0x11	/* SAL_B entry */
+#define FIT_ENTRY_SALRUNTIME	0x12	/* SAL runtime entry */
+#define FIT_ENTRY_EFI		0x1F	/* EFI entry */
+#define FIT_ENTRY_FPSWA		0x20	/* embedded fpswa entry */
+#define FIT_ENTRY_VMLINUX	0x21	/* embedded vmlinux entry */
+
+#define FIT_MAJOR_SHIFT	(32 + 8)
+#define FIT_MAJOR_MASK	((1 << 8) - 1)
+#define FIT_MINOR_SHIFT	32
+#define FIT_MINOR_MASK	((1 << 8) - 1)
+
+#define FIT_MAJOR(q)	\
+	((unsigned) ((q) >> FIT_MAJOR_SHIFT) & FIT_MAJOR_MASK)
+#define FIT_MINOR(q)	\
+	((unsigned) ((q) >> FIT_MINOR_SHIFT) & FIT_MINOR_MASK)
+
+#define FIT_TYPE_SHIFT	(32 + 16)
+#define FIT_TYPE_MASK	((1 << 7) - 1)
+
+#define FIT_TYPE(q)	\
+	((unsigned) ((q) >> FIT_TYPE_SHIFT) & FIT_TYPE_MASK)
+
+#define FIT_ENTRY(type, maj, min, size)					\
+	((((unsigned long)(maj) & FIT_MAJOR_MASK) << FIT_MAJOR_SHIFT) |	\
+	 (((unsigned long)(min) & FIT_MINOR_MASK) << FIT_MINOR_SHIFT) |	\
+	 (((unsigned long)(type) & FIT_TYPE_MASK) << FIT_TYPE_SHIFT) |	\
+	 (size))
+
+struct fit_type_map_t {
+	unsigned char	type;
+	const char	*name;
+};
+
+static const struct fit_type_map_t fit_entry_types[] = {
+	{ FIT_ENTRY_FIT_HEADER, "FIT Header" },
+	{ FIT_ENTRY_PAL_A_GEN,  "Generic PAL_A" },
+	{ FIT_ENTRY_PAL_A_PROC, "Processor-specific PAL_A" },
+	{ FIT_ENTRY_PAL_A,      "PAL_A" },
+	{ FIT_ENTRY_PAL_B,      "PAL_B" },
+	{ FIT_ENTRY_SAL_A,      "SAL_A" },
+	{ FIT_ENTRY_SAL_B,      "SAL_B" },
+	{ FIT_ENTRY_SALRUNTIME, "SAL runtime" },
+	{ FIT_ENTRY_EFI,	"EFI" },
+	{ FIT_ENTRY_VMLINUX,    "Embedded Linux" },
+	{ FIT_ENTRY_FPSWA,      "Embedded FPSWA" },
+	{ FIT_ENTRY_UNUSED,     "Unused" },
+	{ 0xff,                 "Error" },
+};
+
+static const char *
+fit_type_name(unsigned char type)
+{
+	struct fit_type_map_t const*mapp;
+
+	for (mapp = fit_entry_types; mapp->type != 0xff; mapp++)
+		if (type == mapp->type)
+			return mapp->name;
+
+	if ((type > FIT_ENTRY_PAL_A) && (type < FIT_ENTRY_UNUSED))
+		return "OEM type";
+	if ((type > FIT_ENTRY_PAL_B) && (type < FIT_ENTRY_PAL_A))
+		return "Reserved";
+
+	return "Unknown type";
+}
+
+/* These two routines read the FIT table directly from the FLASH PROM
+ * on a specific node.  The PROM can only be accessed using aligned 64
+ * bit reads, so we do that and then shift and mask the result to get
+ * at each field.
+ */
+static int
+dump_fit_entry(char *page, unsigned long *fentry)
+{
+	unsigned long q1, q2;
+	unsigned type;
+
+	TRACE();
+
+	q1 = readq(fentry);
+	q2 = readq(fentry + 1);
+	type = FIT_TYPE(q2);
+	return sprintf(page, "%02x %-25s %x.%02x %016lx %u\n",
+		       type,
+		       fit_type_name(type),
+		       FIT_MAJOR(q2), FIT_MINOR(q2),
+		       q1,
+		       /* mult by sixteen to get size in bytes */
+		       (unsigned)q2 * 16);
+}
+
+/* We assume that the fit table will be small enough that we can print
+ * the whole thing into one page.  (This is true for our default 16kB
+ * pages -- each entry is about 60 chars wide when printed.)  I read
+ * somewhere that the maximum size of the FIT is 128 entries, so we're
+ * OK except for 4kB pages (and no one is going to do that on SN
+ * anyway).
+ */
+static int
+dump_fit(char *page, unsigned long *fit)
+{
+	unsigned long qw;
+	int nentries;
+	int fentry;
+	char *p;
+
+	TRACE();
+
+	DPRINTK("dumping fit from %p\n", (void *)fit);
+
+	qw = readq(fit);
+	DPRINTK("FIT signature: %016lx (%.8s)\n", qw, (char *)&qw);
+	if (qw != FIT_SIGNATURE)
+		printk(KERN_WARNING "Unrecognized FIT signature");
+
+	qw = readq(fit + 1);
+	nentries = (unsigned)qw;
+	DPRINTK("number of fit entries: %u\n", nentries);
+	/* check that we won't overflow the page -- see comment above */
+	BUG_ON(nentries * 60 > PAGE_SIZE);
+
+	p = page;
+	for (fentry = 0; fentry < nentries; fentry++)
+		/* each FIT entry is two 64 bit words */
+		p += dump_fit_entry(p, fit + 2 * fentry);
+
+	return p - page;
+}
+
+static int
+dump_version(char *page, unsigned long *fit)
+{
+	int nentries;
+	int fentry;
+	unsigned long qw;
+
+	TRACE();
+
+	nentries = (unsigned)readq(fit + 1);
+	BUG_ON(nentries * 60 > PAGE_SIZE);
+
+	for (fentry = 0; fentry < nentries; fentry++) {
+		qw = readq(fit + 2 * fentry + 1);
+		if (FIT_TYPE(qw) == FIT_ENTRY_SAL_A)
+			return sprintf(page, "%x.%02x\n",
+				       FIT_MAJOR(qw), FIT_MINOR(qw));
+	}
+	return 0;
+}
+
+/* same as in proc_misc.c */
+static int
+proc_calc_metrics(char *page, char **start, off_t off, int count, int *eof,
+		  int len)
+{
+	if (len <= off+count) *eof = 1;
+	*start = page + off;
+	len -= off;
+	if (len>count) len = count;
+	if (len<0) len = 0;
+	return len;
+}
+
+static int
+read_version_entry(char *page, char **start, off_t off, int count, int *eof,
+		   void *data)
+{
+	int len = 0;
+
+	MOD_INC_USE_COUNT;
+	/* data holds the pointer to this node's FIT */
+	len = dump_version(page, (unsigned long *)data);
+	len = proc_calc_metrics(page, start, off, count, eof, len);
+	MOD_DEC_USE_COUNT;
+	return len;
+}
+
+static int
+read_fit_entry(char *page, char **start, off_t off, int count, int *eof,
+	       void *data)
+{
+	int len = 0;
+
+	MOD_INC_USE_COUNT;
+	/* data holds the pointer to this node's FIT */
+	len = dump_fit(page, (unsigned long *)data);
+	len = proc_calc_metrics(page, start, off, count, eof, len);
+	MOD_DEC_USE_COUNT;
+
+	return len;
+}
+
+/* this is a fake FIT that's used on the medusa simulator which
+ * doesn't usually run a complete PROM. 
+ */
+#ifdef CONFIG_IA64_SGI_SN_SIM
+static unsigned long fakefit[] = {
+	/* this is all we need to satisfy the code below */
+	FIT_SIGNATURE,
+	FIT_ENTRY(FIT_ENTRY_FIT_HEADER, 0x02, 0x60, 2),
+	/* dump something arbitrary for
+	 * /proc/sgi_prominfo/nodeX/version */
+	0xbadbeef00fa3ef17ul,
+	FIT_ENTRY(FIT_ENTRY_SAL_A, 0, 0x99, 0x100)
+};	
+#endif
+
+static unsigned long *
+lookup_fit(int nasid)
+{
+	unsigned long *fitp;
+	unsigned long fit_paddr;
+	unsigned long *fit_vaddr;
+
+#ifdef CONFIG_IA64_SGI_SN_SIM
+	if (IS_RUNNING_ON_SIMULATOR())
+		return fakefit;
+#endif
+
+	fitp = (void *)GLOBAL_MMR_ADDR(nasid, LB_PROM_SPACE - 32);
+	DPRINTK("pointer to fit at %p\n", (void *)fitp);
+	fit_paddr = readq(fitp);
+	DPRINTK("fit pointer contains %lx\n", fit_paddr);
+	/* snag just the node-relative offset */
+	fit_paddr &= ~0ul >> (63-35);
+	/* the pointer to the FIT is relative to IA-64 compatibility
+	 * space.  However, the PROM is mapped at a different offset
+	 * in MMR space (both local and global)
+	 */
+	fit_paddr += 0x700000000;
+	fit_vaddr = (void *)GLOBAL_MMR_ADDR(nasid, fit_paddr);
+	DPRINTK("fit at %p\n", (void *)fit_vaddr);
+	return fit_vaddr;
+}
+
+/* module entry points */
+int __init prominfo_init(void);
+void __exit prominfo_exit(void);
+
+module_init(prominfo_init);
+module_exit(prominfo_exit);
+
+static struct proc_dir_entry **proc_entries;
+static struct proc_dir_entry *sgi_prominfo_entry;
+
+#define NODE_NAME_LEN 11
+
+int __init
+prominfo_init(void)
+{
+	struct proc_dir_entry **entp;
+	cnodeid_t cnodeid;
+	nasid_t nasid;
+	char name[NODE_NAME_LEN];
+
+	TRACE();
+
+	DPRINTK("running on cpu %d\n", smp_processor_id());
+	DPRINTK("numnodes %d\n", numnodes);
+
+	proc_entries = kmalloc(numnodes * sizeof(struct proc_dir_entry *),
+			       GFP_KERNEL);
+
+	sgi_prominfo_entry = proc_mkdir("sgi_prominfo", NULL);
+
+	for (cnodeid = 0, entp = proc_entries;
+	     cnodeid < numnodes;
+	     cnodeid++, entp++) {
+		sprintf(name, "node%d", cnodeid);
+		*entp = proc_mkdir(name, sgi_prominfo_entry);
+		nasid = cnodeid_to_nasid(cnodeid);
+		create_proc_read_entry(
+			"fit", 0, *entp, read_fit_entry,
+			lookup_fit(nasid));
+		create_proc_read_entry(
+			"version", 0, *entp, read_version_entry,
+			lookup_fit(nasid));
+	}
+
+	return 0;
+}
+
+void __exit
+prominfo_exit(void)
+{
+	struct proc_dir_entry **entp;
+	unsigned cnodeid;
+	char name[NODE_NAME_LEN];
+
+	TRACE();
+
+	for (cnodeid = 0, entp = proc_entries;
+	     cnodeid < numnodes;
+	     cnodeid++, entp++) {
+		remove_proc_entry("fit", *entp);
+		remove_proc_entry("version", *entp);
+		sprintf(name, "node%d", cnodeid);
+		remove_proc_entry(name, sgi_prominfo_entry);
+	}
+	remove_proc_entry("sgi_prominfo", NULL);
+	kfree(proc_entries);
+}
diff -Nru a/arch/ia64/sn/kernel/sn2/sn2_smp.c b/arch/ia64/sn/kernel/sn2/sn2_smp.c
--- a/arch/ia64/sn/kernel/sn2/sn2_smp.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/sn/kernel/sn2/sn2_smp.c	Wed Jun 18 23:42:09 2003
@@ -1,7 +1,7 @@
 /*
  * SN2 Platform specific SMP Support
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -79,284 +79,6 @@
 	return ws;
 }
 
-#ifdef PTCG_WAR
-/*
- * The following structure is used to pass params thru smp_call_function
- * to other cpus for flushing TLB ranges.
- */
-typedef struct {
-	unsigned long	start;
-	unsigned long	end;
-	unsigned long	nbits;
-	unsigned int	rid;
-	atomic_t	unfinished_count;
-	char		fill[96];
-} ptc_params_t;
-
-#define NUMPTC	512
-
-static ptc_params_t	ptcParamArray[NUMPTC] __attribute__((__aligned__(128)));
-
-/* use separate cache lines on ptcParamsNextByCpu to avoid false sharing */
-static ptc_params_t	*ptcParamsNextByCpu[NR_CPUS*16] __attribute__((__aligned__(128)));
-static volatile ptc_params_t	*ptcParamsEmpty __cacheline_aligned;
-
-/*REFERENCED*/
-static spinlock_t ptcParamsLock __cacheline_aligned = SPIN_LOCK_UNLOCKED;
-
-static int ptcInit = 0;
-#ifdef PTCDEBUG
-static int ptcParamsAllBusy = 0;		/* debugging/statistics */
-static int ptcCountBacklog = 0;
-static int ptcBacklog[NUMPTC+1];
-static char ptcParamsCounts[NR_CPUS][NUMPTC] __attribute__((__aligned__(128)));
-static char ptcParamsResults[NR_CPUS][NUMPTC] __attribute__((__aligned__(128)));
-#endif
-
-/*
- * Make smp_send_flush_tlbsmp_send_flush_tlb() a weak reference,
- * so that we get a clean compile with the ia64 patch without the
- * actual SN1 specific code in arch/ia64/kernel/smp.c.
- */
-extern void smp_send_flush_tlb (void) __attribute((weak));
-
-
-/**
- * sn1_ptc_l_range - purge local translation cache
- * @start: start of virtual address range
- * @end: end of virtual address range
- * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
- *
- * Purges the range specified from the local processor's translation cache
- * (as opposed to the translation registers).  Note that more than the specified
- * range *may* be cleared from the cache by some processors.
- *
- * This is probably not good enough, but I don't want to try to make it better 
- * until I get some statistics on a running system. At a minimum, we should only 
- * send IPIs to 1 processor in each TLB domain & have it issue a ptc.g on it's 
- * own FSB. Also, we only have to serialize per FSB, not globally.
- *
- * More likely, we will have to do some work to reduce the frequency of calls to
- * this routine.
- */
-static inline void
-sn1_ptc_l_range(unsigned long start, unsigned long end, unsigned long nbits)
-{
-	do {
-		__asm__ __volatile__ ("ptc.l %0,%1" :: "r"(start), "r"(nbits<<2) : "memory");
-		start += (1UL << nbits);
-	} while (start < end);
-	ia64_srlz_d();
-}
-
-/**
- * sn1_received_flush_tlb - cpu tlb flush routine
- *
- * Flushes the TLB of a given processor.
- */
-void
-sn1_received_flush_tlb(void)
-{
-	unsigned long	start, end, nbits;
-	unsigned int	rid, saved_rid;
-	int		cpu = smp_processor_id();
-	int		result;
-	ptc_params_t	*ptcParams;
-
-	ptcParams = ptcParamsNextByCpu[cpu*16];
-	if (ptcParams == ptcParamsEmpty)
-		return;
-
-	do {
-		start = ptcParams->start;
-		saved_rid = (unsigned int) ia64_get_rr(start);
-		end = ptcParams->end;
-		nbits = ptcParams->nbits;
-		rid = ptcParams->rid;
-
-		if (saved_rid != rid) {
-			ia64_set_rr(start, (unsigned long)rid);
-			ia64_srlz_d();
-		}
-
-		sn1_ptc_l_range(start, end, nbits);
-
-		if (saved_rid != rid) 
-			ia64_set_rr(start, (unsigned long)saved_rid);
-
-		ia64_srlz_i();
-
-		result = atomic_dec(&ptcParams->unfinished_count);
-#ifdef PTCDEBUG
-		{
-		    int i = ptcParams-&ptcParamArray[0];
-		    ptcParamsResults[cpu][i] = (char) result;
-		    ptcParamsCounts[cpu][i]++;
-		}
-#endif /* PTCDEBUG */
-
-		if (++ptcParams == &ptcParamArray[NUMPTC])
-			ptcParams = &ptcParamArray[0];
-
-	} while (ptcParams != ptcParamsEmpty);
-
-	ptcParamsNextByCpu[cpu*16] = ptcParams;
-}
-
-/**
- * sn1_global_tlb_purge - flush a translation cache range on all processors
- * @start: start of virtual address range to flush
- * @end: end of virtual address range
- * @nbits: specifies number of bytes to purge per instruction (num = 1<<(nbits & 0xfc))
- *
- * Flushes the translation cache of all processors from @start to @end.
- */
-void
-sn1_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
-{
-	ptc_params_t	*params;
-	ptc_params_t	*next;
-	unsigned long	irqflags;
-#ifdef PTCDEBUG
-	ptc_params_t	*nextnext;
-	int		backlog = 0;
-#endif
-
-	if (smp_num_cpus == 1) {
-		sn1_ptc_l_range(start, end, nbits);
-		return;
-	}
-
-	if (in_interrupt()) {
-		/*
-		 *  If at interrupt level and cannot get spinlock, 
-		 *  then do something useful by flushing own tlbflush queue
-		 *  so as to avoid a possible deadlock.
-		 */
-		while (!spin_trylock(&ptcParamsLock)) {
-			local_irq_save(irqflags);
-			sn1_received_flush_tlb();
-			local_irq_restore(irqflags);
-			udelay(10);	/* take it easier on the bus */	
-		}
-	} else {
-		spin_lock(&ptcParamsLock);
-	}
-
-	if (!ptcInit) {
-		int cpu;
-		ptcInit = 1;
-		memset(ptcParamArray, 0, sizeof(ptcParamArray));
-		ptcParamsEmpty = &ptcParamArray[0];
-		for (cpu=0; cpu<NR_CPUS; cpu++)
-			ptcParamsNextByCpu[cpu*16] = &ptcParamArray[0];
-
-#ifdef PTCDEBUG
-		memset(ptcBacklog, 0, sizeof(ptcBacklog));
-		memset(ptcParamsCounts, 0, sizeof(ptcParamsCounts));
-		memset(ptcParamsResults, 0, sizeof(ptcParamsResults));
-#endif	/* PTCDEBUG */
-	}
-
-	params = (ptc_params_t *) ptcParamsEmpty;
-	next = (ptc_params_t *) ptcParamsEmpty + 1;
-	if (next == &ptcParamArray[NUMPTC])
-		next = &ptcParamArray[0];
-
-#ifdef PTCDEBUG
-	nextnext = next + 1;
-	if (nextnext == &ptcParamArray[NUMPTC])
-		nextnext = &ptcParamArray[0];
-
-	if (ptcCountBacklog) {
-		/* quick count of backlog */
-		ptc_params_t *ptr;
-
-		/* check the current pointer to the beginning */
-		ptr = params;
-		while(--ptr >= &ptcParamArray[0]) {
-			if (atomic_read(&ptr->unfinished_count) == 0)
-				break;
-			++backlog;
-		}
-
-		if (backlog) {
-			/* check the end of the array */
-			ptr = &ptcParamArray[NUMPTC];
-			while (--ptr > params) {
-				if (atomic_read(&ptr->unfinished_count) == 0)
-					break;
-				++backlog;
-			}
-		}
-		ptcBacklog[backlog]++;
-	}
-#endif	/* PTCDEBUG */
-
-	/* wait for the next entry to clear...should be rare */
-	if (atomic_read(&next->unfinished_count) > 0) {
-#ifdef PTCDEBUG
-		ptcParamsAllBusy++;
-
-		if (atomic_read(&nextnext->unfinished_count) == 0) {
-		    if (atomic_read(&next->unfinished_count) > 0) {
-			panic("\nnonzero next zero nextnext %lx %lx\n",
-			    (long)next, (long)nextnext);
-		    }
-		}
-#endif
-
-		/* it could be this cpu that is behind */
-		local_irq_save(irqflags);
-		sn1_received_flush_tlb();
-		local_irq_restore(irqflags);
-
-		/* now we know it's not this cpu, so just wait */
-		while (atomic_read(&next->unfinished_count) > 0) {
-			barrier();
-		}
-	}
-
-	params->start = start;
-	params->end = end;
-	params->nbits = nbits;
-	params->rid = (unsigned int) ia64_get_rr(start);
-	atomic_set(&params->unfinished_count, smp_num_cpus);
-
-	/* The atomic_set above can hit memory *after* the update
-	 * to ptcParamsEmpty below, which opens a timing window
-	 * that other cpus can squeeze into!
-	 */
-	mb();
-
-	/* everything is ready to process:
-	 *	-- global lock is held
-	 *	-- new entry + 1 is free
-	 *	-- new entry is set up
-	 * so now:
-	 *	-- update the global next pointer
-	 *	-- unlock the global lock
-	 *	-- send IPI to notify other cpus
-	 *	-- process the data ourselves
-	 */
-	ptcParamsEmpty = next;
-	spin_unlock(&ptcParamsLock);
-	smp_send_flush_tlb();
-
-	local_irq_save(irqflags);
-	sn1_received_flush_tlb();
-	local_irq_restore(irqflags);
-
-	/* 
-	 * Since IPIs are polled event (for now), we need to wait til the
-	 * TLB flush has started.
-	 * wait for the flush to complete 
-	 */ 
-	while (atomic_read(&params->unfinished_count) > 0)
-		barrier();
-}
-
-#endif /* PTCG_WAR */
 
 
 /**
@@ -372,18 +94,10 @@
 void
 sn2_global_tlb_purge (unsigned long start, unsigned long end, unsigned long nbits)
 {
-	int			cnode, mycnode, nasid;
+	int			cnode, mycnode, nasid, flushed=0;
 	volatile unsigned	long	*ptc0, *ptc1;
 	unsigned long		flags=0, data0, data1;
 
-	/*
-	 * Special case 1 cpu & 1 node. Use local purges.
-	 */
-#ifdef PTCG_WAR
-	sn1_global_tlb_purge(start, end, nbits);
-	return;
-#endif /* PTCG_WAR */
-		
 	data0 = (1UL<<SH_PTC_0_A_SHFT) |
 		(nbits<<SH_PTC_0_PS_SHFT) |
 		((ia64_get_rr(start)>>8)<<SH_PTC_0_RID_SHFT) |
@@ -392,18 +106,9 @@
 	ptc0 = (long*)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_0);
 	ptc1 = (long*)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_1);
 
-	mycnode = local_nodeid;
+	mycnode = numa_node_id();
 
-	/* 
-	 * For now, we don't want to spin uninterruptibly waiting
-	 * for the lock. Makes hangs hard to debug.
-	 */
-	local_irq_save(flags);
-	while (!spin_trylock(&sn2_global_ptc_lock)) {
-		local_irq_restore(flags);
-		udelay(1);
-		local_irq_save(flags);
-	}
+	spin_lock_irqsave(&sn2_global_ptc_lock, flags);
 
 	do {
 		data1 = start | (1UL<<SH_PTC_1_START_SHFT);
@@ -417,11 +122,13 @@
 				ptc0 = CHANGE_NASID(nasid, ptc0);
 				ptc1 = CHANGE_NASID(nasid, ptc1);
 				pio_atomic_phys_write_mmrs(ptc0, data0, ptc1, data1);
+				flushed = 1;
 			}
 		}
 
-		if (wait_piowc() & SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_MASK)
+		if (flushed && (wait_piowc() & SH_PIO_WRITE_STATUS_0_WRITE_DEADLOCK_MASK)) {
 			sn2_ptc_deadlock_recovery(data0, data1);
+		}
 
 		start += (1UL << nbits);
 
@@ -451,7 +158,7 @@
 	ptc1 = (long*)GLOBAL_MMR_PHYS_ADDR(0, SH_PTC_1);
 	piows = (long*)pda->pio_write_status_addr;
 
-	mycnode = local_nodeid;
+	mycnode = numa_node_id();
 
 	for (cnode = 0; cnode < numnodes; cnode++) {
 		if (is_headless_node(cnode) || cnode == mycnode)
@@ -482,16 +189,10 @@
 void
 sn_send_IPI_phys(long physid, int vector, int delivery_mode)
 {
-	long		nasid, slice;
-	long		val;
+	long		nasid, slice, val;
+	unsigned long	flags=0;
 	volatile long	*p;
 
-#ifdef BUS_INT_WAR
-	if (vector != ap_wakeup_vector && delivery_mode == IA64_IPI_DM_INT) {
-		return;
-	}
-#endif
-
 	nasid = cpu_physical_id_to_nasid(physid);
         slice = cpu_physical_id_to_slice(physid);
 
@@ -503,12 +204,15 @@
 		(0x000feeUL<<SH_IPI_INT_BASE_SHFT);
 
 	mb();
+	if (enable_shub_wars_1_1() ) {
+		spin_lock_irqsave(&sn2_global_ptc_lock, flags);
+	}
 	pio_phys_write_mmr(p, val);
+	if (enable_shub_wars_1_1() ) {
+		wait_piowc();
+		spin_unlock_irqrestore(&sn2_global_ptc_lock, flags);
+	}
 
-#ifndef CONFIG_SHUB_1_0_SPECIFIC
-	/* doesn't work on shub 1.0 */
-	wait_piowc();
-#endif
 }
 
 /**
@@ -536,4 +240,3 @@
 
 	sn_send_IPI_phys(physid, vector, delivery_mode);
 }
-
diff -Nru a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c
--- a/arch/ia64/sn/kernel/sn2/sn_proc_fs.c	Wed Jun 18 23:42:09 2003
+++ b/arch/ia64/sn/kernel/sn2/sn_proc_fs.c	Wed Jun 18 23:42:09 2003
@@ -31,6 +31,7 @@
  * http://oss.sgi.com/projects/GenInfo/NoticeExplan
  */
 #include <linux/config.h>
+#include <asm/uaccess.h>
 
 #ifdef CONFIG_PROC_FS
 #include <linux/proc_fs.h>
@@ -43,7 +44,7 @@
 	return sprintf(page, "%d\n", sn_local_partid());
 }
 
-struct proc_dir_entry * sgi_proc_dir = NULL;
+static struct proc_dir_entry * sgi_proc_dir;
 
 void
 register_sn_partition_id(void) {
@@ -135,11 +136,60 @@
 		entry->write_proc = sn_force_interrupt_write_proc;
 	}
 }
+
+extern int sn_linkstats_get(char *);
+extern int sn_linkstats_reset(unsigned long);
+
+static int
+sn_linkstats_read_proc(char *page, char **start, off_t off,
+		int count, int *eof, void *data) {
+       
+	return sn_linkstats_get(page);
+}
+
+static int 
+sn_linkstats_write_proc(struct file *file, const char *buffer,
+                                        unsigned long count, void *data)
+{
+	char		s[64];
+	unsigned long	msecs;
+	int		e = count;
+
+	if (copy_from_user(s, buffer, count < sizeof(s) ? count : sizeof(s)))
+		e = -EFAULT;
+	else {
+		if (sscanf(s, "%lu", &msecs) != 1 || msecs < 5)
+			/* at least 5 milliseconds between updates */
+			e = -EINVAL;
+		else
+			sn_linkstats_reset(msecs);
+	}
+
+	return e;
+}
+
+void
+register_sn_linkstats(void) {
+	struct proc_dir_entry *entry;
+
+	if (!sgi_proc_dir) {
+		sgi_proc_dir = proc_mkdir("sgi_sn", 0);
+	}
+	entry = create_proc_entry("linkstats", 0444, sgi_proc_dir);
+	if (entry) {
+		entry->nlink = 1;
+		entry->data = 0;
+		entry->read_proc = sn_linkstats_read_proc;
+		entry->write_proc = sn_linkstats_write_proc;
+	}
+}
+
 void
 register_sn_procfs(void) {
 	register_sn_partition_id();
 	register_sn_serial_numbers();
 	register_sn_force_interrupt();
+	register_sn_linkstats();
 }
 
 #endif /* CONFIG_PROC_FS */
diff -Nru a/arch/ia64/sn/kernel/sn2/timer.c b/arch/ia64/sn/kernel/sn2/timer.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/arch/ia64/sn/kernel/sn2/timer.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,76 @@
+/*
+ * linux/arch/ia64/sn/kernel/sn2/timer.c
+ *
+ * Copyright (C) 2003 Silicon Graphics, Inc.
+ * Copyright (C) 2003 Hewlett-Packard Co
+ *	David Mosberger <davidm@hpl.hp.com>: updated for new timer-interpolation infrastructure
+ */
+
+#include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/time.h>
+#include <linux/interrupt.h>
+
+#include <asm/hw_irq.h>
+#include <asm/system.h>
+
+#include <asm/sn/leds.h>
+#include <asm/sn/clksupport.h>
+
+
+extern unsigned long sn_rtc_cycles_per_second;
+static volatile unsigned long last_wall_rtc;
+
+static unsigned long rtc_offset;	/* updated only when xtime write-lock is held! */
+static long rtc_nsecs_per_cycle;
+static long rtc_per_timer_tick;
+
+static unsigned long
+getoffset(void)
+{
+	return rtc_offset + (GET_RTC_COUNTER() - last_wall_rtc)*rtc_nsecs_per_cycle;
+}
+
+
+static void
+update(long delta_nsec)
+{
+	unsigned long rtc_counter = GET_RTC_COUNTER();
+	unsigned long offset = rtc_offset + (rtc_counter - last_wall_rtc)*rtc_nsecs_per_cycle;
+
+	/* Be careful about signed/unsigned comparisons here: */
+	if (delta_nsec < 0 || (unsigned long) delta_nsec < offset)
+		rtc_offset = offset - delta_nsec;
+	else
+		rtc_offset = 0;
+	last_wall_rtc = rtc_counter;
+}
+
+
+static void
+reset(void)
+{
+	rtc_offset = 0;
+	last_wall_rtc = GET_RTC_COUNTER();
+}
+
+
+static struct time_interpolator sn2_interpolator = {
+	.get_offset =	getoffset,
+	.update =	update,
+	.reset =	reset
+};
+
+void __init
+sn_timer_init(void)
+{
+	sn2_interpolator.frequency = sn_rtc_cycles_per_second;
+	sn2_interpolator.drift = -1;	/* unknown */
+	register_time_interpolator(&sn2_interpolator);
+
+	rtc_per_timer_tick = sn_rtc_cycles_per_second / HZ;
+	rtc_nsecs_per_cycle = 1000000000 / sn_rtc_cycles_per_second;
+
+	last_wall_rtc = GET_RTC_COUNTER();
+}
diff -Nru a/arch/ia64/sn/kernel/sn_asm.S b/arch/ia64/sn/kernel/sn_asm.S
--- a/arch/ia64/sn/kernel/sn_asm.S	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,107 +0,0 @@
-/*
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/config.h>
-#ifdef CONFIG_IA64_SGI_AUTOTEST
-
-// Testing only.
-// Routine will cause MCAs
-//   zzzmca(n)
-//      n=0 MCA via duplicate TLB dropin
-//      n=1 MCA via read of garbage address
-//      n=2 MCA via lfetch read of garbage address
-//
-
-#define ITIR(key, ps)           ((key<<8) | (ps<<2))
-#define TLB_PAGESIZE            28                      // Use 256MB pages for now.
-
-                        .global zzzmca
-                        .proc   zzzmca
-zzzmca:
-                        alloc   loc4       = ar.pfs,2,8,1,0;;
-                        cmp.ne  p6,p0=r32,r0;;
-                        movl    r2=0x2dead
-                        movl    r3=0x3dead
-                        movl    r15=0x15dead
-                        movl    r16=0x16dead
-                        movl    r31=0x31dead
-                        movl    loc0=0x34beef
-                        movl    loc1=0x35beef
-                        movl    loc2=0x36beef
-                        movl    loc3=0x37beef
-                        movl    out0=0x42beef
-
-                        movl    r20=0x32feed;;
-                        mov     ar32=r20
-                        movl    r20=0x36feed;;
-                        mov     ar36=r20
-                        movl    r20=0x65feed;;
-                        mov     ar65=r20
-                        movl    r20=0x66feed;;
-                        mov     ar66=r20
-
-(p6)                    br.cond.sptk    1f
-
-                        rsm      0x2000;;
-                        srlz.d;
-                        mov      r11      = 5
-                        mov      r3       = ITIR(0,TLB_PAGESIZE);;
-                        mov      cr.itir  = r3
-                        mov      r10      = 0;;
-                        itr.d    dtr[r11] = r10;;
-                        mov      r11      = 6
-
-                        itr.d    dtr[r11] = r10;;
-                        br      9f
-
-1:
-			cmp.eq	p6,p7=1,r32
-#ifdef CONFIG_IA64_SGI_SN1
-                        movl    r8=0xe00000fe00000048;;
-#else
-                        movl    r8=0xe0007fb000000048;;
-#endif
-                 (p6)   ld8     r9=[r8]
-                 (p7)   lfetch.fault.nt2  [r8]
-			;;
-                        mf
-			;;
-                        mf.a
-			;;
-                        srlz.d
-
-9:                      mov     ar.pfs=loc4
-                        br.ret.sptk     rp
-
-                        .endp   zzzmca
-
-#endif
diff -Nru a/arch/ia64/sn/kernel/sn_ksyms.c b/arch/ia64/sn/kernel/sn_ksyms.c
--- a/arch/ia64/sn/kernel/sn_ksyms.c	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/sn/kernel/sn_ksyms.c	Wed Jun 18 23:42:08 2003
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -16,36 +16,16 @@
 
 #include <asm/machvec.h>
 #include <asm/sn/intr.h>
-#include <asm/sn/arch.h>
 
 #include <linux/mm.h>
-#include <linux/devfs_fs_kernel.h>
-extern devfs_handle_t          base_io_scsi_ctlr_vhdl[];
+#include <asm/sn/sgi.h>
+extern vertex_hdl_t          base_io_scsi_ctlr_vhdl[];
 #include <asm/sn/types.h>
 extern cnodeid_t master_node_get(devfs_handle_t vhdl);
 #include <asm/sn/arch.h>
 EXPORT_SYMBOL(base_io_scsi_ctlr_vhdl);
 EXPORT_SYMBOL(master_node_get);
 
-
-/*
- * symbols referenced by the PCIBA module
- */
-#include <asm/sn/invent.h>
-#include <asm/sn/hack.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/pci/pciio.h>
-
-devfs_handle_t
-devfn_to_vertex(unsigned char busnum, unsigned int devfn);
-EXPORT_SYMBOL(devfn_to_vertex);
-EXPORT_SYMBOL(hwgraph_vertex_unref);
-EXPORT_SYMBOL(pciio_config_get);
-EXPORT_SYMBOL(pciio_info_slot_get);
-EXPORT_SYMBOL(hwgraph_edge_add);
-EXPORT_SYMBOL(pciio_info_master_get);
-EXPORT_SYMBOL(pciio_info_get);
-
 #ifdef CONFIG_IA64_SGI_SN_DEBUG
 EXPORT_SYMBOL(__pa_debug);
 EXPORT_SYMBOL(__va_debug);
@@ -55,29 +35,26 @@
 EXPORT_SYMBOL(sn_send_IPI_phys);
 
 /* symbols referenced by partitioning modules */
-#include <asm/sn/bte_copy.h>
+#include <asm/sn/bte.h>
+EXPORT_SYMBOL(bte_copy);
 EXPORT_SYMBOL(bte_unaligned_copy);
 #include <asm/sal.h>
 EXPORT_SYMBOL(ia64_sal);
+EXPORT_SYMBOL(physical_node_map);
 
-#ifdef CONFIG_IA64_SGI_SN2
 #include <asm/sn/sn_sal.h>
 EXPORT_SYMBOL(sal_lock);
 EXPORT_SYMBOL(sn_partid);
 EXPORT_SYMBOL(sn_local_partid);
 EXPORT_SYMBOL(sn_system_serial_number_string);
 EXPORT_SYMBOL(sn_partition_serial_number);
-#endif
+
+EXPORT_SYMBOL(sn_mmiob);
 
 /* added by tduffy 04.08.01 to fix depmod issues */
 #include <linux/mmzone.h>
 
-#ifdef BUS_INT_WAR
-extern void sn_add_polled_interrupt(int, int);
-extern void sn_delete_polled_interrupt(int);
-EXPORT_SYMBOL(sn_add_polled_interrupt);
-EXPORT_SYMBOL(sn_delete_polled_interrupt);
-#endif
-
 extern nasid_t master_nasid;
 EXPORT_SYMBOL(master_nasid);
+
+EXPORT_SYMBOL(sn_flush_all_caches);
diff -Nru a/arch/ia64/sn/kernel/sv.c b/arch/ia64/sn/kernel/sv.c
--- a/arch/ia64/sn/kernel/sv.c	Wed Jun 18 23:42:06 2003
+++ b/arch/ia64/sn/kernel/sv.c	Wed Jun 18 23:42:06 2003
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc.  All rights reserved
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This implemenation of synchronization variables is heavily based on
  * one done by Steve Lord <lord@sgi.com>
diff -Nru a/arch/ia64/tools/Makefile b/arch/ia64/tools/Makefile
--- a/arch/ia64/tools/Makefile	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,51 +0,0 @@
-CFLAGS	= -g -O2 -Wall $(CPPFLAGS)
-
-TARGET	= include/asm-ia64/offsets.h
-
-src = $(obj)
-
-clean-files := print_offsets.s print_offsets offsets.h
-
-$(TARGET): $(obj)/offsets.h
-	@if ! cmp -s $(obj)/offsets.h ${TARGET}; then	\
-		echo -e "*** Updating ${TARGET}...";	\
-		cp $(obj)/offsets.h ${TARGET};		\
-	else						\
-		echo "*** ${TARGET} is up to date";	\
-	fi
-
-#
-# If we're cross-compiling, we use the cross-compiler to translate
-# print_offsets.c into an assembly file and then awk to translate this
-# file into offsets.h.  This avoids having to use a simulator to
-# generate this file.  This is based on an idea suggested by Asit
-# Mallick.  If we're running natively, we can of course just build
-# print_offsets and run it. --davidm
-#
-
-ifeq ($(CROSS_COMPILE),)
-
-$(obj)/offsets.h: $(obj)/print_offsets
-	$(obj)/print_offsets > $(obj)/offsets.h
-
-comma	:= ,
-
-$(obj)/print_offsets: $(src)/print_offsets.c FORCE
-	[ -r $(TARGET) ] || echo "#define IA64_TASK_SIZE 0" > $(TARGET)
-	$(CC) $(CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) \
-		$(src)/print_offsets.c -o $@
-
-FORCE:
-
-else
-
-$(obj)/offsets.h: $(obj)/print_offsets.s
-	$(AWK) -f $(src)/print_offsets.awk $^ > $@
-
-$(obj)/print_offsets.s: $(src)/print_offsets.c
-	[ -r $(TARGET) ] || echo "#define IA64_TASK_SIZE 0" > $(TARGET)
-	$(CC) $(CFLAGS) -DKBUILD_BASENAME=$(subst $(comma),_,$(subst -,_,$(*F))) -S $^ -o $@
-
-endif
-
-.PHONY: all modules modules_install
diff -Nru a/arch/ia64/tools/print_offsets.awk b/arch/ia64/tools/print_offsets.awk
--- a/arch/ia64/tools/print_offsets.awk	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,72 +0,0 @@
-BEGIN {
-	print "#ifndef _ASM_IA64_OFFSETS_H"
-	print "#define _ASM_IA64_OFFSETS_H"
-	print "/*"
-	print " * DO NOT MODIFY"
-	print " *"
-	print " * This file was generated by arch/ia64/tools/print_offsets.awk."
-	print " *"
-	print " */"
-	print ""
-	print "#define CLONE_IDLETASK_BIT	12"
-	print "#define CLONE_SETTLS_BIT	19"
-}
-
-# look for .tab:
-#	stringz "name"
-#	data value
-# sequence
-
-/.*[.]size/ {
-	inside_table = 0
-}
-
-/\/\/ end/ {
-	inside_table = 0
-}
-
-/.*[.]rodata/ {
-	inside_table = 0
-}
-
-{
-	if (inside_table) {
-		if ($1 == "//") getline;
-		name=$2
-		getline
-		getline
-		if ($1 == "//") getline;
-		value=$2
-		len = length(name)
-		name = substr(name, 2, len - 2)
-		len -= 2
-		if (len == 0)
-			print ""
-		else {
-			len += 8
-			if (len >= 40) {
-				space=" "
-			} else {
-				space=""
-				while (len < 40) {
-					len += 8
-					space = space"\t"
-				}
-			}
-			printf("#define %s%s%lu\t/* 0x%lx */\n", name, space, value, value)
-		}
-	}
-}
-
-/tab:/ {
-	inside_table = 1
-}
-
-/tab\#:/ {
-	inside_table = 1
-}
-
-END {
-	print ""
-	print "#endif /* _ASM_IA64_OFFSETS_H */"
-}
diff -Nru a/arch/ia64/tools/print_offsets.c b/arch/ia64/tools/print_offsets.c
--- a/arch/ia64/tools/print_offsets.c	Wed Jun 18 23:42:09 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,220 +0,0 @@
-/*
- * Utility to generate asm-ia64/offsets.h.
- *
- * Copyright (C) 1999-2003 Hewlett-Packard Co
- *	David Mosberger-Tang <davidm@hpl.hp.com>
- *
- * Note that this file has dual use: when building the kernel
- * natively, the file is translated into a binary and executed.  When
- * building the kernel in a cross-development environment, this file
- * gets translated into an assembly file which, in turn, is processed
- * by awk to generate offsets.h.  So if you make any changes to this
- * file, be sure to verify that the awk procedure still works (see
- * print_offsets.awk).
- */
-#include <linux/config.h>
-
-#include <linux/sched.h>
-
-#include <asm-ia64/processor.h>
-#include <asm-ia64/ptrace.h>
-#include <asm-ia64/siginfo.h>
-#include <asm-ia64/sigcontext.h>
-
-#include "../kernel/sigframe.h"
-
-#ifdef offsetof
-# undef offsetof
-#endif
-
-/*
- * We _can't_ include the host's standard header file, as those are in
- *  potential conflict with the what the Linux kernel declares for the
- *  target system.
- */
-extern int printf (const char *, ...);
-
-#define offsetof(type,field)	((char *) &((type *) 0)->field - (char *) 0)
-
-struct
-  {
-    const char name[256];
-    unsigned long value;
-  }
-tab[] =
-  {
-    { "IA64_TASK_SIZE",			sizeof (struct task_struct) },
-    { "IA64_THREAD_INFO_SIZE",		sizeof (struct thread_info) },
-    { "IA64_PT_REGS_SIZE",		sizeof (struct pt_regs) },
-    { "IA64_SWITCH_STACK_SIZE",		sizeof (struct switch_stack) },
-    { "IA64_SIGINFO_SIZE",		sizeof (struct siginfo) },
-    { "IA64_CPU_SIZE",			sizeof (struct cpuinfo_ia64) },
-    { "SIGFRAME_SIZE",			sizeof (struct sigframe) },
-    { "UNW_FRAME_INFO_SIZE",		sizeof (struct unw_frame_info) },
-    { "", 0 },			/* spacer */
-    { "IA64_TASK_CLEAR_CHILD_TID_OFFSET",offsetof (struct task_struct, clear_child_tid) },
-    { "IA64_TASK_GROUP_LEADER_OFFSET",	offsetof (struct task_struct, group_leader) },
-    { "IA64_TASK_PID_OFFSET",		offsetof (struct task_struct, pid) },
-    { "IA64_TASK_REAL_PARENT_OFFSET",	offsetof (struct task_struct, real_parent) },
-    { "IA64_TASK_TGID_OFFSET",		offsetof (struct task_struct, tgid) },
-    { "IA64_TASK_THREAD_KSP_OFFSET",	offsetof (struct task_struct, thread.ksp) },
-    { "IA64_TASK_THREAD_ON_USTACK_OFFSET", offsetof (struct task_struct, thread.on_ustack) },
-    { "IA64_PT_REGS_CR_IPSR_OFFSET",	offsetof (struct pt_regs, cr_ipsr) },
-    { "IA64_PT_REGS_CR_IIP_OFFSET",	offsetof (struct pt_regs, cr_iip) },
-    { "IA64_PT_REGS_CR_IFS_OFFSET",	offsetof (struct pt_regs, cr_ifs) },
-    { "IA64_PT_REGS_AR_UNAT_OFFSET",	offsetof (struct pt_regs, ar_unat) },
-    { "IA64_PT_REGS_AR_PFS_OFFSET",	offsetof (struct pt_regs, ar_pfs) },
-    { "IA64_PT_REGS_AR_RSC_OFFSET",	offsetof (struct pt_regs, ar_rsc) },
-    { "IA64_PT_REGS_AR_RNAT_OFFSET",	offsetof (struct pt_regs, ar_rnat) },
-    { "IA64_PT_REGS_AR_BSPSTORE_OFFSET",offsetof (struct pt_regs, ar_bspstore) },
-    { "IA64_PT_REGS_PR_OFFSET",		offsetof (struct pt_regs, pr) },
-    { "IA64_PT_REGS_B6_OFFSET",		offsetof (struct pt_regs, b6) },
-    { "IA64_PT_REGS_LOADRS_OFFSET",	offsetof (struct pt_regs, loadrs) },
-    { "IA64_PT_REGS_R1_OFFSET",		offsetof (struct pt_regs, r1) },
-    { "IA64_PT_REGS_R2_OFFSET",		offsetof (struct pt_regs, r2) },
-    { "IA64_PT_REGS_R3_OFFSET",		offsetof (struct pt_regs, r3) },
-    { "IA64_PT_REGS_R12_OFFSET",	offsetof (struct pt_regs, r12) },
-    { "IA64_PT_REGS_R13_OFFSET",	offsetof (struct pt_regs, r13) },
-    { "IA64_PT_REGS_R14_OFFSET",	offsetof (struct pt_regs, r14) },
-    { "IA64_PT_REGS_R15_OFFSET",	offsetof (struct pt_regs, r15) },
-    { "IA64_PT_REGS_R8_OFFSET",		offsetof (struct pt_regs, r8) },
-    { "IA64_PT_REGS_R9_OFFSET",		offsetof (struct pt_regs, r9) },
-    { "IA64_PT_REGS_R10_OFFSET",	offsetof (struct pt_regs, r10) },
-    { "IA64_PT_REGS_R11_OFFSET",	offsetof (struct pt_regs, r11) },
-    { "IA64_PT_REGS_R16_OFFSET",	offsetof (struct pt_regs, r16) },
-    { "IA64_PT_REGS_R17_OFFSET",	offsetof (struct pt_regs, r17) },
-    { "IA64_PT_REGS_R18_OFFSET",	offsetof (struct pt_regs, r18) },
-    { "IA64_PT_REGS_R19_OFFSET",	offsetof (struct pt_regs, r19) },
-    { "IA64_PT_REGS_R20_OFFSET",	offsetof (struct pt_regs, r20) },
-    { "IA64_PT_REGS_R21_OFFSET",	offsetof (struct pt_regs, r21) },
-    { "IA64_PT_REGS_R22_OFFSET",	offsetof (struct pt_regs, r22) },
-    { "IA64_PT_REGS_R23_OFFSET",	offsetof (struct pt_regs, r23) },
-    { "IA64_PT_REGS_R24_OFFSET",	offsetof (struct pt_regs, r24) },
-    { "IA64_PT_REGS_R25_OFFSET",	offsetof (struct pt_regs, r25) },
-    { "IA64_PT_REGS_R26_OFFSET",	offsetof (struct pt_regs, r26) },
-    { "IA64_PT_REGS_R27_OFFSET",	offsetof (struct pt_regs, r27) },
-    { "IA64_PT_REGS_R28_OFFSET",	offsetof (struct pt_regs, r28) },
-    { "IA64_PT_REGS_R29_OFFSET",	offsetof (struct pt_regs, r29) },
-    { "IA64_PT_REGS_R30_OFFSET",	offsetof (struct pt_regs, r30) },
-    { "IA64_PT_REGS_R31_OFFSET",	offsetof (struct pt_regs, r31) },
-    { "IA64_PT_REGS_AR_CCV_OFFSET",	offsetof (struct pt_regs, ar_ccv) },
-    { "IA64_PT_REGS_AR_FPSR_OFFSET",	offsetof (struct pt_regs, ar_fpsr) },
-    { "IA64_PT_REGS_B0_OFFSET",		offsetof (struct pt_regs, b0) },
-    { "IA64_PT_REGS_B7_OFFSET",		offsetof (struct pt_regs, b7) },
-    { "IA64_PT_REGS_F6_OFFSET",		offsetof (struct pt_regs, f6) },
-    { "IA64_PT_REGS_F7_OFFSET",		offsetof (struct pt_regs, f7) },
-    { "IA64_PT_REGS_F8_OFFSET",		offsetof (struct pt_regs, f8) },
-    { "IA64_PT_REGS_F9_OFFSET",		offsetof (struct pt_regs, f9) },
-    { "IA64_SWITCH_STACK_CALLER_UNAT_OFFSET",	offsetof (struct switch_stack, caller_unat) },
-    { "IA64_SWITCH_STACK_AR_FPSR_OFFSET",	offsetof (struct switch_stack, ar_fpsr) },
-    { "IA64_SWITCH_STACK_F2_OFFSET",		offsetof (struct switch_stack, f2) },
-    { "IA64_SWITCH_STACK_F3_OFFSET",		offsetof (struct switch_stack, f3) },
-    { "IA64_SWITCH_STACK_F4_OFFSET",		offsetof (struct switch_stack, f4) },
-    { "IA64_SWITCH_STACK_F5_OFFSET",		offsetof (struct switch_stack, f5) },
-    { "IA64_SWITCH_STACK_F10_OFFSET",		offsetof (struct switch_stack, f10) },
-    { "IA64_SWITCH_STACK_F11_OFFSET",		offsetof (struct switch_stack, f11) },
-    { "IA64_SWITCH_STACK_F12_OFFSET",		offsetof (struct switch_stack, f12) },
-    { "IA64_SWITCH_STACK_F13_OFFSET",		offsetof (struct switch_stack, f13) },
-    { "IA64_SWITCH_STACK_F14_OFFSET",		offsetof (struct switch_stack, f14) },
-    { "IA64_SWITCH_STACK_F15_OFFSET",		offsetof (struct switch_stack, f15) },
-    { "IA64_SWITCH_STACK_F16_OFFSET",		offsetof (struct switch_stack, f16) },
-    { "IA64_SWITCH_STACK_F17_OFFSET",		offsetof (struct switch_stack, f17) },
-    { "IA64_SWITCH_STACK_F18_OFFSET",		offsetof (struct switch_stack, f18) },
-    { "IA64_SWITCH_STACK_F19_OFFSET",		offsetof (struct switch_stack, f19) },
-    { "IA64_SWITCH_STACK_F20_OFFSET",		offsetof (struct switch_stack, f20) },
-    { "IA64_SWITCH_STACK_F21_OFFSET",		offsetof (struct switch_stack, f21) },
-    { "IA64_SWITCH_STACK_F22_OFFSET",		offsetof (struct switch_stack, f22) },
-    { "IA64_SWITCH_STACK_F23_OFFSET",		offsetof (struct switch_stack, f23) },
-    { "IA64_SWITCH_STACK_F24_OFFSET",		offsetof (struct switch_stack, f24) },
-    { "IA64_SWITCH_STACK_F25_OFFSET",		offsetof (struct switch_stack, f25) },
-    { "IA64_SWITCH_STACK_F26_OFFSET",		offsetof (struct switch_stack, f26) },
-    { "IA64_SWITCH_STACK_F27_OFFSET",		offsetof (struct switch_stack, f27) },
-    { "IA64_SWITCH_STACK_F28_OFFSET",		offsetof (struct switch_stack, f28) },
-    { "IA64_SWITCH_STACK_F29_OFFSET",		offsetof (struct switch_stack, f29) },
-    { "IA64_SWITCH_STACK_F30_OFFSET",		offsetof (struct switch_stack, f30) },
-    { "IA64_SWITCH_STACK_F31_OFFSET",		offsetof (struct switch_stack, f31) },
-    { "IA64_SWITCH_STACK_R4_OFFSET",		offsetof (struct switch_stack, r4) },
-    { "IA64_SWITCH_STACK_R5_OFFSET",		offsetof (struct switch_stack, r5) },
-    { "IA64_SWITCH_STACK_R6_OFFSET",		offsetof (struct switch_stack, r6) },
-    { "IA64_SWITCH_STACK_R7_OFFSET",		offsetof (struct switch_stack, r7) },
-    { "IA64_SWITCH_STACK_B0_OFFSET",		offsetof (struct switch_stack, b0) },
-    { "IA64_SWITCH_STACK_B1_OFFSET",		offsetof (struct switch_stack, b1) },
-    { "IA64_SWITCH_STACK_B2_OFFSET",		offsetof (struct switch_stack, b2) },
-    { "IA64_SWITCH_STACK_B3_OFFSET",		offsetof (struct switch_stack, b3) },
-    { "IA64_SWITCH_STACK_B4_OFFSET",		offsetof (struct switch_stack, b4) },
-    { "IA64_SWITCH_STACK_B5_OFFSET",		offsetof (struct switch_stack, b5) },
-    { "IA64_SWITCH_STACK_AR_PFS_OFFSET",	offsetof (struct switch_stack, ar_pfs) },
-    { "IA64_SWITCH_STACK_AR_LC_OFFSET",		offsetof (struct switch_stack, ar_lc) },
-    { "IA64_SWITCH_STACK_AR_UNAT_OFFSET",	offsetof (struct switch_stack, ar_unat) },
-    { "IA64_SWITCH_STACK_AR_RNAT_OFFSET",	offsetof (struct switch_stack, ar_rnat) },
-    { "IA64_SWITCH_STACK_AR_BSPSTORE_OFFSET",	offsetof (struct switch_stack, ar_bspstore) },
-    { "IA64_SWITCH_STACK_PR_OFFSET",	offsetof (struct switch_stack, pr) },
-    { "IA64_SIGCONTEXT_IP_OFFSET",	offsetof (struct sigcontext, sc_ip) },
-    { "IA64_SIGCONTEXT_AR_BSP_OFFSET",	offsetof (struct sigcontext, sc_ar_bsp) },
-    { "IA64_SIGCONTEXT_AR_FPSR_OFFSET", offsetof (struct sigcontext, sc_ar_fpsr) },
-    { "IA64_SIGCONTEXT_AR_RNAT_OFFSET",	offsetof (struct sigcontext, sc_ar_rnat) },
-    { "IA64_SIGCONTEXT_AR_UNAT_OFFSET", offsetof (struct sigcontext, sc_ar_unat) },
-    { "IA64_SIGCONTEXT_B0_OFFSET",	offsetof (struct sigcontext, sc_br[0]) },
-    { "IA64_SIGCONTEXT_CFM_OFFSET",	offsetof (struct sigcontext, sc_cfm) },
-    { "IA64_SIGCONTEXT_FLAGS_OFFSET",	offsetof (struct sigcontext, sc_flags) },
-    { "IA64_SIGCONTEXT_FR6_OFFSET",	offsetof (struct sigcontext, sc_fr[6]) },
-    { "IA64_SIGCONTEXT_PR_OFFSET",	offsetof (struct sigcontext, sc_pr) },
-    { "IA64_SIGCONTEXT_R12_OFFSET",	offsetof (struct sigcontext, sc_gr[12]) },
-    { "IA64_SIGCONTEXT_RBS_BASE_OFFSET",offsetof (struct sigcontext, sc_rbs_base) },
-    { "IA64_SIGCONTEXT_LOADRS_OFFSET",	offsetof (struct sigcontext, sc_loadrs) },
-    { "IA64_SIGFRAME_ARG0_OFFSET",		offsetof (struct sigframe, arg0) },
-    { "IA64_SIGFRAME_ARG1_OFFSET",		offsetof (struct sigframe, arg1) },
-    { "IA64_SIGFRAME_ARG2_OFFSET",		offsetof (struct sigframe, arg2) },
-    { "IA64_SIGFRAME_HANDLER_OFFSET",		offsetof (struct sigframe, handler) },
-    { "IA64_SIGFRAME_SIGCONTEXT_OFFSET",	offsetof (struct sigframe, sc) },
-    /* for assembly files which can't include sched.h: */
-    { "IA64_CLONE_VFORK",		CLONE_VFORK },
-    { "IA64_CLONE_VM",			CLONE_VM },
-    /* used by fsys_gettimeofday in arch/ia64/kernel/fsys.S */
-    { "IA64_CPUINFO_ITM_DELTA_OFFSET", 		offsetof (struct cpuinfo_ia64, itm_delta) },
-    { "IA64_CPUINFO_ITM_NEXT_OFFSET", 		offsetof (struct cpuinfo_ia64, itm_next) },
-    { "IA64_CPUINFO_NSEC_PER_CYC_OFFSET",	offsetof (struct cpuinfo_ia64, nsec_per_cyc) },
-    { "IA64_TIMESPEC_TV_NSEC_OFFSET", 		offsetof (struct timespec, tv_nsec) },
-
-};
-
-static const char *tabs = "\t\t\t\t\t\t\t\t\t\t";
-
-int
-main (int argc, char **argv)
-{
-  const char *space;
-  int i, num_tabs;
-  size_t len;
-
-  printf ("#ifndef _ASM_IA64_OFFSETS_H\n");
-  printf ("#define _ASM_IA64_OFFSETS_H\n\n");
-
-  printf ("/*\n * DO NOT MODIFY\n *\n * This file was generated by "
-	  "arch/ia64/tools/print_offsets.\n *\n */\n\n");
-
-  for (i = 0; i < (int) (sizeof (tab) / sizeof (tab[0])); ++i)
-    {
-      if (tab[i].name[0] == '\0')
-	printf ("\n");
-      else
-	{
-	  len = strlen (tab[i].name);
-
-	  num_tabs = (40 - len) / 8;
-	  if (num_tabs <= 0)
-	    space = " ";
-	  else
-	    space = strchr(tabs, '\0') - (40 - len) / 8;
-
-	  printf ("#define %s%s%lu\t/* 0x%lx */\n",
-		  tab[i].name, space, tab[i].value, tab[i].value);
-	}
-    }
-
-  printf ("\n#define CLONE_IDLETASK_BIT	%ld\n", ia64_fls (CLONE_IDLETASK));
-  printf ("\n#define CLONE_SETTLS_BIT	%ld\n", ia64_fls (CLONE_SETTLS));
-
-  printf ("\n#endif /* _ASM_IA64_OFFSETS_H */\n");
-  return 0;
-}
diff -Nru a/arch/ia64/vmlinux.lds.S b/arch/ia64/vmlinux.lds.S
--- a/arch/ia64/vmlinux.lds.S	Wed Jun 18 23:42:08 2003
+++ b/arch/ia64/vmlinux.lds.S	Wed Jun 18 23:42:08 2003
@@ -3,8 +3,9 @@
 #include <asm/cache.h>
 #include <asm/ptrace.h>
 #include <asm/system.h>
+#include <asm/pgtable.h>
 
-#define LOAD_OFFSET PAGE_OFFSET
+#define LOAD_OFFSET KERNEL_START + KERNEL_TR_PAGE_SIZE
 #include <asm-generic/vmlinux.lds.h>
 
 OUTPUT_FORMAT("elf64-ia64-little")
@@ -23,22 +24,22 @@
 	}
 
   v = PAGE_OFFSET;	/* this symbol is here to make debugging easier... */
-  phys_start = _start - PAGE_OFFSET;
+  phys_start = _start - LOAD_OFFSET;
 
   . = KERNEL_START;
 
   _text = .;
   _stext = .;
 
-  .text : AT(ADDR(.text) - PAGE_OFFSET)
+  .text : AT(ADDR(.text) - LOAD_OFFSET)
     {
 	*(.text.ivt)
 	*(.text)
     }
-  .text2 : AT(ADDR(.text2) - PAGE_OFFSET)
+  .text2 : AT(ADDR(.text2) - LOAD_OFFSET)
 	{ *(.text2) }
 #ifdef CONFIG_SMP
-  .text.lock : AT(ADDR(.text.lock) - PAGE_OFFSET)
+  .text.lock : AT(ADDR(.text.lock) - LOAD_OFFSET)
 	{ *(.text.lock) }
 #endif
   _etext = .;
@@ -47,17 +48,24 @@
 
   /* Exception table */
   . = ALIGN(16);
-  __ex_table : AT(ADDR(__ex_table) - PAGE_OFFSET)
+  __ex_table : AT(ADDR(__ex_table) - LOAD_OFFSET)
 	{
 	  __start___ex_table = .;
 	  *(__ex_table)
 	  __stop___ex_table = .;
 	}
 
-  __mckinley_e9_bundles : AT(ADDR(__mckinley_e9_bundles) - PAGE_OFFSET)
+  .data.patch.vtop : AT(ADDR(.data.patch.vtop) - LOAD_OFFSET)
+	{
+	  __start___vtop_patchlist = .;
+	  *(.data.patch.vtop)
+	  __end____vtop_patchlist = .;
+	}
+
+  .data.patch.mckinley_e9 : AT(ADDR(.data.patch.mckinley_e9) - LOAD_OFFSET)
 	{
 	  __start___mckinley_e9_bundles = .;
-	  *(__mckinley_e9_bundles)
+	  *(.data.patch.mckinley_e9)
 	  __end___mckinley_e9_bundles = .;
 	}
 
@@ -67,7 +75,7 @@
 #if defined(CONFIG_IA64_GENERIC)
   /* Machine Vector */
   . = ALIGN(16);
-  .machvec : AT(ADDR(.machvec) - PAGE_OFFSET)
+  .machvec : AT(ADDR(.machvec) - LOAD_OFFSET)
 	{
 	  machvec_start = .;
 	  *(.machvec)
@@ -77,9 +85,9 @@
 
   /* Unwind info & table: */
   . = ALIGN(8);
-  .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - PAGE_OFFSET)
+  .IA_64.unwind_info : AT(ADDR(.IA_64.unwind_info) - LOAD_OFFSET)
 	{ *(.IA_64.unwind_info*) }
-  .IA_64.unwind : AT(ADDR(.IA_64.unwind) - PAGE_OFFSET)
+  .IA_64.unwind : AT(ADDR(.IA_64.unwind) - LOAD_OFFSET)
 	{
 	  ia64_unw_start = .;
 	  *(.IA_64.unwind*)
@@ -88,24 +96,24 @@
 
   RODATA
 
-  .opd : AT(ADDR(.opd) - PAGE_OFFSET)
+  .opd : AT(ADDR(.opd) - LOAD_OFFSET)
 	{ *(.opd) }
 
   /* Initialization code and data: */
 
   . = ALIGN(PAGE_SIZE);
   __init_begin = .;
-  .init.text : AT(ADDR(.init.text) - PAGE_OFFSET)
+  .init.text : AT(ADDR(.init.text) - LOAD_OFFSET)
 	{
 	  _sinittext = .;
 	  *(.init.text)
 	  _einittext = .;
 	}
 
-  .init.data : AT(ADDR(.init.data) - PAGE_OFFSET)
+  .init.data : AT(ADDR(.init.data) - LOAD_OFFSET)
 	{ *(.init.data) }
 
-  .init.ramfs : AT(ADDR(.init.ramfs) - PAGE_OFFSET)
+  .init.ramfs : AT(ADDR(.init.ramfs) - LOAD_OFFSET)
 	{
 	  __initramfs_start = .;
 	  *(.init.ramfs)
@@ -113,19 +121,19 @@
 	}
 
    . = ALIGN(16);
-  .init.setup : AT(ADDR(.init.setup) - PAGE_OFFSET)
+  .init.setup : AT(ADDR(.init.setup) - LOAD_OFFSET)
         {
 	  __setup_start = .;
 	  *(.init.setup)
 	  __setup_end = .;
 	}
-  __param : AT(ADDR(__param) - PAGE_OFFSET)
+  __param : AT(ADDR(__param) - LOAD_OFFSET)
         {
 	  __start___param = .;
 	  *(__param)
 	  __stop___param = .;
 	}
-  .initcall.init : AT(ADDR(.initcall.init) - PAGE_OFFSET)
+  .initcall.init : AT(ADDR(.initcall.init) - LOAD_OFFSET)
 	{
 	  __initcall_start = .;
 	  *(.initcall1.init)
@@ -138,7 +146,7 @@
 	  __initcall_end = .;
 	}
    __con_initcall_start = .;
-  .con_initcall.init : AT(ADDR(.con_initcall.init) - PAGE_OFFSET)
+  .con_initcall.init : AT(ADDR(.con_initcall.init) - LOAD_OFFSET)
 	{ *(.con_initcall.init) }
   __con_initcall_end = .;
   __security_initcall_start = .;
@@ -149,24 +157,24 @@
   __init_end = .;
 
   /* The initial task and kernel stack */
-  .data.init_task : AT(ADDR(.data.init_task) - PAGE_OFFSET)
+  .data.init_task : AT(ADDR(.data.init_task) - LOAD_OFFSET)
 	{ *(.data.init_task) }
 
-  .data.page_aligned : AT(ADDR(.data.page_aligned) - PAGE_OFFSET)
+  .data.page_aligned : AT(ADDR(.data.page_aligned) - LOAD_OFFSET)
         { *(__special_page_section)
 	  __start_gate_section = .;
-	  *(.text.gate)
+	  *(.data.gate)
 	  __stop_gate_section = .;
 	}
+  . = ALIGN(PAGE_SIZE);		/* make sure the gate page doesn't expose kernel data */
 
-  . = ALIGN(SMP_CACHE_BYTES);
-  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - PAGE_OFFSET)
+  .data.cacheline_aligned : AT(ADDR(.data.cacheline_aligned) - LOAD_OFFSET)
         { *(.data.cacheline_aligned) }
 
   /* Per-cpu data: */
   . = ALIGN(PERCPU_PAGE_SIZE);
   __phys_per_cpu_start = .;
-  .data.percpu PERCPU_ADDR : AT(__phys_per_cpu_start - PAGE_OFFSET)
+  .data.percpu PERCPU_ADDR : AT(__phys_per_cpu_start - LOAD_OFFSET)
 	{
 		__per_cpu_start = .;
 		*(.data.percpu)
@@ -174,24 +182,24 @@
 	}
   . = __phys_per_cpu_start + PERCPU_PAGE_SIZE;	/* ensure percpu data fits into percpu page size */
 
-  .data : AT(ADDR(.data) - PAGE_OFFSET)
+  .data : AT(ADDR(.data) - LOAD_OFFSET)
 	{ *(.data) *(.gnu.linkonce.d*) CONSTRUCTORS }
 
   . = ALIGN(16);
   __gp = . + 0x200000;	/* gp must be 16-byte aligned for exc. table */
 
-  .got : AT(ADDR(.got) - PAGE_OFFSET)
+  .got : AT(ADDR(.got) - LOAD_OFFSET)
 	{ *(.got.plt) *(.got) }
   /* 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 : AT(ADDR(.sdata) - PAGE_OFFSET)
+  .sdata : AT(ADDR(.sdata) - LOAD_OFFSET)
 	{ *(.sdata) }
   _edata  =  .;
   _bss = .;
-  .sbss : AT(ADDR(.sbss) - PAGE_OFFSET)
+  .sbss : AT(ADDR(.sbss) - LOAD_OFFSET)
 	{ *(.sbss) *(.scommon) }
-  .bss : AT(ADDR(.bss) - PAGE_OFFSET)
+  .bss : AT(ADDR(.bss) - LOAD_OFFSET)
 	{ *(.bss) *(COMMON) }
 
   _end = .;
diff -Nru a/arch/m68k/Kconfig b/arch/m68k/Kconfig
--- a/arch/m68k/Kconfig	Wed Jun 18 23:42:07 2003
+++ b/arch/m68k/Kconfig	Wed Jun 18 23:42:07 2003
@@ -376,81 +376,7 @@
 
 endchoice
 
-config BINFMT_AOUT
-	tristate "Kernel support for a.out binaries"
-	---help---
-	  A.out (Assembler.OUTput) is a set of formats for libraries and
-	  executables used in the earliest versions of UNIX. Linux used the
-	  a.out formats QMAGIC and ZMAGIC until they were replaced with the
-	  ELF format.
-
-	  As more and more programs are converted to ELF, the use for a.out
-	  will gradually diminish. If you disable this option it will reduce
-	  your kernel by one page. This is not much and by itself does not
-	  warrant removing support. However its removal is a good idea if you
-	  wish to ensure that absolutely none of your programs will use this
-	  older executable format. If you don't know what to answer at this
-	  point then answer Y. If someone told you "You need a kernel with
-	  QMAGIC support" then you'll have to say Y here. You may answer M to
-	  compile a.out support as a module and later load the module when you
-	  want to use a program or library in a.out format. The module will be
-	  called binfmt_aout. Saying M or N here is dangerous though,
-	  because some crucial programs on your system might still be in A.OUT
-	  format.
-
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  use this part of the kernel.
-
-	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 config ZORRO
 	bool "Amiga Zorro (AutoConfig) bus support"
@@ -680,417 +606,7 @@
 	  module if your root file system (the one containing the directory /)
 	  is located on a SCSI device.
 
-comment "SCSI support type (disk, tape, CD-ROM)"
-	depends on SCSI
-
-config BLK_DEV_SD
-	tristate "SCSI disk support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI hard disk or the SCSI or parallel port
-	  version of the IOMEGA ZIP drive under Linux, say Y and read the
-	  SCSI-HOWTO, the Disk-HOWTO and the Multi-Disk-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>. This is NOT for SCSI
-	  CD-ROMs.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sd_mod.  If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.  Do not compile this driver as a
-	  module if your root file system (the one containing the directory /)
-	  is located on a SCSI disk. In this case, do not compile the driver
-	  for your SCSI host adapter (below) as a module either.
-
-config SD_EXTRA_DEVS
-	int "Maximum number of SCSI disks that can be loaded as modules"
-	depends on BLK_DEV_SD
-	default "40"
-	---help---
-	  This controls the amount of additional space allocated in tables for
-	  drivers that are loaded as modules after the kernel is booted.  In
-	  the event that the SCSI core itself was loaded as a module, this
-	  value is the number of additional disks that can be loaded after the
-	  first host driver is loaded.
-
-	  Admittedly this isn't pretty, but there are tons of race conditions
-	  involved with resizing the internal arrays on the fly.  Someday this
-	  flag will go away, and everything will work automatically.
-
-	  If you don't understand what's going on, go with the default.
-
-config CHR_DEV_ST
-	tristate "SCSI tape support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI tape drive under Linux, say Y and read the
-	  SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>, and
-	  <file:Documentation/scsi/st.txt> in the kernel source.  This is NOT for
-	  SCSI CD-ROMs.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called st. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.
-
-config ST_EXTRA_DEVS
-	int "Maximum number of SCSI tapes that can be loaded as modules"
-	depends on CHR_DEV_ST
-	default "2"
-	---help---
-	  This controls the amount of additional space allocated in tables for
-	  drivers that are loaded as modules after the kernel is booted.  In
-	  the event that the SCSI core itself was loaded as a module, this
-	  value is the number of additional tapes that can be loaded after the
-	  first host driver is loaded.
-
-	  Admittedly this isn't pretty, but there are tons of race conditions
-	  involved with resizing the internal arrays on the fly.  Someday this
-	  flag will go away, and everything will work automatically.
-
-	  If you don't understand what's going on, go with the default.
-
-config BLK_DEV_SR
-	tristate "SCSI CDROM support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI CD-ROM under Linux, say Y and read the
-	  SCSI-HOWTO and the CD-ROM-HOWTO at
-	  <http://www.tldp.org/docs.html#howto>. Also make sure to say Y
-	  or M to "ISO 9660 CD-ROM file system support" later.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sr_mod. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.
-
-config BLK_DEV_SR_VENDOR
-	bool "Enable vendor-specific extensions (for SCSI CDROM)"
-	depends on BLK_DEV_SR
-	help
-	  This enables the usage of vendor specific SCSI commands. This is
-	  required to support multisession CDs with old NEC/TOSHIBA cdrom
-	  drives (and HP Writers). If you have such a drive and get the first
-	  session only, try saying Y here; everybody else says N.
-
-config SR_EXTRA_DEVS
-	int "Maximum number of CDROM devices that can be loaded as modules"
-	depends on BLK_DEV_SR
-	default "2"
-	---help---
-	  This controls the amount of additional space allocated in tables for
-	  drivers that are loaded as modules after the kernel is booted. In
-	  the event that the SCSI core itself was loaded as a module, this
-	  value is the number of additional CD-ROMs that can be loaded after
-	  the first host driver is loaded.
-
-	  Admittedly this isn't pretty, but there are tons of race conditions
-	  involved with resizing the internal arrays on the fly.  Someday this
-	  flag will go away, and everything will work automatically.
-
-	  If you don't understand what's going on, go with the default.
-
-config CHR_DEV_SG
-	tristate "SCSI generic support"
-	depends on SCSI
-	---help---
-	  If you want to use SCSI scanners, synthesizers or CD-writers or just
-	  about anything having "SCSI" in its name other than hard disks,
-	  CD-ROMs or tapes, say Y here. These won't be supported by the kernel
-	  directly, so you need some additional software which knows how to
-	  talk to these devices using the SCSI protocol:
-
-	  For scanners, look at SANE (<http://www.mostang.com/sane/>). For CD
-	  writer software look at Cdrtools
-	  (<http://www.fokus.gmd.de/research/cc/glone/employees/joerg.schilling/private/cdrecord.html>)
-	  and for burning a "disk at once": CDRDAO
-	  (<http://cdrdao.sourceforge.net/>). Cdparanoia is a high
-	  quality digital reader of audio CDs (<http://www.xiph.org/paranoia/>).
-	  For other devices, it's possible that you'll have to write the
-	  driver software yourself. Please read the file
-	  <file:Documentation/scsi/scsi-generic.txt> for more information.
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>. The module will be called sg.
-	  If unsure, say N.
-
-comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs"
-	depends on SCSI
-
-config SCSI_MULTI_LUN
-	bool "Probe all LUNs on each SCSI device"
-	depends on SCSI
-	help
-	  If you have a SCSI device that supports more than one LUN (Logical
-	  Unit Number), e.g. a CD jukebox, and only one LUN is detected, you
-	  can say Y here to force the SCSI driver to probe for multiple LUNs.
-	  A SCSI device with multiple LUNs acts logically like multiple SCSI
-	  devices. The vast majority of SCSI devices have only one LUN, and
-	  so most people can say N here and should in fact do so, because it
-	  is safer.
-
-config SCSI_CONSTANTS
-	bool "Verbose SCSI error reporting (kernel size +=12K)"
-	depends on SCSI
-	help
-	  The error messages regarding your SCSI hardware will be easier to
-	  understand if you say Y here; it will enlarge your kernel by about
-	  12 KB. If in doubt, say Y.
-
-config SCSI_LOGGING
-	bool "SCSI logging facility"
-	depends on SCSI
-	---help---
-	  This turns on a logging facility that can be used to debug a number
-	  of SCSI related problems.
-
-	  If you say Y here, no logging output will appear by default, but you
-	  can enable logging by saying Y to "/proc file system support" and
-	  "Sysctl support" below and executing the command
-
-	  echo "scsi log token [level]" > /proc/scsi/scsi
-
-	  at boot time after the /proc file system has been mounted.
-
-	  There are a number of things that can be used for 'token' (you can
-	  find them in the source: <file:drivers/scsi/scsi.c>), and this
-	  allows you to select the types of information you want, and the
-	  level allows you to select the level of verbosity.
-
-	  If you say N here, it may be harder to track down some types of SCSI
-	  problems. If you say Y here your kernel will be somewhat larger, but
-	  there should be no noticeable performance impact as long as you have
-	  logging turned off.
-
-
-menu "SCSI low-level drivers"
-	depends on SCSI!=n
-
-config A3000_SCSI
-	tristate "A3000 WD33C93A support"
-	depends on AMIGA && SCSI
-	help
-	  If you have an Amiga 3000 and have SCSI devices connected to the
-	  built-in SCSI controller, say Y. Otherwise, say N. This driver is
-	  also available as a module ( = code which can be inserted in and
-	  removed from the running kernel whenever you want). The module is
-	  called wd33c93. If you want to compile it as a module, say M here
-	  and read <file:Documentation/modules.txt>.
-
-config A4000T_SCSI
-	bool "A4000T SCSI support (EXPERIMENTAL)"
-	depends on AMIGA && EXPERIMENTAL
-	help
-	  Support for the NCR53C710 SCSI controller on the Amiga 4000T.
-
-config A2091_SCSI
-	tristate "A2091 WD33C93A support"
-	depends on ZORRO && SCSI
-	help
-	  If you have a Commodore A2091 SCSI controller, say Y. Otherwise,
-	  say N. This driver is also available as a module ( = code which can
-	  be inserted in and removed from the running kernel whenever you
-	  want). The module is called wd33c93. If you want to compile it as
-	  a module, say M here and read <file:Documentation/modules.txt>.
-
-config GVP11_SCSI
-	tristate "GVP Series II WD33C93A support"
-	depends on ZORRO && SCSI
-	---help---
-	  If you have a Great Valley Products Series II SCSI controller,
-	  answer Y. Also say Y if you have a later model of GVP SCSI
-	  controller (such as the GVP A4008 or a Combo board). Otherwise,
-	  answer N. This driver does NOT work for the T-Rex series of
-	  accelerators from TekMagic and GVP-M.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you
-	  want). The module will be called gvp11. If you want to compile it
-	  as a module, say M here and read <file:Documentation/modules.txt>.
-
-config CYBERSTORM_SCSI
-	tristate "CyberStorm SCSI support"
-	depends on ZORRO && SCSI
-	help
-	  If you have an Amiga with an original (MkI) Phase5 Cyberstorm
-	  accelerator board and the optional Cyberstorm SCSI controller,
-	  answer Y. Otherwise, say N.
-
-config CYBERSTORMII_SCSI
-	tristate "CyberStorm Mk II SCSI support"
-	depends on ZORRO && SCSI
-	help
-	  If you have an Amiga with a Phase5 Cyberstorm MkII accelerator board
-	  and the optional Cyberstorm SCSI controller, say Y. Otherwise,
-	  answer N.
-
-config BLZ2060_SCSI
-	tristate "Blizzard 2060 SCSI support"
-	depends on ZORRO && SCSI
-	help
-	  If you have an Amiga with a Phase5 Blizzard 2060 accelerator board
-	  and want to use the onboard SCSI controller, say Y. Otherwise,
-	  answer N.
-
-config BLZ1230_SCSI
-	tristate "Blizzard 1230IV/1260 SCSI support"
-	depends on ZORRO && SCSI
-	help
-	  If you have an Amiga 1200 with a Phase5 Blizzard 1230IV or Blizzard
-	  1260 accelerator, and the optional SCSI module, say Y. Otherwise,
-	  say N.
-
-config FASTLANE_SCSI
-	tristate "Fastlane SCSI support"
-	depends on ZORRO && SCSI
-	help
-	  If you have the Phase5 Fastlane Z3 SCSI controller, or plan to use
-	  one in the near future, say Y to this question. Otherwise, say N.
-
-config A4091_SCSI
-	bool "A4091 SCSI support (EXPERIMENTAL)"
-	depends on ZORRO && EXPERIMENTAL
-	help
-	  Support for the NCR53C710 chip on the Amiga 4091 Z3 SCSI2 controller
-	  (1993).  Very obscure -- the 4091 was part of an Amiga 4000 upgrade
-	  plan at the time the Amiga business was sold to DKB.
-
-config WARPENGINE_SCSI
-	bool "WarpEngine SCSI support (EXPERIMENTAL)"
-	depends on ZORRO && EXPERIMENTAL
-	help
-	  Support for MacroSystem Development's WarpEngine Amiga SCSI-2
-	  controller. Info at
-	  <http://www.lysator.liu.se/amiga/ar/guide/ar310.guide?FEATURE5>.
-
-config BLZ603EPLUS_SCSI
-	bool "Blizzard PowerUP 603e+ SCSI (EXPERIMENTAL)"
-	depends on ZORRO && EXPERIMENTAL
-	help
-	  If you have an Amiga 1200 with a Phase5 Blizzard PowerUP 603e+
-	  accelerator, say Y. Otherwise, say N.
-
-config OKTAGON_SCSI
-	tristate "BSC Oktagon SCSI support (EXPERIMENTAL)"
-	depends on ZORRO && EXPERIMENTAL && SCSI
-	help
-	  If you have the BSC Oktagon SCSI disk controller for the Amiga, say
-	  Y to this question.  If you're in doubt about whether you have one,
-	  see the picture at
-	  <http://amiga.multigraph.com/photos/oktagon.html>.
-
-#	 bool 'Cyberstorm Mk III SCSI support (EXPERIMENTAL)' CONFIG_CYBERSTORMIII_SCSI
-#	 bool 'GVP Turbo 040/060 SCSI support (EXPERIMENTAL)' CONFIG_GVP_TURBO_SCSI
-config ATARI_SCSI
-	tristate "Atari native SCSI support"
-	depends on ATARI && SCSI
-	---help---
-	  If you have an Atari with built-in NCR5380 SCSI controller (TT,
-	  Falcon, ...) say Y to get it supported. Of course also, if you have
-	  a compatible SCSI controller (e.g. for Medusa).  This driver is also
-	  available as a module ( = code which can be inserted in and removed
-	  from the running kernel whenever you want).  The module is called
-	  atari_scsi.  If you want to compile it as a module, say M here and
-	  read <file:Documentation/modules.txt>.  This driver supports both
-	  styles of NCR integration into the system: the TT style (separate
-	  DMA), and the Falcon style (via ST-DMA, replacing ACSI).  It does
-	  NOT support other schemes, like in the Hades (without DMA).
-
-config ATARI_SCSI_TOSHIBA_DELAY
-	bool "Long delays for Toshiba CD-ROMs"
-	depends on ATARI_SCSI
-	help
-	  This option increases the delay after a SCSI arbitration to
-	  accommodate some flaky Toshiba CD-ROM drives. Say Y if you intend to
-	  use a Toshiba CD-ROM drive; otherwise, the option is not needed and
-	  would impact performance a bit, so say N.
-
-config ATARI_SCSI_RESET_BOOT
-	bool "Reset SCSI-devices at boottime"
-	depends on ATARI_SCSI
-	help
-	  Reset the devices on your Atari whenever it boots.  This makes the
-	  boot process fractionally longer but may assist recovery from errors
-	  that leave the devices with SCSI operations partway completed.
-
-config TT_DMA_EMUL
-	bool "Hades SCSI DMA emulator"
-	depends on ATARI_SCSI && HADES
-	help
-	  This option enables code which emulates the TT SCSI DMA chip on the
-	  Hades. This increases the SCSI transfer rates at least ten times
-	  compared to PIO transfers.
-
-config MAC_SCSI
-	bool "Macintosh NCR5380 SCSI"
-	depends on MAC
-	help
-	  This is the NCR 5380 SCSI controller included on most of the 68030
-	  based Macintoshes.  If you have one of these say Y and read the
-	  SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-config SCSI_MAC_ESP
-	tristate "Macintosh NCR53c9[46] SCSI"
-	depends on MAC && SCSI
-	help
-	  This is the NCR 53c9x SCSI controller found on most of the 68040
-	  based Macintoshes.  If you have one of these say Y and read the
-	  SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called mac_esp.  If you want to compile it as
-	  a module, say M here and read <file:Documentation/modules.txt>.
-
-#   dep_tristate 'SCSI debugging host adapter' CONFIG_SCSI_DEBUG $CONFIG_SCSI
-config MVME147_SCSI
-	bool "WD33C93 SCSI driver for MVME147"
-	depends on MVME147
-	help
-	  Support for the on-board SCSI controller on the Motorola MVME147
-	  single-board computer.
-
-config MVME16x_SCSI
-	bool "NCR53C710 SCSI driver for MVME16x"
-	depends on MVME16x
-	help
-	  The Motorola MVME162, 166, 167, 172 and 177 boards use the NCR53C710
-	  SCSI controller chip.  Almost everyone using one of these boards
-	  will want to say Y to this question.
-
-config BVME6000_SCSI
-	bool "NCR53C710 SCSI driver for BVME6000"
-	depends on BVME6000
-	help
-	  The BVME4000 and BVME6000 boards from BVM Ltd use the NCR53C710
-	  SCSI controller chip.  Almost everyone using one of these boards
-	  will want to say Y to this question.
-
-config SUN3_SCSI
-	tristate "Sun3 NCR5380 SCSI"
-	depends on SUN3 && SCSI
-	help
-	  This option will enable support for the OBIO (onboard io) NCR5380
-	  SCSI controller found in the Sun 3/50 and 3/60, as well as for
-	  "Sun3" type VME scsi controllers also based on the NCR5380.
-	  General Linux information on the Sun 3 series (now discontinued)
-	  is at <http://www.angelfire.com/ca2/tech68k/sun3.html>.
-
-config SUN3X_ESP
-	bool "Sun3x ESP SCSI"
-	depends on SUN3X
-	help
-	  The ESP was an on-board SCSI controller used on Sun 3/80
-	  machines.  Say Y here to compile in support for it.
-
-endmenu
+source "drivers/scsi/Kconfig"
 
 endmenu
 
diff -Nru a/arch/m68knommu/Kconfig b/arch/m68knommu/Kconfig
--- a/arch/m68knommu/Kconfig	Wed Jun 18 23:42:08 2003
+++ b/arch/m68knommu/Kconfig	Wed Jun 18 23:42:08 2003
@@ -501,16 +501,7 @@
 config KCORE_ELF
 	default y
 
-config BINFMT_FLAT
-	tristate "Kernel support for flat binaries"
-	help
-	  Support uClinux FLAT format binaries.
-
-config BINFMT_ZFLAT
-	bool "  Enable ZFLAT support"
-	depends on BINFMT_FLAT
-	help
-	  Supoprt FLAT format compressed binaries
+source "fs/Kconfig.binfmt"
 
 endmenu
 
diff -Nru a/arch/mips/Kconfig b/arch/mips/Kconfig
--- a/arch/mips/Kconfig	Wed Jun 18 23:42:07 2003
+++ b/arch/mips/Kconfig	Wed Jun 18 23:42:07 2003
@@ -702,82 +702,7 @@
 	bool "ARC console support"
 	depends on ARC32
 
-config BINFMT_AOUT
-	bool
-	---help---
-	  A.out (Assembler.OUTput) is a set of formats for libraries and
-	  executables used in the earliest versions of UNIX. Linux used the
-	  a.out formats QMAGIC and ZMAGIC until they were replaced with the
-	  ELF format.
-
-	  As more and more programs are converted to ELF, the use for a.out
-	  will gradually diminish. If you disable this option it will reduce
-	  your kernel by one page. This is not much and by itself does not
-	  warrant removing support. However its removal is a good idea if you
-	  wish to ensure that absolutely none of your programs will use this
-	  older executable format. If you don't know what to answer at this
-	  point then answer Y. If someone told you "You need a kernel with
-	  QMAGIC support" then you'll have to say Y here. You may answer M to
-	  compile a.out support as a module and later load the module when you
-	  want to use a program or library in a.out format. The module will be
-	  called binfmt_aout. Saying M or N here is dangerous though,
-	  because some crucial programs on your system might still be in A.OUT
-	  format.
-
-config BINFMT_ELF
-	bool
-	default y
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  use this part of the kernel.
-
-	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 source "drivers/pci/Kconfig"
 
diff -Nru a/arch/mips64/Kconfig b/arch/mips64/Kconfig
--- a/arch/mips64/Kconfig	Wed Jun 18 23:42:06 2003
+++ b/arch/mips64/Kconfig	Wed Jun 18 23:42:06 2003
@@ -335,34 +335,7 @@
 	bool "ARC console support"
 	depends on ARC32
 
-config BINFMT_ELF
-	tristate "Kernel support for 64-bit ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
+source "fs/Kconfig.binfmt"
 
 config MIPS32_COMPAT
 	bool "Kernel support for Linux/MIPS 32-bit binary compatibility"
@@ -378,36 +351,11 @@
 
 config BINFMT_ELF32
 	bool
-	depends on MIPS32_COMPAT
+	depends on BINFMT_ELF && MIPS32_COMPAT
 	default y
 	help
 	  This allows you to run 32-bit Linux/ELF binaries on your Ultra.
 	  Everybody wants this; say Y.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  use this part of the kernel.
-
-	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc. If you
-	  don't know what to answer at this point, say Y.
 
 endmenu
 
diff -Nru a/arch/parisc/Kconfig b/arch/parisc/Kconfig
--- a/arch/parisc/Kconfig	Wed Jun 18 23:42:07 2003
+++ b/arch/parisc/Kconfig	Wed Jun 18 23:42:07 2003
@@ -166,66 +166,7 @@
 	depends on PROC_FS
 	default y
 
-config BINFMT_SOM
-	tristate "Kernel support for SOM binaries"
-	depends on HPUX
-	help
-	  SOM is a binary executable format inherited from HP/UX.  Say Y here
-	  to be able to load and execute SOM binaries directly.
-
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  use this part of the kernel.
-
-	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 endmenu
 
diff -Nru a/arch/ppc/Kconfig b/arch/ppc/Kconfig
--- a/arch/ppc/Kconfig	Wed Jun 18 23:42:09 2003
+++ b/arch/ppc/Kconfig	Wed Jun 18 23:42:09 2003
@@ -808,42 +808,11 @@
 	  "-g" option to preserve debugging information. It is mainly used
 	  for examining kernel data structures on the live kernel.
 
-config BINFMT_ELF
-	bool
-	default y
-	help
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems.
-
 config KERNEL_ELF
 	bool
 	default y
 
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp.  It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>).  Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  use this part of the kernel.
-
-	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 source "drivers/pci/Kconfig"
 
diff -Nru a/arch/ppc64/Kconfig b/arch/ppc64/Kconfig
--- a/arch/ppc64/Kconfig	Wed Jun 18 23:42:07 2003
+++ b/arch/ppc64/Kconfig	Wed Jun 18 23:42:07 2003
@@ -191,37 +191,7 @@
 	  "-g" option to preserve debugging information. It is mainly used
 	  for examining kernel data structures on the live kernel.
 
-config BINFMT_ELF
-	bool "Kernel support for 64-bit ELF binaries"
-	help
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp.  It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>).  Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  use this part of the kernel.
-
-	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 source "drivers/pci/Kconfig"
 
diff -Nru a/arch/s390/Kconfig b/arch/s390/Kconfig
--- a/arch/s390/Kconfig	Wed Jun 18 23:42:07 2003
+++ b/arch/s390/Kconfig	Wed Jun 18 23:42:07 2003
@@ -192,78 +192,8 @@
 config KCORE_ELF
 	bool
 	default y
-	---help---
-	  If you enabled support for /proc file system then the file
-	  /proc/kcore will contain the kernel core image. This can be used
-	  in gdb:
 
-	  $ cd /usr/src/linux ; gdb vmlinux /proc/kcore
-
-	  You have two choices here: ELF and A.OUT. Selecting ELF will make
-	  /proc/kcore appear in ELF core format as defined by the Executable
-	  and Linking Format specification. Selecting A.OUT will choose the
-	  old "a.out" format which may be necessary for some old versions
-	  of binutils or on some architectures.
-
-	  This is especially useful if you have compiled the kernel with the
-	  "-g" option to preserve debugging information. It is mainly used
-	  for examining kernel data structures on the live kernel so if you
-	  don't understand what this means or are not a kernel hacker, just
-	  leave it at its default value ELF.
-
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  use this part of the kernel.
-
-	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 config PROCESS_DEBUG
 	bool "Show crashed user process info"
diff -Nru a/arch/sh/Kconfig b/arch/sh/Kconfig
--- a/arch/sh/Kconfig	Wed Jun 18 23:42:09 2003
+++ b/arch/sh/Kconfig	Wed Jun 18 23:42:09 2003
@@ -763,62 +763,7 @@
 
 endchoice
 
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_FLAT
-	tristate "Kernel support for FLAT binaries"
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  use this part of the kernel.
-
-	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 endmenu
 
diff -Nru a/arch/sparc/Kconfig b/arch/sparc/Kconfig
--- a/arch/sparc/Kconfig	Wed Jun 18 23:42:05 2003
+++ b/arch/sparc/Kconfig	Wed Jun 18 23:42:05 2003
@@ -277,81 +277,7 @@
 	  don't understand what this means or are not a kernel hacker, just
 	  leave it at its default value ELF.
 
-config BINFMT_AOUT
-	tristate "Kernel support for a.out binaries"
-	---help---
-	  A.out (Assembler.OUTput) is a set of formats for libraries and
-	  executables used in the earliest versions of UNIX. Linux used the
-	  a.out formats QMAGIC and ZMAGIC until they were replaced with the
-	  ELF format.
-
-	  As more and more programs are converted to ELF, the use for a.out
-	  will gradually diminish. If you disable this option it will reduce
-	  your kernel by one page. This is not much and by itself does not
-	  warrant removing support. However its removal is a good idea if you
-	  wish to ensure that absolutely none of your programs will use this
-	  older executable format. If you don't know what to answer at this
-	  point then answer Y. If someone told you "You need a kernel with
-	  QMAGIC support" then you'll have to say Y here. You may answer M to
-	  compile a.out support as a module and later load the module when you
-	  want to use a program or library in a.out format. The module will be
-	  called binfmt_aout. Saying M or N here is dangerous though,
-	  because some crucial programs on your system might still be in A.OUT
-	  format.
-
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  use this part of the kernel.
-
-	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 config SUNOS_EMUL
 	bool "SunOS binary emulation"
@@ -576,232 +502,7 @@
 	  module if your root file system (the one containing the directory /)
 	  is located on a SCSI device.
 
-comment "SCSI support type (disk, tape, CDrom)"
-	depends on SCSI
-
-config BLK_DEV_SD
-	tristate "SCSI disk support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI hard disk or the SCSI or parallel port
-	  version of the IOMEGA ZIP drive under Linux, say Y and read the
-	  SCSI-HOWTO, the Disk-HOWTO and the Multi-Disk-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>. This is NOT for SCSI
-	  CD-ROMs.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sd_mod.  If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.  Do not compile this driver as a
-	  module if your root file system (the one containing the directory /)
-	  is located on a SCSI disk. In this case, do not compile the driver
-	  for your SCSI host adapter (below) as a module either.
-
-config SD_EXTRA_DEVS
-	int "Maximum number of SCSI disks that can be loaded as modules"
-	depends on BLK_DEV_SD
-	default "40"
-	---help---
-	  This controls the amount of additional space allocated in tables for
-	  drivers that are loaded as modules after the kernel is booted.  In
-	  the event that the SCSI core itself was loaded as a module, this
-	  value is the number of additional disks that can be loaded after the
-	  first host driver is loaded.
-
-	  Admittedly this isn't pretty, but there are tons of race conditions
-	  involved with resizing the internal arrays on the fly.  Someday this
-	  flag will go away, and everything will work automatically.
-
-	  If you don't understand what's going on, go with the default.
-
-config CHR_DEV_ST
-	tristate "SCSI tape support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI tape drive under Linux, say Y and read the
-	  SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>, and
-	  <file:Documentation/scsi/st.txt> in the kernel source.  This is NOT
-	  for SCSI CD-ROMs.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called st. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.
-
-config CHR_DEV_OSST
-	tristate "SCSI OnStream SC-x0 tape support"
-	depends on SCSI
-	---help---
-	  The OnStream SC-x0 SCSI tape drives can not be driven by the
-	  standard st driver, but instead need this special osst driver and
-	  use the  /dev/osstX char device nodes (major 206).  Via usb-storage
-	  and ide-scsi, you may be able to drive the USB-x0 and DI-x0 drives
-	  as well.  Note that there is also a second generation of OnStream
-	  tape drives (ADR-x0) that supports the standard SCSI-2 commands for
-	  tapes (QIC-157) and can be driven by the standard driver st.
-	  For more information, you may have a look at the SCSI-HOWTO
-	  <http://www.tldp.org/docs.html#howto>  and
-	  <file:Documentation/scsi/osst.txt>  in the kernel source.
-	  More info on the OnStream driver may be found on
-	  <http://linux1.onstream.nl/test/>
-	  Please also have a look at the standard st docu, as most of it
-	  applies to osst as well.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called osst. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.
-
-config BLK_DEV_SR
-	tristate "SCSI CDROM support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI CD-ROM under Linux, say Y and read the
-	  SCSI-HOWTO and the CD-ROM-HOWTO at
-	  <http://www.tldp.org/docs.html#howto>. Also make sure to say Y
-	  or M to "ISO 9660 CD-ROM file system support" later.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sr_mod. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.
-
-config BLK_DEV_SR_VENDOR
-	bool "Enable vendor-specific extensions (for SCSI CDROM)"
-	depends on BLK_DEV_SR
-	help
-	  This enables the usage of vendor specific SCSI commands. This is
-	  required to support multisession CDs with old NEC/TOSHIBA cdrom
-	  drives (and HP Writers). If you have such a drive and get the first
-	  session only, try saying Y here; everybody else says N.
-
-config SR_EXTRA_DEVS
-	int "Maximum number of CDROM devices that can be loaded as modules"
-	depends on BLK_DEV_SR
-	default "2"
-	---help---
-	  This controls the amount of additional space allocated in tables for
-	  drivers that are loaded as modules after the kernel is booted. In
-	  the event that the SCSI core itself was loaded as a module, this
-	  value is the number of additional CD-ROMs that can be loaded after
-	  the first host driver is loaded.
-
-	  Admittedly this isn't pretty, but there are tons of race conditions
-	  involved with resizing the internal arrays on the fly.  Someday this
-	  flag will go away, and everything will work automatically.
-
-	  If you don't understand what's going on, go with the default.
-
-config CHR_DEV_SG
-	tristate "SCSI generic support"
-	depends on SCSI
-	---help---
-	  If you want to use SCSI scanners, synthesizers or CD-writers or just
-	  about anything having "SCSI" in its name other than hard disks,
-	  CD-ROMs or tapes, say Y here. These won't be supported by the kernel
-	  directly, so you need some additional software which knows how to
-	  talk to these devices using the SCSI protocol:
-
-	  For scanners, look at SANE (<http://www.mostang.com/sane/>). For CD
-	  writer software look at Cdrtools
-	  (<http://www.fokus.gmd.de/research/cc/glone/employees/joerg.schilling/private/cdrecord.html>)
-	  and for burning a "disk at once": CDRDAO
-	  (<http://cdrdao.sourceforge.net/>). Cdparanoia is a high
-	  quality digital reader of audio CDs (<http://www.xiph.org/paranoia/>).
-	  For other devices, it's possible that you'll have to write the
-	  driver software yourself. Please read the file
-	  <file:Documentation/scsi/scsi-generic.txt> for more information.
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>. The module will be called sg.
-	  If unsure, say N.
-
-comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs"
-	depends on SCSI
-
-config SCSI_MULTI_LUN
-	bool "Probe all LUNs on each SCSI device"
-	depends on SCSI
-	help
-	  If you have a SCSI device that supports more than one LUN (Logical
-	  Unit Number), e.g. a CD jukebox, and only one LUN is detected, you
-	  can say Y here to force the SCSI driver to probe for multiple LUNs.
-	  A SCSI device with multiple LUNs acts logically like multiple SCSI
-	  devices. The vast majority of SCSI devices have only one LUN, and
-	  so most people can say N here and should in fact do so, because it
-	  is safer.
-
-config SCSI_CONSTANTS
-	bool "Verbose SCSI error reporting (kernel size +=12K)"
-	depends on SCSI
-	help
-	  The error messages regarding your SCSI hardware will be easier to
-	  understand if you say Y here; it will enlarge your kernel by about
-	  12 KB. If in doubt, say Y.
-
-config SCSI_LOGGING
-	bool "SCSI logging facility"
-	depends on SCSI
-	---help---
-	  This turns on a logging facility that can be used to debug a number
-	  of SCSI related problems.
-
-	  If you say Y here, no logging output will appear by default, but you
-	  can enable logging by saying Y to "/proc file system support" and
-	  "Sysctl support" below and executing the command
-
-	  echo "scsi log token [level]" > /proc/scsi/scsi
-
-	  at boot time after the /proc file system has been mounted.
-
-	  There are a number of things that can be used for 'token' (you can
-	  find them in the source: <file:drivers/scsi/scsi.c>), and this
-	  allows you to select the types of information you want, and the
-	  level allows you to select the level of verbosity.
-
-	  If you say N here, it may be harder to track down some types of SCSI
-	  problems. If you say Y here your kernel will be somewhat larger, but
-	  there should be no noticeable performance impact as long as you have
-	  logging turned off.
-
-
-menu "SCSI low-level drivers"
-	depends on SCSI!=n
-
-config SCSI_SUNESP
-	tristate "Sparc ESP Scsi Driver"
-	depends on SCSI
-	help
-	  This is the driver for the Sun ESP SCSI host adapter. The ESP
-	  chipset is present in most SPARC SBUS-based computers.
-
-	  This support is also available as a module called esp ( = code
-	  which can be inserted in and removed from the running kernel
-	  whenever you want). If you want to compile it as a module, say M
-	  here and read <file:Documentation/modules.txt>.
-
-config SCSI_QLOGICPTI
-	tristate "PTI Qlogic,ISP Driver"
-	depends on SCSI
-	help
-	  This driver supports SBUS SCSI controllers from PTI or QLogic. These
-	  controllers are known under Solaris as qpti and in the openprom as
-	  PTI,ptisp or QLGC,isp. Note that PCI QLogic SCSI controllers are
-	  driven by a different driver.
-
-	  This support is also available as a module called qlogicpti ( =
-	  code which can be inserted in and removed from the running kernel
-	  whenever you want). If you want to compile it as a module, say M
-	  here and read <file:Documentation/modules.txt>.
-
-endmenu
+source "drivers/scsi/Kconfig"
 
 endmenu
 
diff -Nru a/arch/sparc/kernel/time.c b/arch/sparc/kernel/time.c
--- a/arch/sparc/kernel/time.c	Wed Jun 18 23:42:07 2003
+++ b/arch/sparc/kernel/time.c	Wed Jun 18 23:42:07 2003
@@ -408,9 +408,9 @@
 	mon = MSTK_REG_MONTH(mregs);
 	year = MSTK_CVT_YEAR( MSTK_REG_YEAR(mregs) );
 	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
-	wall_to_monotonic.tv_sec = -xtime.tv_sec + INITIAL_JIFFIES / HZ;
+	wall_to_monotonic.tv_sec = -xtime.tv_sec;
 	xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
-	wall_to_monotonic.tv_nsec = 0;
+	wall_to_monotonic.tv_nsec = -xtime.tv_nsec;
 	mregs->creg &= ~MSTK_CREG_READ;
 	spin_unlock_irq(&mostek_lock);
 #ifdef CONFIG_SUN4
@@ -441,9 +441,9 @@
 		intersil_start(iregs);
 
 		xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
-		wall_to_monotonic.tv_sec = -xtime.tv_sec + INITIAL_JIFFIES / HZ;
+		wall_to_monotonic.tv_sec = -xtime.tv_sec;
 		xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
-		wall_to_monotonic.tv_nsec = 0;
+		wall_to_monotonic.tv_nsec = -xtime.tv_nsec;
 		printk("%u/%u/%u %u:%u:%u\n",day,mon,year,hour,min,sec);
 	}
 #endif
diff -Nru a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
--- a/arch/sparc64/Kconfig	Wed Jun 18 23:42:09 2003
+++ b/arch/sparc64/Kconfig	Wed Jun 18 23:42:09 2003
@@ -415,59 +415,7 @@
 	  If you want to run SunOS binaries (see SunOS binary emulation below)
 	  or other a.out binaries, say Y. If unsure, say N.
 
-config BINFMT_ELF
-	tristate "Kernel support for 64-bit ELF binaries"
-	---help---
-	  ELF (Executable and Linkable Format) is a format for libraries and
-	  executables used across different architectures and operating
-	  systems. Saying Y here will enable your kernel to run ELF binaries
-	  and enlarge it by about 13 KB. ELF support under Linux has now all
-	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
-	  because it is portable (this does *not* mean that you will be able
-	  to run executables from different architectures or operating systems
-	  however) and makes building run-time libraries very easy. Many new
-	  executables are distributed solely in ELF format. You definitely
-	  want to say Y here.
-
-	  Information about ELF is contained in the ELF HOWTO available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  If you find that after upgrading from Linux kernel 1.2 and saying Y
-	  here, you still can't run any ELF binaries (they just crash), then
-	  you'll have to install the newest ELF runtime libraries, including
-	  ld.so (check the file <file:Documentation/Changes> for location and
-	  latest version).
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called binfmt_elf. Saying M or N here is dangerous because
-	  some crucial programs on your system might be in ELF format.
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. It's also useful if you often run DOS executables under
-	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>). Once you have
-	  registered such a binary class with the kernel, you can start one of
-	  those programs simply by typing in its name at a shell prompt; Linux
-	  will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  use this part of the kernel.
-
-	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 config SUNOS_EMUL
 	bool "SunOS binary emulation"
@@ -748,642 +696,7 @@
 	  module if your root file system (the one containing the directory /)
 	  is located on a SCSI device.
 
-comment "SCSI support type (disk, tape, CDrom)"
-	depends on SCSI
-
-config BLK_DEV_SD
-	tristate "SCSI disk support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI hard disk or the SCSI or parallel port
-	  version of the IOMEGA ZIP drive under Linux, say Y and read the
-	  SCSI-HOWTO, the Disk-HOWTO and the Multi-Disk-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>. This is NOT for SCSI
-	  CD-ROMs.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sd_mod.  If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.  Do not compile this driver as a
-	  module if your root file system (the one containing the directory /)
-	  is located on a SCSI disk. In this case, do not compile the driver
-	  for your SCSI host adapter (below) as a module either.
-
-config SD_EXTRA_DEVS
-	int "Maximum number of SCSI disks that can be loaded as modules"
-	depends on BLK_DEV_SD
-	default "40"
-	---help---
-	  This controls the amount of additional space allocated in tables for
-	  drivers that are loaded as modules after the kernel is booted.  In
-	  the event that the SCSI core itself was loaded as a module, this
-	  value is the number of additional disks that can be loaded after the
-	  first host driver is loaded.
-
-	  Admittedly this isn't pretty, but there are tons of race conditions
-	  involved with resizing the internal arrays on the fly.  Someday this
-	  flag will go away, and everything will work automatically.
-
-	  If you don't understand what's going on, go with the default.
-
-config CHR_DEV_ST
-	tristate "SCSI tape support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI tape drive under Linux, say Y and read the
-	  SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>, and
-	  <file:Documentation/scsi/st.txt> in the kernel source.  This is NOT
-	  for SCSI CD-ROMs.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called st. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.
-
-config CHR_DEV_OSST
-	tristate "SCSI OnStream SC-x0 tape support"
-	depends on SCSI
-	---help---
-	  The OnStream SC-x0 SCSI tape drives can not be driven by the
-	  standard st driver, but instead need this special osst driver and
-	  use the  /dev/osstX char device nodes (major 206).  Via usb-storage
-	  and ide-scsi, you may be able to drive the USB-x0 and DI-x0 drives
-	  as well.  Note that there is also a second generation of OnStream
-	  tape drives (ADR-x0) that supports the standard SCSI-2 commands for
-	  tapes (QIC-157) and can be driven by the standard driver st.
-	  For more information, you may have a look at the SCSI-HOWTO
-	  <http://www.tldp.org/docs.html#howto>  and
-	  <file:Documentation/scsi/osst.txt>  in the kernel source.
-	  More info on the OnStream driver may be found on
-	  <http://linux1.onstream.nl/test/>
-	  Please also have a look at the standard st docu, as most of it
-	  applies to osst as well.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called osst. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.
-
-config BLK_DEV_SR
-	tristate "SCSI CDROM support"
-	depends on SCSI
-	---help---
-	  If you want to use a SCSI CD-ROM under Linux, say Y and read the
-	  SCSI-HOWTO and the CD-ROM-HOWTO at
-	  <http://www.tldp.org/docs.html#howto>. Also make sure to say Y
-	  or M to "ISO 9660 CD-ROM file system support" later.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called sr_mod. If you want to compile it as a
-	  module, say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>.
-
-config BLK_DEV_SR_VENDOR
-	bool "Enable vendor-specific extensions (for SCSI CDROM)"
-	depends on BLK_DEV_SR
-	help
-	  This enables the usage of vendor specific SCSI commands. This is
-	  required to support multisession CDs with old NEC/TOSHIBA cdrom
-	  drives (and HP Writers). If you have such a drive and get the first
-	  session only, try saying Y here; everybody else says N.
-
-config SR_EXTRA_DEVS
-	int "Maximum number of CDROM devices that can be loaded as modules"
-	depends on BLK_DEV_SR
-	default "2"
-	---help---
-	  This controls the amount of additional space allocated in tables for
-	  drivers that are loaded as modules after the kernel is booted. In
-	  the event that the SCSI core itself was loaded as a module, this
-	  value is the number of additional CD-ROMs that can be loaded after
-	  the first host driver is loaded.
-
-	  Admittedly this isn't pretty, but there are tons of race conditions
-	  involved with resizing the internal arrays on the fly.  Someday this
-	  flag will go away, and everything will work automatically.
-
-	  If you don't understand what's going on, go with the default.
-
-config CHR_DEV_SG
-	tristate "SCSI generic support"
-	depends on SCSI
-	---help---
-	  If you want to use SCSI scanners, synthesizers or CD-writers or just
-	  about anything having "SCSI" in its name other than hard disks,
-	  CD-ROMs or tapes, say Y here. These won't be supported by the kernel
-	  directly, so you need some additional software which knows how to
-	  talk to these devices using the SCSI protocol:
-
-	  For scanners, look at SANE (<http://www.mostang.com/sane/>). For CD
-	  writer software look at Cdrtools
-	  (<http://www.fokus.gmd.de/research/cc/glone/employees/joerg.schilling/private/cdrecord.html>)
-	  and for burning a "disk at once": CDRDAO
-	  (<http://cdrdao.sourceforge.net/>). Cdparanoia is a high
-	  quality digital reader of audio CDs (<http://www.xiph.org/paranoia/>).
-	  For other devices, it's possible that you'll have to write the
-	  driver software yourself. Please read the file
-	  <file:Documentation/scsi/scsi-generic.txt> for more information.
-
-	  If you want to compile this as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt> and
-	  <file:Documentation/scsi/scsi.txt>. The module will be called sg.
-	  If unsure, say N.
-
-comment "Some SCSI devices (e.g. CD jukebox) support multiple LUNs"
-	depends on SCSI
-
-config SCSI_MULTI_LUN
-	bool "Probe all LUNs on each SCSI device"
-	depends on SCSI
-	help
-	  If you have a SCSI device that supports more than one LUN (Logical
-	  Unit Number), e.g. a CD jukebox, and only one LUN is detected, you
-	  can say Y here to force the SCSI driver to probe for multiple LUNs.
-	  A SCSI device with multiple LUNs acts logically like multiple SCSI
-	  devices. The vast majority of SCSI devices have only one LUN, and
-	  so most people can say N here and should in fact do so, because it
-	  is safer.
-
-config SCSI_CONSTANTS
-	bool "Verbose SCSI error reporting (kernel size +=12K)"
-	depends on SCSI
-	help
-	  The error messages regarding your SCSI hardware will be easier to
-	  understand if you say Y here; it will enlarge your kernel by about
-	  12 KB. If in doubt, say Y.
-
-config SCSI_LOGGING
-	bool "SCSI logging facility"
-	depends on SCSI
-	---help---
-	  This turns on a logging facility that can be used to debug a number
-	  of SCSI related problems.
-
-	  If you say Y here, no logging output will appear by default, but you
-	  can enable logging by saying Y to "/proc file system support" and
-	  "Sysctl support" below and executing the command
-
-	  echo "scsi log token [level]" > /proc/scsi/scsi
-
-	  at boot time after the /proc file system has been mounted.
-
-	  There are a number of things that can be used for 'token' (you can
-	  find them in the source: <file:drivers/scsi/scsi.c>), and this
-	  allows you to select the types of information you want, and the
-	  level allows you to select the level of verbosity.
-
-	  If you say N here, it may be harder to track down some types of SCSI
-	  problems. If you say Y here your kernel will be somewhat larger, but
-	  there should be no noticeable performance impact as long as you have
-	  logging turned off.
-
-
-menu "SCSI low-level drivers"
-	depends on SCSI!=n
-
-config SCSI_SUNESP
-	tristate "Sparc ESP Scsi Driver"
-	depends on SCSI
-	help
-	  This is the driver for the Sun ESP SCSI host adapter. The ESP
-	  chipset is present in most SPARC SBUS-based computers.
-
-	  This support is also available as a module called esp ( = code
-	  which can be inserted in and removed from the running kernel
-	  whenever you want). If you want to compile it as a module, say M
-	  here and read <file:Documentation/modules.txt>.
-
-config SCSI_QLOGICPTI
-	tristate "PTI Qlogic, ISP Driver"
-	depends on SCSI
-	help
-	  This driver supports SBUS SCSI controllers from PTI or QLogic. These
-	  controllers are known under Solaris as qpti and in the openprom as
-	  PTI,ptisp or QLGC,isp. Note that PCI QLogic SCSI controllers are
-	  driven by a different driver.
-
-	  This support is also available as a module called qlogicpti ( =
-	  code which can be inserted in and removed from the running kernel
-	  whenever you want). If you want to compile it as a module, say M
-	  here and read <file:Documentation/modules.txt>.
-
-
-choice
-	prompt "Adaptec AIC7xxx support"
-	optional
-	depends on SCSI && PCI
-
-source "drivers/scsi/aic7xxx/Kconfig.aic7xxx"
-
-config SCSI_AIC7XXX_OLD
-	tristate "Old driver"
-	---help---
-	  WARNING This driver is an older aic7xxx driver and is no longer
-	  under active development.  Adaptec, Inc. is writing a new driver to
-	  take the place of this one, and it is recommended that whenever
-	  possible, people should use the new Adaptec written driver instead
-	  of this one.  This driver will eventually be phased out entirely.
-
-	  This is support for the various aic7xxx based Adaptec SCSI
-	  controllers. These include the 274x EISA cards; 284x VLB cards;
-	  2902, 2910, 293x, 294x, 394x, 3985 and several other PCI and
-	  motherboard based SCSI controllers from Adaptec. It does not support
-	  the AAA-13x RAID controllers from Adaptec, nor will it likely ever
-	  support them. It does not support the 2920 cards from Adaptec that
-	  use the Future Domain SCSI controller chip. For those cards, you
-	  need the "Future Domain 16xx SCSI support" driver.
-
-	  In general, if the controller is based on an Adaptec SCSI controller
-	  chip from the aic777x series or the aic78xx series, this driver
-	  should work. The only exception is the 7810 which is specifically
-	  not supported (that's the RAID controller chip on the AAA-13x
-	  cards).
-
-	  Note that the AHA2920 SCSI host adapter is *not* supported by this
-	  driver; choose "Future Domain 16xx SCSI support" instead if you have
-	  one of those.
-
-	  Information on the configuration options for this controller can be
-	  found by checking the help file for each of the available
-	  configuration options. You should read
-	  <file:Documentation/scsi/aic7xxx_old.txt> at a minimum before
-	  contacting the maintainer with any questions.  The SCSI-HOWTO,
-	  available from <http://www.tldp.org/docs.html#howto>, can also
-	  be of great help.
-
-	  If you want to compile this driver as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want),
-	  say M here and read <file:Documentation/modules.txt>.  The module
-	  will be called aic7xxx_old.
-
-config AIC7XXX_OLD_TCQ_ON_BY_DEFAULT
-	bool "Enable Tagged Command Queueing (TCQ) by default"
-	depends on SCSI_AIC7XXX_OLD
-	---help---
-	  This option causes the aic7xxx driver to attempt to use Tagged
-	  Command Queueing (TCQ) on all devices that claim to support it.
-
-	  TCQ is a feature of SCSI-2 which improves performance: the host
-	  adapter can send several SCSI commands to a device's queue even if
-	  previous commands haven't finished yet.  Because the device is
-	  intelligent, it can optimize its operations (like head positioning)
-	  based on its own request queue.  Not all devices implement this
-	  correctly.
-
-	  If you say Y here, you can still turn off TCQ on troublesome devices
-	  with the use of the tag_info boot parameter.  See the file
-	  <file:Documentation/scsi/aic7xxx.txt> for more information on that and
-	  other aic7xxx setup commands.  If this option is turned off, you may
-	  still enable TCQ on known good devices by use of the tag_info boot
-	  parameter.
-
-	  If you are unsure about your devices then it is safest to say N
-	  here.
-
-	  However, TCQ can increase performance on some hard drives by as much
-	  as 50% or more, so it is recommended that if you say N here, you
-	  should at least read the <file:Documentation/scsi/aic7xxx.txt> file so
-	  you will know how to enable this option manually should your drives
-	  prove to be safe in regards to TCQ.
-
-	  Conversely, certain drives are known to lock up or cause bus resets
-	  when TCQ is enabled on them.  If you have a Western Digital
-	  Enterprise SCSI drive for instance, then don't even bother to enable
-	  TCQ on it as the drive will become unreliable, and it will actually
-	  reduce performance.
-
-config AIC7XXX_OLD_CMDS_PER_DEVICE
-	int "Maximum number of TCQ commands per device"
-	depends on SCSI_AIC7XXX_OLD
-	default "8"
-	---help---
-	  Specify the number of commands you would like to allocate per SCSI
-	  device when Tagged Command Queueing (TCQ) is enabled on that device.
-
-	  Reasonable figures are in the range of 8 to 24 commands per device,
-	  but depending on hardware could be increased or decreased from that
-	  figure. If the number is too high for any particular device, the
-	  driver will automatically compensate usually after only 10 minutes
-	  of uptime. It will not hinder performance if some of your devices
-	  eventually have their command depth reduced, but is a waste of
-	  memory if all of your devices end up reducing this number down to a
-	  more reasonable figure.
-
-	  NOTE: Certain very broken drives are known to lock up when given
-	  more commands than they like to deal with. Quantum Fireball drives
-	  are the most common in this category. For the Quantum Fireball
-	  drives it is suggested to use no more than 8 commands per device.
-
-	  Default: 8
-
-config AIC7XXX_OLD_PROC_STATS
-	bool "Collect statistics to report in /proc"
-	depends on SCSI_AIC7XXX_OLD
-	---help---
-	  This option tells the driver to keep track of how many commands have
-	  been sent to each particular device and report that information to
-	  the user via the /proc/scsi/aic7xxx/n file, where n is the number of
-	  the aic7xxx controller you want the information on. This adds a
-	  small amount of overhead to each and every SCSI command the aic7xxx
-	  driver handles, so if you aren't really interested in this
-	  information, it is best to leave it disabled. This will only work if
-	  you also say Y to "/proc file system support", below.
-
-	  If unsure, say N.
-
-endchoice
-
-config SCSI_SYM53C8XX_2
-	tristate "SYM53C8XX Version 2 SCSI support"
-	depends on PCI && SCSI
-	---help---
-	  This driver supports the whole NCR53C8XX/SYM53C8XX family of 
-	  PCI-SCSI controllers. It also supports the subset of LSI53C10XX 
-	  Ultra-160 controllers that are based on the SYM53C8XX SCRIPTS 
-	  language. It does not support LSI53C10XX Ultra-320 PCI-X SCSI 
-	  controllers.
-
-	  If your system has problems using this new major version of the
-	  SYM53C8XX driver, you may switch back to driver version 1.
-
-	  Please read <file:drivers/scsi/sym53c8xx_2/Documentation.txt> for more
-	  information.
-
-config SCSI_SYM53C8XX_DMA_ADDRESSING_MODE
-	int "DMA addressing mode"
-	depends on SCSI_SYM53C8XX_2
-	default "1"
-	---help---
-	  This option only applies to PCI-SCSI chip that are PCI DAC capable 
-	  (875A, 895A, 896, 1010-33, 1010-66, 1000).
-
-	  When set to 0, only PCI 32 bit DMA addressing (SAC) will be performed.
-	  When set to 1, 40 bit DMA addressing (with upper 24 bits of address 
-	  set to zero) is supported. The addressable range is here 1 TB.
-	  When set to 2, full 64 bits of address for DMA are supported, but only
-	  16 segments of 4 GB can be addressed. The addressable range is so 
-	  limited to 64 GB.
-
-	  The safest value is 0 (32 bit DMA addressing) that is guessed to still 
-	  fit most of real machines.
-
-	  The preferred value 1 (40 bit DMA addressing) should make happy 
-	  properly engineered PCI DAC capable host bridges. You may configure
-	  this option for Intel platforms with more than 4 GB of memory.
-
-	  The still experimental value 2 (64 bit DMA addressing with 16 x 4GB 
-	  segments limitation) can be used on systems that require PCI address 
-	  bits past bit 39 to be set for the addressing of memory using PCI 
-	  DAC cycles.
-
-config SCSI_SYM53C8XX_DEFAULT_TAGS
-	int "default tagged command queue depth"
-	depends on SCSI_SYM53C8XX_2
-	default "16"
-	help
-	  This is the default value of the command queue depth the driver will 
-	  announce to the generic SCSI layer for devices that support tagged 
-	  command queueing. This value can be changed from the boot command line.
-	  This is a soft limit that cannot exceed CONFIG_SCSI_SYM53C8XX_MAX_TAGS.
-
-config SCSI_SYM53C8XX_MAX_TAGS
-	int "maximum number of queued commands"
-	depends on SCSI_SYM53C8XX_2
-	default "64"
-	help
-	  This option allows you to specify the maximum number of commands
-	  that can be queued to any device, when tagged command queuing is
-	  possible. The driver supports up to 256 queued commands per device.
-	  This value is used as a compiled-in hard limit.
-
-config SCSI_SYM53C8XX_IOMAPPED
-	bool "use normal IO"
-	depends on SCSI_SYM53C8XX_2
-	help
-	  If you say Y here, the driver will preferently use normal IO rather than 
-	  memory mapped IO.
-
-config SCSI_NCR53C8XX
-	tristate "NCR53C8XX SCSI support"
-	depends on PCI && SCSI_SYM53C8XX_2!=y && SCSI
-	---help---
-	  This is the BSD ncr driver adapted to Linux for the NCR53C8XX family
-	  of PCI-SCSI controllers.  This driver supports parity checking,
-	  tagged command queuing and fast synchronous data transfers up to 80
-	  MB/s with wide FAST-40 LVD devices and controllers.
-
-	  Recent versions of the 53C8XX chips are better supported by the
-	  option "SYM53C8XX SCSI support", below.
-
-	  Note: there is yet another driver for the 53c8xx family of
-	  controllers ("NCR53c7,8xx SCSI support" above).  If you want to use
-	  them both, you need to say M to both and build them as modules, but
-	  only one may be active at a time.  If you have a 53c8xx board, you
-	  probably do not want to use the "NCR53c7,8xx SCSI support".
-
-	  Please read <file:Documentation/scsi/ncr53c8xx.txt> for more
-	  information.
-
-config SCSI_SYM53C8XX
-	tristate "SYM53C8XX SCSI support"
-	depends on PCI && SCSI_SYM53C8XX_2!=y && SCSI
-	---help---
-	  This driver supports all the features of recent 53C8XX chips (used
-	  in PCI SCSI controllers), notably the hardware phase mismatch
-	  feature of the SYM53C896.
-
-	  Older versions of the 53C8XX chips are not supported by this
-	  driver.  If your system uses either a 810 rev. < 16, a 815, or a 825
-	  rev. < 16 PCI SCSI processor, you must use the generic NCR53C8XX
-	  driver ("NCR53C8XX SCSI support" above) or configure both the
-	  NCR53C8XX and this SYM53C8XX drivers either as module or linked to
-	  the kernel image.
-
-	  When both drivers are linked into the kernel, the SYM53C8XX driver
-	  is called first at initialization and you can use the 'excl=ioaddr'
-	  driver boot option to exclude attachment of adapters by the
-	  SYM53C8XX driver.  For example, entering
-	  'sym53c8xx=excl:0xb400,excl=0xc000' at the lilo prompt prevents
-	  adapters at io address 0xb400 and 0xc000 from being attached by the
-	  SYM53C8XX driver, thus allowing the NCR53C8XX driver to attach them.
-	  The 'excl' option is also supported by the NCR53C8XX driver.
-
-	  Please read <file:Documentation/scsi/ncr53c8xx.txt> for more
-	  information.
-
-config SCSI_NCR53C8XX_DEFAULT_TAGS
-	int "default tagged command queue depth"
-	depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX)
-	default "8"
-	---help---
-	  "Tagged command queuing" is a feature of SCSI-2 which improves
-	  performance: the host adapter can send several SCSI commands to a
-	  device's queue even if previous commands haven't finished yet.
-	  Because the device is intelligent, it can optimize its operations
-	  (like head positioning) based on its own request queue. Some SCSI
-	  devices don't implement this properly; if you want to disable this
-	  feature, enter 0 or 1 here (it doesn't matter which).
-
-	  The default value is 8 and should be supported by most hard disks.
-	  This value can be overridden from the boot command line using the
-	  'tags' option as follows (example):
-	  'ncr53c8xx=tags:4/t2t3q16/t0u2q10' will set default queue depth to
-	  4, set queue depth to 16 for target 2 and target 3 on controller 0
-	  and set queue depth to 10 for target 0 / lun 2 on controller 1.
-
-	  The normal answer therefore is to go with the default 8 and to use
-	  a boot command line option for devices that need to use a different
-	  command queue depth.
-
-	  There is no safe option other than using good SCSI devices.
-
-config SCSI_NCR53C8XX_MAX_TAGS
-	int "maximum number of queued commands"
-	depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX)
-	default "32"
-	---help---
-	  This option allows you to specify the maximum number of commands
-	  that can be queued to any device, when tagged command queuing is
-	  possible. The default value is 32. Minimum is 2, maximum is 64.
-	  Modern hard disks are able to support 64 tags and even more, but
-	  do not seem to be faster when more than 32 tags are being used.
-
-	  So, the normal answer here is to go with the default value 32 unless
-	  you are using very large hard disks with large cache (>= 1 MB) that
-	  are able to take advantage of more than 32 tagged commands.
-
-	  There is no safe option and the default answer is recommended.
-
-config SCSI_NCR53C8XX_SYNC
-	int "synchronous transfers frequency in MHz"
-	depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX)
-	default "10"
-	---help---
-	  The SCSI Parallel Interface-2 Standard defines 5 classes of transfer
-	  rates: FAST-5, FAST-10, FAST-20, FAST-40 and FAST-80.  The numbers
-	  are respectively the maximum data transfer rates in mega-transfers
-	  per second for each class.  For example, a FAST-20 Wide 16 device is
-	  able to transfer data at 20 million 16 bit packets per second for a
-	  total rate of 40 MB/s.
-
-	  You may specify 0 if you want to only use asynchronous data
-	  transfers. This is the safest and slowest option. Otherwise, specify
-	  a value between 5 and 80, depending on the capability of your SCSI
-	  controller.  The higher the number, the faster the data transfer.
-	  Note that 80 should normally be ok since the driver decreases the
-	  value automatically according to the controller's capabilities.
-
-	  Your answer to this question is ignored for controllers with NVRAM,
-	  since the driver will get this information from the user set-up.  It
-	  also can be overridden using a boot setup option, as follows
-	  (example): 'ncr53c8xx=sync:12' will allow the driver to negotiate
-	  for FAST-20 synchronous data transfer (20 mega-transfers per
-	  second).
-
-	  The normal answer therefore is not to go with the default but to
-	  select the maximum value 80 allowing the driver to use the maximum
-	  value supported by each controller. If this causes problems with
-	  your SCSI devices, you should come back and decrease the value.
-
-	  There is no safe option other than using good cabling, right
-	  terminations and SCSI conformant devices.
-
-config SCSI_NCR53C8XX_PROFILE
-	bool "enable profiling"
-	depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX)
-	help
-	  This option allows you to enable profiling information gathering.
-	  These statistics are not very accurate due to the low frequency
-	  of the kernel clock (100 Hz on i386) and have performance impact
-	  on systems that use very fast devices.
-
-	  The normal answer therefore is N.
-
-config SCSI_NCR53C8XX_PQS_PDS
-	bool "include support for the NCR PQS/PDS SCSI card"
-	depends on (SCSI_NCR53C8XX || SCSI_SYM53C8XX) && SCSI_SYM53C8XX
-	help
-	  Say Y here if you have a special SCSI adapter produced by NCR
-	  corporation called a PCI Quad SCSI or PCI Dual SCSI. You do not need
-	  this if you do not have one of these adapters. However, since this
-	  device is detected as a specific PCI device, this option is quite
-	  safe.
-
-	  The common answer here is N, but answering Y is safe.
-
-config SCSI_NCR53C8XX_NO_DISCONNECT
-	bool "not allow targets to disconnect"
-	depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX) && SCSI_NCR53C8XX_DEFAULT_TAGS=0
-	help
-	  This option is only provided for safety if you suspect some SCSI
-	  device of yours to not support properly the target-disconnect
-	  feature. In that case, you would say Y here. In general however, to
-	  not allow targets to disconnect is not reasonable if there is more
-	  than 1 device on a SCSI bus. The normal answer therefore is N.
-
-config SCSI_NCR53C8XX_SYMBIOS_COMPAT
-	bool "assume boards are SYMBIOS compatible (EXPERIMENTAL)"
-	depends on PCI && SCSI_SYM53C8XX_2!=y && (SCSI_NCR53C8XX || SCSI_SYM53C8XX) && EXPERIMENTAL
-	---help---
-	  This option allows you to enable some features depending on GPIO
-	  wiring. These General Purpose Input/Output pins can be used for
-	  vendor specific features or implementation of the standard SYMBIOS
-	  features. Genuine SYMBIOS controllers use GPIO0 in output for
-	  controller LED and GPIO3 bit as a flag indicating
-	  singled-ended/differential interface. The Tekram DC-390U/F boards
-	  uses a different GPIO wiring.
-
-	  Your answer to this question is ignored if all your controllers have
-	  NVRAM, since the driver is able to detect the board type from the
-	  NVRAM format.
-
-	  If all the controllers in your system are genuine SYMBIOS boards or
-	  use BIOS and drivers from SYMBIOS, you would want to say Y here,
-	  otherwise N. N is the safe answer.
-
-config SCSI_QLOGIC_ISP
-	tristate "Qlogic ISP SCSI support"
-	depends on PCI && SCSI
-	---help---
-	  This driver works for all QLogic PCI SCSI host adapters (IQ-PCI,
-	  IQ-PCI-10, IQ_PCI-D) except for the PCI-basic card.  (This latter
-	  card is supported by the "AM53/79C974 PCI SCSI" driver.)
-
-	  If you say Y here, make sure to choose "BIOS" at the question "PCI
-	  access mode".
-
-	  Please read the file <file:Documentation/scsi/qlogicisp.txt>.  You
-	  should also read the SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called qlogicisp.  If you want to compile it as
-	  a module, say M here and read <file:Documentation/modules.txt>.
-
-config SCSI_QLOGIC_FC
-	tristate "Qlogic ISP FC SCSI support"
-	depends on PCI && SCSI
-	help
-	  This is a driver for the QLogic ISP2100 SCSI-FCP host adapter.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called qlogicfc.  If you want to compile it as
-	  a module, say M here and read <file:Documentation/modules.txt>.
-
-config SCSI_QLOGIC_FC_FIRMWARE
-	bool
-	depends on SCSI_QLOGIC_FC
-	default y
-
-endmenu
+source "drivers/scsi/Kconfig"
 
 endmenu
 
diff -Nru a/arch/sparc64/kernel/time.c b/arch/sparc64/kernel/time.c
--- a/arch/sparc64/kernel/time.c	Wed Jun 18 23:42:07 2003
+++ b/arch/sparc64/kernel/time.c	Wed Jun 18 23:42:07 2003
@@ -703,9 +703,9 @@
 	}
 
 	xtime.tv_sec = mktime(year, mon, day, hour, min, sec);
-	wall_to_monotonic.tv_sec = -xtime.tv_sec + INITIAL_JIFFIES / HZ;
+	wall_to_monotonic.tv_sec = -xtime.tv_sec;
 	xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
-	wall_to_monotonic.tv_nsec = 0;
+	wall_to_monotonic.tv_nsec = -xtime.tv_nsec;
 
 	if (mregs) {
 		tmp = mostek_read(mregs + MOSTEK_CREG);
@@ -743,9 +743,9 @@
 			(unsigned int) (long) &unix_tod);
 		prom_feval(obp_gettod);
 		xtime.tv_sec = unix_tod;
-		wall_to_monotonic.tv_sec = -xtime.tv_sec + INITIAL_JIFFIES / HZ;
+		wall_to_monotonic.tv_sec = -xtime.tv_sec;
 		xtime.tv_nsec = (INITIAL_JIFFIES % HZ) * (NSEC_PER_SEC / HZ);
-		wall_to_monotonic.tv_nsec = 0;
+		wall_to_monotonic.tv_nsec = -xtime.tv_nsec;
 		return;
 	}
 
diff -Nru a/arch/um/Kconfig b/arch/um/Kconfig
--- a/arch/um/Kconfig	Wed Jun 18 23:42:07 2003
+++ b/arch/um/Kconfig	Wed Jun 18 23:42:07 2003
@@ -62,14 +62,7 @@
 config NET
 	bool "Networking support"
 
-config BINFMT_AOUT
-	tristate "Kernel support for a.out binaries"
-
-config BINFMT_ELF
-	tristate "Kernel support for ELF binaries"
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
+source "fs/Kconfig.binfmt"
 
 config HOSTFS
 	tristate "Host filesystem"
diff -Nru a/arch/v850/Kconfig b/arch/v850/Kconfig
--- a/arch/v850/Kconfig	Wed Jun 18 23:42:07 2003
+++ b/arch/v850/Kconfig	Wed Jun 18 23:42:07 2003
@@ -243,16 +243,7 @@
 config KCORE_ELF
 	default y
 
-config BINFMT_FLAT
-	tristate "Kernel support for flat binaries"
-	help
-	  Support uClinux FLAT format binaries.
-
-config BINFMT_ZFLAT
-	bool "  Enable ZFLAT support"
-	depends on BINFMT_FLAT
-	help
-	  Support FLAT format compressed binaries
+source "fs/Kconfig.binfmt"
 
 endmenu
 
diff -Nru a/arch/v850/vmlinux.lds.S b/arch/v850/vmlinux.lds.S
--- a/arch/v850/vmlinux.lds.S	Wed Jun 18 23:42:08 2003
+++ b/arch/v850/vmlinux.lds.S	Wed Jun 18 23:42:08 2003
@@ -95,7 +95,10 @@
 			*(.initcall6.init)				      \
 			*(.initcall7.init)				      \
 		. = ALIGN (4) ;						      \
-		___initcall_end = . ;
+		___initcall_end = . ;					      \
+		___con_initcall_start = .;				      \
+			*(.con_initcall.init)				      \
+		___con_initcall_end = .;
 
 /* Contents of `init' section for a kernel that's loaded into RAM.  */
 #define RAMK_INIT_CONTENTS						      \
@@ -232,5 +235,15 @@
 #  include "rte_ma1_cb-rom.ld"
 # else
 #  include "rte_ma1_cb.ld"
+# endif
+#endif
+
+#ifdef CONFIG_RTE_CB_NB85E
+# ifdef CONFIG_ROM_KERNEL
+#  include "rte_nb85e_cb-rom.ld"
+# elif defined(CONFIG_RTE_CB_MULTI)
+#  include "rte_nb85e_cb-multi.ld"
+# else
+#  include "rte_nb85e_cb.ld"
 # endif
 #endif
diff -Nru a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
--- a/arch/x86_64/Kconfig	Wed Jun 18 23:42:08 2003
+++ b/arch/x86_64/Kconfig	Wed Jun 18 23:42:08 2003
@@ -375,31 +375,7 @@
 	depends on PROC_FS
 	default y
 
-config BINFMT_ELF
-	bool
-	default y
-
-config BINFMT_MISC
-	tristate "Kernel support for MISC binaries"
-	---help---
-	  If you say Y here, it will be possible to plug wrapper-driven binary
-	  formats into the kernel. You will like this especially when you use
-	  programs that need an interpreter to run like Java, Python or
-	  Emacs-Lisp. Once you have registered such a binary class with the kernel, 
-	  you can start one of those programs simply by typing in its name at a shell 
-	  prompt; Linux will automatically feed it to the correct interpreter.
-
-	  You can do other nice things, too. Read the file
-	  <file:Documentation/binfmt_misc.txt> to learn how to use this
-	  feature, and <file:Documentation/java.txt> for information about how
-	  to include Java support.
-
-	  You must say Y to "/proc file system support" (CONFIG_PROC_FS) to
-	  use this part of the kernel.
-
-	  You may say M here for module support and later load the module when
-	  you have use for it; the module is called binfmt_misc. If you
-	  don't know what to answer at this point, say Y.
+source "fs/Kconfig.binfmt"
 
 config IA32_EMULATION
 	bool "IA32 Emulation"
diff -Nru a/drivers/atm/he.c b/drivers/atm/he.c
--- a/drivers/atm/he.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/atm/he.c	Wed Jun 18 23:42:06 2003
@@ -2710,12 +2710,13 @@
 		remove_wait_queue(&he_vcc->tx_waitq, &wait);
 		set_current_state(TASK_RUNNING);
 
+		spin_lock_irqsave(&he_dev->global_lock, flags);
+
 		if (timeout == 0) {
 			hprintk("close tx timeout cid 0x%x\n", cid);
 			goto close_tx_incomplete;
 		}
 
-		spin_lock_irqsave(&he_dev->global_lock, flags);
 		while (!((tsr4 = he_readl_tsr4(he_dev, cid)) & TSR4_SESSION_ENDED)) {
 			HPRINTK("close tx cid 0x%x !TSR4_SESSION_ENDED (tsr4 = 0x%x)\n", cid, tsr4);
 			udelay(250);
diff -Nru a/drivers/block/cciss_scsi.c b/drivers/block/cciss_scsi.c
--- a/drivers/block/cciss_scsi.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/block/cciss_scsi.c	Wed Jun 18 23:42:06 2003
@@ -698,7 +698,7 @@
 {
 	struct Scsi_Host *sh;
 
-	sh = scsi_register(&cciss_driver_template, sizeof(struct ctlr_info *));
+	sh = scsi_host_alloc(&cciss_driver_template, sizeof(struct ctlr_info *));
 	if (sh == NULL)
 		return 0;
 
@@ -1357,7 +1357,7 @@
 	if (sa->registered) {
 		spin_unlock_irqrestore(CCISS_LOCK(ctlr), flags);
 		scsi_remove_host(sa->scsi_host);
-		scsi_unregister(sa->scsi_host);
+		scsi_host_put(sa->scsi_host);
 		spin_lock_irqsave(CCISS_LOCK(ctlr), flags);
 	}
 
diff -Nru a/drivers/block/ll_rw_blk.c b/drivers/block/ll_rw_blk.c
--- a/drivers/block/ll_rw_blk.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/block/ll_rw_blk.c	Wed Jun 18 23:42:06 2003
@@ -49,8 +49,6 @@
 static int queue_nr_requests;
 
 unsigned long blk_max_low_pfn, blk_max_pfn;
-int blk_nohighio = 0;
-
 static wait_queue_head_t congestion_wqh[2];
 
 /*
@@ -2334,7 +2332,6 @@
 EXPORT_SYMBOL(blk_queue_segment_boundary);
 EXPORT_SYMBOL(blk_queue_dma_alignment);
 EXPORT_SYMBOL(blk_rq_map_sg);
-EXPORT_SYMBOL(blk_nohighio);
 EXPORT_SYMBOL(blk_dump_rq_flags);
 EXPORT_SYMBOL(submit_bio);
 EXPORT_SYMBOL(blk_phys_contig_segment);
diff -Nru a/drivers/char/moxa.c b/drivers/char/moxa.c
--- a/drivers/char/moxa.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/char/moxa.c	Wed Jun 18 23:42:09 2003
@@ -339,7 +339,6 @@
 {
 	int i, n, numBoards;
 	struct moxa_str *ch;
-	int ret1, ret2;
 
 	printk(KERN_INFO "MOXA Intellio family driver version %s\n", MOXA_VERSION);
 	moxaDriver = alloc_tty_driver(MAX_PORTS + 1);
@@ -615,7 +614,7 @@
 	}
 	ch->asyncflags |= ASYNC_CLOSING;
 
-	ch->cflag = *tty->termios->c_cflag;
+	ch->cflag = tty->termios->c_cflag;
 	if (ch->asyncflags & ASYNC_INITIALIZED) {
 		setup_empty_event(tty);
 		tty_wait_until_sent(tty, 30 * HZ);	/* 30 seconds timeout */
diff -Nru a/drivers/i2c/busses/i2c-ali15x3.c b/drivers/i2c/busses/i2c-ali15x3.c
--- a/drivers/i2c/busses/i2c-ali15x3.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/i2c/busses/i2c-ali15x3.c	Wed Jun 18 23:42:07 2003
@@ -177,17 +177,18 @@
 	if(force_addr) {
 		dev_info(&ALI15X3_dev->dev, "forcing ISA address 0x%04X\n",
 			ali15x3_smba);
-		if (PCIBIOS_SUCCESSFUL !=
-		    pci_write_config_word(ALI15X3_dev, SMBBA, ali15x3_smba))
-			return -ENODEV;
-		if (PCIBIOS_SUCCESSFUL !=
-		    pci_read_config_word(ALI15X3_dev, SMBBA, &a))
-			return -ENODEV;
+		if (PCIBIOS_SUCCESSFUL != pci_write_config_word(ALI15X3_dev,
+								SMBBA,
+								ali15x3_smba))
+			goto error;
+		if (PCIBIOS_SUCCESSFUL != pci_read_config_word(ALI15X3_dev,
+								SMBBA, &a))
+			goto error;
 		if ((a & ~(ALI15X3_SMB_IOSIZE - 1)) != ali15x3_smba) {
 			/* make sure it works */
 			dev_err(&ALI15X3_dev->dev,
 				"force address failed - not supported?\n");
-			return -ENODEV;
+			goto error;
 		}
 	}
 	/* check if whole device is enabled */
@@ -219,6 +220,9 @@
 	dev_dbg(&ALI15X3_dev->dev, "iALI15X3_smba = 0x%X\n", ali15x3_smba);
 
 	return 0;
+error:
+	release_region(ali15x3_smba, ALI15X3_SMB_IOSIZE);
+	return -ENODEV;
 }
 
 /* Internally used pause function */
diff -Nru a/drivers/i2c/busses/i2c-i801.c b/drivers/i2c/busses/i2c-i801.c
--- a/drivers/i2c/busses/i2c-i801.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/i2c/busses/i2c-i801.c	Wed Jun 18 23:42:07 2003
@@ -27,6 +27,7 @@
     82801BA		2443           
     82801CA/CAM		2483           
     82801DB		24C3   (HW PEC supported, 32 byte buffer not supported)
+    82801EB		24D3   (HW PEC supported, 32 byte buffer not supported)
 
     This driver supports several versions of Intel's I/O Controller Hubs (ICH).
     For SMBus support, they are similar to the PIIX4 and are part
@@ -121,7 +122,8 @@
 		return -ENODEV;
 
 	I801_dev = dev;
-	if (dev->device == PCI_DEVICE_ID_INTEL_82801DB_3)
+	if ((dev->device == PCI_DEVICE_ID_INTEL_82801DB_3) ||
+	    (dev->device == PCI_DEVICE_ID_INTEL_82801EB_3))
 		isich4 = 1;
 	else
 		isich4 = 0;
@@ -584,6 +586,12 @@
 		.device =	PCI_DEVICE_ID_INTEL_82801DB_3,
 		.subvendor =	PCI_ANY_ID,
 		.subdevice =	PCI_ANY_ID,
+	},
+	{
+		.vendor =   PCI_VENDOR_ID_INTEL,
+		.device =   PCI_DEVICE_ID_INTEL_82801EB_3,
+		.subvendor =    PCI_ANY_ID,
+		.subdevice =    PCI_ANY_ID,
 	},
 	{ 0, }
 };
diff -Nru a/drivers/i2c/chips/Kconfig b/drivers/i2c/chips/Kconfig
--- a/drivers/i2c/chips/Kconfig	Wed Jun 18 23:42:07 2003
+++ b/drivers/i2c/chips/Kconfig	Wed Jun 18 23:42:07 2003
@@ -62,6 +62,20 @@
 	  in the lm_sensors package, which you can download at 
 	  http://www.lm-sensors.nu
 	  
+config SENSORS_LM78
+	tristate "  National Semiconductors LM78 and compatibles"
+	depends on I2C && EXPERIMENTAL
+	help
+	  If you say yes here you get support for National Semiconductor LM78,
+	  LM78-J and LM79.  This can also be built as a module which can be
+	  inserted and removed while the kernel is running.
+
+	  The module will be called lm78.
+
+	  You will also need the latest user-space utilties: you can find them
+	  in the lm_sensors package, which you can download at 
+	  http://www.lm-sensors.nu
+	  
 config SENSORS_VIA686A
 	tristate "  VIA686A"
 	depends on I2C && EXPERIMENTAL
diff -Nru a/drivers/i2c/chips/Makefile b/drivers/i2c/chips/Makefile
--- a/drivers/i2c/chips/Makefile	Wed Jun 18 23:42:05 2003
+++ b/drivers/i2c/chips/Makefile	Wed Jun 18 23:42:05 2003
@@ -5,6 +5,7 @@
 obj-$(CONFIG_SENSORS_ADM1021)	+= adm1021.o
 obj-$(CONFIG_SENSORS_IT87)	+= it87.o
 obj-$(CONFIG_SENSORS_LM75)	+= lm75.o
+obj-$(CONFIG_SENSORS_LM78)	+= lm78.o
 obj-$(CONFIG_SENSORS_LM85)	+= lm85.o
 obj-$(CONFIG_SENSORS_VIA686A)	+= via686a.o
 obj-$(CONFIG_SENSORS_W83781D)	+= w83781d.o
diff -Nru a/drivers/i2c/chips/adm1021.c b/drivers/i2c/chips/adm1021.c
--- a/drivers/i2c/chips/adm1021.c	Wed Jun 18 23:42:05 2003
+++ b/drivers/i2c/chips/adm1021.c	Wed Jun 18 23:42:05 2003
@@ -88,8 +88,8 @@
    these macros are called: arguments may be evaluated more than once.
    Fixing this is just not worth it. */
 /* Conversions  note: 1021 uses normal integer signed-byte format*/
-#define TEMP_FROM_REG(val)	(val > 127 ? val-256 : val)
-#define TEMP_TO_REG(val)	(SENSORS_LIMIT((val < 0 ? val+256 : val),0,255))
+#define TEMP_FROM_REG(val)	(val > 127 ? (val-256)*1000 : val*1000)
+#define TEMP_TO_REG(val)	(SENSORS_LIMIT((val < 0 ? (val/1000)+256 : val/1000),0,255))
 
 /* Initial values */
 
@@ -172,8 +172,18 @@
 show(remote_temp_max);
 show(remote_temp_hyst);
 show(remote_temp_input);
-show(alarms);
-show(die_code);
+
+#define show2(value)	\
+static ssize_t show_##value(struct device *dev, char *buf)	\
+{								\
+	struct i2c_client *client = to_i2c_client(dev);		\
+	struct adm1021_data *data = i2c_get_clientdata(client);	\
+								\
+	adm1021_update_client(client);				\
+	return sprintf(buf, "%d\n", data->value);		\
+}
+show2(alarms);
+show2(die_code);
 
 #define set(value, reg)	\
 static ssize_t set_##value(struct device *dev, const char *buf, size_t count)	\
diff -Nru a/drivers/i2c/chips/lm78.c b/drivers/i2c/chips/lm78.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/i2c/chips/lm78.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,895 @@
+/*
+    lm78.c - Part of lm_sensors, Linux kernel modules for hardware
+             monitoring
+    Copyright (c) 1998, 1999  Frodo Looijaard <frodol@dds.nl> 
+
+    This program is free software; you can redistribute it and/or modify
+    it under the terms of the GNU General Public License as published by
+    the Free Software Foundation; either version 2 of the License, or
+    (at your option) any later version.
+
+    This program is distributed in the hope that it will be useful,
+    but WITHOUT ANY WARRANTY; without even the implied warranty of
+    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+    GNU General Public License for more details.
+
+    You should have received a copy of the GNU General Public License
+    along with this program; if not, write to the Free Software
+    Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+*/
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/i2c-sensor.h>
+#include <asm/io.h>
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { I2C_CLIENT_END };
+static unsigned short normal_i2c_range[] = { 0x20, 0x2f, I2C_CLIENT_END };
+static unsigned int normal_isa[] = { 0x0290, I2C_CLIENT_ISA_END };
+static unsigned int normal_isa_range[] = { I2C_CLIENT_ISA_END };
+
+/* Insmod parameters */
+SENSORS_INSMOD_3(lm78, lm78j, lm79);
+
+/* Many LM78 constants specified below */
+
+/* Length of ISA address segment */
+#define LM78_EXTENT 8
+
+/* Where are the ISA address/data registers relative to the base address */
+#define LM78_ADDR_REG_OFFSET 5
+#define LM78_DATA_REG_OFFSET 6
+
+/* The LM78 registers */
+#define LM78_REG_IN_MAX(nr) (0x2b + (nr) * 2)
+#define LM78_REG_IN_MIN(nr) (0x2c + (nr) * 2)
+#define LM78_REG_IN(nr) (0x20 + (nr))
+
+#define LM78_REG_FAN_MIN(nr) (0x3b + (nr))
+#define LM78_REG_FAN(nr) (0x28 + (nr))
+
+#define LM78_REG_TEMP 0x27
+#define LM78_REG_TEMP_OVER 0x39
+#define LM78_REG_TEMP_HYST 0x3a
+
+#define LM78_REG_ALARM1 0x41
+#define LM78_REG_ALARM2 0x42
+
+#define LM78_REG_VID_FANDIV 0x47
+
+#define LM78_REG_CONFIG 0x40
+#define LM78_REG_CHIPID 0x49
+#define LM78_REG_I2C_ADDR 0x48
+
+
+/* Conversions. Rounding and limit checking is only done on the TO_REG 
+   variants. */
+
+/* IN: mV, (0V to 4.08V)
+   REG: 16mV/bit */
+static inline u8 IN_TO_REG(unsigned long val)
+{
+	unsigned long nval = SENSORS_LIMIT(val, 0, 4080);
+	return (nval + 8) / 16;
+}
+#define IN_FROM_REG(val) ((val) *  16)
+
+static inline u8 FAN_TO_REG(long rpm, int div)
+{
+	if (rpm == 0)
+		return 255;
+	rpm = SENSORS_LIMIT(rpm, 1, 1000000);
+	return SENSORS_LIMIT((1350000 + rpm * div / 2) / (rpm * div), 1, 254);
+}
+
+static inline int FAN_FROM_REG(u8 val, int div)
+{
+	return val==0 ? -1 : val==255 ? 0 : 1350000/(val*div);
+}
+
+/* TEMP: mC (-128C to +127C)
+   REG: 1C/bit, two's complement */
+static inline u8 TEMP_TO_REG(int val)
+{
+	int nval = SENSORS_LIMIT(val, -128000, 127000) ;
+	return nval<0 ? (nval-500)/1000+0x100 : (nval+500)/1000;
+}
+
+static inline int TEMP_FROM_REG(u8 val)
+{
+	return (val>=0x80 ? val-0x100 : val) * 1000;
+}
+
+/* VID: mV
+   REG: (see doc/vid) */
+static inline int VID_FROM_REG(u8 val)
+{
+	return val==0x1f ? 0 : val>=0x10 ? 5100-val*100 : 2050-val*50;
+}
+
+/* ALARMS: chip-specific bitmask
+   REG: (same) */
+#define ALARMS_FROM_REG(val) (val)
+
+/* FAN DIV: 1, 2, 4, or 8 (defaults to 2)
+   REG: 0, 1, 2, or 3 (respectively) (defaults to 1) */
+static inline u8 DIV_TO_REG(int val)
+{
+	return val==8 ? 3 : val==4 ? 2 : val==1 ? 0 : 1;
+}
+#define DIV_FROM_REG(val) (1 << (val))
+
+/* Initial limits. To keep them sane, we use the 'standard' translation as
+   specified in the LM78 sheet. Use the config file to set better limits. */
+#define LM78_INIT_IN_0(vid) ((vid)==3500 ? 2800 : (vid))
+#define LM78_INIT_IN_1(vid) ((vid)==3500 ? 2800 : (vid))
+#define LM78_INIT_IN_2 3300
+#define LM78_INIT_IN_3 (((5000)   * 100)/168)
+#define LM78_INIT_IN_4 (((12000)  * 10)/38)
+#define LM78_INIT_IN_5 (((-12000) * -604)/2100)
+#define LM78_INIT_IN_6 (((-5000)  * -604)/909)
+
+#define LM78_INIT_IN_PERCENTAGE 10
+
+#define LM78_INIT_IN_MIN_0(vid) (LM78_INIT_IN_0(vid) - \
+	LM78_INIT_IN_0(vid) * LM78_INIT_IN_PERCENTAGE / 100)
+#define LM78_INIT_IN_MAX_0(vid) (LM78_INIT_IN_0(vid) + \
+	LM78_INIT_IN_0(vid) * LM78_INIT_IN_PERCENTAGE / 100)
+#define LM78_INIT_IN_MIN_1(vid) (LM78_INIT_IN_1(vid) - \
+	LM78_INIT_IN_1(vid) * LM78_INIT_IN_PERCENTAGE / 100)
+#define LM78_INIT_IN_MAX_1(vid) (LM78_INIT_IN_1(vid) + \
+	LM78_INIT_IN_1(vid) * LM78_INIT_IN_PERCENTAGE / 100)
+
+#define LM78_INIT_IN_MIN_2 \
+        (LM78_INIT_IN_2 - LM78_INIT_IN_2 * LM78_INIT_IN_PERCENTAGE / 100)
+#define LM78_INIT_IN_MAX_2 \
+        (LM78_INIT_IN_2 + LM78_INIT_IN_2 * LM78_INIT_IN_PERCENTAGE / 100)
+#define LM78_INIT_IN_MIN_3 \
+        (LM78_INIT_IN_3 - LM78_INIT_IN_3 * LM78_INIT_IN_PERCENTAGE / 100)
+#define LM78_INIT_IN_MAX_3 \
+        (LM78_INIT_IN_3 + LM78_INIT_IN_3 * LM78_INIT_IN_PERCENTAGE / 100)
+#define LM78_INIT_IN_MIN_4 \
+        (LM78_INIT_IN_4 - LM78_INIT_IN_4 * LM78_INIT_IN_PERCENTAGE / 100)
+#define LM78_INIT_IN_MAX_4 \
+        (LM78_INIT_IN_4 + LM78_INIT_IN_4 * LM78_INIT_IN_PERCENTAGE / 100)
+#define LM78_INIT_IN_MIN_5 \
+        (LM78_INIT_IN_5 - LM78_INIT_IN_5 * LM78_INIT_IN_PERCENTAGE / 100)
+#define LM78_INIT_IN_MAX_5 \
+        (LM78_INIT_IN_5 + LM78_INIT_IN_5 * LM78_INIT_IN_PERCENTAGE / 100)
+#define LM78_INIT_IN_MIN_6 \
+        (LM78_INIT_IN_6 - LM78_INIT_IN_6 * LM78_INIT_IN_PERCENTAGE / 100)
+#define LM78_INIT_IN_MAX_6 \
+        (LM78_INIT_IN_6 + LM78_INIT_IN_6 * LM78_INIT_IN_PERCENTAGE / 100)
+
+#define LM78_INIT_FAN_MIN_1 3000
+#define LM78_INIT_FAN_MIN_2 3000
+#define LM78_INIT_FAN_MIN_3 3000
+
+#define LM78_INIT_TEMP_OVER 60000
+#define LM78_INIT_TEMP_HYST 50000
+
+/* There are some complications in a module like this. First off, LM78 chips
+   may be both present on the SMBus and the ISA bus, and we have to handle
+   those cases separately at some places. Second, there might be several
+   LM78 chips available (well, actually, that is probably never done; but
+   it is a clean illustration of how to handle a case like that). Finally,
+   a specific chip may be attached to *both* ISA and SMBus, and we would
+   not like to detect it double. Fortunately, in the case of the LM78 at
+   least, a register tells us what SMBus address we are on, so that helps
+   a bit - except if there could be more than one SMBus. Groan. No solution
+   for this yet. */
+
+/* This module may seem overly long and complicated. In fact, it is not so
+   bad. Quite a lot of bookkeeping is done. A real driver can often cut
+   some corners. */
+
+/* For each registered LM78, we need to keep some data in memory. That
+   data is pointed to by lm78_list[NR]->data. The structure itself is
+   dynamically allocated, at the same time when a new lm78 client is
+   allocated. */
+struct lm78_data {
+	struct semaphore lock;
+	enum chips type;
+
+	struct semaphore update_lock;
+	char valid;		/* !=0 if following fields are valid */
+	unsigned long last_updated;	/* In jiffies */
+
+	u8 in[7];		/* Register value */
+	u8 in_max[7];		/* Register value */
+	u8 in_min[7];		/* Register value */
+	u8 fan[3];		/* Register value */
+	u8 fan_min[3];		/* Register value */
+	u8 temp;		/* Register value */
+	u8 temp_over;		/* Register value */
+	u8 temp_hyst;		/* Register value */
+	u8 fan_div[3];		/* Register encoding, shifted right */
+	u8 vid;			/* Register encoding, combined */
+	u16 alarms;		/* Register encoding, combined */
+};
+
+
+static int lm78_attach_adapter(struct i2c_adapter *adapter);
+static int lm78_detect(struct i2c_adapter *adapter, int address, int kind);
+static int lm78_detach_client(struct i2c_client *client);
+
+static int lm78_read_value(struct i2c_client *client, u8 register);
+static int lm78_write_value(struct i2c_client *client, u8 register, u8 value);
+static void lm78_update_client(struct i2c_client *client);
+static void lm78_init_client(struct i2c_client *client);
+
+
+static struct i2c_driver lm78_driver = {
+	.owner		= THIS_MODULE,
+	.name		= "lm78",
+	.id		= I2C_DRIVERID_LM78,
+	.flags		= I2C_DF_NOTIFY,
+	.attach_adapter	= lm78_attach_adapter,
+	.detach_client	= lm78_detach_client,
+};
+
+/* 7 Voltages */
+static ssize_t show_in(struct device *dev, char *buf, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	lm78_update_client(client);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in[nr]));
+}
+
+static ssize_t show_in_min(struct device *dev, char *buf, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	lm78_update_client(client);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_min[nr]));
+}
+
+static ssize_t show_in_max(struct device *dev, char *buf, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	lm78_update_client(client);
+	return sprintf(buf, "%d\n", IN_FROM_REG(data->in_max[nr]));
+}
+
+static ssize_t set_in_min(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	data->in_min[nr] = IN_TO_REG(val);
+	lm78_write_value(client, LM78_REG_IN_MIN(nr), data->in_min[nr]);
+	return count;
+}
+
+static ssize_t set_in_max(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	data->in_max[nr] = IN_TO_REG(val);
+	lm78_write_value(client, LM78_REG_IN_MAX(nr), data->in_max[nr]);
+	return count;
+}
+	
+#define show_in_offset(offset)					\
+static ssize_t							\
+	show_in##offset (struct device *dev, char *buf)		\
+{								\
+	return show_in(dev, buf, 0x##offset);			\
+}								\
+static DEVICE_ATTR(in_input##offset, S_IRUGO, 			\
+		show_in##offset, NULL)				\
+static ssize_t							\
+	show_in##offset##_min (struct device *dev, char *buf)   \
+{								\
+	return show_in_min(dev, buf, 0x##offset);		\
+}								\
+static ssize_t							\
+	show_in##offset##_max (struct device *dev, char *buf)   \
+{								\
+	return show_in_max(dev, buf, 0x##offset);		\
+}								\
+static ssize_t set_in##offset##_min (struct device *dev,	\
+		const char *buf, size_t count)			\
+{								\
+	return set_in_min(dev, buf, count, 0x##offset);		\
+}								\
+static ssize_t set_in##offset##_max (struct device *dev,	\
+		const char *buf, size_t count)			\
+{								\
+	return set_in_max(dev, buf, count, 0x##offset);		\
+}								\
+static DEVICE_ATTR(in_min##offset, S_IRUGO | S_IWUSR,		\
+		show_in##offset##_min, set_in##offset##_min)    \
+static DEVICE_ATTR(in_max##offset, S_IRUGO | S_IWUSR,		\
+		show_in##offset##_max, set_in##offset##_max)
+
+show_in_offset(0);
+show_in_offset(1);
+show_in_offset(2);
+show_in_offset(3);
+show_in_offset(4);
+show_in_offset(5);
+show_in_offset(6);
+
+/* Temperature */
+static ssize_t show_temp(struct device *dev, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	lm78_update_client(client);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp));
+}
+
+static ssize_t show_temp_over(struct device *dev, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	lm78_update_client(client);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_over));
+}
+
+static ssize_t set_temp_over(struct device *dev, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+	data->temp_over = TEMP_TO_REG(val);
+	lm78_write_value(client, LM78_REG_TEMP_OVER, data->temp_over);
+	return count;
+}
+
+static ssize_t show_temp_hyst(struct device *dev, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	lm78_update_client(client);
+	return sprintf(buf, "%d\n", TEMP_FROM_REG(data->temp_hyst));
+}
+
+static ssize_t set_temp_hyst(struct device *dev, const char *buf, size_t count)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	long val = simple_strtol(buf, NULL, 10);
+	data->temp_hyst = TEMP_TO_REG(val);
+	lm78_write_value(client, LM78_REG_TEMP_HYST, data->temp_hyst);
+	return count;
+}
+
+static DEVICE_ATTR(temp_input, S_IRUGO, show_temp, NULL)
+static DEVICE_ATTR(temp_max, S_IRUGO | S_IWUSR,
+		show_temp_over, set_temp_over)
+static DEVICE_ATTR(temp_min, S_IRUGO | S_IWUSR,
+		show_temp_hyst, set_temp_hyst)
+
+/* 3 Fans */
+static ssize_t show_fan(struct device *dev, char *buf, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	lm78_update_client(client);
+	return sprintf(buf, "%d\n", FAN_FROM_REG(data->fan[nr],
+		DIV_FROM_REG(data->fan_div[nr])) );
+}
+
+static ssize_t show_fan_min(struct device *dev, char *buf, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	lm78_update_client(client);
+	return sprintf(buf,"%d\n", FAN_FROM_REG(data->fan_min[nr],
+		DIV_FROM_REG(data->fan_div[nr])) );
+}
+
+static ssize_t set_fan_min(struct device *dev, const char *buf,
+		size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	data->fan_min[nr] = FAN_TO_REG(val, DIV_FROM_REG(data->fan_div[nr]));
+	lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
+	return count;
+}
+
+static ssize_t show_fan_div(struct device *dev, char *buf, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	lm78_update_client(client);
+	return sprintf(buf, "%d\n", DIV_FROM_REG(data->fan_div[nr]) );
+}
+
+/* Note: we save and restore the fan minimum here, because its value is
+   determined in part by the fan divisor.  This follows the principle of
+   least suprise; the user doesn't expect the fan minimum to change just
+   because the divisor changed. */
+static ssize_t set_fan_div(struct device *dev, const char *buf,
+	size_t count, int nr)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	unsigned long min = FAN_FROM_REG(data->fan_min[nr],
+			DIV_FROM_REG(data->fan_div[nr]));
+	unsigned long val = simple_strtoul(buf, NULL, 10);
+	int reg = lm78_read_value(client, LM78_REG_VID_FANDIV);
+	data->fan_div[nr] = DIV_TO_REG(val);
+	switch (nr) {
+	case 0:
+		reg = (reg & 0xcf) | (data->fan_div[nr] << 4);
+		break;
+	case 1:
+		reg = (reg & 0x3f) | (data->fan_div[nr] << 6);
+		break;
+	}
+	lm78_write_value(client, LM78_REG_VID_FANDIV, reg);
+	data->fan_min[nr] =
+		FAN_TO_REG(min, DIV_FROM_REG(data->fan_div[nr]));
+	lm78_write_value(client, LM78_REG_FAN_MIN(nr), data->fan_min[nr]);
+	return count;
+}
+
+#define show_fan_offset(offset)						\
+static ssize_t show_fan_##offset (struct device *dev, char *buf)	\
+{									\
+	return show_fan(dev, buf, 0x##offset - 1);			\
+}									\
+static ssize_t show_fan_##offset##_min (struct device *dev, char *buf)  \
+{									\
+	return show_fan_min(dev, buf, 0x##offset - 1);			\
+}									\
+static ssize_t show_fan_##offset##_div (struct device *dev, char *buf)  \
+{									\
+	return show_fan_div(dev, buf, 0x##offset - 1);			\
+}									\
+static ssize_t set_fan_##offset##_min (struct device *dev,		\
+		const char *buf, size_t count)				\
+{									\
+	return set_fan_min(dev, buf, count, 0x##offset - 1);		\
+}									\
+static DEVICE_ATTR(fan_input##offset, S_IRUGO, show_fan_##offset, NULL) \
+static DEVICE_ATTR(fan_min##offset, S_IRUGO | S_IWUSR,			\
+		show_fan_##offset##_min, set_fan_##offset##_min)
+
+static ssize_t set_fan_1_div(struct device *dev, const char *buf,
+		size_t count)
+{
+	return set_fan_div(dev, buf, count, 0) ;
+}
+
+static ssize_t set_fan_2_div(struct device *dev, const char *buf,
+		size_t count)
+{
+	return set_fan_div(dev, buf, count, 1) ;
+}
+
+show_fan_offset(1);
+show_fan_offset(2);
+show_fan_offset(3);
+
+/* Fan 3 divisor is locked in H/W */
+static DEVICE_ATTR(fan_div1, S_IRUGO | S_IWUSR,
+		show_fan_1_div, set_fan_1_div)
+static DEVICE_ATTR(fan_div2, S_IRUGO | S_IWUSR,
+		show_fan_2_div, set_fan_2_div)
+static DEVICE_ATTR(fan_div3, S_IRUGO, show_fan_3_div, NULL)
+
+/* VID */
+static ssize_t show_vid(struct device *dev, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	lm78_update_client(client);
+	return sprintf(buf, "%d\n", VID_FROM_REG(data->vid));
+}
+static DEVICE_ATTR(vid, S_IRUGO, show_vid, NULL);
+
+/* Alarms */
+static ssize_t show_alarms(struct device *dev, char *buf)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct lm78_data *data = i2c_get_clientdata(client);
+	lm78_update_client(client);
+	return sprintf(buf, "%d\n", ALARMS_FROM_REG(data->alarms));
+}
+static DEVICE_ATTR(alarms, S_IRUGO, show_alarms, NULL);
+
+/* This function is called when:
+     * lm78_driver is inserted (when this module is loaded), for each
+       available adapter
+     * when a new adapter is inserted (and lm78_driver is still present) */
+static int lm78_attach_adapter(struct i2c_adapter *adapter)
+{
+	if (!(adapter->class & I2C_ADAP_CLASS_SMBUS))
+		return 0;
+	return i2c_detect(adapter, &addr_data, lm78_detect);
+}
+
+/* This function is called by i2c_detect */
+int lm78_detect(struct i2c_adapter *adapter, int address, int kind)
+{
+	int i, err;
+	struct i2c_client *new_client;
+	struct lm78_data *data;
+	const char *client_name = "";
+	int is_isa = i2c_is_isa_adapter(adapter);
+
+	if (!is_isa &&
+	    !i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA)) {
+		err = -ENODEV;
+		goto ERROR0;
+	}
+
+	/* Reserve the ISA region */
+	if (is_isa)
+		if (!request_region(address, LM78_EXTENT, "lm78")) {
+			err = -EBUSY;
+			goto ERROR0;
+		}
+
+	/* Probe whether there is anything available on this address. Already
+	   done for SMBus clients */
+	if (kind < 0) {
+		if (is_isa) {
+
+#define REALLY_SLOW_IO
+			/* We need the timeouts for at least some LM78-like
+			   chips. But only if we read 'undefined' registers. */
+			i = inb_p(address + 1);
+			if (inb_p(address + 2) != i) {
+				err = -ENODEV;
+				goto ERROR1;
+			}
+			if (inb_p(address + 3) != i) {
+				err = -ENODEV;
+				goto ERROR1;
+			}
+			if (inb_p(address + 7) != i) {
+				err = -ENODEV;
+				goto ERROR1;
+			}
+#undef REALLY_SLOW_IO
+
+			/* Let's just hope nothing breaks here */
+			i = inb_p(address + 5) & 0x7f;
+			outb_p(~i & 0x7f, address + 5);
+			if ((inb_p(address + 5) & 0x7f) != (~i & 0x7f)) {
+				outb_p(i, address + 5);
+				err = -ENODEV;
+				goto ERROR1;
+			}
+		}
+	}
+
+	/* OK. For now, we presume we have a valid client. We now create the
+	   client structure, even though we cannot fill it completely yet.
+	   But it allows us to access lm78_{read,write}_value. */
+
+	if (!(new_client = kmalloc((sizeof(struct i2c_client)) +
+				   sizeof(struct lm78_data),
+				   GFP_KERNEL))) {
+		err = -ENOMEM;
+		goto ERROR1;
+	}
+	memset(new_client, 0, sizeof(struct i2c_client) + 
+			      sizeof(struct lm78_data));
+
+	data = (struct lm78_data *) (new_client + 1);
+	if (is_isa)
+		init_MUTEX(&data->lock);
+	i2c_set_clientdata(new_client, data);
+	new_client->addr = address;
+	new_client->adapter = adapter;
+	new_client->driver = &lm78_driver;
+	new_client->flags = 0;
+
+	/* Now, we do the remaining detection. */
+	if (kind < 0) {
+		if (lm78_read_value(new_client, LM78_REG_CONFIG) & 0x80) {
+			err = -ENODEV;
+			goto ERROR2;
+		}
+		if (!is_isa && (lm78_read_value(
+				new_client, LM78_REG_I2C_ADDR) != address)) {
+			err = -ENODEV;
+			goto ERROR2;
+		}
+	}
+
+	/* Determine the chip type. */
+	if (kind <= 0) {
+		i = lm78_read_value(new_client, LM78_REG_CHIPID);
+		if (i == 0x00 || i == 0x20)
+			kind = lm78;
+		else if (i == 0x40)
+			kind = lm78j;
+		else if ((i & 0xfe) == 0xc0)
+			kind = lm79;
+		else {
+			if (kind == 0)
+				printk(KERN_WARNING "lm78.o: Ignoring 'force' "
+					"parameter for unknown chip at "
+					"adapter %d, address 0x%02x\n",
+					i2c_adapter_id(adapter), address);
+			err = -ENODEV;
+			goto ERROR2;
+		}
+	}
+
+	if (kind == lm78) {
+		client_name = "LM78 chip";
+	} else if (kind == lm78j) {
+		client_name = "LM78-J chip";
+	} else if (kind == lm79) {
+		client_name = "LM79 chip";
+	} else {
+		dev_dbg(&adapter->dev, "Internal error: unknown kind (%d)?!?",
+			kind);
+		err = -ENODEV;
+		goto ERROR2;
+	}
+
+	/* Fill in the remaining client fields and put into the global list */
+	strlcpy(new_client->dev.name, client_name, DEVICE_NAME_SIZE);
+	data->type = kind;
+
+	data->valid = 0;
+	init_MUTEX(&data->update_lock);
+
+	/* Tell the I2C layer a new client has arrived */
+	if ((err = i2c_attach_client(new_client)))
+		goto ERROR2;
+
+	/* register sysfs hooks */
+	device_create_file(&new_client->dev, &dev_attr_in_input0);
+	device_create_file(&new_client->dev, &dev_attr_in_min0);
+	device_create_file(&new_client->dev, &dev_attr_in_max0);
+	device_create_file(&new_client->dev, &dev_attr_in_input1);
+	device_create_file(&new_client->dev, &dev_attr_in_min1);
+	device_create_file(&new_client->dev, &dev_attr_in_max1);
+	device_create_file(&new_client->dev, &dev_attr_in_input2);
+	device_create_file(&new_client->dev, &dev_attr_in_min2);
+	device_create_file(&new_client->dev, &dev_attr_in_max2);
+	device_create_file(&new_client->dev, &dev_attr_in_input3);
+	device_create_file(&new_client->dev, &dev_attr_in_min3);
+	device_create_file(&new_client->dev, &dev_attr_in_max3);
+	device_create_file(&new_client->dev, &dev_attr_in_input4);
+	device_create_file(&new_client->dev, &dev_attr_in_min4);
+	device_create_file(&new_client->dev, &dev_attr_in_max4);
+	device_create_file(&new_client->dev, &dev_attr_in_input5);
+	device_create_file(&new_client->dev, &dev_attr_in_min5);
+	device_create_file(&new_client->dev, &dev_attr_in_max5);
+	device_create_file(&new_client->dev, &dev_attr_in_input6);
+	device_create_file(&new_client->dev, &dev_attr_in_min6);
+	device_create_file(&new_client->dev, &dev_attr_in_max6);
+	device_create_file(&new_client->dev, &dev_attr_temp_input);
+	device_create_file(&new_client->dev, &dev_attr_temp_min);
+	device_create_file(&new_client->dev, &dev_attr_temp_max);
+	device_create_file(&new_client->dev, &dev_attr_fan_input1);
+	device_create_file(&new_client->dev, &dev_attr_fan_min1);
+	device_create_file(&new_client->dev, &dev_attr_fan_div1);
+	device_create_file(&new_client->dev, &dev_attr_fan_input2);
+	device_create_file(&new_client->dev, &dev_attr_fan_min2);
+	device_create_file(&new_client->dev, &dev_attr_fan_div2);
+	device_create_file(&new_client->dev, &dev_attr_fan_input3);
+	device_create_file(&new_client->dev, &dev_attr_fan_min3);
+	device_create_file(&new_client->dev, &dev_attr_fan_div3);
+	device_create_file(&new_client->dev, &dev_attr_alarms);
+	device_create_file(&new_client->dev, &dev_attr_vid);
+
+	/* Initialize the LM78 chip */
+	lm78_init_client(new_client);
+	return 0;
+
+ERROR2:
+	kfree(new_client);
+ERROR1:
+	if (is_isa)
+		release_region(address, LM78_EXTENT);
+ERROR0:
+	return err;
+}
+
+static int lm78_detach_client(struct i2c_client *client)
+{
+	int err;
+
+	/* release ISA region first */
+	if(i2c_is_isa_client(client))
+		release_region(client->addr, LM78_EXTENT);
+
+	/* now it's safe to scrap the rest */
+	if ((err = i2c_detach_client(client))) {
+		dev_err(&client->dev,
+		    "Client deregistration failed, client not detached.\n");
+		return err;
+	}
+
+	kfree(client);
+
+	return 0;
+}
+
+/* The SMBus locks itself, but ISA access must be locked explicitely! 
+   We don't want to lock the whole ISA bus, so we lock each client
+   separately.
+   We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
+   would slow down the LM78 access and should not be necessary. 
+   There are some ugly typecasts here, but the good new is - they should
+   nowhere else be necessary! */
+static int lm78_read_value(struct i2c_client *client, u8 reg)
+{
+	int res;
+	if (i2c_is_isa_client(client)) {
+		struct lm78_data *data = i2c_get_clientdata(client);
+		down(&data->lock);
+		outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET);
+		res = inb_p(client->addr + LM78_DATA_REG_OFFSET);
+		up(&data->lock);
+		return res;
+	} else
+		return i2c_smbus_read_byte_data(client, reg);
+}
+
+/* The SMBus locks itself, but ISA access muse be locked explicitely! 
+   We don't want to lock the whole ISA bus, so we lock each client
+   separately.
+   We ignore the LM78 BUSY flag at this moment - it could lead to deadlocks,
+   would slow down the LM78 access and should not be necessary. 
+   There are some ugly typecasts here, but the good new is - they should
+   nowhere else be necessary! */
+static int lm78_write_value(struct i2c_client *client, u8 reg, u8 value)
+{
+	if (i2c_is_isa_client(client)) {
+		struct lm78_data *data = i2c_get_clientdata(client);
+		down(&data->lock);
+		outb_p(reg, client->addr + LM78_ADDR_REG_OFFSET);
+		outb_p(value, client->addr + LM78_DATA_REG_OFFSET);
+		up(&data->lock);
+		return 0;
+	} else
+		return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+/* Called when we have found a new LM78. It should set limits, etc. */
+static void lm78_init_client(struct i2c_client *client)
+{
+	struct lm78_data *data = i2c_get_clientdata(client);
+	int vid;
+
+	/* Reset all except Watchdog values and last conversion values
+	   This sets fan-divs to 2, among others */
+	lm78_write_value(client, LM78_REG_CONFIG, 0x80);
+
+	vid = lm78_read_value(client, LM78_REG_VID_FANDIV) & 0x0f;
+	if (data->type == lm79)
+		vid |=
+		    (lm78_read_value(client, LM78_REG_CHIPID) & 0x01) << 4;
+	else
+		vid |= 0x10;
+	vid = VID_FROM_REG(vid);
+
+	lm78_write_value(client, LM78_REG_IN_MIN(0),
+			 IN_TO_REG(LM78_INIT_IN_MIN_0(vid)));
+	lm78_write_value(client, LM78_REG_IN_MAX(0),
+			 IN_TO_REG(LM78_INIT_IN_MAX_0(vid)));
+	lm78_write_value(client, LM78_REG_IN_MIN(1),
+			 IN_TO_REG(LM78_INIT_IN_MIN_1(vid)));
+	lm78_write_value(client, LM78_REG_IN_MAX(1),
+			 IN_TO_REG(LM78_INIT_IN_MAX_1(vid)));
+	lm78_write_value(client, LM78_REG_IN_MIN(2),
+			 IN_TO_REG(LM78_INIT_IN_MIN_2));
+	lm78_write_value(client, LM78_REG_IN_MAX(2),
+			 IN_TO_REG(LM78_INIT_IN_MAX_2));
+	lm78_write_value(client, LM78_REG_IN_MIN(3),
+			 IN_TO_REG(LM78_INIT_IN_MIN_3));
+	lm78_write_value(client, LM78_REG_IN_MAX(3),
+			 IN_TO_REG(LM78_INIT_IN_MAX_3));
+	lm78_write_value(client, LM78_REG_IN_MIN(4),
+			 IN_TO_REG(LM78_INIT_IN_MIN_4));
+	lm78_write_value(client, LM78_REG_IN_MAX(4),
+			 IN_TO_REG(LM78_INIT_IN_MAX_4));
+	lm78_write_value(client, LM78_REG_IN_MIN(5),
+			 IN_TO_REG(LM78_INIT_IN_MIN_5));
+	lm78_write_value(client, LM78_REG_IN_MAX(5),
+			 IN_TO_REG(LM78_INIT_IN_MAX_5));
+	lm78_write_value(client, LM78_REG_IN_MIN(6),
+			 IN_TO_REG(LM78_INIT_IN_MIN_6));
+	lm78_write_value(client, LM78_REG_IN_MAX(6),
+			 IN_TO_REG(LM78_INIT_IN_MAX_6));
+	lm78_write_value(client, LM78_REG_FAN_MIN(0),
+			 FAN_TO_REG(LM78_INIT_FAN_MIN_1, 2));
+	lm78_write_value(client, LM78_REG_FAN_MIN(1),
+			 FAN_TO_REG(LM78_INIT_FAN_MIN_2, 2));
+	lm78_write_value(client, LM78_REG_FAN_MIN(2),
+			 FAN_TO_REG(LM78_INIT_FAN_MIN_3, 2));
+	lm78_write_value(client, LM78_REG_TEMP_OVER,
+			 TEMP_TO_REG(LM78_INIT_TEMP_OVER));
+	lm78_write_value(client, LM78_REG_TEMP_HYST,
+			 TEMP_TO_REG(LM78_INIT_TEMP_HYST));
+
+	/* Start monitoring */
+	lm78_write_value(client, LM78_REG_CONFIG,
+			 (lm78_read_value(client, LM78_REG_CONFIG) & 0xf7)
+			 | 0x01);
+
+}
+
+static void lm78_update_client(struct i2c_client *client)
+{
+	struct lm78_data *data = i2c_get_clientdata(client);
+	int i;
+
+	down(&data->update_lock);
+
+	if ((jiffies - data->last_updated > HZ + HZ / 2) ||
+	    (jiffies < data->last_updated) || !data->valid) {
+
+		dev_dbg(&client->dev, "Starting lm78 update\n");
+
+		for (i = 0; i <= 6; i++) {
+			data->in[i] =
+			    lm78_read_value(client, LM78_REG_IN(i));
+			data->in_min[i] =
+			    lm78_read_value(client, LM78_REG_IN_MIN(i));
+			data->in_max[i] =
+			    lm78_read_value(client, LM78_REG_IN_MAX(i));
+		}
+		for (i = 0; i < 3; i++) {
+			data->fan[i] =
+			    lm78_read_value(client, LM78_REG_FAN(i));
+			data->fan_min[i] =
+			    lm78_read_value(client, LM78_REG_FAN_MIN(i));
+		}
+		data->temp = lm78_read_value(client, LM78_REG_TEMP);
+		data->temp_over =
+		    lm78_read_value(client, LM78_REG_TEMP_OVER);
+		data->temp_hyst =
+		    lm78_read_value(client, LM78_REG_TEMP_HYST);
+		i = lm78_read_value(client, LM78_REG_VID_FANDIV);
+		data->vid = i & 0x0f;
+		if (data->type == lm79)
+			data->vid |=
+			    (lm78_read_value(client, LM78_REG_CHIPID) &
+			     0x01) << 4;
+		else
+			data->vid |= 0x10;
+		data->fan_div[0] = (i >> 4) & 0x03;
+		data->fan_div[1] = i >> 6;
+		data->alarms = lm78_read_value(client, LM78_REG_ALARM1) +
+		    (lm78_read_value(client, LM78_REG_ALARM2) << 8);
+		data->last_updated = jiffies;
+		data->valid = 1;
+
+		data->fan_div[2] = 1;
+	}
+
+	up(&data->update_lock);
+}
+
+static int __init sm_lm78_init(void)
+{
+	return i2c_add_driver(&lm78_driver);
+}
+
+static void __exit sm_lm78_exit(void)
+{
+	i2c_del_driver(&lm78_driver);
+}
+
+
+
+MODULE_AUTHOR("Frodo Looijaard <frodol@dds.nl>");
+MODULE_DESCRIPTION("LM78, LM78-J and LM79 driver");
+MODULE_LICENSE("GPL");
+
+module_init(sm_lm78_init);
+module_exit(sm_lm78_exit);
diff -Nru a/drivers/i2c/chips/lm85.c b/drivers/i2c/chips/lm85.c
--- a/drivers/i2c/chips/lm85.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/i2c/chips/lm85.c	Wed Jun 18 23:42:06 2003
@@ -148,20 +148,17 @@
 #define SCALE(val,from,to)		(((val)*(to) + ((from)/2))/(from))
 #define INS_TO_REG(n,val)		(SENSORS_LIMIT(SCALE(val,lm85_scaling[n],192),0,255))
 #define INSEXT_FROM_REG(n,val,ext)	(SCALE((val)*4 + (ext),192*4,lm85_scaling[n]))
-/*
 #define INS_FROM_REG(n,val)		(INSEXT_FROM_REG(n,val,0))
-*/
-#define INS_FROM_REG(n,val)		( ( (val*4*lm85_scaling[n]) + (192*4/2) ) / (192*4) )
 
 /* FAN speed is measured using 90kHz clock */
 #define FAN_TO_REG(val)		(SENSORS_LIMIT( (val)<=0?0: 5400000/(val),0,65534))
 #define FAN_FROM_REG(val)	((val)==0?-1:(val)==0xffff?0:5400000/(val))
 
-/* Temperature is reported in .01 degC increments */
-#define TEMP_TO_REG(val)		(SENSORS_LIMIT(((val)+50)/100,-127,127))
-#define TEMPEXT_FROM_REG(val,ext)	((val)*100 + (ext)*25)
+/* Temperature is reported in .001 degC increments */
+#define TEMP_TO_REG(val)		(SENSORS_LIMIT(((val)+500)/1000,-127,127))
+#define TEMPEXT_FROM_REG(val,ext)	((val)*1000 + (ext)*250)
 #define TEMP_FROM_REG(val)		(TEMPEXT_FROM_REG(val,0))
-#define EXTTEMP_TO_REG(val)		(SENSORS_LIMIT((val)/25,-127,127))
+#define EXTTEMP_TO_REG(val)		(SENSORS_LIMIT((val)/250,-127,127))
 
 #define PWM_TO_REG(val)			(SENSORS_LIMIT(val,0,255))
 #define PWM_FROM_REG(val)		(val)
@@ -437,10 +434,13 @@
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
+	int	val;
 
-	int val = simple_strtol(buf, NULL, 10);
+	down(&data->update_lock);
+	val = simple_strtol(buf, NULL, 10);
 	data->fan_min[nr] = FAN_TO_REG(val);
 	lm85_write_value(client, LM85_REG_FAN_MIN(nr), data->fan_min[nr]);
+	up(&data->update_lock);
 	return count;
 }
 
@@ -528,10 +528,13 @@
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
+	int	val;
 
-	int val = simple_strtol(buf, NULL, 10);
+	down(&data->update_lock);
+	val = simple_strtol(buf, NULL, 10);
 	data->pwm[nr] = PWM_TO_REG(val);
 	lm85_write_value(client, LM85_REG_PWM(nr), data->pwm[nr]);
+	up(&data->update_lock);
 	return count;
 }
 static ssize_t show_pwm_enable(struct device *dev, char *buf, int nr)
@@ -590,10 +593,13 @@
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
+	int	val;
 
-	int val = simple_strtol(buf, NULL, 10);
+	down(&data->update_lock);
+	val = simple_strtol(buf, NULL, 10);
 	data->in_min[nr] = INS_TO_REG(nr, val);
 	lm85_write_value(client, LM85_REG_IN_MIN(nr), data->in_min[nr]);
+	up(&data->update_lock);
 	return count;
 }
 static ssize_t show_in_max(struct device *dev, char *buf, int nr)
@@ -609,10 +615,13 @@
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
+	int	val;
 
-	int val = simple_strtol(buf, NULL, 10);
+	down(&data->update_lock);
+	val = simple_strtol(buf, NULL, 10);
 	data->in_max[nr] = INS_TO_REG(nr, val);
 	lm85_write_value(client, LM85_REG_IN_MAX(nr), data->in_max[nr]);
+	up(&data->update_lock);
 	return count;
 }
 #define show_in_reg(offset)						\
@@ -673,10 +682,13 @@
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
+	int	val;
 
-	int val = simple_strtol(buf, NULL, 10);
+	down(&data->update_lock);
+	val = simple_strtol(buf, NULL, 10);
 	data->temp_min[nr] = TEMP_TO_REG(val);
 	lm85_write_value(client, LM85_REG_TEMP_MIN(nr), data->temp_min[nr]);
+	up(&data->update_lock);
 	return count;
 }
 static ssize_t show_temp_max(struct device *dev, char *buf, int nr)
@@ -692,10 +704,13 @@
 {
 	struct i2c_client *client = to_i2c_client(dev);
 	struct lm85_data *data = i2c_get_clientdata(client);
+	int	val;
 
-	int val = simple_strtol(buf, NULL, 10);
+	down(&data->update_lock);
+	val = simple_strtol(buf, NULL, 10);
 	data->temp_max[nr] = TEMP_TO_REG(val);
 	lm85_write_value(client, LM85_REG_TEMP_MAX(nr), data->temp_max[nr]);
+	up(&data->update_lock);
 	return count;
 }
 #define show_temp_reg(offset)						\
diff -Nru a/drivers/i2c/chips/w83781d.c b/drivers/i2c/chips/w83781d.c
--- a/drivers/i2c/chips/w83781d.c	Wed Jun 18 23:42:05 2003
+++ b/drivers/i2c/chips/w83781d.c	Wed Jun 18 23:42:05 2003
@@ -28,6 +28,7 @@
     asb100 "bach" (type_name = as99127f)	0x30	0x0694	yes	no
     w83781d	7	3	0	3	0x10	0x5ca3	yes	yes
     w83627hf	9	3	2	3	0x20	0x5ca3	yes	yes(LPC)
+    w83627thf	9	3	2	3	0x90	0x5ca3	no	yes(LPC)
     w83782d	9	3	2-4	3	0x30	0x5ca3	yes	yes
     w83783s	5-6	3	2	1-2	0x40	0x5ca3	yes	no
     w83697hf	8	2	2	2	0x60	0x5ca3	no	yes(LPC)
@@ -299,8 +300,8 @@
 	char valid;		/* !=0 if following fields are valid */
 	unsigned long last_updated;	/* In jiffies */
 
-	struct i2c_client *lm75;	/* for secondary I2C addresses */
-	/* pointer to array of 2 subclients */
+	struct i2c_client *lm75[2];	/* for secondary I2C addresses */
+	/* array of 2 pointers to subclients */
 
 	u8 in[9];		/* Register value - 8 & 9 for 782D only */
 	u8 in_max[9];		/* Register value - 8 & 9 for 782D only */
@@ -1043,12 +1044,12 @@
 	const char *client_name;
 	struct w83781d_data *data = i2c_get_clientdata(new_client);
 
-	if (!(data->lm75 = kmalloc(2 * sizeof (struct i2c_client),
-			GFP_KERNEL))) {
+	data->lm75[0] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+	if (!(data->lm75[0])) {
 		err = -ENOMEM;
 		goto ERROR_SC_0;
 	}
-	memset(data->lm75, 0x00, 2 * sizeof (struct i2c_client));
+	memset(data->lm75[0], 0x00, sizeof (struct i2c_client));
 
 	id = i2c_adapter_id(adapter);
 
@@ -1066,25 +1067,33 @@
 		w83781d_write_value(new_client, W83781D_REG_I2C_SUBADDR,
 				(force_subclients[2] & 0x07) |
 				((force_subclients[3] & 0x07) << 4));
-		data->lm75[0].addr = force_subclients[2];
+		data->lm75[0]->addr = force_subclients[2];
 	} else {
 		val1 = w83781d_read_value(new_client, W83781D_REG_I2C_SUBADDR);
-		data->lm75[0].addr = 0x48 + (val1 & 0x07);
+		data->lm75[0]->addr = 0x48 + (val1 & 0x07);
 	}
 
 	if (kind != w83783s) {
+
+		data->lm75[1] = kmalloc(sizeof(struct i2c_client), GFP_KERNEL);
+		if (!(data->lm75[1])) {
+			err = -ENOMEM;
+			goto ERROR_SC_1;
+		}
+		memset(data->lm75[1], 0x0, sizeof(struct i2c_client));
+
 		if (force_subclients[0] == id &&
 		    force_subclients[1] == address) {
-			data->lm75[1].addr = force_subclients[3];
+			data->lm75[1]->addr = force_subclients[3];
 		} else {
-			data->lm75[1].addr = 0x48 + ((val1 >> 4) & 0x07);
+			data->lm75[1]->addr = 0x48 + ((val1 >> 4) & 0x07);
 		}
-		if (data->lm75[0].addr == data->lm75[1].addr) {
+		if (data->lm75[0]->addr == data->lm75[1]->addr) {
 			dev_err(&new_client->dev,
 			       "Duplicate addresses 0x%x for subclients.\n",
-			       data->lm75[0].addr);
+			       data->lm75[0]->addr);
 			err = -EBUSY;
-			goto ERROR_SC_1;
+			goto ERROR_SC_2;
 		}
 	}
 
@@ -1103,19 +1112,19 @@
 
 	for (i = 0; i <= 1; i++) {
 		/* store all data in w83781d */
-		i2c_set_clientdata(&data->lm75[i], NULL);
-		data->lm75[i].adapter = adapter;
-		data->lm75[i].driver = &w83781d_driver;
-		data->lm75[i].flags = 0;
-		strlcpy(data->lm75[i].dev.name, client_name,
+		i2c_set_clientdata(data->lm75[i], NULL);
+		data->lm75[i]->adapter = adapter;
+		data->lm75[i]->driver = &w83781d_driver;
+		data->lm75[i]->flags = 0;
+		strlcpy(data->lm75[i]->dev.name, client_name,
 			DEVICE_NAME_SIZE);
-		if ((err = i2c_attach_client(&(data->lm75[i])))) {
+		if ((err = i2c_attach_client(data->lm75[i]))) {
 			dev_err(&new_client->dev, "Subclient %d "
 				"registration at address 0x%x "
-				"failed.\n", i, data->lm75[i].addr);
+				"failed.\n", i, data->lm75[i]->addr);
 			if (i == 1)
-				goto ERROR_SC_2;
-			goto ERROR_SC_1;
+				goto ERROR_SC_3;
+			goto ERROR_SC_2;
 		}
 		if (kind == w83783s)
 			break;
@@ -1124,10 +1133,14 @@
 	return 0;
 
 /* Undo inits in case of errors */
+ERROR_SC_3:
+	i2c_detach_client(data->lm75[0]);
 ERROR_SC_2:
-	i2c_detach_client(&(data->lm75[0]));
+	if (NULL != data->lm75[1])
+		kfree(data->lm75[1]);
 ERROR_SC_1:
-	kfree(data->lm75);
+	if (NULL != data->lm75[0])
+		kfree(data->lm75[0]);
 ERROR_SC_0:
 	return err;
 }
@@ -1273,7 +1286,7 @@
 			kind = w83782d;
 		else if (val1 == 0x40 && vendid == winbond && !is_isa)
 			kind = w83783s;
-		else if (val1 == 0x20 && vendid == winbond)
+		else if ((val1 == 0x20 || val1 == 0x90) && vendid == winbond)
 			kind = w83627hf;
 		else if (val1 == 0x30 && vendid == asus && !is_isa)
 			kind = as99127f;
@@ -1297,7 +1310,10 @@
 	} else if (kind == w83783s) {
 		client_name = "W83783S chip";
 	} else if (kind == w83627hf) {
-		client_name = "W83627HF chip";
+		if (val1 == 0x90)
+			client_name = "W83627THF chip";
+		else
+			client_name = "W83627HF chip";
 	} else if (kind == as99127f) {
 		client_name = "AS99127F chip";
 	} else if (kind == w83697hf) {
@@ -1326,7 +1342,8 @@
 				kind, new_client)))
 			goto ERROR3;
 	} else {
-		data->lm75 = NULL;
+		data->lm75[0] = NULL;
+		data->lm75[1] = NULL;
 	}
 
 	device_create_file_in(new_client, 0);
@@ -1409,20 +1426,11 @@
 static int
 w83781d_detach_client(struct i2c_client *client)
 {
-	struct w83781d_data *data = i2c_get_clientdata(client);
 	int err;
 
-	/* release ISA region or I2C subclients first */
-	if (i2c_is_isa_client(client)) {
+	if (i2c_is_isa_client(client))
 		release_region(client->addr, W83781D_EXTENT);
-	} else {
-		i2c_detach_client(&data->lm75[0]);
-		if (data->type != w83783s)
-			i2c_detach_client(&data->lm75[1]);
-		kfree(data->lm75);
-	}
 
-	/* now it's safe to scrap the rest */
 	if ((err = i2c_detach_client(client))) {
 		dev_err(&client->dev,
 		       "Client deregistration failed, client not detached.\n");
@@ -1484,7 +1492,7 @@
 			res = i2c_smbus_read_byte_data(client, reg & 0xff);
 		} else {
 			/* switch to subclient */
-			cl = &data->lm75[bank - 1];
+			cl = data->lm75[bank - 1];
 			/* convert from ISA to LM75 I2C addresses */
 			switch (reg & 0xff) {
 			case 0x50:	/* TEMP */
@@ -1555,7 +1563,7 @@
 						  value & 0xff);
 		} else {
 			/* switch to subclient */
-			cl = &data->lm75[bank - 1];
+			cl = data->lm75[bank - 1];
 			/* convert from ISA to LM75 I2C addresses */
 			switch (reg & 0xff) {
 			case 0x52:	/* CONFIG */
diff -Nru a/drivers/ieee1394/sbp2.c b/drivers/ieee1394/sbp2.c
--- a/drivers/ieee1394/sbp2.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/ieee1394/sbp2.c	Wed Jun 18 23:42:06 2003
@@ -707,7 +707,7 @@
 		return hi;
 
 	/* Register our host with the SCSI stack. */
-	scsi_host = scsi_register (&scsi_driver_template, 0);
+	scsi_host = scsi_host_alloc(&scsi_driver_template, 0);
 	if (!scsi_host) {
 		SBP2_ERR("failed to register scsi host");
 		return NULL;
@@ -716,7 +716,7 @@
 	hi = hpsb_create_hostinfo(&sbp2_highlevel, host, sizeof(*hi));
 	if (!hi) {
 		SBP2_ERR("failed to allocate hostinfo");
-		scsi_unregister(hi->scsi_host);
+		scsi_host_put(hi->scsi_host);
 	}
 
 	hpsb_set_hostinfo_key(&sbp2_highlevel, host, (unsigned long)scsi_host);
@@ -732,7 +732,7 @@
 	 * enabled (scsi-host uses classdata member of the device). */
 	if (scsi_add_host(hi->scsi_host, NULL)) {
 		SBP2_ERR("failed to add scsi host");
-		scsi_unregister(hi->scsi_host);
+		scsi_host_put(hi->scsi_host);
 		hpsb_destroy_hostinfo(&sbp2_highlevel, host);
 	}
 
@@ -753,7 +753,7 @@
 
 	if (hi) {
 		scsi_remove_host(hi->scsi_host);
-		scsi_unregister(hi->scsi_host);
+		scsi_host_put(hi->scsi_host);
 	}
 }
 
diff -Nru a/drivers/input/serio/ambakmi.c b/drivers/input/serio/ambakmi.c
--- a/drivers/input/serio/ambakmi.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/input/serio/ambakmi.c	Wed Jun 18 23:42:08 2003
@@ -1,7 +1,7 @@
 /*
- *  linux/drivers/input/serio/amba_kmi.c
+ *  linux/drivers/input/serio/ambakmi.c
  *
- *  Copyright (C) 2000 Deep Blue Solutions Ltd.
+ *  Copyright (C) 2000-2003 Deep Blue Solutions Ltd.
  *  Copyright (C) 2002 Russell King.
  *
  * This program is free software; you can redistribute it and/or modify
@@ -21,6 +21,7 @@
 
 #include <asm/io.h>
 #include <asm/irq.h>
+#include <asm/hardware/amba.h>
 #include <asm/hardware/amba_kmi.h>
 
 #define KMI_BASE	(kmi->base)
@@ -28,11 +29,10 @@
 struct amba_kmi_port {
 	struct serio		io;
 	struct amba_kmi_port	*next;
-	void			*base;
+	unsigned char		*base;
 	unsigned int		irq;
 	unsigned int		divisor;
-	char			name[32];
-	char			phys[16];
+	unsigned int		open;
 	struct resource		*res;
 };
 
@@ -73,7 +73,7 @@
 	writeb(kmi->divisor, KMICLKDIV);
 	writeb(KMICR_EN, KMICR);
 
-	ret = request_irq(kmi->irq, amba_kmi_int, 0, kmi->phys, kmi);
+	ret = request_irq(kmi->irq, amba_kmi_int, 0, kmi->io.phys, kmi);
 	if (ret) {
 		printk(KERN_ERR "kmi: failed to claim IRQ%d\n", kmi->irq);
 		writeb(0, KMICR);
@@ -94,9 +94,7 @@
 	free_irq(kmi->irq, kmi);
 }
 
-static struct amba_kmi_port *list;
-
-static int __init amba_kmi_init_one(char *type, unsigned long base, int irq, int nr)
+static int amba_kmi_probe(struct amba_device *dev, void *id)
 {
 	struct amba_kmi_port *kmi;
 
@@ -110,58 +108,83 @@
 	kmi->io.write	= amba_kmi_write;
 	kmi->io.open	= amba_kmi_open;
 	kmi->io.close	= amba_kmi_close;
-	kmi->io.name	= kmi->name;
-	kmi->io.phys	= kmi->phys;
+	kmi->io.name	= dev->dev.name;
+	kmi->io.phys	= dev->dev.bus_id;
 	kmi->io.driver	= kmi;
 
-	snprintf(kmi->name, sizeof(kmi->name), "AMBA KMI PS/2 %s port", type);
-	snprintf(kmi->phys, sizeof(kmi->phys), "amba/serio%d", nr);
-
-	kmi->res	= request_mem_region(base, KMI_SIZE, kmi->phys);
+	kmi->res	= request_mem_region(dev->res.start, KMI_SIZE, kmi->io.phys);
 	if (!kmi->res) {
 		kfree(kmi);
 		return -EBUSY;
 	}
 
-	kmi->base	= ioremap(base, KMI_SIZE);
+	kmi->base	= ioremap(dev->res.start, KMI_SIZE);
 	if (!kmi->base) {
 		release_resource(kmi->res);
 		kfree(kmi);
 		return -ENOMEM;
 	}
 
-	kmi->irq	= irq;
+	kmi->irq	= dev->irq;
 	kmi->divisor	= 24 / 8 - 1;
 
-	kmi->next	= list;
-	list		= kmi;
+	amba_set_drvdata(dev, kmi);
 
 	serio_register_port(&kmi->io);
 	return 0;
 }
 
-static int __init amba_kmi_init(void)
+static int amba_kmi_remove(struct amba_device *dev)
 {
-	amba_kmi_init_one("keyboard", KMI0_BASE, IRQ_KMIINT0, 0);
-	amba_kmi_init_one("mouse", KMI1_BASE, IRQ_KMIINT1, 1);
+	struct amba_kmi_port *kmi = amba_get_drvdata(dev);
+
+	amba_set_drvdata(dev, NULL);
+
+	serio_unregister_port(&kmi->io);
+	iounmap(kmi->base);
+	release_resource(kmi->res);
+	kfree(kmi);
 	return 0;
 }
 
-static void __exit amba_kmi_exit(void)
+static int amba_kmi_resume(struct amba_device *dev, u32 level)
 {
-	struct amba_kmi_port *kmi, *next;
+	struct amba_kmi_port *kmi = amba_get_drvdata(dev);
 
-	kmi = list;
-	while (kmi) {
-		next = kmi->next;
+	if (level == RESUME_ENABLE) {
+		/* kick the serio layer to rescan this port */
+		serio_rescan(&kmi->io);
+	}
 
-		serio_unregister_port(&kmi->io);
-		iounmap(kmi->base);
-		release_resource(kmi->res);
-		kfree(kmi);
+	return 0;
+}
 
-		kmi = next;
-	}
+static struct amba_id amba_kmi_idtable[] = {
+	{
+		.id	= 0x00041050,
+		.mask	= 0x000fffff,
+	},
+	{ 0, 0 }
+};
+
+static struct amba_driver ambakmi_driver = {
+	.drv		= {
+		.name	= "kmi-pl050",
+	},
+	.id_table	= amba_kmi_idtable,
+	.probe		= amba_kmi_probe,
+	.remove		= amba_kmi_remove,
+	.resume		= amba_kmi_resume,
+};
+
+static int __init amba_kmi_init(void)
+{
+	return amba_driver_register(&ambakmi_driver);
+}
+
+static void __exit amba_kmi_exit(void)
+{
+	return amba_driver_unregister(&ambakmi_driver);
 }
 
 module_init(amba_kmi_init);
diff -Nru a/drivers/md/dm-ioctl.c b/drivers/md/dm-ioctl.c
--- a/drivers/md/dm-ioctl.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/md/dm-ioctl.c	Wed Jun 18 23:42:06 2003
@@ -297,13 +297,14 @@
 	/*
 	 * rename and move the name cell.
 	 */
+	unregister_with_devfs(hc);
+
 	list_del(&hc->name_list);
 	old_name = hc->name;
 	hc->name = new_name;
 	list_add(&hc->name_list, _name_buckets + hash_str(new_name));
 
 	/* rename the device node in devfs */
-	unregister_with_devfs(hc);
 	register_with_devfs(hc);
 
 	up_write(&_hash_lock);
diff -Nru a/drivers/message/i2o/i2o_scsi.c b/drivers/message/i2o/i2o_scsi.c
--- a/drivers/message/i2o/i2o_scsi.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/message/i2o/i2o_scsi.c	Wed Jun 18 23:42:08 2003
@@ -866,34 +866,6 @@
 }
 
 /**
- *	internal_done	-	legacy scsi glue
- *	@SCPnt: command
- *
- *	Completion function for a synchronous command
- */
-
-static void internal_done(Scsi_Cmnd * SCpnt)
-{
-	SCpnt->SCp.Status++;
-}
-
-/**
- *	i2o_scsi_command	-	issue a scsi command and wait
- *	@SCPnt: command
- *
- *	Issue a SCSI command and wait for it to complete.
- */
- 
-static int i2o_scsi_command(Scsi_Cmnd * SCpnt)
-{
-	i2o_scsi_queuecommand(SCpnt, internal_done);
-	SCpnt->SCp.Status = 0;
-	while (!SCpnt->SCp.Status)
-		barrier();
-	return SCpnt->result;
-}
-
-/**
  *	i2o_scsi_abort	-	abort a running command
  *	@SCpnt: command to abort
  *
@@ -1091,7 +1063,6 @@
 	.detect			= i2o_scsi_detect,
 	.release		= i2o_scsi_release,
 	.info			= i2o_scsi_info,
-	.command		= i2o_scsi_command,
 	.queuecommand		= i2o_scsi_queuecommand,
 	.eh_abort_handler	= i2o_scsi_abort,
 	.eh_bus_reset_handler	= i2o_scsi_bus_reset,
diff -Nru a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
--- a/drivers/net/bonding/bond_main.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/net/bonding/bond_main.c	Wed Jun 18 23:42:09 2003
@@ -497,9 +497,7 @@
 {	NULL,		-1},
 };
 
-static int first_pass	= 1;
-static struct bonding *these_bonds =  NULL;
-static struct net_device *dev_bonds = NULL;
+static LIST_HEAD(bond_dev_list);
 
 MODULE_PARM(max_bonds, "i");
 MODULE_PARM_DESC(max_bonds, "Max number of bonded devices");
@@ -952,8 +950,6 @@
 		add_timer(alb_timer);
 	}
 
-	MOD_INC_USE_COUNT;
-
 	if (miimon > 0) {  /* link check interval, in milliseconds. */
 		init_timer(timer);
 		timer->expires  = jiffies + (miimon * HZ / 1000);
@@ -1027,7 +1023,6 @@
 		bond_alb_deinitialize(bond);
 	}
 
-	MOD_DEC_USE_COUNT;
 	return 0;
 }
 
@@ -3411,7 +3406,7 @@
 
 static int bond_get_info(char *buf, char **start, off_t offset, int length)
 {
-	bonding_t *bond = these_bonds;
+	bonding_t *bond;
 	int len = 0;
 	off_t begin = 0;
 	u16 link;
@@ -3419,7 +3414,8 @@
 
 	len += sprintf(buf + len, "%s\n", version);
 
-	while (bond != NULL) {
+	read_lock(&dev_base_lock);
+	list_for_each_entry(bond, &bond_dev_list, bond_list) {
 		/*
 		 * This function locks the mutex, so we can't lock it until 
 		 * afterwards
@@ -3529,93 +3525,48 @@
 			len = 0;
 		}
 
-
-		bond = bond->next_bond;
 	}
+	read_unlock(&dev_base_lock);
+
 	return len;
 }
 
 static int bond_event(struct notifier_block *this, unsigned long event, 
 			void *ptr)
 {
-	struct bonding *this_bond = (struct bonding *)these_bonds;
-	struct bonding *last_bond;
 	struct net_device *event_dev = (struct net_device *)ptr;
+	struct net_device *master = event_dev->master;
 
-	/* while there are bonds configured */
-	while (this_bond != NULL) {
-		if (this_bond == event_dev->priv ) {
-			switch (event) {
-			case NETDEV_UNREGISTER:
-				/* 
-				 * remove this bond from a linked list of 
-				 * bonds 
-				 */
-				if (this_bond == these_bonds) {
-					these_bonds = this_bond->next_bond;
-				} else {
-					for (last_bond = these_bonds; 
-					     last_bond != NULL; 
-					     last_bond = last_bond->next_bond) {
-						if (last_bond->next_bond == 
-						    this_bond) {
-							last_bond->next_bond = 
-							this_bond->next_bond;
-						}
-					}
-				}
-				return NOTIFY_DONE;
+	if (event == NETDEV_UNREGISTER && master != NULL) 
+		bond_release(master, event_dev);
 
-			default:
-				return NOTIFY_DONE;
-			}
-		} else if (this_bond->device == event_dev->master) {
-			switch (event) {
-			case NETDEV_UNREGISTER:
-				bond_release(this_bond->device, event_dev);
-				break;
-			}
-			return NOTIFY_DONE;
-		}
-		this_bond = this_bond->next_bond;
-	}
 	return NOTIFY_DONE;
 }
 
 static struct notifier_block bond_netdev_notifier = {
-	notifier_call: bond_event,
+	.notifier_call = bond_event,
 };
 
 static int __init bond_init(struct net_device *dev)
 {
-	bonding_t *bond, *this_bond, *last_bond;
+	bonding_t *bond;
 	int count;
 
 #ifdef BONDING_DEBUG
 	printk (KERN_INFO "Begin bond_init for %s\n", dev->name);
 #endif
-	bond = kmalloc(sizeof(struct bonding), GFP_KERNEL);
-	if (bond == NULL) {
-		return -ENOMEM;
-	}
-	memset(bond, 0, sizeof(struct bonding));
+	bond = dev->priv;
 
 	/* initialize rwlocks */
 	rwlock_init(&bond->lock);
 	rwlock_init(&bond->ptrlock);
 	
-	bond->stats = kmalloc(sizeof(struct net_device_stats), GFP_KERNEL);
-	if (bond->stats == NULL) {
-		kfree(bond);
-		return -ENOMEM;
-	}
-	memset(bond->stats, 0, sizeof(struct net_device_stats));
-
+	/* space is reserved for stats in alloc_netdev call. */
+	bond->stats = (struct net_device_stats *)(bond + 1);
 	bond->next = bond->prev = (slave_t *)bond;
 	bond->current_slave = NULL;
 	bond->current_arp_slave = NULL;
 	bond->device = dev;
-	dev->priv = bond;
 
 	/* Initialize the device structure. */
 	switch (bond_mode) {
@@ -3640,8 +3591,6 @@
 		break;
 	default:
 		printk(KERN_ERR "Unknown bonding mode %d\n", bond_mode);
-		kfree(bond->stats);
-		kfree(bond);
 		return -EINVAL;
 	}
 
@@ -3651,13 +3600,6 @@
 	dev->set_multicast_list = set_multicast_list;
 	dev->do_ioctl = bond_ioctl;
 
-	/* 
-	 * Fill in the fields of the device structure with ethernet-generic 
-	 * values. 
-	 */
-
-	ether_setup(dev);
-
 	dev->tx_queue_len = 0;
 	dev->flags |= IFF_MASTER|IFF_MULTICAST;
 #ifdef CONFIG_NET_FASTROUTE
@@ -3690,10 +3632,10 @@
 	if (bond->bond_proc_dir == NULL) {
 		printk(KERN_ERR "%s: Cannot init /proc/net/%s/\n", 
 			dev->name, dev->name);
-		kfree(bond->stats);
-		kfree(bond);
 		return -ENOMEM;
 	}
+	bond->bond_proc_dir->owner = THIS_MODULE;
+
 	bond->bond_proc_info_file = 
 		create_proc_info_entry("info", 0, bond->bond_proc_dir, 
 					bond_get_info);
@@ -3701,26 +3643,13 @@
 		printk(KERN_ERR "%s: Cannot init /proc/net/%s/info\n", 
 			dev->name, dev->name);
 		remove_proc_entry(dev->name, proc_net);
-		kfree(bond->stats);
-		kfree(bond);
 		return -ENOMEM;
 	}
+	bond->bond_proc_info_file->owner = THIS_MODULE;
 #endif /* CONFIG_PROC_FS */
 
-	if (first_pass == 1) {
-		these_bonds = bond;
-		register_netdevice_notifier(&bond_netdev_notifier);
-		first_pass = 0;
-	} else {
-		last_bond = these_bonds;
-		this_bond = these_bonds->next_bond;
-		while (this_bond != NULL) {
-			last_bond = this_bond;
-			this_bond = this_bond->next_bond;
-		}
-		last_bond->next_bond = bond;
-	} 
 
+	list_add_tail(&bond->bond_list, &bond_dev_list);
 	return 0;
 }
 
@@ -3753,15 +3682,11 @@
 	return -1;
 }
 
-
 static int __init bonding_init(void)
 {
 	int no;
 	int err;
 
-	/* Find a name for this unit */
-	static struct net_device *dev_bond = NULL;
-
 	printk(KERN_INFO "%s", version);
 
 	/*
@@ -3812,12 +3737,6 @@
 		       max_bonds, 1, INT_MAX, BOND_DEFAULT_MAX_BONDS);
 		max_bonds = BOND_DEFAULT_MAX_BONDS;
 	}
-	dev_bond = dev_bonds = kmalloc(max_bonds*sizeof(struct net_device), 
-					GFP_KERNEL);
-	if (dev_bond == NULL) {
-		return -ENOMEM;
-	}
-	memset(dev_bonds, 0, max_bonds*sizeof(struct net_device));
 
 	if (miimon < 0) {
 		printk(KERN_WARNING 
@@ -4005,48 +3924,50 @@
 		primary = NULL;
 	}
 
+	register_netdevice_notifier(&bond_netdev_notifier);
 
 	for (no = 0; no < max_bonds; no++) {
-		dev_bond->init = bond_init;
-	
-		err = dev_alloc_name(dev_bond,"bond%d");
-		if (err < 0) {
-			kfree(dev_bonds);
+		struct net_device *dev;
+		char name[IFNAMSIZ];
+
+		snprintf(name, IFNAMSIZ, "bond%d", no);
+
+		dev = alloc_netdev(sizeof(bonding_t) 
+				   + sizeof(struct net_device_stats),
+				   name, ether_setup);
+		if (!dev)
+			return -ENOMEM;
+
+		dev->init = bond_init;
+		SET_MODULE_OWNER(dev);
+
+		if ( (err = register_netdev(dev)) ) {
+#ifdef BONDING_DEBUG
+			printk(KERN_INFO "%s: register_netdev failed %d\n",
+			       dev->name, err);
+#endif
+			kfree(dev);
 			return err;
-		}
-		SET_MODULE_OWNER(dev_bond);
-		if (register_netdev(dev_bond) != 0) {
-			kfree(dev_bonds);
-			return -EIO;
 		}	
-		dev_bond++;
 	}
 	return 0;
 }
 
 static void __exit bonding_exit(void)
 {
-	struct net_device *dev_bond = dev_bonds;
-	struct bonding *bond;
-	int no;
+	struct bonding *bond, *nxt;
 
 	unregister_netdevice_notifier(&bond_netdev_notifier);
 		 
-	for (no = 0; no < max_bonds; no++) {
-
+	list_for_each_entry_safe(bond, nxt, &bond_dev_list, bond_list) {
+		struct net_device *dev = bond->device;
 #ifdef CONFIG_PROC_FS
-		bond = (struct bonding *) dev_bond->priv;
 		remove_proc_entry("info", bond->bond_proc_dir);
-		remove_proc_entry(dev_bond->name, proc_net);
+		remove_proc_entry(dev->name, proc_net);
 #endif
-		unregister_netdev(dev_bond);
-		kfree(bond->stats);
-		kfree(dev_bond->priv);
-		
-		dev_bond->priv = NULL;
-		dev_bond++;
+		unregister_netdev(dev);
+		kfree(dev);
 	}
-	kfree(dev_bonds);
 }
 
 module_init(bonding_init);
diff -Nru a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
--- a/drivers/net/bonding/bonding.h	Wed Jun 18 23:42:06 2003
+++ b/drivers/net/bonding/bonding.h	Wed Jun 18 23:42:06 2003
@@ -104,7 +104,7 @@
 	struct proc_dir_entry *bond_proc_dir;
 	struct proc_dir_entry *bond_proc_info_file;
 #endif /* CONFIG_PROC_FS */
-	struct bonding *next_bond;
+	struct list_head bond_list;
 	struct net_device *device;
 	struct dev_mc_list *mc_list;
 	unsigned short flags;
diff -Nru a/drivers/net/rcpci45.c b/drivers/net/rcpci45.c
--- a/drivers/net/rcpci45.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/net/rcpci45.c	Wed Jun 18 23:42:08 2003
@@ -171,13 +171,14 @@
 	 * will be assigned to the LAN API layer.
 	 */
 
-	dev = init_etherdev (NULL, sizeof (*pDpa));
+	dev = alloc_etherdev(sizeof(*pDpa));
 	if (!dev) {
 		printk (KERN_ERR
-			"(rcpci45 driver:) init_etherdev alloc failed\n");
+			"(rcpci45 driver:) alloc_etherdev alloc failed\n");
 		error = -ENOMEM;
 		goto err_out;
 	}
+
 	SET_MODULE_OWNER(dev);
 	SET_NETDEV_DEV(dev, &pdev->dev);
 
@@ -257,6 +258,9 @@
 	dev->do_ioctl = &RCioctl;
 	dev->set_config = &RCconfig;
 
+	if ((error = register_netdev(dev)))
+		goto err_out_free_region;
+
 	return 0;		/* success */
 
 err_out_free_region:
@@ -265,7 +269,6 @@
 	pci_free_consistent (pdev, MSG_BUF_SIZE, pDpa->msgbuf,
 			     pDpa->msgbuf_dma);
 err_out_free_dev:
-	unregister_netdev (dev);
 	kfree (dev);
 err_out:
 	card_idx--;
@@ -534,17 +537,6 @@
 			(PFNCALLBACK) RCreset_callback);
 }
 
-int
-broadcast_packet (unsigned char *address)
-{
-	int i;
-	for (i = 0; i < 6; i++)
-		if (address[i] != 0xff)
-			return 0;
-
-	return 1;
-}
-
 /*
  * RCrecv_callback()
  * 
@@ -717,11 +709,9 @@
 
 		if (retry > REBOOT_REINIT_RETRY_LIMIT) {
 			printk (KERN_WARNING "%s unable to reinitialize adapter after reboot\n", dev->name);
-			printk (KERN_WARNING "%s decrementing driver and closing interface\n", dev->name);
+			printk (KERN_WARNING "%s shutting down interface\n", dev->name);
 			RCDisableI2OInterrupts (dev);
 			dev->flags &= ~IFF_UP;
-			MOD_DEC_USE_COUNT;
-			/* FIXME: kill MOD_DEC_USE_COUNT, use dev_put */
 		} else {
 			printk (KERN_INFO "%s: rescheduling timer...\n",
 					dev->name);
diff -Nru a/drivers/net/shaper.c b/drivers/net/shaper.c
--- a/drivers/net/shaper.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/net/shaper.c	Wed Jun 18 23:42:08 2003
@@ -630,7 +630,7 @@
  *	Add a shaper device to the system
  */
  
-static int __init shaper_probe(struct net_device *dev)
+static void __init shaper_setup(struct net_device *dev)
 {
 	/*
 	 *	Set up the shaper.
@@ -642,6 +642,7 @@
 
 	dev->open		= shaper_open;
 	dev->stop		= shaper_close;
+	dev->destructor 	= (void (*)(struct net_device *))kfree;
 	dev->hard_start_xmit 	= shaper_start_xmit;
 	dev->get_stats 		= shaper_get_stats;
 	dev->set_multicast_list = NULL;
@@ -669,12 +670,6 @@
 	dev->addr_len		= 0;
 	dev->tx_queue_len	= 10;
 	dev->flags		= 0;
-		
-	/*
-	 *	Shaper is ok
-	 */	
-	 
-	return 0;
 }
  
 static int shapers = 1;
@@ -695,35 +690,38 @@
 
 #endif /* MODULE */
 
-static struct net_device *devs;
+static struct net_device **devs;
 
 static unsigned int shapers_registered = 0;
 
 static int __init shaper_init(void)
 {
-	int i, err;
+	int i;
 	size_t alloc_size;
-	struct shaper *sp;
+	struct net_device *dev;
+	char name[IFNAMSIZ];
 
 	if (shapers < 1)
 		return -ENODEV;
 
-	alloc_size = (sizeof(*devs) * shapers) +
-		     (sizeof(struct shaper) * shapers);
+	alloc_size = sizeof(*dev) * shapers;
 	devs = kmalloc(alloc_size, GFP_KERNEL);
 	if (!devs)
 		return -ENOMEM;
 	memset(devs, 0, alloc_size);
-	sp = (struct shaper *) &devs[shapers];
 
 	for (i = 0; i < shapers; i++) {
-		err = dev_alloc_name(&devs[i], "shaper%d");
-		if (err < 0)
+
+		snprintf(name, IFNAMSIZ, "shaper%d", i);
+		dev = alloc_netdev(sizeof(struct shaper), name,
+				   shaper_setup);
+		if (!dev) 
 			break;
-		devs[i].init = shaper_probe;
-		devs[i].priv = &sp[i];
-		if (register_netdev(&devs[i]))
+
+		if (register_netdev(dev))
 			break;
+
+		devs[i] = dev;
 		shapers_registered++;
 	}
 
@@ -740,7 +738,8 @@
 	int i;
 
 	for (i = 0; i < shapers_registered; i++)
-		unregister_netdev(&devs[i]);
+		if (devs[i])
+			unregister_netdev(devs[i]);
 
 	kfree(devs);
 	devs = NULL;
diff -Nru a/drivers/net/wan/syncppp.c b/drivers/net/wan/syncppp.c
--- a/drivers/net/wan/syncppp.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/net/wan/syncppp.c	Wed Jun 18 23:42:06 2003
@@ -132,6 +132,9 @@
 static struct timer_list sppp_keepalive_timer;
 static spinlock_t spppq_lock = SPIN_LOCK_UNLOCKED;
 
+/* global xmit queue for sending packets while spinlock is held */
+static struct sk_buff_head tx_queue;
+
 static void sppp_keepalive (unsigned long dummy);
 static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type,
 	u8 ident, u16 len, void *data);
@@ -150,6 +153,20 @@
 
 static int debug;
 
+/* Flush global outgoing packet queue to dev_queue_xmit().
+ *
+ * dev_queue_xmit() must be called with interrupts enabled
+ * which means it can't be called with spinlocks held.
+ * If a packet needs to be sent while a spinlock is held,
+ * then put the packet into tx_queue, and call sppp_flush_xmit()
+ * after spinlock is released.
+ */
+static void sppp_flush_xmit()
+{
+	struct sk_buff *skb;
+	while ((skb = skb_dequeue(&tx_queue)) != NULL)
+		dev_queue_xmit(skb);
+}
 
 /*
  *	Interface down stub
@@ -207,7 +224,8 @@
 {
 	struct ppp_header *h;
 	struct sppp *sp = (struct sppp *)sppp_of(dev);
-	
+	unsigned long flags;
+
 	skb->dev=dev;
 	skb->mac.raw=skb->data;
 
@@ -223,7 +241,7 @@
 		if (sp->pp_flags & PP_DEBUG)
 			printk (KERN_DEBUG "%s: input packet is too small, %d bytes\n",
 				dev->name, skb->len);
-drop:           kfree_skb(skb);
+		kfree_skb(skb);
 		return;
 	}
 
@@ -231,13 +249,11 @@
 	h = (struct ppp_header *)skb->data;
 	skb_pull(skb,sizeof(struct ppp_header));
 
+	spin_lock_irqsave(&sp->lock, flags);
+	
 	switch (h->address) {
 	default:        /* Invalid PPP packet. */
-invalid:        if (sp->pp_flags & PP_DEBUG)
-			printk (KERN_WARNING "%s: invalid input packet <0x%x 0x%x 0x%x>\n",
-				dev->name,
-				h->address, h->control, ntohs (h->protocol));
-		goto drop;
+		goto invalid;
 	case PPP_ALLSTATIONS:
 		if (h->control != PPP_UI)
 			goto invalid;
@@ -261,15 +277,13 @@
 			goto drop;
 		case PPP_LCP:
 			sppp_lcp_input (sp, skb);
-			kfree_skb(skb);
-			return;
+			goto drop;
 		case PPP_IPCP:
 			if (sp->lcp.state == LCP_STATE_OPENED)
 				sppp_ipcp_input (sp, skb);
 			else
 				printk(KERN_DEBUG "IPCP when still waiting LCP finish.\n");
-			kfree_skb(skb);
-			return;
+			goto drop;
 		case PPP_IP:
 			if (sp->ipcp.state == IPCP_STATE_OPENED) {
 				if(sp->pp_flags&PP_DEBUG)
@@ -277,7 +291,7 @@
 				skb->protocol=htons(ETH_P_IP);
 				netif_rx(skb);
 				dev->last_rx = jiffies;
-				return;
+				goto done;
 			}
 			break;
 #ifdef IPX
@@ -287,7 +301,7 @@
 				skb->protocol=htons(ETH_P_IPX);
 				netif_rx(skb);
 				dev->last_rx = jiffies;
-				return;
+				goto done;
 			}
 			break;
 #endif
@@ -308,26 +322,36 @@
 			goto invalid;
 		case CISCO_KEEPALIVE:
 			sppp_cisco_input (sp, skb);
-			kfree_skb(skb);
-			return;
+			goto drop;
 #ifdef CONFIG_INET
 		case ETH_P_IP:
 			skb->protocol=htons(ETH_P_IP);
 			netif_rx(skb);
 			dev->last_rx = jiffies;
-			return;
+			goto done;
 #endif
 #ifdef CONFIG_IPX
 		case ETH_P_IPX:
 			skb->protocol=htons(ETH_P_IPX);
 			netif_rx(skb);
 			dev->last_rx = jiffies;
-			return;
+			goto done;
 #endif
 		}
 		break;
 	}
+	goto drop;
+
+invalid:
+	if (sp->pp_flags & PP_DEBUG)
+		printk (KERN_WARNING "%s: invalid input packet <0x%x 0x%x 0x%x>\n",
+			dev->name, h->address, h->control, ntohs (h->protocol));
+drop:
 	kfree_skb(skb);
+done:
+	spin_unlock_irqrestore(&sp->lock, flags);
+	sppp_flush_xmit();
+	return;
 }
 
 EXPORT_SYMBOL(sppp_input);
@@ -394,10 +418,14 @@
 		    ! (dev->flags & IFF_UP))
 			continue;
 
+		spin_lock(&sp->lock);
+
 		/* No keepalive in PPP mode if LCP not opened yet. */
 		if (! (sp->pp_flags & PP_CISCO) &&
-		    sp->lcp.state != LCP_STATE_OPENED)
+		    sp->lcp.state != LCP_STATE_OPENED) {
+			spin_unlock(&sp->lock);
 			continue;
+		}
 
 		if (sp->pp_alivecnt == MAXALIVECNT) {
 			/* No keepalive packets got.  Stop the interface. */
@@ -424,8 +452,11 @@
 			sppp_cp_send (sp, PPP_LCP, LCP_ECHO_REQ,
 				sp->lcp.echoid, 4, &nmagic);
 		}
+
+		spin_unlock(&sp->lock);
 	}
 	spin_unlock_irqrestore(&spppq_lock, flags);
+	sppp_flush_xmit();
 	sppp_keepalive_timer.expires=jiffies+10*HZ;
 	add_timer(&sppp_keepalive_timer);
 }
@@ -757,6 +788,7 @@
 	}
 }
 
+
 /*
  * Send PPP LCP packet.
  */
@@ -804,7 +836,7 @@
 	/* Control is high priority so it doesn't get queued behind data */
 	skb->priority=TC_PRIO_CONTROL;
 	skb->dev = dev;
-	dev_queue_xmit(skb);
+	skb_queue_tail(&tx_queue, skb);
 }
 
 /*
@@ -846,7 +878,7 @@
 	sp->obytes += skb->len;
 	skb->priority=TC_PRIO_CONTROL;
 	skb->dev = dev;
-	dev_queue_xmit(skb);
+	skb_queue_tail(&tx_queue, skb);
 }
 
 /**
@@ -861,10 +893,15 @@
 int sppp_close (struct net_device *dev)
 {
 	struct sppp *sp = (struct sppp *)sppp_of(dev);
+	unsigned long flags;
+
+	spin_lock_irqsave(&sp->lock, flags);
 	sp->pp_link_state = SPPP_LINK_DOWN;
 	sp->lcp.state = LCP_STATE_CLOSED;
 	sp->ipcp.state = IPCP_STATE_CLOSED;
 	sppp_clear_timeout (sp);
+	spin_unlock_irqrestore(&sp->lock, flags);
+
 	return 0;
 }
 
@@ -883,11 +920,18 @@
 int sppp_open (struct net_device *dev)
 {
 	struct sppp *sp = (struct sppp *)sppp_of(dev);
+	unsigned long flags;
+
 	sppp_close(dev);
+
+	spin_lock_irqsave(&sp->lock, flags);
 	if (!(sp->pp_flags & PP_CISCO)) {
 		sppp_lcp_open (sp);
 	}
 	sp->pp_link_state = SPPP_LINK_DOWN;
+	spin_unlock_irqrestore(&sp->lock, flags);
+	sppp_flush_xmit();
+
 	return 0;
 }
 
@@ -912,7 +956,11 @@
 int sppp_reopen (struct net_device *dev)
 {
 	struct sppp *sp = (struct sppp *)sppp_of(dev);
+	unsigned long flags;
+
 	sppp_close(dev);
+
+	spin_lock_irqsave(&sp->lock, flags);
 	if (!(sp->pp_flags & PP_CISCO))
 	{
 		sp->lcp.magic = jiffies;
@@ -923,6 +971,8 @@
 		sppp_set_timeout (sp, 1);
 	} 
 	sp->pp_link_state=SPPP_LINK_DOWN;
+	spin_unlock_irqrestore(&sp->lock, flags);
+
 	return 0;
 }
 
@@ -1040,6 +1090,7 @@
 	sp->lcp.state = LCP_STATE_CLOSED;
 	sp->ipcp.state = IPCP_STATE_CLOSED;
 	sp->pp_if = dev;
+	spin_lock_init(&sp->lock);
 	
 	/* 
 	 *	Device specific setup. All but interrupt handler and
@@ -1290,11 +1341,11 @@
 	struct sppp *sp = (struct sppp*) arg;
 	unsigned long flags;
 
-	spin_lock_irqsave(&spppq_lock, flags);
+	spin_lock_irqsave(&sp->lock, flags);
 
 	sp->pp_flags &= ~PP_TIMO;
 	if (! (sp->pp_if->flags & IFF_UP) || (sp->pp_flags & PP_CISCO)) {
-		spin_unlock_irqrestore(&spppq_lock, flags);
+		spin_unlock_irqrestore(&sp->lock, flags);
 		return;
 	}
 	switch (sp->lcp.state) {
@@ -1333,7 +1384,8 @@
 		}
 		break;
 	}
-	spin_unlock_irqrestore(&spppq_lock, flags);
+	spin_unlock_irqrestore(&sp->lock, flags);
+	sppp_flush_xmit();
 }
 
 static char *sppp_lcp_type_name (u8 type)
@@ -1393,6 +1445,8 @@
 
 static int sppp_rcv(struct sk_buff *skb, struct net_device *dev, struct packet_type *p)
 {
+	if ((skb = skb_share_check(skb, GFP_ATOMIC)) == NULL)
+		return NET_RX_DROP;
 	sppp_input(dev,skb);
 	return 0;
 }
@@ -1400,6 +1454,7 @@
 struct packet_type sppp_packet_type = {
 	.type	= __constant_htons(ETH_P_WAN_PPP),
 	.func	= sppp_rcv,
+	.data   = (void*)1, /* must be non-NULL to indicate 'new' protocol */
 };
 
 static char banner[] __initdata = 
@@ -1412,6 +1467,7 @@
 	if(debug)
 		debug=PP_DEBUG;
 	printk(banner);
+	skb_queue_head_init(&tx_queue);
 	dev_add_pack(&sppp_packet_type);
 	return 0;
 }
diff -Nru a/drivers/net/wireless/airo.c b/drivers/net/wireless/airo.c
--- a/drivers/net/wireless/airo.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/net/wireless/airo.c	Wed Jun 18 23:42:06 2003
@@ -888,7 +888,7 @@
 
 #ifdef WIRELESS_EXT
 // Frequency list (map channels to frequencies)
-const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
+static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
 				2447, 2452, 2457, 2462, 2467, 2472, 2484 };
 
 // A few details needed for WEP (Wireless Equivalent Privacy)
diff -Nru a/drivers/net/wireless/atmel.c b/drivers/net/wireless/atmel.c
--- a/drivers/net/wireless/atmel.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/net/wireless/atmel.c	Wed Jun 18 23:42:06 2003
@@ -1903,7 +1903,7 @@
 	return 0;
 }
 
-const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
+static const long frequency_list[] = { 2412, 2417, 2422, 2427, 2432, 2437, 2442,
 				2447, 2452, 2457, 2462, 2467, 2472, 2484 };
 
 static int atmel_set_freq(struct net_device *dev,
diff -Nru a/drivers/oprofile/buffer_sync.c b/drivers/oprofile/buffer_sync.c
--- a/drivers/oprofile/buffer_sync.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/oprofile/buffer_sync.c	Wed Jun 18 23:42:06 2003
@@ -425,7 +425,7 @@
 {
 	struct mm_struct * mm = 0;
 	struct task_struct * new;
-	unsigned long cookie;
+	unsigned long cookie = 0;
 	int in_kernel = 1;
 	unsigned int i;
  
@@ -442,13 +442,15 @@
 				in_kernel = s->event;
 				add_kernel_ctx_switch(s->event);
 			} else {
+				struct mm_struct * oldmm = mm;
+
 				/* userspace context switch */
 				new = (struct task_struct *)s->event;
 
-				release_mm(mm);
+				release_mm(oldmm);
 				mm = take_tasks_mm(new);
-
-				cookie = get_exec_dcookie(mm);
+				if (mm != oldmm)
+					cookie = get_exec_dcookie(mm);
 				add_user_ctx_switch(new, cookie);
 			}
 		} else {
diff -Nru a/drivers/pcmcia/Makefile b/drivers/pcmcia/Makefile
--- a/drivers/pcmcia/Makefile	Wed Jun 18 23:42:08 2003
+++ b/drivers/pcmcia/Makefile	Wed Jun 18 23:42:08 2003
@@ -3,7 +3,7 @@
 #
 
 obj-$(CONFIG_PCMCIA)				+= pcmcia_core.o ds.o
-obj-$(CONFIG_YENTA) 				+= yenta.o
+obj-$(CONFIG_YENTA) 				+= yenta_socket.o
 
 obj-$(CONFIG_I82365)				+= i82365.o
 obj-$(CONFIG_I82092)				+= i82092.o
diff -Nru a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
--- a/drivers/pcmcia/cistpl.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/pcmcia/cistpl.c	Wed Jun 18 23:42:06 2003
@@ -106,11 +106,10 @@
     pccard_mem_map *mem = &s->cis_mem;
     if (!(s->features & SS_CAP_STATIC_MAP) &&
 	mem->sys_start == 0) {
-	int low = !(s->features & SS_CAP_PAGE_REGS);
 	validate_mem(s);
 	mem->sys_start = 0;
 	if (find_mem_region(&mem->sys_start, s->map_size,
-			    s->map_size, low, "card services", s)) {
+			    s->map_size, 0, "card services", s)) {
 	    printk(KERN_NOTICE "cs: unable to map card memory!\n");
 	    return NULL;
 	}
diff -Nru a/drivers/pcmcia/cs.c b/drivers/pcmcia/cs.c
--- a/drivers/pcmcia/cs.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/pcmcia/cs.c	Wed Jun 18 23:42:06 2003
@@ -816,7 +816,8 @@
 				if ((skt->state & SOCKET_PRESENT) &&
 				     !(status & SS_DETECT))
 					socket_shutdown(skt);
-				if (status & SS_DETECT)
+				if (!(skt->state & SOCKET_PRESENT) &&
+				    (status & SS_DETECT))
 					socket_insert(skt);
 			}
 			if (events & SS_BATDEAD)
@@ -2043,8 +2044,7 @@
 
     if (!(s->features & SS_CAP_STATIC_MAP) &&
 	find_mem_region(&win->base, win->size, align,
-			(req->Attributes & WIN_MAP_BELOW_1MB) ||
-			!(s->features & SS_CAP_PAGE_REGS),
+			(req->Attributes & WIN_MAP_BELOW_1MB),
 			(*handle)->dev_info, s))
 	return CS_IN_USE;
     (*handle)->state |= CLIENT_WIN_REQ(w);
diff -Nru a/drivers/pcmcia/cs_internal.h b/drivers/pcmcia/cs_internal.h
--- a/drivers/pcmcia/cs_internal.h	Wed Jun 18 23:42:05 2003
+++ b/drivers/pcmcia/cs_internal.h	Wed Jun 18 23:42:05 2003
@@ -168,7 +168,7 @@
 int find_io_region(ioaddr_t *base, ioaddr_t num, ioaddr_t align,
 		   char *name, struct pcmcia_socket *s);
 int find_mem_region(u_long *base, u_long num, u_long align,
-		    int force_low, char *name, struct pcmcia_socket *s);
+		    int low, char *name, struct pcmcia_socket *s);
 int try_irq(u_int Attributes, int irq, int specific);
 void undo_irq(u_int Attributes, int irq);
 int adjust_resource_info(client_handle_t handle, adjust_t *adj);
diff -Nru a/drivers/pcmcia/rsrc_mgr.c b/drivers/pcmcia/rsrc_mgr.c
--- a/drivers/pcmcia/rsrc_mgr.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/pcmcia/rsrc_mgr.c	Wed Jun 18 23:42:07 2003
@@ -139,22 +139,6 @@
 	return 0;
 }
 
-/* FIXME: Fundamentally racy. */
-static inline int check_mem_resource(unsigned long b, unsigned long n,
-				     struct pci_dev *dev)
-{
-	struct resource *region;
-
-	region = __request_region(resource_parent(b, n, IORESOURCE_MEM, dev),
-				  b, n, "check_mem_resource");
-	if (!region)
-		return -EBUSY;
-
-	release_resource(region);
-	kfree(region);
-	return 0;
-}
-
 static struct resource *make_resource(unsigned long b, unsigned long n,
 				      int flags, char *name)
 {
@@ -340,52 +324,103 @@
 ======================================================================*/
 
 /* Validation function for cards with a valid CIS */
-static int cis_readable(struct pcmcia_socket *s, u_long base)
+static int readable(struct pcmcia_socket *s, struct resource *res, cisinfo_t *info)
 {
-    cisinfo_t info1, info2;
-    int ret;
-    s->cis_mem.sys_start = base;
-    s->cis_mem.sys_stop = base+s->map_size-1;
-    s->cis_virt = ioremap(base, s->map_size);
-    ret = pcmcia_validate_cis(s->clients, &info1);
-    /* invalidate mapping and CIS cache */
-    iounmap(s->cis_virt);
-    destroy_cis_cache(s);
-    if ((ret != 0) || (info1.Chains == 0))
-	return 0;
-    s->cis_mem.sys_start = base+s->map_size;
-    s->cis_mem.sys_stop = base+2*s->map_size-1;
-    s->cis_virt = ioremap(base+s->map_size, s->map_size);
-    ret = pcmcia_validate_cis(s->clients, &info2);
-    iounmap(s->cis_virt);
-    destroy_cis_cache(s);
-    return ((ret == 0) && (info1.Chains == info2.Chains));
+	int ret = -1;
+
+	s->cis_mem.sys_start = res->start;
+	s->cis_mem.sys_stop = res->end;
+	s->cis_virt = ioremap(res->start, s->map_size);
+	if (s->cis_virt) {
+		ret = pcmcia_validate_cis(s->clients, info);
+		/* invalidate mapping and CIS cache */
+		iounmap(s->cis_virt);
+		s->cis_virt = NULL;
+		destroy_cis_cache(s);
+	}
+	s->cis_mem.sys_start = 0;
+	s->cis_mem.sys_stop = 0;
+	if ((ret != 0) || (info->Chains == 0))
+		return 0;
+	return 1;
 }
 
 /* Validation function for simple memory cards */
-static int checksum(struct pcmcia_socket *s, u_long base)
+static int checksum(struct pcmcia_socket *s, struct resource *res)
 {
-    int i, a, b, d;
-    s->cis_mem.sys_start = base;
-    s->cis_mem.sys_stop = base+s->map_size-1;
-    s->cis_virt = ioremap(base, s->map_size);
-    s->cis_mem.card_start = 0;
-    s->cis_mem.flags = MAP_ACTIVE;
-    s->ss_entry->set_mem_map(s, &s->cis_mem);
-    /* Don't bother checking every word... */
-    a = 0; b = -1;
-    for (i = 0; i < s->map_size; i += 44) {
-	d = readl(s->cis_virt+i);
-	a += d; b &= d;
-    }
-    iounmap(s->cis_virt);
-    return (b == -1) ? -1 : (a>>1);
+	pccard_mem_map map;
+	int i, a = 0, b = -1, d;
+	void *virt;
+
+	virt = ioremap(res->start, s->map_size);
+	if (virt) {
+		map.map = 0;
+		map.flags = MAP_ACTIVE;
+		map.speed = 0;
+		map.sys_start = res->start;
+		map.sys_stop = res->end;
+		map.card_start = 0;
+		s->ss_entry->set_mem_map(s, &map);
+
+		/* Don't bother checking every word... */
+		for (i = 0; i < s->map_size; i += 44) {
+			d = readl(virt+i);
+			a += d;
+			b &= d;
+		}
+
+		map.flags = 0;
+		s->ss_entry->set_mem_map(s, &map);
+
+		iounmap(virt);
+	}
+
+	return (b == -1) ? -1 : (a>>1);
 }
 
-static int checksum_match(struct pcmcia_socket *s, u_long base)
+static int
+cis_readable(struct pcmcia_socket *s, unsigned long base, unsigned long size)
 {
-    int a = checksum(s, base), b = checksum(s, base+s->map_size);
-    return ((a == b) && (a >= 0));
+	struct resource *res1, *res2;
+	cisinfo_t info1, info2;
+	int ret = 0;
+
+	res1 = request_mem_region(base, size/2, "cs memory probe");
+	res2 = request_mem_region(base + size/2, size/2, "cs memory probe");
+
+	if (res1 && res2) {
+		ret = readable(s, res1, &info1);
+		ret += readable(s, res2, &info2);
+	}
+
+	if (res2)
+		release_resource(res2);
+	if (res1)
+		release_resource(res1);
+
+	return (ret == 2) && (info1.Chains == info2.Chains);
+}
+
+static int
+checksum_match(struct pcmcia_socket *s, unsigned long base, unsigned long size)
+{
+	struct resource *res1, *res2;
+	int a = -1, b = -1;
+
+	res1 = request_mem_region(base, size/2, "cs memory probe");
+	res2 = request_mem_region(base + size/2, size/2, "cs memory probe");
+
+	if (res1 && res2) {
+		a = checksum(s, res1);
+		b = checksum(s, res2);
+	}
+
+	if (res2)
+		release_resource(res2);
+	if (res1)
+		release_resource(res1);
+
+	return (a == b) && (a >= 0);
 }
 
 /*======================================================================
@@ -409,16 +444,16 @@
 	step = 2 * s->map_size;
     for (i = j = base; i < base+num; i = j + step) {
 	if (!fail) {	
-	    for (j = i; j < base+num; j += step)
-		if ((check_mem_resource(j, step, s->cb_dev) == 0) &&
-		    cis_readable(s, j))
+	    for (j = i; j < base+num; j += step) {
+		if (cis_readable(s, j, step))
 		    break;
+	    }
 	    fail = ((i == base) && (j == base+num));
 	}
 	if (fail) {
 	    for (j = i; j < base+num; j += 2*step)
-		if ((check_mem_resource(j, 2*step, s->cb_dev) == 0) &&
-		    checksum_match(s, j) && checksum_match(s, j + step))
+		if (checksum_match(s, j, step) &&
+		    checksum_match(s, j + step, step))
 		    break;
 	}
 	if (i != j) {
@@ -555,17 +590,19 @@
 }
 
 int find_mem_region(u_long *base, u_long num, u_long align,
-		    int force_low, char *name, struct pcmcia_socket *s)
+		    int low, char *name, struct pcmcia_socket *s)
 {
     u_long try;
     resource_map_t *m;
     int ret = -1;
 
+    low = low || !(s->features & SS_CAP_PAGE_REGS);
+
     down(&rsrc_sem);
     while (1) {
 	for (m = mem_db.next; m != &mem_db; m = m->next) {
 	    /* first pass >1MB, second pass <1MB */
-	    if ((force_low != 0) ^ (m->base < 0x100000))
+	    if ((low != 0) ^ (m->base < 0x100000))
 		continue;
 
 	    try = (m->base & ~(align-1)) + *base;
@@ -581,9 +618,9 @@
 		    break;
 	    }
 	}
-	if (force_low)
+	if (low)
 	    break;
-	force_low++;
+	low++;
     }
  out:
     up(&rsrc_sem);
diff -Nru a/drivers/pcmcia/yenta.c b/drivers/pcmcia/yenta.c
--- a/drivers/pcmcia/yenta.c	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,974 +0,0 @@
-/*
- * Regular cardbus driver ("yenta")
- *
- * (C) Copyright 1999, 2000 Linus Torvalds
- *
- * Changelog:
- * Aug 2002: Manfred Spraul <manfred@colorfullife.com>
- * 	Dynamically adjust the size of the bridge resource
- * 	
- * May 2003: Dominik Brodowski <linux@brodo.de>
- * 	Merge pci_socket.c and yenta.c into one file
- */
-#include <linux/init.h>
-#include <linux/pci.h>
-#include <linux/sched.h>
-#include <linux/workqueue.h>
-#include <linux/interrupt.h>
-#include <linux/delay.h>
-#include <linux/module.h>
-
-#include <pcmcia/version.h>
-#include <pcmcia/cs_types.h>
-#include <pcmcia/ss.h>
-#include <pcmcia/cs.h>
-
-#include <asm/io.h>
-
-#include "yenta.h"
-#include "i82365.h"
-
-
-#if 0
-#define DEBUG(x,args...)	printk("%s: " x, __FUNCTION__, ##args)
-#else
-#define DEBUG(x,args...)
-#endif
-
-/* Don't ask.. */
-#define to_cycles(ns)	((ns)/120)
-#define to_ns(cycles)	((cycles)*120)
-
-/*
- * Generate easy-to-use ways of reading a cardbus sockets
- * regular memory space ("cb_xxx"), configuration space
- * ("config_xxx") and compatibility space ("exca_xxxx")
- */
-static inline u32 cb_readl(struct yenta_socket *socket, unsigned reg)
-{
-	u32 val = readl(socket->base + reg);
-	DEBUG("%p %04x %08x\n", socket, reg, val);
-	return val;
-}
-
-static inline void cb_writel(struct yenta_socket *socket, unsigned reg, u32 val)
-{
-	DEBUG("%p %04x %08x\n", socket, reg, val);
-	writel(val, socket->base + reg);
-}
-
-static inline u8 config_readb(struct yenta_socket *socket, unsigned offset)
-{
-	u8 val;
-	pci_read_config_byte(socket->dev, offset, &val);
-	DEBUG("%p %04x %02x\n", socket, offset, val);
-	return val;
-}
-
-static inline u16 config_readw(struct yenta_socket *socket, unsigned offset)
-{
-	u16 val;
-	pci_read_config_word(socket->dev, offset, &val);
-	DEBUG("%p %04x %04x\n", socket, offset, val);
-	return val;
-}
-
-static inline u32 config_readl(struct yenta_socket *socket, unsigned offset)
-{
-	u32 val;
-	pci_read_config_dword(socket->dev, offset, &val);
-	DEBUG("%p %04x %08x\n", socket, offset, val);
-	return val;
-}
-
-static inline void config_writeb(struct yenta_socket *socket, unsigned offset, u8 val)
-{
-	DEBUG("%p %04x %02x\n", socket, offset, val);
-	pci_write_config_byte(socket->dev, offset, val);
-}
-
-static inline void config_writew(struct yenta_socket *socket, unsigned offset, u16 val)
-{
-	DEBUG("%p %04x %04x\n", socket, offset, val);
-	pci_write_config_word(socket->dev, offset, val);
-}
-
-static inline void config_writel(struct yenta_socket *socket, unsigned offset, u32 val)
-{
-	DEBUG("%p %04x %08x\n", socket, offset, val);
-	pci_write_config_dword(socket->dev, offset, val);
-}
-
-static inline u8 exca_readb(struct yenta_socket *socket, unsigned reg)
-{
-	u8 val = readb(socket->base + 0x800 + reg);
-	DEBUG("%p %04x %02x\n", socket, reg, val);
-	return val;
-}
-
-static inline u8 exca_readw(struct yenta_socket *socket, unsigned reg)
-{
-	u16 val;
-	val = readb(socket->base + 0x800 + reg);
-	val |= readb(socket->base + 0x800 + reg + 1) << 8;
-	DEBUG("%p %04x %04x\n", socket, reg, val);
-	return val;
-}
-
-static inline void exca_writeb(struct yenta_socket *socket, unsigned reg, u8 val)
-{
-	DEBUG("%p %04x %02x\n", socket, reg, val);
-	writeb(val, socket->base + 0x800 + reg);
-}
-
-static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val)
-{
-	DEBUG("%p %04x %04x\n", socket, reg, val);
-	writeb(val, socket->base + 0x800 + reg);
-	writeb(val >> 8, socket->base + 0x800 + reg + 1);
-}
-
-/*
- * Ugh, mixed-mode cardbus and 16-bit pccard state: things depend
- * on what kind of card is inserted..
- */
-static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-	unsigned int val;
-	u32 state = cb_readl(socket, CB_SOCKET_STATE);
-
-	val  = (state & CB_3VCARD) ? SS_3VCARD : 0;
-	val |= (state & CB_XVCARD) ? SS_XVCARD : 0;
-	val |= (state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD | CB_3VCARD
-			 | CB_XVCARD | CB_YVCARD)) ? 0 : SS_PENDING;
-
-	if (state & CB_CBCARD) {
-		val |= SS_CARDBUS;	
-		val |= (state & CB_CARDSTS) ? SS_STSCHG : 0;
-		val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT;
-		val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0;
-	} else {
-		u8 status = exca_readb(socket, I365_STATUS);
-		val |= ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0;
-		if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
-			val |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
-		} else {
-			val |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;
-			val |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;
-		}
-		val |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;
-		val |= (status & I365_CS_READY) ? SS_READY : 0;
-		val |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
-	}
-
-	*value = val;
-	return 0;
-}
-
-static int yenta_Vcc_power(u32 control)
-{
-	switch (control & CB_SC_VCC_MASK) {
-	case CB_SC_VCC_5V: return 50;
-	case CB_SC_VCC_3V: return 33;
-	default: return 0;
-	}
-}
-
-static int yenta_Vpp_power(u32 control)
-{
-	switch (control & CB_SC_VPP_MASK) {
-	case CB_SC_VPP_12V: return 120;
-	case CB_SC_VPP_5V: return 50;
-	case CB_SC_VPP_3V: return 33;
-	default: return 0;
-	}
-}
-
-static int yenta_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-	u8 reg;
-	u32 control;
-
-	control = cb_readl(socket, CB_SOCKET_CONTROL);
-
-	state->Vcc = yenta_Vcc_power(control);
-	state->Vpp = yenta_Vpp_power(control);
-	state->io_irq = socket->io_irq;
-
-	if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) {
-		u16 bridge = config_readw(socket, CB_BRIDGE_CONTROL);
-		if (bridge & CB_BRIDGE_CRST)
-			state->flags |= SS_RESET;
-		return 0;
-	}
-
-	/* 16-bit card state.. */
-	reg = exca_readb(socket, I365_POWER);
-	state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
-	state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
-
-	reg = exca_readb(socket, I365_INTCTL);
-	state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;
-	state->flags |= (reg & I365_PC_IOCARD) ? SS_IOCARD : 0;
-
-	reg = exca_readb(socket, I365_CSCINT);
-	state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0;
-	if (state->flags & SS_IOCARD) {
-		state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0;
-	} else {
-		state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0;
-		state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0;
-		state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0;
-	}
-
-	return 0;
-}
-
-static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state)
-{
-	u32 reg = 0;	/* CB_SC_STPCLK? */
-	switch (state->Vcc) {
-	case 33: reg = CB_SC_VCC_3V; break;
-	case 50: reg = CB_SC_VCC_5V; break;
-	default: reg = 0; break;
-	}
-	switch (state->Vpp) {
-	case 33:  reg |= CB_SC_VPP_3V; break;
-	case 50:  reg |= CB_SC_VPP_5V; break;
-	case 120: reg |= CB_SC_VPP_12V; break;
-	}
-	if (reg != cb_readl(socket, CB_SOCKET_CONTROL))
-		cb_writel(socket, CB_SOCKET_CONTROL, reg);
-}
-
-static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-	u16 bridge;
-
-	if (state->flags & SS_DEBOUNCED) {
-		/* The insertion debounce period has ended.  Clear any pending insertion events */
-		socket->events &= ~SS_DETECT;
-		state->flags &= ~SS_DEBOUNCED;		/* SS_DEBOUNCED is oneshot */
-	}
-	yenta_set_power(socket, state);
-	socket->io_irq = state->io_irq;
-	bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~(CB_BRIDGE_CRST | CB_BRIDGE_INTR);
-	if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) {
-		u8 intr;
-		bridge |= (state->flags & SS_RESET) ? CB_BRIDGE_CRST : 0;
-
-		/* ISA interrupt control? */
-		intr = exca_readb(socket, I365_INTCTL);
-		intr = (intr & ~0xf);
-		if (!socket->cb_irq) {
-			intr |= state->io_irq;
-			bridge |= CB_BRIDGE_INTR;
-		}
-		exca_writeb(socket, I365_INTCTL, intr);
-	}  else {
-		u8 reg;
-
-		reg = exca_readb(socket, I365_INTCTL) & (I365_RING_ENA | I365_INTR_ENA);
-		reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
-		reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
-		if (state->io_irq != socket->cb_irq) {
-			reg |= state->io_irq;
-			bridge |= CB_BRIDGE_INTR;
-		}
-		exca_writeb(socket, I365_INTCTL, reg);
-
-		reg = exca_readb(socket, I365_POWER) & (I365_VCC_MASK|I365_VPP1_MASK);
-		reg |= I365_PWR_NORESET;
-		if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO;
-		if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT;
-		if (exca_readb(socket, I365_POWER) != reg)
-			exca_writeb(socket, I365_POWER, reg);
-
-		/* CSC interrupt: no ISA irq for CSC */
-		reg = I365_CSC_DETECT;
-		if (state->flags & SS_IOCARD) {
-			if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;
-		} else {
-			if (state->csc_mask & SS_BATDEAD) reg |= I365_CSC_BVD1;
-			if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2;
-			if (state->csc_mask & SS_READY) reg |= I365_CSC_READY;
-		}
-		exca_writeb(socket, I365_CSCINT, reg);
-		exca_readb(socket, I365_CSC);
-	}
-	config_writew(socket, CB_BRIDGE_CONTROL, bridge);
-	/* Socket event mask: get card insert/remove events.. */
-	cb_writel(socket, CB_SOCKET_EVENT, -1);
-	cb_writel(socket, CB_SOCKET_MASK, CB_CDMASK);
-	return 0;
-}
-
-static int yenta_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-	int map;
-	unsigned char ioctl, addr, enable;
-
-	map = io->map;
-
-	if (map > 1)
-		return -EINVAL;
-
-	enable = I365_ENA_IO(map);
-	addr = exca_readb(socket, I365_ADDRWIN);
-
-	/* Disable the window before changing it.. */
-	if (addr & enable) {
-		addr &= ~enable;
-		exca_writeb(socket, I365_ADDRWIN, addr);
-	}
-
-	exca_writew(socket, I365_IO(map)+I365_W_START, io->start);
-	exca_writew(socket, I365_IO(map)+I365_W_STOP, io->stop);
-
-	ioctl = exca_readb(socket, I365_IOCTL) & ~I365_IOCTL_MASK(map);
-	if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
-	if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);
-	if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);
-	exca_writeb(socket, I365_IOCTL, ioctl);
-
-	if (io->flags & MAP_ACTIVE)
-		exca_writeb(socket, I365_ADDRWIN, addr | enable);
-	return 0;
-}
-
-static int yenta_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-	int map;
-	unsigned char addr, enable;
-	unsigned int start, stop, card_start;
-	unsigned short word;
-
-	map = mem->map;
-	start = mem->sys_start;
-	stop = mem->sys_stop;
-	card_start = mem->card_start;
-
-	if (map > 4 || start > stop || ((start ^ stop) >> 24) ||
-	    (card_start >> 26) || mem->speed > 1000)
-		return -EINVAL;
-
-	enable = I365_ENA_MEM(map);
-	addr = exca_readb(socket, I365_ADDRWIN);
-	if (addr & enable) {
-		addr &= ~enable;
-		exca_writeb(socket, I365_ADDRWIN, addr);
-	}
-
-	exca_writeb(socket, CB_MEM_PAGE(map), start >> 24);
-
-	word = (start >> 12) & 0x0fff;
-	if (mem->flags & MAP_16BIT)
-		word |= I365_MEM_16BIT;
-	if (mem->flags & MAP_0WS)
-		word |= I365_MEM_0WS;
-	exca_writew(socket, I365_MEM(map) + I365_W_START, word);
-
-	word = (stop >> 12) & 0x0fff;
-	switch (to_cycles(mem->speed)) {
-		case 0: break;
-		case 1:  word |= I365_MEM_WS0; break;
-		case 2:  word |= I365_MEM_WS1; break;
-		default: word |= I365_MEM_WS1 | I365_MEM_WS0; break;
-	}
-	exca_writew(socket, I365_MEM(map) + I365_W_STOP, word);
-
-	word = ((card_start - start) >> 12) & 0x3fff;
-	if (mem->flags & MAP_WRPROT)
-		word |= I365_MEM_WRPROT;
-	if (mem->flags & MAP_ATTRIB)
-		word |= I365_MEM_REG;
-	exca_writew(socket, I365_MEM(map) + I365_W_OFF, word);
-
-	if (mem->flags & MAP_ACTIVE)
-		exca_writeb(socket, I365_ADDRWIN, addr | enable);
-	return 0;
-}
-
-
-static unsigned int yenta_events(struct yenta_socket *socket)
-{
-	u8 csc;
-	u32 cb_event;
-	unsigned int events;
-
-	/* Clear interrupt status for the event */
-	cb_event = cb_readl(socket, CB_SOCKET_EVENT);
-	cb_writel(socket, CB_SOCKET_EVENT, cb_event);
-
-	csc = exca_readb(socket, I365_CSC);
-
-	events = (cb_event & (CB_CD1EVENT | CB_CD2EVENT)) ? SS_DETECT : 0 ;
-	events |= (csc & I365_CSC_DETECT) ? SS_DETECT : 0;
-	if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
-		events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0;
-	} else {
-		events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0;
-		events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
-		events |= (csc & I365_CSC_READY) ? SS_READY : 0;
-	}
-	return events;
-}
-
-
-static void yenta_bh(void *data)
-{
-	struct yenta_socket *socket = data;
-	unsigned int events;
-
-	spin_lock_irq(&socket->event_lock);
-	events = socket->events;
-	socket->events = 0;
-	spin_unlock_irq(&socket->event_lock);
-	if (socket->handler)
-		socket->handler(socket->info, events);
-}
-
-static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
-{
-	unsigned int events;
-	struct yenta_socket *socket = (struct yenta_socket *) dev_id;
-
-	events = yenta_events(socket);
-	if (events) {
-		spin_lock(&socket->event_lock);
-		socket->events |= events;
-		spin_unlock(&socket->event_lock);
-		schedule_work(&socket->tq_task);
-		return IRQ_HANDLED;
-	}
-	return IRQ_NONE;
-}
-
-static void yenta_interrupt_wrapper(unsigned long data)
-{
-	struct yenta_socket *socket = (struct yenta_socket *) data;
-
-	yenta_interrupt(0, (void *)socket, NULL);
-	socket->poll_timer.expires = jiffies + HZ;
-	add_timer(&socket->poll_timer);
-}
-
-/*
- * Only probe "regular" interrupts, don't
- * touch dangerous spots like the mouse irq,
- * because there are mice that apparently
- * get really confused if they get fondled
- * too intimately.
- *
- * Default to 11, 10, 9, 7, 6, 5, 4, 3.
- */
-static u32 isa_interrupts = 0x0ef8;
-
-static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask)
-{
-	int i;
-	unsigned long val;
-	u16 bridge_ctrl;
-	u32 mask;
-
-	/* Set up ISA irq routing to probe the ISA irqs.. */
-	bridge_ctrl = config_readw(socket, CB_BRIDGE_CONTROL);
-	if (!(bridge_ctrl & CB_BRIDGE_INTR)) {
-		bridge_ctrl |= CB_BRIDGE_INTR;
-		config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
-	}
-
-	/*
-	 * Probe for usable interrupts using the force
-	 * register to generate bogus card status events.
-	 */
-	cb_writel(socket, CB_SOCKET_EVENT, -1);
-	cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
-	exca_writeb(socket, I365_CSCINT, 0);
-	val = probe_irq_on() & isa_irq_mask;
-	for (i = 1; i < 16; i++) {
-		if (!((val >> i) & 1))
-			continue;
-		exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG | (i << 4));
-		cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS);
-		udelay(100);
-		cb_writel(socket, CB_SOCKET_EVENT, -1);
-	}
-	cb_writel(socket, CB_SOCKET_MASK, 0);
-	exca_writeb(socket, I365_CSCINT, 0);
-	
-	mask = probe_irq_mask(val) & 0xffff;
-
-	bridge_ctrl &= ~CB_BRIDGE_INTR;
-	config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
-
-	return mask;
-}
-
-/*
- * Set static data that doesn't need re-initializing..
- */
-static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask)
-{
-	socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
-	socket->socket.map_size = 0x1000;
-	socket->socket.pci_irq = socket->cb_irq;
-	socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
-	socket->socket.cb_dev = socket->dev;
-
-	printk("Yenta IRQ list %04x, PCI irq%d\n", socket->socket.irq_mask, socket->cb_irq);
-}
-
-
-static void yenta_clear_maps(struct yenta_socket *socket)
-{
-	int i;
-	pccard_io_map io = { 0, 0, 0, 0, 1 };
-	pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
-
-	mem.sys_stop = 0x0fff;
-	yenta_set_socket(&socket->socket, &dead_socket);
-	for (i = 0; i < 2; i++) {
-		io.map = i;
-		yenta_set_io_map(&socket->socket, &io);
-	}
-	for (i = 0; i < 5; i++) {
-		mem.map = i;
-		yenta_set_mem_map(&socket->socket, &mem);
-	}
-}
-
-/*
- * Initialize the standard cardbus registers
- */
-static void yenta_config_init(struct yenta_socket *socket)
-{
-	u16 bridge;
-	struct pci_dev *dev = socket->dev;
-
-	pci_set_power_state(socket->dev, 0);
-
-	config_writel(socket, CB_LEGACY_MODE_BASE, 0);
-	config_writel(socket, PCI_BASE_ADDRESS_0, dev->resource[0].start);
-	config_writew(socket, PCI_COMMAND,
-			PCI_COMMAND_IO |
-			PCI_COMMAND_MEMORY |
-			PCI_COMMAND_MASTER |
-			PCI_COMMAND_WAIT);
-
-	/* MAGIC NUMBERS! Fixme */
-	config_writeb(socket, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
-	config_writeb(socket, PCI_LATENCY_TIMER, 168);
-	config_writel(socket, PCI_PRIMARY_BUS,
-		(176 << 24) |			   /* sec. latency timer */
-		(dev->subordinate->subordinate << 16) | /* subordinate bus */
-		(dev->subordinate->secondary << 8) |  /* secondary bus */
-		dev->subordinate->primary);		   /* primary bus */
-
-	/*
-	 * Set up the bridging state:
-	 *  - enable write posting.
-	 *  - memory window 0 prefetchable, window 1 non-prefetchable
-	 *  - PCI interrupts enabled if a PCI interrupt exists..
-	 */
-	bridge = config_readw(socket, CB_BRIDGE_CONTROL);
-	bridge &= ~(CB_BRIDGE_CRST | CB_BRIDGE_PREFETCH1 | CB_BRIDGE_INTR | CB_BRIDGE_ISAEN | CB_BRIDGE_VGAEN);
-	bridge |= CB_BRIDGE_PREFETCH0 | CB_BRIDGE_POSTEN;
-	if (!socket->cb_irq)
-		bridge |= CB_BRIDGE_INTR;
-	config_writew(socket, CB_BRIDGE_CONTROL, bridge);
-
-	exca_writeb(socket, I365_GBLCTL, 0x00);
-	exca_writeb(socket, I365_GENCTL, 0x00);
-
-	/* Redo card voltage interrogation */
-	cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
-}
-
-/* Called at resume and initialization events */
-static int yenta_init(struct pcmcia_socket *sock)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-	yenta_config_init(socket);
-	yenta_clear_maps(socket);
-
-	/* Re-enable interrupts */
-	cb_writel(socket, CB_SOCKET_MASK, CB_CDMASK);
-	return 0;
-}
-
-static int yenta_suspend(struct pcmcia_socket *sock)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-
-	yenta_set_socket(sock, &dead_socket);
-
-	/* Disable interrupts */
-	cb_writel(socket, CB_SOCKET_MASK, 0x0);
-
-	/*
-	 * This does not work currently. The controller
-	 * loses too much information during D3 to come up
-	 * cleanly. We should probably fix yenta_init()
-	 * to update all the critical registers, notably
-	 * the IO and MEM bridging region data.. That is
-	 * something that pci_set_power_state() should
-	 * probably know about bridges anyway.
-	 *
-	pci_set_power_state(socket->dev, 3);
-	 */
-
-	return 0;
-}
-
-/*
- * Use an adaptive allocation for the memory resource,
- * sometimes the memory behind pci bridges is limited:
- * 1/8 of the size of the io window of the parent.
- * max 4 MB, min 16 kB.
- */
-#define BRIDGE_MEM_MAX 4*1024*1024
-#define BRIDGE_MEM_MIN 16*1024
-
-#define BRIDGE_IO_MAX 256
-#define BRIDGE_IO_MIN 32
-
-static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type)
-{
-	struct pci_bus *bus;
-	struct resource *root, *res;
-	u32 start, end;
-	u32 align, size, min;
-	unsigned offset;
-	unsigned mask;
-
-	/* The granularity of the memory limit is 4kB, on IO it's 4 bytes */
-	mask = ~0xfff;
-	if (type & IORESOURCE_IO)
-		mask = ~3;
-
-	offset = 0x1c + 8*nr;
-	bus = socket->dev->subordinate;
-	res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;
-	res->name = bus->name;
-	res->flags = type;
-	res->start = 0;
-	res->end = 0;
-	root = pci_find_parent_resource(socket->dev, res);
-
-	if (!root)
-		return;
-
-	start = config_readl(socket, offset) & mask;
-	end = config_readl(socket, offset+4) | ~mask;
-	if (start && end > start) {
-		res->start = start;
-		res->end = end;
-		if (request_resource(root, res) == 0)
-			return;
-		printk(KERN_INFO "yenta %s: Preassigned resource %d busy, reconfiguring...\n",
-				socket->dev->slot_name, nr);
-		res->start = res->end = 0;
-	}
-
-	if (type & IORESOURCE_IO) {
-		align = 1024;
-		size = BRIDGE_IO_MAX;
-		min = BRIDGE_IO_MIN;
-		start = PCIBIOS_MIN_IO;
-		end = ~0U;
-	} else {
-		unsigned long avail = root->end - root->start;
-		int i;
-		size = BRIDGE_MEM_MAX;
-		if (size > avail/8) {
-			size=(avail+1)/8;
-			/* round size down to next power of 2 */
-			i = 0;
-			while ((size /= 2) != 0)
-				i++;
-			size = 1 << i;
-		}
-		if (size < BRIDGE_MEM_MIN)
-			size = BRIDGE_MEM_MIN;
-		min = BRIDGE_MEM_MIN;
-		align = size;
-		start = PCIBIOS_MIN_MEM;
-		end = ~0U;
-	}
-	
-	do {
-		if (allocate_resource(root, res, size, start, end, align, NULL, NULL)==0) {
-			config_writel(socket, offset, res->start);
-			config_writel(socket, offset+4, res->end);
-			return;
-		}
-		size = size/2;
-		align = size;
-	} while (size >= min);
-	printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n",
-			socket->dev->slot_name, type);
-	res->start = res->end = 0;
-}
-
-/*
- * Allocate the bridge mappings for the device..
- */
-static void yenta_allocate_resources(struct yenta_socket *socket)
-{
-	yenta_allocate_res(socket, 0, IORESOURCE_MEM|IORESOURCE_PREFETCH);
-	yenta_allocate_res(socket, 1, IORESOURCE_MEM);
-	yenta_allocate_res(socket, 2, IORESOURCE_IO);
-	yenta_allocate_res(socket, 3, IORESOURCE_IO);	/* PCI isn't clever enough to use this one yet */
-}
-
-
-/*
- * Free the bridge mappings for the device..
- */
-static void yenta_free_resources(struct yenta_socket *socket)
-{
-	int i;
-	for (i=0;i<4;i++) {
-		struct resource *res;
-		res = socket->dev->resource + PCI_BRIDGE_RESOURCES + i;
-		if (res->start != 0 && res->end != 0)
-			release_resource(res);
-		res->start = res->end = 0;
-	}
-}
-
-
-/*
- * Close it down - release our resources and go home..
- */
-static void yenta_close(struct pci_dev *dev)
-{
-	struct yenta_socket *sock = pci_get_drvdata(dev);
-
-	/* we don't want a dying socket registered */
-	pcmcia_unregister_socket(&sock->socket);
-	
-	/* Disable all events so we don't die in an IRQ storm */
-	cb_writel(sock, CB_SOCKET_MASK, 0x0);
-	exca_writeb(sock, I365_CSCINT, 0);
-
-	if (sock->cb_irq)
-		free_irq(sock->cb_irq, sock);
-	else
-		del_timer_sync(&sock->poll_timer);
-
-	if (sock->base)
-		iounmap(sock->base);
-	yenta_free_resources(sock);
-
-	pci_set_drvdata(dev, NULL);
-}
-
-
-static int yenta_register_callback(struct pcmcia_socket *sock, void (*handler)(void *, unsigned int), void * info)
-{
-	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
-
-	socket->handler = handler;
-	socket->info = info;
-	return 0;
-}
-
-
-static struct pccard_operations yenta_socket_operations = {
-	.owner			= THIS_MODULE,
-	.init			= yenta_init,
-	.suspend		= yenta_suspend,
-	.register_callback	= yenta_register_callback,
-	.get_status		= yenta_get_status,
-	.get_socket		= yenta_get_socket,
-	.set_socket		= yenta_set_socket,
-	.set_io_map		= yenta_set_io_map,
-	.set_mem_map		= yenta_set_mem_map,
-};
-
-
-#include "ti113x.h"
-#include "ricoh.h"
-
-/*
- * Different cardbus controllers have slightly different
- * initialization sequences etc details. List them here..
- */
-#define PD(x,y) PCI_VENDOR_ID_##x, PCI_DEVICE_ID_##x##_##y
-struct cardbus_override_struct {
-	unsigned short vendor;
-	unsigned short device;
-	int (*override) (struct yenta_socket *socket);
-} cardbus_override[] = {
-	{ PD(TI,1130),	&ti113x_override },
-	{ PD(TI,1031),	&ti_override },
-	{ PD(TI,1131),	&ti113x_override },
-	{ PD(TI,1250),	&ti1250_override },
-	{ PD(TI,1220),	&ti_override },
-	{ PD(TI,1221),	&ti_override },
-	{ PD(TI,1210),	&ti_override },
-	{ PD(TI,1450),	&ti_override },
-	{ PD(TI,1225),	&ti_override },
-	{ PD(TI,1251A),	&ti_override },
-	{ PD(TI,1211),	&ti_override },
-	{ PD(TI,1251B),	&ti_override },
-	{ PD(TI,1410),	ti1250_override },
-	{ PD(TI,1420),	&ti_override },
-	{ PD(TI,4410),	&ti_override },
-	{ PD(TI,4451),	&ti_override },
-
-	{ PD(RICOH,RL5C465), &ricoh_override },
-	{ PD(RICOH,RL5C466), &ricoh_override },
-	{ PD(RICOH,RL5C475), &ricoh_override },
-	{ PD(RICOH,RL5C476), &ricoh_override },
-	{ PD(RICOH,RL5C478), &ricoh_override },
-
-	{ }, /* all zeroes */
-};
-
-
-/*
- * Initialize a cardbus controller. Make sure we have a usable
- * interrupt, and that we can map the cardbus area. Fill in the
- * socket information structure..
- */
-static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_id *id)
-{
-	struct yenta_socket *socket;
-	struct cardbus_override_struct *d;
-	
-	socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL);
-	if (!socket)
-		return -ENOMEM;
-	memset(socket, 0, sizeof(*socket));
-
-	/* prepare pcmcia_socket */
-	socket->socket.ss_entry = &yenta_socket_operations;
-	socket->socket.dev.dev = &dev->dev;
-	socket->socket.driver_data = socket;
-
-	/* prepare struct yenta_socket */
-	socket->dev = dev;
-	pci_set_drvdata(dev, socket);
-	spin_lock_init(&socket->event_lock);
-
-	/*
-	 * Do some basic sanity checking..
-	 */
-	if (pci_enable_device(dev))
-		return -1;
-	if (!pci_resource_start(dev, 0)) {
-		printk("No cardbus resource!\n");
-		return -1;
-	}
-
-	/*
-	 * Ok, start setup.. Map the cardbus registers,
-	 * and request the IRQ.
-	 */
-	socket->base = ioremap(pci_resource_start(dev, 0), 0x1000);
-	if (!socket->base)
-		return -1;
-
-	yenta_config_init(socket);
-
-	/* Disable all events */
-	cb_writel(socket, CB_SOCKET_MASK, 0x0);
-
-	/* Set up the bridge regions.. */
-	yenta_allocate_resources(socket);
-
-	socket->cb_irq = dev->irq;
-
-	/* Do we have special options for the device? */
-	d = cardbus_override;
-	while (d->override) {
-		if ((dev->vendor == d->vendor) && (dev->device == d->device)) {
-			int retval = d->override(socket);
-			if (retval < 0)
-				return retval;
-		}
-		d++;
-	}
-
-	/* We must finish initialization here */
-
-	INIT_WORK(&socket->tq_task, yenta_bh, socket);
-
-	if (!socket->cb_irq || request_irq(socket->cb_irq, yenta_interrupt, SA_SHIRQ, socket->dev->dev.name, socket)) {
-		/* No IRQ or request_irq failed. Poll */
-		socket->cb_irq = 0; /* But zero is a valid IRQ number. */
-		init_timer(&socket->poll_timer);
-		socket->poll_timer.function = yenta_interrupt_wrapper;
-		socket->poll_timer.data = (unsigned long)socket;
-		socket->poll_timer.expires = jiffies + HZ;
-		add_timer(&socket->poll_timer);
-	}
-
-	/* Figure out what the dang thing can do for the PCMCIA layer... */
-	yenta_get_socket_capabilities(socket, isa_interrupts);
-	printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
-
-	/* Register it with the pcmcia layer.. */
-	return pcmcia_register_socket(&socket->socket);
-}
-
-
-static int yenta_dev_suspend (struct pci_dev *dev, u32 state)
-{
-	return pcmcia_socket_dev_suspend(&dev->dev, state, 0);
-}
-
-
-static int yenta_dev_resume (struct pci_dev *dev)
-{
-	return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE);
-}
-
-
-static struct pci_device_id yenta_table [] __devinitdata = { {
-	.class		= PCI_CLASS_BRIDGE_CARDBUS << 8,
-	.class_mask	= ~0,
-
-	.vendor		= PCI_ANY_ID,
-	.device		= PCI_ANY_ID,
-	.subvendor	= PCI_ANY_ID,
-	.subdevice	= PCI_ANY_ID,
-}, { /* all zeroes */ }
-};
-MODULE_DEVICE_TABLE(pci, yenta_table);
-
-
-static struct pci_driver yenta_cardbus_driver = {
-	.name		= "yenta_cardbus",
-	.id_table	= yenta_table,
-	.probe		= yenta_probe,
-	.remove		= __devexit_p(yenta_close),
-	.suspend	= yenta_dev_suspend,
-	.resume		= yenta_dev_resume,
-};
-
-
-static int __init yenta_socket_init(void)
-{
-	return pci_register_driver (&yenta_cardbus_driver);
-}
-
-
-static void __exit yenta_socket_exit (void)
-{
-	pci_unregister_driver (&yenta_cardbus_driver);
-}
-
-
-module_init(yenta_socket_init);
-module_exit(yenta_socket_exit);
-
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/pcmcia/yenta.h b/drivers/pcmcia/yenta.h
--- a/drivers/pcmcia/yenta.h	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,116 +0,0 @@
-#ifndef __YENTA_H
-#define __YENTA_H
-
-#include <asm/io.h>
-
-#define CB_SOCKET_EVENT		0x00
-#define    CB_CSTSEVENT		0x00000001	/* Card status event */
-#define    CB_CD1EVENT		0x00000002	/* Card detect 1 change event */
-#define    CB_CD2EVENT		0x00000004	/* Card detect 2 change event */
-#define    CB_PWREVENT		0x00000008	/* PWRCYCLE change event */
-
-#define CB_SOCKET_MASK		0x04
-#define    CB_CSTSMASK		0x00000001	/* Card status mask */
-#define    CB_CDMASK		0x00000006	/* Card detect 1&2 mask */
-#define    CB_PWRMASK		0x00000008	/* PWRCYCLE change mask */
-
-#define CB_SOCKET_STATE		0x08
-#define    CB_CARDSTS		0x00000001	/* CSTSCHG status */
-#define    CB_CDETECT1		0x00000002	/* Card detect status 1 */
-#define    CB_CDETECT2		0x00000004	/* Card detect status 2 */
-#define    CB_PWRCYCLE		0x00000008	/* Socket powered */
-#define    CB_16BITCARD		0x00000010	/* 16-bit card detected */
-#define    CB_CBCARD		0x00000020	/* CardBus card detected */
-#define    CB_IREQCINT		0x00000040	/* READY(xIRQ)/xCINT high */
-#define    CB_NOTACARD		0x00000080	/* Unrecognizable PC card detected */
-#define    CB_DATALOST		0x00000100	/* Potential data loss due to card removal */
-#define    CB_BADVCCREQ		0x00000200	/* Invalid Vcc request by host software */
-#define    CB_5VCARD		0x00000400	/* Card Vcc at 5.0 volts? */
-#define    CB_3VCARD		0x00000800	/* Card Vcc at 3.3 volts? */
-#define    CB_XVCARD		0x00001000	/* Card Vcc at X.X volts? */
-#define    CB_YVCARD		0x00002000	/* Card Vcc at Y.Y volts? */
-#define    CB_5VSOCKET		0x10000000	/* Socket Vcc at 5.0 volts? */
-#define    CB_3VSOCKET		0x20000000	/* Socket Vcc at 3.3 volts? */
-#define    CB_XVSOCKET		0x40000000	/* Socket Vcc at X.X volts? */
-#define    CB_YVSOCKET		0x80000000	/* Socket Vcc at Y.Y volts? */
-
-#define CB_SOCKET_FORCE		0x0C
-#define    CB_FCARDSTS		0x00000001	/* Force CSTSCHG */
-#define    CB_FCDETECT1		0x00000002	/* Force CD1EVENT */
-#define    CB_FCDETECT2		0x00000004	/* Force CD2EVENT */
-#define    CB_FPWRCYCLE		0x00000008	/* Force PWREVENT */
-#define    CB_F16BITCARD	0x00000010	/* Force 16-bit PCMCIA card */
-#define    CB_FCBCARD		0x00000020	/* Force CardBus line */
-#define    CB_FNOTACARD		0x00000080	/* Force NOTACARD */
-#define    CB_FDATALOST		0x00000100	/* Force data lost */
-#define    CB_FBADVCCREQ	0x00000200	/* Force bad Vcc request */
-#define    CB_F5VCARD		0x00000400	/* Force 5.0 volt card */
-#define    CB_F3VCARD		0x00000800	/* Force 3.3 volt card */
-#define    CB_FXVCARD		0x00001000	/* Force X.X volt card */
-#define    CB_FYVCARD		0x00002000	/* Force Y.Y volt card */
-#define    CB_CVSTEST		0x00004000	/* Card VS test */
-
-#define CB_SOCKET_CONTROL	0x10
-#define  CB_SC_VPP_MASK		0x00000007
-#define   CB_SC_VPP_OFF		0x00000000
-#define   CB_SC_VPP_12V		0x00000001
-#define   CB_SC_VPP_5V		0x00000002
-#define   CB_SC_VPP_3V		0x00000003
-#define   CB_SC_VPP_XV		0x00000004
-#define   CB_SC_VPP_YV		0x00000005
-#define  CB_SC_VCC_MASK		0x00000070
-#define   CB_SC_VCC_OFF		0x00000000
-#define   CB_SC_VCC_5V		0x00000020
-#define   CB_SC_VCC_3V		0x00000030
-#define   CB_SC_VCC_XV		0x00000040
-#define   CB_SC_VCC_YV		0x00000050
-#define  CB_SC_CCLK_STOP	0x00000080
-
-#define CB_SOCKET_POWER		0x20
-#define    CB_SKTACCES		0x02000000	/* A PC card access has occurred (clear on read) */
-#define    CB_SKTMODE		0x01000000	/* Clock frequency has changed (clear on read) */
-#define    CB_CLKCTRLEN		0x00010000	/* Clock control enabled (RW) */
-#define    CB_CLKCTRL		0x00000001	/* Stop(0) or slow(1) CB clock (RW) */
-
-/*
- * Cardbus configuration space
- */
-#define CB_BRIDGE_BASE(m)	(0x1c + 8*(m))
-#define CB_BRIDGE_LIMIT(m)	(0x20 + 8*(m))
-#define CB_BRIDGE_CONTROL	0x3e
-#define   CB_BRIDGE_CPERREN	0x00000001
-#define   CB_BRIDGE_CSERREN	0x00000002
-#define   CB_BRIDGE_ISAEN	0x00000004
-#define   CB_BRIDGE_VGAEN	0x00000008
-#define   CB_BRIDGE_MABTMODE	0x00000020
-#define   CB_BRIDGE_CRST	0x00000040
-#define   CB_BRIDGE_INTR	0x00000080
-#define   CB_BRIDGE_PREFETCH0	0x00000100
-#define   CB_BRIDGE_PREFETCH1	0x00000200
-#define   CB_BRIDGE_POSTEN	0x00000400
-#define CB_LEGACY_MODE_BASE	0x44
-
-/*
- * ExCA area extensions in Yenta
- */
-#define CB_MEM_PAGE(map)	(0x40 + (map))
-
-struct yenta_socket {
-	struct pci_dev *dev;
-	int cb_irq, io_irq;
-	void *base;
-	void (*handler)(void *, unsigned int);
-	void *info;
-	spinlock_t event_lock;
-	unsigned int events;
-	struct work_struct tq_task;
-	struct timer_list poll_timer;
-
-	struct pcmcia_socket socket;
-
-	/* A few words of private data for special stuff of overrides... */
-	unsigned int private[8];
-};
-
-
-#endif
diff -Nru a/drivers/pcmcia/yenta_socket.c b/drivers/pcmcia/yenta_socket.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/pcmcia/yenta_socket.c	Wed Jun 18 23:42:07 2003
@@ -0,0 +1,974 @@
+/*
+ * Regular cardbus driver ("yenta_socket")
+ *
+ * (C) Copyright 1999, 2000 Linus Torvalds
+ *
+ * Changelog:
+ * Aug 2002: Manfred Spraul <manfred@colorfullife.com>
+ * 	Dynamically adjust the size of the bridge resource
+ * 	
+ * May 2003: Dominik Brodowski <linux@brodo.de>
+ * 	Merge pci_socket.c and yenta.c into one file
+ */
+#include <linux/init.h>
+#include <linux/pci.h>
+#include <linux/sched.h>
+#include <linux/workqueue.h>
+#include <linux/interrupt.h>
+#include <linux/delay.h>
+#include <linux/module.h>
+
+#include <pcmcia/version.h>
+#include <pcmcia/cs_types.h>
+#include <pcmcia/ss.h>
+#include <pcmcia/cs.h>
+
+#include <asm/io.h>
+
+#include "yenta_socket.h"
+#include "i82365.h"
+
+
+#if 0
+#define DEBUG(x,args...)	printk("%s: " x, __FUNCTION__, ##args)
+#else
+#define DEBUG(x,args...)
+#endif
+
+/* Don't ask.. */
+#define to_cycles(ns)	((ns)/120)
+#define to_ns(cycles)	((cycles)*120)
+
+/*
+ * Generate easy-to-use ways of reading a cardbus sockets
+ * regular memory space ("cb_xxx"), configuration space
+ * ("config_xxx") and compatibility space ("exca_xxxx")
+ */
+static inline u32 cb_readl(struct yenta_socket *socket, unsigned reg)
+{
+	u32 val = readl(socket->base + reg);
+	DEBUG("%p %04x %08x\n", socket, reg, val);
+	return val;
+}
+
+static inline void cb_writel(struct yenta_socket *socket, unsigned reg, u32 val)
+{
+	DEBUG("%p %04x %08x\n", socket, reg, val);
+	writel(val, socket->base + reg);
+}
+
+static inline u8 config_readb(struct yenta_socket *socket, unsigned offset)
+{
+	u8 val;
+	pci_read_config_byte(socket->dev, offset, &val);
+	DEBUG("%p %04x %02x\n", socket, offset, val);
+	return val;
+}
+
+static inline u16 config_readw(struct yenta_socket *socket, unsigned offset)
+{
+	u16 val;
+	pci_read_config_word(socket->dev, offset, &val);
+	DEBUG("%p %04x %04x\n", socket, offset, val);
+	return val;
+}
+
+static inline u32 config_readl(struct yenta_socket *socket, unsigned offset)
+{
+	u32 val;
+	pci_read_config_dword(socket->dev, offset, &val);
+	DEBUG("%p %04x %08x\n", socket, offset, val);
+	return val;
+}
+
+static inline void config_writeb(struct yenta_socket *socket, unsigned offset, u8 val)
+{
+	DEBUG("%p %04x %02x\n", socket, offset, val);
+	pci_write_config_byte(socket->dev, offset, val);
+}
+
+static inline void config_writew(struct yenta_socket *socket, unsigned offset, u16 val)
+{
+	DEBUG("%p %04x %04x\n", socket, offset, val);
+	pci_write_config_word(socket->dev, offset, val);
+}
+
+static inline void config_writel(struct yenta_socket *socket, unsigned offset, u32 val)
+{
+	DEBUG("%p %04x %08x\n", socket, offset, val);
+	pci_write_config_dword(socket->dev, offset, val);
+}
+
+static inline u8 exca_readb(struct yenta_socket *socket, unsigned reg)
+{
+	u8 val = readb(socket->base + 0x800 + reg);
+	DEBUG("%p %04x %02x\n", socket, reg, val);
+	return val;
+}
+
+static inline u8 exca_readw(struct yenta_socket *socket, unsigned reg)
+{
+	u16 val;
+	val = readb(socket->base + 0x800 + reg);
+	val |= readb(socket->base + 0x800 + reg + 1) << 8;
+	DEBUG("%p %04x %04x\n", socket, reg, val);
+	return val;
+}
+
+static inline void exca_writeb(struct yenta_socket *socket, unsigned reg, u8 val)
+{
+	DEBUG("%p %04x %02x\n", socket, reg, val);
+	writeb(val, socket->base + 0x800 + reg);
+}
+
+static void exca_writew(struct yenta_socket *socket, unsigned reg, u16 val)
+{
+	DEBUG("%p %04x %04x\n", socket, reg, val);
+	writeb(val, socket->base + 0x800 + reg);
+	writeb(val >> 8, socket->base + 0x800 + reg + 1);
+}
+
+/*
+ * Ugh, mixed-mode cardbus and 16-bit pccard state: things depend
+ * on what kind of card is inserted..
+ */
+static int yenta_get_status(struct pcmcia_socket *sock, unsigned int *value)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+	unsigned int val;
+	u32 state = cb_readl(socket, CB_SOCKET_STATE);
+
+	val  = (state & CB_3VCARD) ? SS_3VCARD : 0;
+	val |= (state & CB_XVCARD) ? SS_XVCARD : 0;
+	val |= (state & (CB_CDETECT1 | CB_CDETECT2 | CB_5VCARD | CB_3VCARD
+			 | CB_XVCARD | CB_YVCARD)) ? 0 : SS_PENDING;
+
+	if (state & CB_CBCARD) {
+		val |= SS_CARDBUS;	
+		val |= (state & CB_CARDSTS) ? SS_STSCHG : 0;
+		val |= (state & (CB_CDETECT1 | CB_CDETECT2)) ? 0 : SS_DETECT;
+		val |= (state & CB_PWRCYCLE) ? SS_POWERON | SS_READY : 0;
+	} else {
+		u8 status = exca_readb(socket, I365_STATUS);
+		val |= ((status & I365_CS_DETECT) == I365_CS_DETECT) ? SS_DETECT : 0;
+		if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
+			val |= (status & I365_CS_STSCHG) ? 0 : SS_STSCHG;
+		} else {
+			val |= (status & I365_CS_BVD1) ? 0 : SS_BATDEAD;
+			val |= (status & I365_CS_BVD2) ? 0 : SS_BATWARN;
+		}
+		val |= (status & I365_CS_WRPROT) ? SS_WRPROT : 0;
+		val |= (status & I365_CS_READY) ? SS_READY : 0;
+		val |= (status & I365_CS_POWERON) ? SS_POWERON : 0;
+	}
+
+	*value = val;
+	return 0;
+}
+
+static int yenta_Vcc_power(u32 control)
+{
+	switch (control & CB_SC_VCC_MASK) {
+	case CB_SC_VCC_5V: return 50;
+	case CB_SC_VCC_3V: return 33;
+	default: return 0;
+	}
+}
+
+static int yenta_Vpp_power(u32 control)
+{
+	switch (control & CB_SC_VPP_MASK) {
+	case CB_SC_VPP_12V: return 120;
+	case CB_SC_VPP_5V: return 50;
+	case CB_SC_VPP_3V: return 33;
+	default: return 0;
+	}
+}
+
+static int yenta_get_socket(struct pcmcia_socket *sock, socket_state_t *state)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+	u8 reg;
+	u32 control;
+
+	control = cb_readl(socket, CB_SOCKET_CONTROL);
+
+	state->Vcc = yenta_Vcc_power(control);
+	state->Vpp = yenta_Vpp_power(control);
+	state->io_irq = socket->io_irq;
+
+	if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) {
+		u16 bridge = config_readw(socket, CB_BRIDGE_CONTROL);
+		if (bridge & CB_BRIDGE_CRST)
+			state->flags |= SS_RESET;
+		return 0;
+	}
+
+	/* 16-bit card state.. */
+	reg = exca_readb(socket, I365_POWER);
+	state->flags = (reg & I365_PWR_AUTO) ? SS_PWR_AUTO : 0;
+	state->flags |= (reg & I365_PWR_OUT) ? SS_OUTPUT_ENA : 0;
+
+	reg = exca_readb(socket, I365_INTCTL);
+	state->flags |= (reg & I365_PC_RESET) ? 0 : SS_RESET;
+	state->flags |= (reg & I365_PC_IOCARD) ? SS_IOCARD : 0;
+
+	reg = exca_readb(socket, I365_CSCINT);
+	state->csc_mask = (reg & I365_CSC_DETECT) ? SS_DETECT : 0;
+	if (state->flags & SS_IOCARD) {
+		state->csc_mask |= (reg & I365_CSC_STSCHG) ? SS_STSCHG : 0;
+	} else {
+		state->csc_mask |= (reg & I365_CSC_BVD1) ? SS_BATDEAD : 0;
+		state->csc_mask |= (reg & I365_CSC_BVD2) ? SS_BATWARN : 0;
+		state->csc_mask |= (reg & I365_CSC_READY) ? SS_READY : 0;
+	}
+
+	return 0;
+}
+
+static void yenta_set_power(struct yenta_socket *socket, socket_state_t *state)
+{
+	u32 reg = 0;	/* CB_SC_STPCLK? */
+	switch (state->Vcc) {
+	case 33: reg = CB_SC_VCC_3V; break;
+	case 50: reg = CB_SC_VCC_5V; break;
+	default: reg = 0; break;
+	}
+	switch (state->Vpp) {
+	case 33:  reg |= CB_SC_VPP_3V; break;
+	case 50:  reg |= CB_SC_VPP_5V; break;
+	case 120: reg |= CB_SC_VPP_12V; break;
+	}
+	if (reg != cb_readl(socket, CB_SOCKET_CONTROL))
+		cb_writel(socket, CB_SOCKET_CONTROL, reg);
+}
+
+static int yenta_set_socket(struct pcmcia_socket *sock, socket_state_t *state)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+	u16 bridge;
+
+	if (state->flags & SS_DEBOUNCED) {
+		/* The insertion debounce period has ended.  Clear any pending insertion events */
+		socket->events &= ~SS_DETECT;
+		state->flags &= ~SS_DEBOUNCED;		/* SS_DEBOUNCED is oneshot */
+	}
+	yenta_set_power(socket, state);
+	socket->io_irq = state->io_irq;
+	bridge = config_readw(socket, CB_BRIDGE_CONTROL) & ~(CB_BRIDGE_CRST | CB_BRIDGE_INTR);
+	if (cb_readl(socket, CB_SOCKET_STATE) & CB_CBCARD) {
+		u8 intr;
+		bridge |= (state->flags & SS_RESET) ? CB_BRIDGE_CRST : 0;
+
+		/* ISA interrupt control? */
+		intr = exca_readb(socket, I365_INTCTL);
+		intr = (intr & ~0xf);
+		if (!socket->cb_irq) {
+			intr |= state->io_irq;
+			bridge |= CB_BRIDGE_INTR;
+		}
+		exca_writeb(socket, I365_INTCTL, intr);
+	}  else {
+		u8 reg;
+
+		reg = exca_readb(socket, I365_INTCTL) & (I365_RING_ENA | I365_INTR_ENA);
+		reg |= (state->flags & SS_RESET) ? 0 : I365_PC_RESET;
+		reg |= (state->flags & SS_IOCARD) ? I365_PC_IOCARD : 0;
+		if (state->io_irq != socket->cb_irq) {
+			reg |= state->io_irq;
+			bridge |= CB_BRIDGE_INTR;
+		}
+		exca_writeb(socket, I365_INTCTL, reg);
+
+		reg = exca_readb(socket, I365_POWER) & (I365_VCC_MASK|I365_VPP1_MASK);
+		reg |= I365_PWR_NORESET;
+		if (state->flags & SS_PWR_AUTO) reg |= I365_PWR_AUTO;
+		if (state->flags & SS_OUTPUT_ENA) reg |= I365_PWR_OUT;
+		if (exca_readb(socket, I365_POWER) != reg)
+			exca_writeb(socket, I365_POWER, reg);
+
+		/* CSC interrupt: no ISA irq for CSC */
+		reg = I365_CSC_DETECT;
+		if (state->flags & SS_IOCARD) {
+			if (state->csc_mask & SS_STSCHG) reg |= I365_CSC_STSCHG;
+		} else {
+			if (state->csc_mask & SS_BATDEAD) reg |= I365_CSC_BVD1;
+			if (state->csc_mask & SS_BATWARN) reg |= I365_CSC_BVD2;
+			if (state->csc_mask & SS_READY) reg |= I365_CSC_READY;
+		}
+		exca_writeb(socket, I365_CSCINT, reg);
+		exca_readb(socket, I365_CSC);
+	}
+	config_writew(socket, CB_BRIDGE_CONTROL, bridge);
+	/* Socket event mask: get card insert/remove events.. */
+	cb_writel(socket, CB_SOCKET_EVENT, -1);
+	cb_writel(socket, CB_SOCKET_MASK, CB_CDMASK);
+	return 0;
+}
+
+static int yenta_set_io_map(struct pcmcia_socket *sock, struct pccard_io_map *io)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+	int map;
+	unsigned char ioctl, addr, enable;
+
+	map = io->map;
+
+	if (map > 1)
+		return -EINVAL;
+
+	enable = I365_ENA_IO(map);
+	addr = exca_readb(socket, I365_ADDRWIN);
+
+	/* Disable the window before changing it.. */
+	if (addr & enable) {
+		addr &= ~enable;
+		exca_writeb(socket, I365_ADDRWIN, addr);
+	}
+
+	exca_writew(socket, I365_IO(map)+I365_W_START, io->start);
+	exca_writew(socket, I365_IO(map)+I365_W_STOP, io->stop);
+
+	ioctl = exca_readb(socket, I365_IOCTL) & ~I365_IOCTL_MASK(map);
+	if (io->flags & MAP_0WS) ioctl |= I365_IOCTL_0WS(map);
+	if (io->flags & MAP_16BIT) ioctl |= I365_IOCTL_16BIT(map);
+	if (io->flags & MAP_AUTOSZ) ioctl |= I365_IOCTL_IOCS16(map);
+	exca_writeb(socket, I365_IOCTL, ioctl);
+
+	if (io->flags & MAP_ACTIVE)
+		exca_writeb(socket, I365_ADDRWIN, addr | enable);
+	return 0;
+}
+
+static int yenta_set_mem_map(struct pcmcia_socket *sock, struct pccard_mem_map *mem)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+	int map;
+	unsigned char addr, enable;
+	unsigned int start, stop, card_start;
+	unsigned short word;
+
+	map = mem->map;
+	start = mem->sys_start;
+	stop = mem->sys_stop;
+	card_start = mem->card_start;
+
+	if (map > 4 || start > stop || ((start ^ stop) >> 24) ||
+	    (card_start >> 26) || mem->speed > 1000)
+		return -EINVAL;
+
+	enable = I365_ENA_MEM(map);
+	addr = exca_readb(socket, I365_ADDRWIN);
+	if (addr & enable) {
+		addr &= ~enable;
+		exca_writeb(socket, I365_ADDRWIN, addr);
+	}
+
+	exca_writeb(socket, CB_MEM_PAGE(map), start >> 24);
+
+	word = (start >> 12) & 0x0fff;
+	if (mem->flags & MAP_16BIT)
+		word |= I365_MEM_16BIT;
+	if (mem->flags & MAP_0WS)
+		word |= I365_MEM_0WS;
+	exca_writew(socket, I365_MEM(map) + I365_W_START, word);
+
+	word = (stop >> 12) & 0x0fff;
+	switch (to_cycles(mem->speed)) {
+		case 0: break;
+		case 1:  word |= I365_MEM_WS0; break;
+		case 2:  word |= I365_MEM_WS1; break;
+		default: word |= I365_MEM_WS1 | I365_MEM_WS0; break;
+	}
+	exca_writew(socket, I365_MEM(map) + I365_W_STOP, word);
+
+	word = ((card_start - start) >> 12) & 0x3fff;
+	if (mem->flags & MAP_WRPROT)
+		word |= I365_MEM_WRPROT;
+	if (mem->flags & MAP_ATTRIB)
+		word |= I365_MEM_REG;
+	exca_writew(socket, I365_MEM(map) + I365_W_OFF, word);
+
+	if (mem->flags & MAP_ACTIVE)
+		exca_writeb(socket, I365_ADDRWIN, addr | enable);
+	return 0;
+}
+
+
+static unsigned int yenta_events(struct yenta_socket *socket)
+{
+	u8 csc;
+	u32 cb_event;
+	unsigned int events;
+
+	/* Clear interrupt status for the event */
+	cb_event = cb_readl(socket, CB_SOCKET_EVENT);
+	cb_writel(socket, CB_SOCKET_EVENT, cb_event);
+
+	csc = exca_readb(socket, I365_CSC);
+
+	events = (cb_event & (CB_CD1EVENT | CB_CD2EVENT)) ? SS_DETECT : 0 ;
+	events |= (csc & I365_CSC_DETECT) ? SS_DETECT : 0;
+	if (exca_readb(socket, I365_INTCTL) & I365_PC_IOCARD) {
+		events |= (csc & I365_CSC_STSCHG) ? SS_STSCHG : 0;
+	} else {
+		events |= (csc & I365_CSC_BVD1) ? SS_BATDEAD : 0;
+		events |= (csc & I365_CSC_BVD2) ? SS_BATWARN : 0;
+		events |= (csc & I365_CSC_READY) ? SS_READY : 0;
+	}
+	return events;
+}
+
+
+static void yenta_bh(void *data)
+{
+	struct yenta_socket *socket = data;
+	unsigned int events;
+
+	spin_lock_irq(&socket->event_lock);
+	events = socket->events;
+	socket->events = 0;
+	spin_unlock_irq(&socket->event_lock);
+	if (socket->handler)
+		socket->handler(socket->info, events);
+}
+
+static irqreturn_t yenta_interrupt(int irq, void *dev_id, struct pt_regs *regs)
+{
+	unsigned int events;
+	struct yenta_socket *socket = (struct yenta_socket *) dev_id;
+
+	events = yenta_events(socket);
+	if (events) {
+		spin_lock(&socket->event_lock);
+		socket->events |= events;
+		spin_unlock(&socket->event_lock);
+		schedule_work(&socket->tq_task);
+		return IRQ_HANDLED;
+	}
+	return IRQ_NONE;
+}
+
+static void yenta_interrupt_wrapper(unsigned long data)
+{
+	struct yenta_socket *socket = (struct yenta_socket *) data;
+
+	yenta_interrupt(0, (void *)socket, NULL);
+	socket->poll_timer.expires = jiffies + HZ;
+	add_timer(&socket->poll_timer);
+}
+
+/*
+ * Only probe "regular" interrupts, don't
+ * touch dangerous spots like the mouse irq,
+ * because there are mice that apparently
+ * get really confused if they get fondled
+ * too intimately.
+ *
+ * Default to 11, 10, 9, 7, 6, 5, 4, 3.
+ */
+static u32 isa_interrupts = 0x0ef8;
+
+static unsigned int yenta_probe_irq(struct yenta_socket *socket, u32 isa_irq_mask)
+{
+	int i;
+	unsigned long val;
+	u16 bridge_ctrl;
+	u32 mask;
+
+	/* Set up ISA irq routing to probe the ISA irqs.. */
+	bridge_ctrl = config_readw(socket, CB_BRIDGE_CONTROL);
+	if (!(bridge_ctrl & CB_BRIDGE_INTR)) {
+		bridge_ctrl |= CB_BRIDGE_INTR;
+		config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
+	}
+
+	/*
+	 * Probe for usable interrupts using the force
+	 * register to generate bogus card status events.
+	 */
+	cb_writel(socket, CB_SOCKET_EVENT, -1);
+	cb_writel(socket, CB_SOCKET_MASK, CB_CSTSMASK);
+	exca_writeb(socket, I365_CSCINT, 0);
+	val = probe_irq_on() & isa_irq_mask;
+	for (i = 1; i < 16; i++) {
+		if (!((val >> i) & 1))
+			continue;
+		exca_writeb(socket, I365_CSCINT, I365_CSC_STSCHG | (i << 4));
+		cb_writel(socket, CB_SOCKET_FORCE, CB_FCARDSTS);
+		udelay(100);
+		cb_writel(socket, CB_SOCKET_EVENT, -1);
+	}
+	cb_writel(socket, CB_SOCKET_MASK, 0);
+	exca_writeb(socket, I365_CSCINT, 0);
+	
+	mask = probe_irq_mask(val) & 0xffff;
+
+	bridge_ctrl &= ~CB_BRIDGE_INTR;
+	config_writew(socket, CB_BRIDGE_CONTROL, bridge_ctrl);
+
+	return mask;
+}
+
+/*
+ * Set static data that doesn't need re-initializing..
+ */
+static void yenta_get_socket_capabilities(struct yenta_socket *socket, u32 isa_irq_mask)
+{
+	socket->socket.features |= SS_CAP_PAGE_REGS | SS_CAP_PCCARD | SS_CAP_CARDBUS;
+	socket->socket.map_size = 0x1000;
+	socket->socket.pci_irq = socket->cb_irq;
+	socket->socket.irq_mask = yenta_probe_irq(socket, isa_irq_mask);
+	socket->socket.cb_dev = socket->dev;
+
+	printk("Yenta IRQ list %04x, PCI irq%d\n", socket->socket.irq_mask, socket->cb_irq);
+}
+
+
+static void yenta_clear_maps(struct yenta_socket *socket)
+{
+	int i;
+	pccard_io_map io = { 0, 0, 0, 0, 1 };
+	pccard_mem_map mem = { 0, 0, 0, 0, 0, 0 };
+
+	mem.sys_stop = 0x0fff;
+	yenta_set_socket(&socket->socket, &dead_socket);
+	for (i = 0; i < 2; i++) {
+		io.map = i;
+		yenta_set_io_map(&socket->socket, &io);
+	}
+	for (i = 0; i < 5; i++) {
+		mem.map = i;
+		yenta_set_mem_map(&socket->socket, &mem);
+	}
+}
+
+/*
+ * Initialize the standard cardbus registers
+ */
+static void yenta_config_init(struct yenta_socket *socket)
+{
+	u16 bridge;
+	struct pci_dev *dev = socket->dev;
+
+	pci_set_power_state(socket->dev, 0);
+
+	config_writel(socket, CB_LEGACY_MODE_BASE, 0);
+	config_writel(socket, PCI_BASE_ADDRESS_0, dev->resource[0].start);
+	config_writew(socket, PCI_COMMAND,
+			PCI_COMMAND_IO |
+			PCI_COMMAND_MEMORY |
+			PCI_COMMAND_MASTER |
+			PCI_COMMAND_WAIT);
+
+	/* MAGIC NUMBERS! Fixme */
+	config_writeb(socket, PCI_CACHE_LINE_SIZE, L1_CACHE_BYTES / 4);
+	config_writeb(socket, PCI_LATENCY_TIMER, 168);
+	config_writel(socket, PCI_PRIMARY_BUS,
+		(176 << 24) |			   /* sec. latency timer */
+		(dev->subordinate->subordinate << 16) | /* subordinate bus */
+		(dev->subordinate->secondary << 8) |  /* secondary bus */
+		dev->subordinate->primary);		   /* primary bus */
+
+	/*
+	 * Set up the bridging state:
+	 *  - enable write posting.
+	 *  - memory window 0 prefetchable, window 1 non-prefetchable
+	 *  - PCI interrupts enabled if a PCI interrupt exists..
+	 */
+	bridge = config_readw(socket, CB_BRIDGE_CONTROL);
+	bridge &= ~(CB_BRIDGE_CRST | CB_BRIDGE_PREFETCH1 | CB_BRIDGE_INTR | CB_BRIDGE_ISAEN | CB_BRIDGE_VGAEN);
+	bridge |= CB_BRIDGE_PREFETCH0 | CB_BRIDGE_POSTEN;
+	if (!socket->cb_irq)
+		bridge |= CB_BRIDGE_INTR;
+	config_writew(socket, CB_BRIDGE_CONTROL, bridge);
+
+	exca_writeb(socket, I365_GBLCTL, 0x00);
+	exca_writeb(socket, I365_GENCTL, 0x00);
+
+	/* Redo card voltage interrogation */
+	cb_writel(socket, CB_SOCKET_FORCE, CB_CVSTEST);
+}
+
+/* Called at resume and initialization events */
+static int yenta_init(struct pcmcia_socket *sock)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+	yenta_config_init(socket);
+	yenta_clear_maps(socket);
+
+	/* Re-enable interrupts */
+	cb_writel(socket, CB_SOCKET_MASK, CB_CDMASK);
+	return 0;
+}
+
+static int yenta_suspend(struct pcmcia_socket *sock)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+
+	yenta_set_socket(sock, &dead_socket);
+
+	/* Disable interrupts */
+	cb_writel(socket, CB_SOCKET_MASK, 0x0);
+
+	/*
+	 * This does not work currently. The controller
+	 * loses too much information during D3 to come up
+	 * cleanly. We should probably fix yenta_init()
+	 * to update all the critical registers, notably
+	 * the IO and MEM bridging region data.. That is
+	 * something that pci_set_power_state() should
+	 * probably know about bridges anyway.
+	 *
+	pci_set_power_state(socket->dev, 3);
+	 */
+
+	return 0;
+}
+
+/*
+ * Use an adaptive allocation for the memory resource,
+ * sometimes the memory behind pci bridges is limited:
+ * 1/8 of the size of the io window of the parent.
+ * max 4 MB, min 16 kB.
+ */
+#define BRIDGE_MEM_MAX 4*1024*1024
+#define BRIDGE_MEM_MIN 16*1024
+
+#define BRIDGE_IO_MAX 256
+#define BRIDGE_IO_MIN 32
+
+static void yenta_allocate_res(struct yenta_socket *socket, int nr, unsigned type)
+{
+	struct pci_bus *bus;
+	struct resource *root, *res;
+	u32 start, end;
+	u32 align, size, min;
+	unsigned offset;
+	unsigned mask;
+
+	/* The granularity of the memory limit is 4kB, on IO it's 4 bytes */
+	mask = ~0xfff;
+	if (type & IORESOURCE_IO)
+		mask = ~3;
+
+	offset = 0x1c + 8*nr;
+	bus = socket->dev->subordinate;
+	res = socket->dev->resource + PCI_BRIDGE_RESOURCES + nr;
+	res->name = bus->name;
+	res->flags = type;
+	res->start = 0;
+	res->end = 0;
+	root = pci_find_parent_resource(socket->dev, res);
+
+	if (!root)
+		return;
+
+	start = config_readl(socket, offset) & mask;
+	end = config_readl(socket, offset+4) | ~mask;
+	if (start && end > start) {
+		res->start = start;
+		res->end = end;
+		if (request_resource(root, res) == 0)
+			return;
+		printk(KERN_INFO "yenta %s: Preassigned resource %d busy, reconfiguring...\n",
+				socket->dev->slot_name, nr);
+		res->start = res->end = 0;
+	}
+
+	if (type & IORESOURCE_IO) {
+		align = 1024;
+		size = BRIDGE_IO_MAX;
+		min = BRIDGE_IO_MIN;
+		start = PCIBIOS_MIN_IO;
+		end = ~0U;
+	} else {
+		unsigned long avail = root->end - root->start;
+		int i;
+		size = BRIDGE_MEM_MAX;
+		if (size > avail/8) {
+			size=(avail+1)/8;
+			/* round size down to next power of 2 */
+			i = 0;
+			while ((size /= 2) != 0)
+				i++;
+			size = 1 << i;
+		}
+		if (size < BRIDGE_MEM_MIN)
+			size = BRIDGE_MEM_MIN;
+		min = BRIDGE_MEM_MIN;
+		align = size;
+		start = PCIBIOS_MIN_MEM;
+		end = ~0U;
+	}
+	
+	do {
+		if (allocate_resource(root, res, size, start, end, align, NULL, NULL)==0) {
+			config_writel(socket, offset, res->start);
+			config_writel(socket, offset+4, res->end);
+			return;
+		}
+		size = size/2;
+		align = size;
+	} while (size >= min);
+	printk(KERN_INFO "yenta %s: no resource of type %x available, trying to continue...\n",
+			socket->dev->slot_name, type);
+	res->start = res->end = 0;
+}
+
+/*
+ * Allocate the bridge mappings for the device..
+ */
+static void yenta_allocate_resources(struct yenta_socket *socket)
+{
+	yenta_allocate_res(socket, 0, IORESOURCE_MEM|IORESOURCE_PREFETCH);
+	yenta_allocate_res(socket, 1, IORESOURCE_MEM);
+	yenta_allocate_res(socket, 2, IORESOURCE_IO);
+	yenta_allocate_res(socket, 3, IORESOURCE_IO);	/* PCI isn't clever enough to use this one yet */
+}
+
+
+/*
+ * Free the bridge mappings for the device..
+ */
+static void yenta_free_resources(struct yenta_socket *socket)
+{
+	int i;
+	for (i=0;i<4;i++) {
+		struct resource *res;
+		res = socket->dev->resource + PCI_BRIDGE_RESOURCES + i;
+		if (res->start != 0 && res->end != 0)
+			release_resource(res);
+		res->start = res->end = 0;
+	}
+}
+
+
+/*
+ * Close it down - release our resources and go home..
+ */
+static void yenta_close(struct pci_dev *dev)
+{
+	struct yenta_socket *sock = pci_get_drvdata(dev);
+
+	/* we don't want a dying socket registered */
+	pcmcia_unregister_socket(&sock->socket);
+	
+	/* Disable all events so we don't die in an IRQ storm */
+	cb_writel(sock, CB_SOCKET_MASK, 0x0);
+	exca_writeb(sock, I365_CSCINT, 0);
+
+	if (sock->cb_irq)
+		free_irq(sock->cb_irq, sock);
+	else
+		del_timer_sync(&sock->poll_timer);
+
+	if (sock->base)
+		iounmap(sock->base);
+	yenta_free_resources(sock);
+
+	pci_set_drvdata(dev, NULL);
+}
+
+
+static int yenta_register_callback(struct pcmcia_socket *sock, void (*handler)(void *, unsigned int), void * info)
+{
+	struct yenta_socket *socket = container_of(sock, struct yenta_socket, socket);
+
+	socket->handler = handler;
+	socket->info = info;
+	return 0;
+}
+
+
+static struct pccard_operations yenta_socket_operations = {
+	.owner			= THIS_MODULE,
+	.init			= yenta_init,
+	.suspend		= yenta_suspend,
+	.register_callback	= yenta_register_callback,
+	.get_status		= yenta_get_status,
+	.get_socket		= yenta_get_socket,
+	.set_socket		= yenta_set_socket,
+	.set_io_map		= yenta_set_io_map,
+	.set_mem_map		= yenta_set_mem_map,
+};
+
+
+#include "ti113x.h"
+#include "ricoh.h"
+
+/*
+ * Different cardbus controllers have slightly different
+ * initialization sequences etc details. List them here..
+ */
+#define PD(x,y) PCI_VENDOR_ID_##x, PCI_DEVICE_ID_##x##_##y
+struct cardbus_override_struct {
+	unsigned short vendor;
+	unsigned short device;
+	int (*override) (struct yenta_socket *socket);
+} cardbus_override[] = {
+	{ PD(TI,1130),	&ti113x_override },
+	{ PD(TI,1031),	&ti_override },
+	{ PD(TI,1131),	&ti113x_override },
+	{ PD(TI,1250),	&ti1250_override },
+	{ PD(TI,1220),	&ti_override },
+	{ PD(TI,1221),	&ti_override },
+	{ PD(TI,1210),	&ti_override },
+	{ PD(TI,1450),	&ti_override },
+	{ PD(TI,1225),	&ti_override },
+	{ PD(TI,1251A),	&ti_override },
+	{ PD(TI,1211),	&ti_override },
+	{ PD(TI,1251B),	&ti_override },
+	{ PD(TI,1410),	ti1250_override },
+	{ PD(TI,1420),	&ti_override },
+	{ PD(TI,4410),	&ti_override },
+	{ PD(TI,4451),	&ti_override },
+
+	{ PD(RICOH,RL5C465), &ricoh_override },
+	{ PD(RICOH,RL5C466), &ricoh_override },
+	{ PD(RICOH,RL5C475), &ricoh_override },
+	{ PD(RICOH,RL5C476), &ricoh_override },
+	{ PD(RICOH,RL5C478), &ricoh_override },
+
+	{ }, /* all zeroes */
+};
+
+
+/*
+ * Initialize a cardbus controller. Make sure we have a usable
+ * interrupt, and that we can map the cardbus area. Fill in the
+ * socket information structure..
+ */
+static int __devinit yenta_probe (struct pci_dev *dev, const struct pci_device_id *id)
+{
+	struct yenta_socket *socket;
+	struct cardbus_override_struct *d;
+	
+	socket = kmalloc(sizeof(struct yenta_socket), GFP_KERNEL);
+	if (!socket)
+		return -ENOMEM;
+	memset(socket, 0, sizeof(*socket));
+
+	/* prepare pcmcia_socket */
+	socket->socket.ss_entry = &yenta_socket_operations;
+	socket->socket.dev.dev = &dev->dev;
+	socket->socket.driver_data = socket;
+
+	/* prepare struct yenta_socket */
+	socket->dev = dev;
+	pci_set_drvdata(dev, socket);
+	spin_lock_init(&socket->event_lock);
+
+	/*
+	 * Do some basic sanity checking..
+	 */
+	if (pci_enable_device(dev))
+		return -1;
+	if (!pci_resource_start(dev, 0)) {
+		printk("No cardbus resource!\n");
+		return -1;
+	}
+
+	/*
+	 * Ok, start setup.. Map the cardbus registers,
+	 * and request the IRQ.
+	 */
+	socket->base = ioremap(pci_resource_start(dev, 0), 0x1000);
+	if (!socket->base)
+		return -1;
+
+	yenta_config_init(socket);
+
+	/* Disable all events */
+	cb_writel(socket, CB_SOCKET_MASK, 0x0);
+
+	/* Set up the bridge regions.. */
+	yenta_allocate_resources(socket);
+
+	socket->cb_irq = dev->irq;
+
+	/* Do we have special options for the device? */
+	d = cardbus_override;
+	while (d->override) {
+		if ((dev->vendor == d->vendor) && (dev->device == d->device)) {
+			int retval = d->override(socket);
+			if (retval < 0)
+				return retval;
+		}
+		d++;
+	}
+
+	/* We must finish initialization here */
+
+	INIT_WORK(&socket->tq_task, yenta_bh, socket);
+
+	if (!socket->cb_irq || request_irq(socket->cb_irq, yenta_interrupt, SA_SHIRQ, socket->dev->dev.name, socket)) {
+		/* No IRQ or request_irq failed. Poll */
+		socket->cb_irq = 0; /* But zero is a valid IRQ number. */
+		init_timer(&socket->poll_timer);
+		socket->poll_timer.function = yenta_interrupt_wrapper;
+		socket->poll_timer.data = (unsigned long)socket;
+		socket->poll_timer.expires = jiffies + HZ;
+		add_timer(&socket->poll_timer);
+	}
+
+	/* Figure out what the dang thing can do for the PCMCIA layer... */
+	yenta_get_socket_capabilities(socket, isa_interrupts);
+	printk("Socket status: %08x\n", cb_readl(socket, CB_SOCKET_STATE));
+
+	/* Register it with the pcmcia layer.. */
+	return pcmcia_register_socket(&socket->socket);
+}
+
+
+static int yenta_dev_suspend (struct pci_dev *dev, u32 state)
+{
+	return pcmcia_socket_dev_suspend(&dev->dev, state, 0);
+}
+
+
+static int yenta_dev_resume (struct pci_dev *dev)
+{
+	return pcmcia_socket_dev_resume(&dev->dev, RESUME_RESTORE_STATE);
+}
+
+
+static struct pci_device_id yenta_table [] __devinitdata = { {
+	.class		= PCI_CLASS_BRIDGE_CARDBUS << 8,
+	.class_mask	= ~0,
+
+	.vendor		= PCI_ANY_ID,
+	.device		= PCI_ANY_ID,
+	.subvendor	= PCI_ANY_ID,
+	.subdevice	= PCI_ANY_ID,
+}, { /* all zeroes */ }
+};
+MODULE_DEVICE_TABLE(pci, yenta_table);
+
+
+static struct pci_driver yenta_cardbus_driver = {
+	.name		= "yenta_cardbus",
+	.id_table	= yenta_table,
+	.probe		= yenta_probe,
+	.remove		= __devexit_p(yenta_close),
+	.suspend	= yenta_dev_suspend,
+	.resume		= yenta_dev_resume,
+};
+
+
+static int __init yenta_socket_init(void)
+{
+	return pci_register_driver (&yenta_cardbus_driver);
+}
+
+
+static void __exit yenta_socket_exit (void)
+{
+	pci_unregister_driver (&yenta_cardbus_driver);
+}
+
+
+module_init(yenta_socket_init);
+module_exit(yenta_socket_exit);
+
+MODULE_LICENSE("GPL");
diff -Nru a/drivers/pcmcia/yenta_socket.h b/drivers/pcmcia/yenta_socket.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/pcmcia/yenta_socket.h	Wed Jun 18 23:42:06 2003
@@ -0,0 +1,116 @@
+#ifndef __YENTA_H
+#define __YENTA_H
+
+#include <asm/io.h>
+
+#define CB_SOCKET_EVENT		0x00
+#define    CB_CSTSEVENT		0x00000001	/* Card status event */
+#define    CB_CD1EVENT		0x00000002	/* Card detect 1 change event */
+#define    CB_CD2EVENT		0x00000004	/* Card detect 2 change event */
+#define    CB_PWREVENT		0x00000008	/* PWRCYCLE change event */
+
+#define CB_SOCKET_MASK		0x04
+#define    CB_CSTSMASK		0x00000001	/* Card status mask */
+#define    CB_CDMASK		0x00000006	/* Card detect 1&2 mask */
+#define    CB_PWRMASK		0x00000008	/* PWRCYCLE change mask */
+
+#define CB_SOCKET_STATE		0x08
+#define    CB_CARDSTS		0x00000001	/* CSTSCHG status */
+#define    CB_CDETECT1		0x00000002	/* Card detect status 1 */
+#define    CB_CDETECT2		0x00000004	/* Card detect status 2 */
+#define    CB_PWRCYCLE		0x00000008	/* Socket powered */
+#define    CB_16BITCARD		0x00000010	/* 16-bit card detected */
+#define    CB_CBCARD		0x00000020	/* CardBus card detected */
+#define    CB_IREQCINT		0x00000040	/* READY(xIRQ)/xCINT high */
+#define    CB_NOTACARD		0x00000080	/* Unrecognizable PC card detected */
+#define    CB_DATALOST		0x00000100	/* Potential data loss due to card removal */
+#define    CB_BADVCCREQ		0x00000200	/* Invalid Vcc request by host software */
+#define    CB_5VCARD		0x00000400	/* Card Vcc at 5.0 volts? */
+#define    CB_3VCARD		0x00000800	/* Card Vcc at 3.3 volts? */
+#define    CB_XVCARD		0x00001000	/* Card Vcc at X.X volts? */
+#define    CB_YVCARD		0x00002000	/* Card Vcc at Y.Y volts? */
+#define    CB_5VSOCKET		0x10000000	/* Socket Vcc at 5.0 volts? */
+#define    CB_3VSOCKET		0x20000000	/* Socket Vcc at 3.3 volts? */
+#define    CB_XVSOCKET		0x40000000	/* Socket Vcc at X.X volts? */
+#define    CB_YVSOCKET		0x80000000	/* Socket Vcc at Y.Y volts? */
+
+#define CB_SOCKET_FORCE		0x0C
+#define    CB_FCARDSTS		0x00000001	/* Force CSTSCHG */
+#define    CB_FCDETECT1		0x00000002	/* Force CD1EVENT */
+#define    CB_FCDETECT2		0x00000004	/* Force CD2EVENT */
+#define    CB_FPWRCYCLE		0x00000008	/* Force PWREVENT */
+#define    CB_F16BITCARD	0x00000010	/* Force 16-bit PCMCIA card */
+#define    CB_FCBCARD		0x00000020	/* Force CardBus line */
+#define    CB_FNOTACARD		0x00000080	/* Force NOTACARD */
+#define    CB_FDATALOST		0x00000100	/* Force data lost */
+#define    CB_FBADVCCREQ	0x00000200	/* Force bad Vcc request */
+#define    CB_F5VCARD		0x00000400	/* Force 5.0 volt card */
+#define    CB_F3VCARD		0x00000800	/* Force 3.3 volt card */
+#define    CB_FXVCARD		0x00001000	/* Force X.X volt card */
+#define    CB_FYVCARD		0x00002000	/* Force Y.Y volt card */
+#define    CB_CVSTEST		0x00004000	/* Card VS test */
+
+#define CB_SOCKET_CONTROL	0x10
+#define  CB_SC_VPP_MASK		0x00000007
+#define   CB_SC_VPP_OFF		0x00000000
+#define   CB_SC_VPP_12V		0x00000001
+#define   CB_SC_VPP_5V		0x00000002
+#define   CB_SC_VPP_3V		0x00000003
+#define   CB_SC_VPP_XV		0x00000004
+#define   CB_SC_VPP_YV		0x00000005
+#define  CB_SC_VCC_MASK		0x00000070
+#define   CB_SC_VCC_OFF		0x00000000
+#define   CB_SC_VCC_5V		0x00000020
+#define   CB_SC_VCC_3V		0x00000030
+#define   CB_SC_VCC_XV		0x00000040
+#define   CB_SC_VCC_YV		0x00000050
+#define  CB_SC_CCLK_STOP	0x00000080
+
+#define CB_SOCKET_POWER		0x20
+#define    CB_SKTACCES		0x02000000	/* A PC card access has occurred (clear on read) */
+#define    CB_SKTMODE		0x01000000	/* Clock frequency has changed (clear on read) */
+#define    CB_CLKCTRLEN		0x00010000	/* Clock control enabled (RW) */
+#define    CB_CLKCTRL		0x00000001	/* Stop(0) or slow(1) CB clock (RW) */
+
+/*
+ * Cardbus configuration space
+ */
+#define CB_BRIDGE_BASE(m)	(0x1c + 8*(m))
+#define CB_BRIDGE_LIMIT(m)	(0x20 + 8*(m))
+#define CB_BRIDGE_CONTROL	0x3e
+#define   CB_BRIDGE_CPERREN	0x00000001
+#define   CB_BRIDGE_CSERREN	0x00000002
+#define   CB_BRIDGE_ISAEN	0x00000004
+#define   CB_BRIDGE_VGAEN	0x00000008
+#define   CB_BRIDGE_MABTMODE	0x00000020
+#define   CB_BRIDGE_CRST	0x00000040
+#define   CB_BRIDGE_INTR	0x00000080
+#define   CB_BRIDGE_PREFETCH0	0x00000100
+#define   CB_BRIDGE_PREFETCH1	0x00000200
+#define   CB_BRIDGE_POSTEN	0x00000400
+#define CB_LEGACY_MODE_BASE	0x44
+
+/*
+ * ExCA area extensions in Yenta
+ */
+#define CB_MEM_PAGE(map)	(0x40 + (map))
+
+struct yenta_socket {
+	struct pci_dev *dev;
+	int cb_irq, io_irq;
+	void *base;
+	void (*handler)(void *, unsigned int);
+	void *info;
+	spinlock_t event_lock;
+	unsigned int events;
+	struct work_struct tq_task;
+	struct timer_list poll_timer;
+
+	struct pcmcia_socket socket;
+
+	/* A few words of private data for special stuff of overrides... */
+	unsigned int private[8];
+};
+
+
+#endif
diff -Nru a/drivers/scsi/53c700.c b/drivers/scsi/53c700.c
--- a/drivers/scsi/53c700.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/53c700.c	Wed Jun 18 23:42:06 2003
@@ -168,7 +168,6 @@
 STATIC int NCR_700_bus_reset(Scsi_Cmnd * SCpnt);
 STATIC int NCR_700_dev_reset(Scsi_Cmnd * SCpnt);
 STATIC int NCR_700_host_reset(Scsi_Cmnd * SCpnt);
-STATIC int NCR_700_proc_directory_info(struct Scsi_Host *, char *, char **, off_t, int, int);
 STATIC void NCR_700_chip_setup(struct Scsi_Host *host);
 STATIC void NCR_700_chip_reset(struct Scsi_Host *host);
 STATIC int NCR_700_slave_configure(Scsi_Device *SDpnt);
@@ -281,7 +280,6 @@
 	tpnt->sg_tablesize = NCR_700_SG_SEGMENTS;
 	tpnt->cmd_per_lun = NCR_700_CMD_PER_LUN;
 	tpnt->use_clustering = DISABLE_CLUSTERING;
-	tpnt->proc_info = NCR_700_proc_directory_info;
 	tpnt->slave_configure = NCR_700_slave_configure;
 	tpnt->slave_destroy = NCR_700_slave_destroy;
 	tpnt->use_blk_tcq = 1;
@@ -293,7 +291,8 @@
 		tpnt->proc_name = "53c700";
 	
 
-	if((host = scsi_register(tpnt, 4)) == NULL)
+	host = scsi_host_alloc(tpnt, 4);
+	if (!host)
 		return NULL;
 	memset(hostdata->slots, 0, sizeof(struct NCR_700_command_slot)
 	       * NCR_700_COMMAND_SLOTS_PER_HOST);
@@ -1707,35 +1706,6 @@
  out_unlock:
 	spin_unlock_irqrestore(host->host_lock, flags);
 	return IRQ_RETVAL(handled);
-}
-
-STATIC int
-NCR_700_proc_directory_info(struct Scsi_Host *host, char *proc_buf, char **startp,
-			 off_t offset, int bytes_available, int write)
-{
-	static char buf[4096];	/* 1 page should be sufficient */
-	int len = 0;
-	struct NCR_700_Host_Parameters *hostdata;
-	Scsi_Device *SDp;
-
-	if(write) {
-		/* FIXME: Clear internal statistics here */
-		return 0;
-	}
-	hostdata = (struct NCR_700_Host_Parameters *)host->hostdata[0];
-	len += sprintf(&buf[len], "Total commands outstanding: %d\n", hostdata->command_slot_count);
-	len += sprintf(&buf[len],"\
-Target	Active  Next Tag\n\
-======	======  ========\n");
-	list_for_each_entry(SDp, &host->my_devices, siblings) {
-		len += sprintf(&buf[len]," %2d:%2d   %4d      %4d\n", SDp->id, SDp->lun, NCR_700_get_depth(SDp), SDp->current_tag);
-	}
-	if((len -= offset) <= 0)
-		return 0;
-	if(len > bytes_available)
-		len = bytes_available;
-	memcpy(proc_buf, buf + offset, len);
-	return len;
 }
 
 STATIC int
diff -Nru a/drivers/scsi/53c700.h b/drivers/scsi/53c700.h
--- a/drivers/scsi/53c700.h	Wed Jun 18 23:42:05 2003
+++ b/drivers/scsi/53c700.h	Wed Jun 18 23:42:05 2003
@@ -12,6 +12,10 @@
 
 #include <asm/io.h>
 
+#if defined(CONFIG_53C700_MEM_MAPPED) && defined(CONFIG_53C700_IO_MAPPED)
+#define CONFIG_53C700_BOTH_MAPPED
+#endif
+
 /* Turn on for general debugging---too verbose for normal use */
 #undef	NCR_700_DEBUG
 /* Debug the tag queues, checking hash queue allocation and deallocation
@@ -178,6 +182,9 @@
 	/* NOTHING BELOW HERE NEEDS ALTERING */
 	__u32	fast:1;		/* if we can alter the SCSI bus clock
                                    speed (so can negiotiate sync) */
+#ifdef CONFIG_53C700_BOTH_MAPPED
+	__u32	mem_mapped;	/* set if memory mapped */
+#endif
 	int	sync_clock;	/* The speed of the SYNC core */
 
 	__u32	*script;		/* pointer to script location */
@@ -428,11 +435,8 @@
 	} \
 }
 
-#endif
-
-#ifdef CONFIG_53C700_MEM_MAPPED
 static inline __u8
-NCR_700_readb(struct Scsi_Host *host, __u32 reg)
+NCR_700_mem_readb(struct Scsi_Host *host, __u32 reg)
 {
 	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
 		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
@@ -441,7 +445,7 @@
 }
 
 static inline __u32
-NCR_700_readl(struct Scsi_Host *host, __u32 reg)
+NCR_700_mem_readl(struct Scsi_Host *host, __u32 reg)
 {
 	__u32 value = __raw_readl(host->base + reg);
 	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
@@ -456,7 +460,7 @@
 }
 
 static inline void
-NCR_700_writeb(__u8 value, struct Scsi_Host *host, __u32 reg)
+NCR_700_mem_writeb(__u8 value, struct Scsi_Host *host, __u32 reg)
 {
 	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
 		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
@@ -465,7 +469,7 @@
 }
 
 static inline void
-NCR_700_writel(__u32 value, struct Scsi_Host *host, __u32 reg)
+NCR_700_mem_writel(__u32 value, struct Scsi_Host *host, __u32 reg)
 {
 	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
 		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
@@ -478,9 +482,9 @@
 
 	__raw_writel(bS_to_host(value), host->base + reg);
 }
-#elif defined(CONFIG_53C700_IO_MAPPED)
+
 static inline __u8
-NCR_700_readb(struct Scsi_Host *host, __u32 reg)
+NCR_700_io_readb(struct Scsi_Host *host, __u32 reg)
 {
 	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
 		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
@@ -489,7 +493,7 @@
 }
 
 static inline __u32
-NCR_700_readl(struct Scsi_Host *host, __u32 reg)
+NCR_700_io_readl(struct Scsi_Host *host, __u32 reg)
 {
 	__u32 value = inl(host->base + reg);
 	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
@@ -505,7 +509,7 @@
 }
 
 static inline void
-NCR_700_writeb(__u8 value, struct Scsi_Host *host, __u32 reg)
+NCR_700_io_writeb(__u8 value, struct Scsi_Host *host, __u32 reg)
 {
 	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
 		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
@@ -514,7 +518,7 @@
 }
 
 static inline void
-NCR_700_writel(__u32 value, struct Scsi_Host *host, __u32 reg)
+NCR_700_io_writel(__u32 value, struct Scsi_Host *host, __u32 reg)
 {
 	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
 		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
@@ -527,4 +531,100 @@
 
 	outl(bS_to_host(value), host->base + reg);
 }
+
+#ifdef CONFIG_53C700_BOTH_MAPPED
+
+static inline __u8
+NCR_700_readb(struct Scsi_Host *host, __u32 reg)
+{
+	__u8 val;
+
+	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+	if(hostdata->mem_mapped)
+		val = NCR_700_mem_readb(host, reg);
+	else
+		val = NCR_700_io_readb(host, reg);
+
+	return val;
+}
+
+static inline __u32
+NCR_700_readl(struct Scsi_Host *host, __u32 reg)
+{
+	__u32 val;
+
+	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+	if(hostdata->mem_mapped)
+		val = NCR_700_mem_readl(host, reg);
+	else
+		val = NCR_700_io_readl(host, reg);
+
+	return val;
+}
+
+static inline void
+NCR_700_writeb(__u8 value, struct Scsi_Host *host, __u32 reg)
+{
+	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+	if(hostdata->mem_mapped)
+		NCR_700_mem_writeb(value, host, reg);
+	else
+		NCR_700_io_writeb(value, host, reg);
+}
+
+static inline void
+NCR_700_writel(__u32 value, struct Scsi_Host *host, __u32 reg)
+{
+	const struct NCR_700_Host_Parameters *hostdata __attribute__((unused))
+		= (struct NCR_700_Host_Parameters *)host->hostdata[0];
+
+	if(hostdata->mem_mapped)
+		NCR_700_mem_writel(value, host, reg);
+	else
+		NCR_700_io_writel(value, host, reg);
+}
+
+static inline void
+NCR_700_set_mem_mapped(struct NCR_700_Host_Parameters *hostdata)
+{
+	hostdata->mem_mapped = 1;
+}
+
+static inline void
+NCR_700_set_io_mapped(struct NCR_700_Host_Parameters *hostdata)
+{
+	hostdata->mem_mapped = 0;
+}
+
+
+#elif defined(CONFIG_53C700_IO_MAPPED)
+
+#define NCR_700_readb NCR_700_io_readb
+#define NCR_700_readl NCR_700_io_readl
+#define NCR_700_writeb NCR_700_io_writeb
+#define NCR_700_writel NCR_700_io_writel
+
+#define NCR_700_set_io_mapped(x)
+#define NCR_700_set_mem_mapped(x)	error I/O mapped only
+
+#elif defined(CONFIG_53C700_MEM_MAPPED)
+
+#define NCR_700_readb NCR_700_mem_readb
+#define NCR_700_readl NCR_700_mem_readl
+#define NCR_700_writeb NCR_700_mem_writeb
+#define NCR_700_writel NCR_700_mem_writel
+
+#define NCR_700_set_io_mapped(x)	error MEM mapped only
+#define NCR_700_set_mem_mapped(x)
+
+#else
+#error neither CONFIG_53C700_MEM_MAPPED nor CONFIG_53C700_IO_MAPPED is set
+#endif
+
 #endif
diff -Nru a/drivers/scsi/AM53C974.c b/drivers/scsi/AM53C974.c
--- a/drivers/scsi/AM53C974.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/AM53C974.c	Wed Jun 18 23:42:07 2003
@@ -817,22 +817,6 @@
 	return (info);
 }
 
-/************************************************************************** 
-* Function : int AM53C974_command (Scsi_Cmnd *SCpnt)                      *
-*                                                                         *
-* Purpose : the unqueued SCSI command function, replaced by the           *
-*           AM53C974_queue_command function                               *
-*                                                                         *
-* Inputs : SCpnt - pointer to command structure                           *
-*                                                                         *
-* Returns :status, see hosts.h for details                                *
-***************************************************************************/
-static int AM53C974_command(Scsi_Cmnd * SCpnt)
-{
-	DEB(printk("AM53C974_command called\n"));
-	return 0;
-}
-
 /**************************************************************************
 * Function : void initialize_SCp(Scsi_Cmnd *cmd)                          *
 *                                                                         *
@@ -2466,7 +2450,6 @@
 	.detect         	= AM53C974_pci_detect,
 	.release        	= AM53C974_release,	
 	.info			= AM53C974_info,
-	.command		= AM53C974_command,
 	.queuecommand		= AM53C974_queue_command,
 	.abort			= AM53C974_abort,
 	.reset			= AM53C974_reset,
diff -Nru a/drivers/scsi/Kconfig b/drivers/scsi/Kconfig
--- a/drivers/scsi/Kconfig	Wed Jun 18 23:42:09 2003
+++ b/drivers/scsi/Kconfig	Wed Jun 18 23:42:09 2003
@@ -27,8 +27,8 @@
 	  If you want to use a SCSI tape drive under Linux, say Y and read the
 	  SCSI-HOWTO, available from
 	  <http://www.tldp.org/docs.html#howto>, and
-	  <file:Documentation/scsi/st.txt> in the kernel source.  This is NOT for
-	  SCSI CD-ROMs.
+	  <file:Documentation/scsi/st.txt> in the kernel source.  This is NOT
+	  for SCSI CD-ROMs.
 
 	  This driver is also available as a module ( = code which can be
 	  inserted in and removed from the running kernel whenever you want).
@@ -131,11 +131,11 @@
 	depends on SCSI
 	default y
 	help
-	  If you want to build with SCSI REPORT LUNS support in the kernel, say Y here.
-	  The REPORT LUNS command is useful for devices (such as disk arrays) with
-	  large numbers of LUNs where the LUN values are not contiguous (sparse LUN).
-	  REPORT LUNS scanning is done only for SCSI-3 devices. Most users can safely
-	  answer N here.
+	  If you want support for SCSI REPORT LUNS, say Y here.
+	  The REPORT LUNS command is useful for devices (such as disk arrays)
+	  with large numbers of LUNs where the LUN values are not contiguous
+	  (sparse LUN).  REPORT LUNS scanning is done only for SCSI-3 devices.
+	  Most users can safely answer N here.
 
 config SCSI_CONSTANTS
 	bool "Verbose SCSI error reporting (kernel size +=12K)"
@@ -207,7 +207,7 @@
 
 config SCSI_7000FASST
 	tristate "7000FASST SCSI support"
-	depends on SCSI && ISA
+	depends on ISA && SCSI
 	help
 	  This driver supports the Western Digital 7000 SCSI host adapter
 	  family.  Some information is in the source:
@@ -220,7 +220,7 @@
 
 config SCSI_ACARD
 	tristate "ACARD SCSI support"
-	depends on SCSI
+	depends on PCI && SCSI
 	help
 	  This driver supports the ACARD 870U/W SCSI host adapter.
 
@@ -285,6 +285,7 @@
 
 config SCSI_AIC7XXX_OLD
 	tristate "Adaptec AIC7xxx support (old driver)"
+	depends on SCSI
 	help
 	  WARNING This driver is an older aic7xxx driver and is no longer
 	  under active development.  Adaptec, Inc. is writing a new driver to
@@ -343,7 +344,7 @@
 
 config SCSI_ADVANSYS
 	tristate "AdvanSys SCSI support"
-	depends on SCSI
+	depends on (ISA || EISA || PCI) && SCSI
 	help
 	  This is a driver for all SCSI host adapters manufactured by
 	  AdvanSys. It is documented in the kernel source in
@@ -357,7 +358,7 @@
 
 config SCSI_IN2000
 	tristate "Always IN2000 SCSI support"
-	depends on SCSI
+	depends on ISA && SCSI
 	help
 	  This is support for an ISA bus SCSI host adapter.  You'll find more
 	  information in <file:Documentation/scsi/in2000.txt>. If it doesn't work
@@ -369,10 +370,10 @@
 	  say M here and read <file:Documentation/modules.txt>.  The module
 	  will be called in2000.
 
-# does not use pci dma and seems to be isa/onboard only for old machines
+# does not use pci dma and seems to be onboard only for old machines
 config SCSI_AM53C974
 	tristate "AM53/79C974 PCI SCSI support"
-	depends on !X86_64 && SCSI && PCI
+	depends on X86 && PCI && SCSI
 	---help---
 	  This is support for the AM53/79C974 SCSI host adapters.  Please read
 	  <file:Documentation/scsi/AM53C974.txt> for details.  Also, the
@@ -390,7 +391,7 @@
 
 config SCSI_MEGARAID
 	tristate "AMI MegaRAID support"
-	depends on SCSI
+	depends on PCI && SCSI
 	help
 	  This driver supports the AMI MegaRAID 418, 428, 438, 466, 762, 490
 	  and 467 SCSI host adapters.
@@ -402,7 +403,7 @@
 
 config SCSI_BUSLOGIC
 	tristate "BusLogic SCSI support"
-	depends on SCSI
+	depends on (PCI || ISA) && SCSI
 	---help---
 	  This is support for BusLogic MultiMaster and FlashPoint SCSI Host
 	  Adapters. Consult the SCSI-HOWTO, available from
@@ -436,7 +437,7 @@
 
 config SCSI_DMX3191D
 	tristate "DMX3191D SCSI support"
-	depends on SCSI && PCI
+	depends on PCI && SCSI
 	help
 	  This is support for Domex DMX3191D SCSI Host Adapters.
 
@@ -447,7 +448,7 @@
 
 config SCSI_DTC3280
 	tristate "DTC3180/3280 SCSI support"
-	depends on SCSI && ISA
+	depends on ISA && SCSI
 	help
 	  This is support for DTC 3180/3280 SCSI Host Adapters.  Please read
 	  the SCSI-HOWTO, available from
@@ -461,7 +462,7 @@
 
 config SCSI_EATA
 	tristate "EATA ISA/EISA/PCI (DPT and generic EATA/DMA-compliant boards) support"
-	depends on SCSI
+	depends on (ISA || EISA || PCI) && SCSI
 	---help---
 	  This driver supports all EATA/DMA-compliant SCSI host adapters.  DPT
 	  ISA and all EISA I/O addresses are probed looking for the "EATA"
@@ -527,7 +528,7 @@
 
 config SCSI_FUTURE_DOMAIN
 	tristate "Future Domain 16xx SCSI/AHA-2920A support"
-	depends on SCSI
+	depends on (ISA || PCI) && SCSI
 	---help---
 	  This is support for Future Domain's 16-bit SCSI host adapters
 	  (TMC-1660/1680, TMC-1650/1670, TMC-3260, TMC-1610M/MER/MEX) and
@@ -563,7 +564,7 @@
 
 config SCSI_GDTH
 	tristate "Intel/ICP (former GDT SCSI Disk Array) RAID Controller support"
-	depends on SCSI
+	depends on (ISA || EISA || PCI) && SCSI
 	---help---
 	  Formerly called GDT SCSI Disk Array Controller Support.
 
@@ -579,7 +580,7 @@
 
 config SCSI_GENERIC_NCR5380
 	tristate "Generic NCR5380/53c400 SCSI PIO support"
-	depends on SCSI
+	depends on ISA && SCSI
 	---help---
 	  This is a driver for the old NCR 53c80 series of SCSI controllers
 	  on boards using PIO. Most boards such as the Trantor T130 fit this
@@ -600,7 +601,7 @@
 
 config SCSI_GENERIC_NCR5380_MMIO
 	tristate "Generic NCR5380/53c400 SCSI MMIO support"
-	depends on SCSI
+	depends on ISA && SCSI
 	---help---
 	  This is a driver for the old NCR 53c80 series of SCSI controllers
 	  on boards using memory mapped I/O. 
@@ -609,10 +610,11 @@
 	  of the box, you may have to change some settings in
 	  <file:drivers/scsi/g_NCR5380.h>.
 
-	  This driver is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called g_NCR5380.  If you want to compile it as
-	  a module, say M here and read <file:Documentation/modules.txt>.
+	  This driver is also available as a module ( = code which can
+	  be inserted in and removed from the running kernel whenever
+	  you want).  The module will be called g_NCR5380_mmio.
+	  If you want to compile it as a module, say M here and read
+	  <file:Documentation/modules.txt>.
 
 config SCSI_GENERIC_NCR53C400
 	bool "Enable NCR53c400 extensions"
@@ -699,7 +701,7 @@
 
 config SCSI_IPS
 	tristate "IBM ServeRAID support"
-	depends on X86 && SCSI && PCI
+	depends on X86 && PCI && SCSI
 	---help---
 	  This is support for the IBM ServeRAID hardware RAID controllers.
 	  See <http://www.developer.ibm.com/welcome/netfinity/serveraid.html>
@@ -715,7 +717,7 @@
 
 config SCSI_INITIO
 	tristate "Initio 9100U(W) support"
-	depends on SCSI && PCI
+	depends on PCI && SCSI
 	help
 	  This is support for the Initio 91XXU(W) SCSI host adapter.  Please
 	  read the SCSI-HOWTO, available from
@@ -728,7 +730,7 @@
 
 config SCSI_INIA100
 	tristate "Initio INI-A100U2W support"
-	depends on SCSI && PCI
+	depends on PCI && SCSI
 	help
 	  This is support for the Initio INI-A100U2W SCSI host adapter.
 	  Please read the SCSI-HOWTO, available from
@@ -828,7 +830,7 @@
 
 config SCSI_NCR53C406A
 	tristate "NCR53c406a SCSI support"
-	depends on SCSI && ISA
+	depends on ISA && SCSI
 	help
 	  This is support for the NCR53c406a SCSI host adapter.  For user
 	  configurable parameters, check out <file:drivers/scsi/NCR53c406a.c>
@@ -857,14 +859,12 @@
 	default y
 
 config SCSI_LASI700
-	tristate "HP LASI SCSI support for 53c700/710"
-	depends on PARISC && SCSI
+	tristate "HP Lasi SCSI support for 53c700/710"
+	depends on GSC && SCSI
 	help
-	  This is a driver for the lasi baseboard in some parisc machines
-	  which is based on the 53c700 chip.  Will also support LASI subsystems
-	  based on the 710 chip using 700 emulation mode.
-
-	  Unless you know you have a 53c700 or 53c710 based lasi, say N here
+	  This is a driver for the SCSI controller in the Lasi chip found in
+	  many PA-RISC workstations & servers.  If you do not know whether you
+	  have a Lasi chip, it is safe to say "Y" here.
 
 config 53C700_MEM_MAPPED
 	bool
@@ -876,72 +876,15 @@
 	depends on SCSI_LASI700
 	default y
 
-config SCSI_NCR53C7xx
-	tristate "NCR53c7,8xx SCSI support"
-	depends on SCSI && PCI
-	---help---
-	  This is a driver for the 53c7 and 8xx NCR family of SCSI
-	  controllers, not to be confused with the NCR 5380 controllers.  It
-	  is explained in section 3.8 of the SCSI-HOWTO, available from
-	  <http://www.tldp.org/docs.html#howto>.  If it doesn't work out
-	  of the box, you may have to change some settings in
-	  <file:drivers/scsi/53c7,8xx.h>.  Please read
-	  <file:Documentation/scsi/ncr53c7xx.txt> for the available boot time
-	  command line options.
-
-	  Note: there is another driver for the 53c8xx family of controllers
-	  ("NCR53C8XX SCSI support" below).  If you want to use them both, you
-	  need to say M to both and build them as modules, but only one may be
-	  active at a time. If you have a 53c8xx board, it's better to use the
-	  other driver.
-
-	  This driver is also available as a module ( = code which can be
-	  inserted in and removed from the running kernel whenever you want).
-	  The module will be called 53c7,8xx.  If you want to compile it as
-	  a module, say M here and read <file:Documentation/modules.txt>.
-
-config SCSI_NCR53C7xx_sync
-	bool "always negotiate synchronous transfers"
-	depends on SCSI_NCR53C7xx
-	help
-	  In general, this is good; however, it is a bit dangerous since there
-	  are some broken SCSI devices out there. Take your chances. Safe bet
-	  is N.
-
-config SCSI_NCR53C7xx_FAST
-	bool "allow FAST-SCSI [10MHz]"
-	depends on SCSI_NCR53C7xx
-	help
-	  This will enable 10MHz FAST-SCSI transfers with your host
-	  adapter. Some systems have problems with that speed, so it's safest
-	  to say N here.
-
-config SCSI_NCR53C7xx_DISCONNECT
-	bool "allow DISCONNECT"
-	depends on SCSI_NCR53C7xx
-	help
-	  This enables the disconnect/reconnect feature of the NCR SCSI
-	  controller. When you say Y here, a slow SCSI device will not lock
-	  the SCSI bus while processing a request, allowing simultaneous use
-	  of e.g. a SCSI hard disk and SCSI tape or CD-ROM drive, and
-	  providing much better performance when using slow and fast SCSI
-	  devices at the same time. Some devices, however, do not operate
-	  properly with this option enabled, and will cause your SCSI system
-	  to hang, which might cause a system crash. The safe answer
-	  therefore is to say N.
-
 config SCSI_SYM53C8XX_2
 	tristate "SYM53C8XX Version 2 SCSI support"
 	depends on PCI && SCSI
 	---help---
-	  This driver supports the whole NCR53C8XX/SYM53C8XX family of 
-	  PCI-SCSI controllers. It also supports the subset of LSI53C10XX 
-	  Ultra-160 controllers that are based on the SYM53C8XX SCRIPTS 
-	  language. It does not support LSI53C10XX Ultra-320 PCI-X SCSI 
-	  controllers.
-
-	  If your system has problems using this new major version of the
-	  SYM53C8XX driver, you may switch back to driver version 1.
+	  This driver supports the whole NCR53C8XX/SYM53C8XX family of
+	  PCI-SCSI controllers.  It also supports the subset of LSI53C10XX
+	  Ultra-160 controllers that are based on the SYM53C8XX SCRIPTS
+	  language.  It does not support LSI53C10XX Ultra-320 PCI-X SCSI
+	  controllers; you need to use the Fusion MPT driver for that.
 
 	  Please read <file:drivers/scsi/sym53c8xx_2/Documentation.txt> for more
 	  information.
@@ -1216,7 +1159,7 @@
 
 config SCSI_PAS16
 	tristate "PAS16 SCSI support"
-	depends on SCSI && ISA
+	depends on ISA && SCSI
 	---help---
 	  This is support for a SCSI host adapter.  It is explained in section
 	  3.10 of the SCSI-HOWTO, available from
@@ -1231,7 +1174,7 @@
 
 config SCSI_PCI2000
 	tristate "PCI2000 support"
-	depends on SCSI
+	depends on PCI && SCSI
 	help
 	  This is support for the PCI2000I EIDE interface card which acts as a
 	  SCSI host adapter.  Please read the SCSI-HOWTO, available from
@@ -1244,7 +1187,7 @@
 
 config SCSI_PCI2220I
 	tristate "PCI2220i support"
-	depends on SCSI
+	depends on PCI && SCSI
 	help
 	  This is support for the PCI2220i EIDE interface card which acts as a
 	  SCSI host adapter.  Please read the SCSI-HOWTO, available from
@@ -1257,7 +1200,7 @@
 
 config SCSI_PSI240I
 	tristate "PSI240i support"
-	depends on SCSI && ISA
+	depends on ISA && SCSI
 	help
 	  This is support for the PSI240i EIDE interface card which acts as a
 	  SCSI host adapter.  Please read the SCSI-HOWTO, available from
@@ -1270,7 +1213,7 @@
 
 config SCSI_QLOGIC_FAS
 	tristate "Qlogic FAS SCSI support"
-	depends on SCSI && ISA
+	depends on ISA && SCSI
 	---help---
 	  This is a driver for the ISA, VLB, and PCMCIA versions of the Qlogic
 	  FastSCSI! cards as well as any other card based on the FASXX chip
@@ -1340,6 +1283,20 @@
 	  The module will be called qla1280. If you want to compile it as
 	  a module, say M here and read <file:Documentation/modules.txt>.
 
+config SCSI_QLOGICPTI
+	tristate "PTI Qlogic, ISP Driver"
+	depends on SBUS && SCSI
+	help
+	  This driver supports SBUS SCSI controllers from PTI or QLogic. These
+	  controllers are known under Solaris as qpti and in the openprom as
+	  PTI,ptisp or QLGC,isp. Note that PCI QLogic SCSI controllers are
+	  driven by a different driver.
+
+	  This support is also available as a module called qlogicpti ( =
+	  code which can be inserted in and removed from the running kernel
+	  whenever you want). If you want to compile it as a module, say M
+	  here and read <file:Documentation/modules.txt>.
+
 config SCSI_SEAGATE
 	tristate "Seagate ST-02 and Future Domain TMC-8xx SCSI support"
 	depends on X86 && ISA && SCSI
@@ -1355,10 +1312,10 @@
 	  The module will be called seagate.  If you want to compile it as a
 	  module, say M here and read <file:Documentation/modules.txt>.
 
-# definitely looks note 64bit safe:
+# definitely looks not 64bit safe:
 config SCSI_SIM710
 	tristate "Simple 53c710 SCSI support (Compaq, NCR machines)"
-	depends on (EISA || MCA && !X86_64) && SCSI
+	depends on (EISA || MCA) && SCSI
 	---help---
 	  This driver for NCR53c710 based SCSI host adapters.
 
@@ -1371,7 +1328,7 @@
 
 config SCSI_SYM53C416
 	tristate "Symbios 53c416 SCSI support"
-	depends on SCSI && ISA
+	depends on ISA && SCSI
 	---help---
 	  This is support for the sym53c416 SCSI host adapter, the SCSI
 	  adapter that comes with some HP scanners. This driver requires that
@@ -1392,7 +1349,7 @@
 
 config SCSI_DC395x
 	tristate "Tekram DC395(U/UW/F) and DC315(U) SCSI support (EXPERIMENTAL)"
-	depends on EXPERIMENTAL && PCI && SCSI
+	depends on PCI && SCSI && EXPERIMENTAL
 	---help---
 	  This driver supports PCI SCSI host adapters based on the ASIC
 	  TRM-S1040 chip, e.g Tekram DC395(U/UW/F) and DC315(U) variants.
@@ -1446,7 +1403,7 @@
 
 config SCSI_T128
 	tristate "Trantor T128/T128F/T228 SCSI support"
-	depends on SCSI && ISA
+	depends on ISA && SCSI
 	---help---
 	  This is support for a SCSI host adapter. It is explained in section
 	  3.11 of the SCSI-HOWTO, available from
@@ -1463,7 +1420,7 @@
 
 config SCSI_U14_34F
 	tristate "UltraStor 14F/34F support"
-	depends on SCSI
+	depends on ISA && SCSI
 	---help---
 	  This is support for the UltraStor 14F and 34F SCSI-2 host adapters.
 	  The source at <file:drivers/scsi/u14-34f.c> contains some
@@ -1533,7 +1490,7 @@
 
 config SCSI_NSP32
 	tristate "Workbit NinjaSCSI-32Bi/UDE support"
-	depends on SCSI
+	depends on PCI && SCSI
 	help
 	  This is support for the Workbit NinjaSCSI-32Bi/UDE PCI/Cardbus
 	  SCSI host adapter. Please read the SCSI-HOWTO, available from
@@ -1606,7 +1563,7 @@
 
 config JAZZ_ESP
 	bool "MIPS JAZZ FAS216 SCSI support"
-	depends on MIPS_JAZZ
+	depends on MIPS_JAZZ && SCSI
 	help
 	  This is the driver for the onboard SCSI host adapter of MIPS Magnum
 	  4000, Acer PICA, Olivetti M700-10 and a few other identical OEM
@@ -1625,7 +1582,7 @@
 
 config A4000T_SCSI
 	bool "A4000T SCSI support (EXPERIMENTAL)"
-	depends on AMIGA && EXPERIMENTAL
+	depends on AMIGA && SCSI && EXPERIMENTAL
 	help
 	  Support for the NCR53C710 SCSI controller on the Amiga 4000T.
 
@@ -1695,7 +1652,7 @@
 
 config A4091_SCSI
 	bool "A4091 SCSI support (EXPERIMENTAL)"
-	depends on ZORRO && EXPERIMENTAL
+	depends on ZORRO && SCSI && EXPERIMENTAL
 	help
 	  Support for the NCR53C710 chip on the Amiga 4091 Z3 SCSI2 controller
 	  (1993).  Very obscure -- the 4091 was part of an Amiga 4000 upgrade
@@ -1703,7 +1660,7 @@
 
 config WARPENGINE_SCSI
 	bool "WarpEngine SCSI support (EXPERIMENTAL)"
-	depends on ZORRO && EXPERIMENTAL
+	depends on ZORRO && SCSI && EXPERIMENTAL
 	help
 	  Support for MacroSystem Development's WarpEngine Amiga SCSI-2
 	  controller. Info at
@@ -1711,19 +1668,142 @@
 
 config BLZ603EPLUS_SCSI
 	bool "Blizzard PowerUP 603e+ SCSI (EXPERIMENTAL)"
-	depends on ZORRO && EXPERIMENTAL
+	depends on ZORRO && SCSI && EXPERIMENTAL
 	help
 	  If you have an Amiga 1200 with a Phase5 Blizzard PowerUP 603e+
 	  accelerator, say Y. Otherwise, say N.
 
 config OKTAGON_SCSI
 	tristate "BSC Oktagon SCSI support (EXPERIMENTAL)"
-	depends on ZORRO && EXPERIMENTAL && SCSI
+	depends on ZORRO && SCSI && EXPERIMENTAL
 	help
 	  If you have the BSC Oktagon SCSI disk controller for the Amiga, say
 	  Y to this question.  If you're in doubt about whether you have one,
 	  see the picture at
 	  <http://amiga.multigraph.com/photos/oktagon.html>.
+
+config ATARI_SCSI
+	tristate "Atari native SCSI support"
+	depends on ATARI && SCSI
+	---help---
+	  If you have an Atari with built-in NCR5380 SCSI controller (TT,
+	  Falcon, ...) say Y to get it supported. Of course also, if you have
+	  a compatible SCSI controller (e.g. for Medusa).  This driver is also
+	  available as a module ( = code which can be inserted in and removed
+	  from the running kernel whenever you want).  The module is called
+	  atari_scsi.  If you want to compile it as a module, say M here and
+	  read <file:Documentation/modules.txt>.  This driver supports both
+	  styles of NCR integration into the system: the TT style (separate
+	  DMA), and the Falcon style (via ST-DMA, replacing ACSI).  It does
+	  NOT support other schemes, like in the Hades (without DMA).
+
+config ATARI_SCSI_TOSHIBA_DELAY
+	bool "Long delays for Toshiba CD-ROMs"
+	depends on ATARI_SCSI
+	help
+	  This option increases the delay after a SCSI arbitration to
+	  accommodate some flaky Toshiba CD-ROM drives. Say Y if you intend to
+	  use a Toshiba CD-ROM drive; otherwise, the option is not needed and
+	  would impact performance a bit, so say N.
+
+config ATARI_SCSI_RESET_BOOT
+	bool "Reset SCSI-devices at boottime"
+	depends on ATARI_SCSI
+	help
+	  Reset the devices on your Atari whenever it boots.  This makes the
+	  boot process fractionally longer but may assist recovery from errors
+	  that leave the devices with SCSI operations partway completed.
+
+config TT_DMA_EMUL
+	bool "Hades SCSI DMA emulator"
+	depends on ATARI_SCSI && HADES
+	help
+	  This option enables code which emulates the TT SCSI DMA chip on the
+	  Hades. This increases the SCSI transfer rates at least ten times
+	  compared to PIO transfers.
+
+config MAC_SCSI
+	bool "Macintosh NCR5380 SCSI"
+	depends on MAC && SCSI
+	help
+	  This is the NCR 5380 SCSI controller included on most of the 68030
+	  based Macintoshes.  If you have one of these say Y and read the
+	  SCSI-HOWTO, available from
+	  <http://www.tldp.org/docs.html#howto>.
+
+config SCSI_MAC_ESP
+	tristate "Macintosh NCR53c9[46] SCSI"
+	depends on MAC && SCSI
+	help
+	  This is the NCR 53c9x SCSI controller found on most of the 68040
+	  based Macintoshes.  If you have one of these say Y and read the
+	  SCSI-HOWTO, available from
+	  <http://www.tldp.org/docs.html#howto>.
+
+	  This driver is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  The module will be called mac_esp.  If you want to compile it as
+	  a module, say M here and read <file:Documentation/modules.txt>.
+
+config MVME147_SCSI
+	bool "WD33C93 SCSI driver for MVME147"
+	depends on MVME147 && SCSI
+	help
+	  Support for the on-board SCSI controller on the Motorola MVME147
+	  single-board computer.
+
+config MVME16x_SCSI
+	bool "NCR53C710 SCSI driver for MVME16x"
+	depends on MVME16x && SCSI
+	help
+	  The Motorola MVME162, 166, 167, 172 and 177 boards use the NCR53C710
+	  SCSI controller chip.  Almost everyone using one of these boards
+	  will want to say Y to this question.
+
+config BVME6000_SCSI
+	bool "NCR53C710 SCSI driver for BVME6000"
+	depends on BVME6000 && SCSI
+	help
+	  The BVME4000 and BVME6000 boards from BVM Ltd use the NCR53C710
+	  SCSI controller chip.  Almost everyone using one of these boards
+	  will want to say Y to this question.
+
+config SCSI_NCR53C7xx_FAST
+	bool "allow FAST-SCSI [10MHz]"
+	depends on A4000T_SCSI || A4091_SCSI || BLZ603EPLUS_SCSI || WARPENGINE_SCSI || MVME16x_SCSI || BVME6000_SCSI
+	help
+	  This will enable 10MHz FAST-SCSI transfers with your host
+	  adapter. Some systems have problems with that speed, so it's safest
+	  to say N here.
+
+config SUN3_SCSI
+	tristate "Sun3 NCR5380 SCSI"
+	depends on SUN3 && SCSI
+	help
+	  This option will enable support for the OBIO (onboard io) NCR5380
+	  SCSI controller found in the Sun 3/50 and 3/60, as well as for
+	  "Sun3" type VME scsi controllers also based on the NCR5380.
+	  General Linux information on the Sun 3 series (now discontinued)
+	  is at <http://www.angelfire.com/ca2/tech68k/sun3.html>.
+
+config SUN3X_ESP
+	bool "Sun3x ESP SCSI"
+	depends on SUN3X && SCSI
+	help
+	  The ESP was an on-board SCSI controller used on Sun 3/80
+	  machines.  Say Y here to compile in support for it.
+
+config SCSI_SUNESP
+	tristate "Sparc ESP Scsi Driver"
+	depends on SBUS && SCSI
+	help
+	  This is the driver for the Sun ESP SCSI host adapter. The ESP
+	  chipset is present in most SPARC SBUS-based computers.
+
+	  This support is also available as a module called esp ( = code
+	  which can be inserted in and removed from the running kernel
+	  whenever you want). If you want to compile it as a module, say M
+	  here and read <file:Documentation/modules.txt>.
 
 config SCSI_PC980155
 	tristate "NEC PC-9801-55 SCSI support"
diff -Nru a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
--- a/drivers/scsi/NCR53c406a.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/NCR53c406a.c	Wed Jun 18 23:42:07 2003
@@ -170,7 +170,6 @@
 /* Static function prototypes */
 static void NCR53c406a_intr(int, void *, struct pt_regs *);
 static irqreturn_t do_NCR53c406a_intr(int, void *, struct pt_regs *);
-static void internal_done(Scsi_Cmnd *);
 static void wait_intr(void);
 static void chip_init(void);
 static void calc_port_addr(void);
@@ -205,8 +204,6 @@
 #endif
 
 static Scsi_Cmnd *current_SC;
-static volatile int internal_done_flag;
-static volatile int internal_done_errcode;
 static char info_msg[256];
 
 /* ================================================================= */
@@ -544,10 +541,13 @@
 	} else if (irq_level == 0) {
 		tpnt->can_queue = 0;
 		DEB(printk("NCR53c406a: No interrupts detected\n"));
+		printk("NCR53c406a driver no longer supports polling interface\n");
+		printk("Please email linux-scsi@vger.kernel.org\n");
+                        
 #if USE_DMA
 		printk("NCR53c406a: No interrupts found and DMA mode defined. Giving up.\n");
-		goto err_free_scsi;
 #endif				/* USE_DMA */
+		goto err_free_scsi;
 	} else {
 		DEB(printk("NCR53c406a: Shouldn't get here!\n"));
 		goto err_free_scsi;
@@ -590,6 +590,21 @@
 	return 0;
 }
 
+static int NCR53c406a_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+#ifdef USE_DMA
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+#endif
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+
+	scsi_unregister(shost);
+	return 0;
+}
+
 /* called from init/main.c */
 static void __init NCR53c406a_setup(char *str, int *ints)
 {
@@ -649,13 +664,6 @@
 	return (info_msg);
 }
 
-static void internal_done(Scsi_Cmnd * SCpnt)
-{
-	internal_done_errcode = SCpnt->result;
-	++internal_done_flag;
-}
-
-
 static void wait_intr(void)
 {
 	unsigned long i = jiffies + WATCHDOG;
@@ -709,21 +717,6 @@
 	return 0;
 }
 
-static int NCR53c406a_command(Scsi_Cmnd * SCpnt)
-{
-	DEB(printk("NCR53c406a_command called\n"));
-	NCR53c406a_queue(SCpnt, internal_done);
-	if (irq_level)
-		while (!internal_done_flag)
-			cpu_relax();
-	else			/* interrupts not supported */
-		while (!internal_done_flag)
-			wait_intr();
-
-	internal_done_flag = 0;
-	return internal_done_errcode;
-}
-
 static int NCR53c406a_abort(Scsi_Cmnd * SCpnt)
 {
 	DEB(printk("NCR53c406a_abort called\n"));
@@ -1074,8 +1067,8 @@
      .proc_name         	= "NCR53c406a"		/* proc_name */,        
      .name              	= "NCR53c406a"		/* name */,             
      .detect            	= NCR53c406a_detect	/* detect */,           
+     .release            	= NCR53c406a_release,
      .info              	= NCR53c406a_info		/* info */,             
-     .command           	= NCR53c406a_command	/* command */,          
      .queuecommand      	= NCR53c406a_queue	/* queuecommand */,     
      .eh_abort_handler  	= NCR53c406a_abort	/* abort */,            
      .eh_bus_reset_handler      = NCR53c406a_bus_reset	/* reset */,            
diff -Nru a/drivers/scsi/NCR_D700.c b/drivers/scsi/NCR_D700.c
--- a/drivers/scsi/NCR_D700.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/NCR_D700.c	Wed Jun 18 23:42:06 2003
@@ -197,6 +197,8 @@
 	hostdata->differential = (((1<<siop) & differential) != 0);
 	hostdata->clock = NCR_D700_CLOCK_MHZ;
 
+	NCR_700_set_io_mapped(hostdata);
+
 	/* and register the siop */
 	host = NCR_700_detect(&NCR_D700_driver_template, hostdata);
 	if (!host) {
@@ -223,7 +225,7 @@
 	return 0;
 
  irq_failed:
-	scsi_unregister(host);
+	scsi_host_put(host);
 	NCR_700_release(host);
  detect_failed:
 	release_region(host->base, 64);
diff -Nru a/drivers/scsi/aha152x.c b/drivers/scsi/aha152x.c
--- a/drivers/scsi/aha152x.c	Wed Jun 18 23:42:05 2003
+++ b/drivers/scsi/aha152x.c	Wed Jun 18 23:42:05 2003
@@ -1515,16 +1515,6 @@
 		up(SCSEM(SCpnt));
 }
 
-static int aha152x_command(Scsi_Cmnd * SCpnt)
-{
-	DECLARE_MUTEX_LOCKED(sem);
-
-	aha152x_internal_queue(SCpnt, &sem, 0, 0, internal_done);
-	down(&sem);
-
-	return SUCCESS;
-}
-
 /*
  *  Abort a command
  *
@@ -3876,7 +3866,6 @@
 	.proc_name		= "aha152x",
 	.proc_info		= aha152x_proc_info,
 	.detect			= aha152x_detect,
-	.command		= aha152x_command,
 	.queuecommand		= aha152x_queue,
 	.eh_abort_handler	= aha152x_abort,
 	.eh_device_reset_handler = aha152x_device_reset,
diff -Nru a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
--- a/drivers/scsi/aha1542.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/aha1542.c	Wed Jun 18 23:42:07 2003
@@ -774,23 +774,6 @@
 	return 0;
 }
 
-static void internal_done(Scsi_Cmnd * SCpnt)
-{
-	SCpnt->SCp.Status++;
-}
-
-static int aha1542_command(Scsi_Cmnd * SCpnt)
-{
-	DEB(printk("aha1542_command: ..calling aha1542_queuecommand\n"));
-
-	aha1542_queuecommand(SCpnt, internal_done);
-
-	SCpnt->SCp.Status = 0;
-	while (!SCpnt->SCp.Status)
-		barrier();
-	return SCpnt->result;
-}
-
 /* Initialize mailboxes */
 static void setup_mailboxes(int bse, struct Scsi_Host *shpnt)
 {
@@ -1325,6 +1308,18 @@
 	return count;
 }
 
+static int aha1542_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static int aha1542_restart(struct Scsi_Host *shost)
 {
 	int i;
@@ -1817,7 +1812,7 @@
 	.proc_name		= "aha1542",
 	.name			= "Adaptec 1542",
 	.detect			= aha1542_detect,
-	.command		= aha1542_command,
+	.release		= aha1542_release,
 	.queuecommand		= aha1542_queuecommand,
 	.eh_abort_handler	= aha1542_abort,
 	.eh_device_reset_handler= aha1542_dev_reset,
diff -Nru a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c
--- a/drivers/scsi/aha1740.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/aha1740.c	Wed Jun 18 23:42:06 2003
@@ -102,6 +102,7 @@
     if (len > length)
 	len = length;
     return len;
+}
 
 
 static int aha1740_makecode(unchar *sense, unchar *status)
@@ -476,23 +477,6 @@
     return 0;
 }
 
-static void internal_done(Scsi_Cmnd * SCpnt)
-{
-    SCpnt->SCp.Status++;
-}
-
-static int aha1740_command(Scsi_Cmnd * SCpnt)
-{
-    aha1740_queuecommand(SCpnt, internal_done);
-    SCpnt->SCp.Status = 0;
-    while (!SCpnt->SCp.Status)
-    {
-	cpu_relax();
-	barrier();
-    }
-    return SCpnt->result;
-}
-
 /* Query the board for its irq_level.  Nothing else matters
    in enhanced mode on an EISA bus. */
 
@@ -567,6 +551,16 @@
     return count;
 }
 
+static int aha1740_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static int aha1740_biosparam(struct scsi_device *sdev, struct block_device *dev,
 		sector_t capacity, int* ip)
 {
@@ -596,7 +590,7 @@
 	.proc_info		= aha1740_proc_info,
 	.name			= "Adaptec 174x (EISA)",
 	.detect			= aha1740_detect,
-	.command		= aha1740_command,
+	.release		= aha1740_release,
 	.queuecommand		= aha1740_queuecommand,
 	.bios_param		= aha1740_biosparam,
 	.can_queue		= AHA1740_ECBS,
diff -Nru a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c	Wed Jun 18 23:42:07 2003
@@ -2098,7 +2098,7 @@
 	u_long	target;
 
 	template->name = ahd->description;
-	host = scsi_register(template, sizeof(struct ahd_softc *));
+	host = scsi_host_alloc(template, sizeof(struct ahd_softc *));
 	if (host == NULL)
 		return (ENOMEM);
 
@@ -2308,7 +2308,7 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 			scsi_remove_host(ahd->platform_data->host);
 #endif
-			scsi_unregister(ahd->platform_data->host);
+			scsi_host_put(ahd->platform_data->host);
 		}
 
 		/* destroy all of the device and target objects */
diff -Nru a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c	Wed Jun 18 23:42:06 2003
@@ -1725,7 +1725,7 @@
 	u_int	 targ_offset;
 
 	template->name = ahc->description;
-	host = scsi_register(template, sizeof(struct ahc_softc *));
+	host = scsi_host_alloc(template, sizeof(struct ahc_softc *));
 	if (host == NULL)
 		return (ENOMEM);
 
@@ -1978,7 +1978,7 @@
 #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,5,0)
 			scsi_remove_host(ahc->platform_data->host);
 #endif
-			scsi_unregister(ahc->platform_data->host);
+			scsi_host_put(ahc->platform_data->host);
 		}
 
 		/* destroy all of the device and target objects */
diff -Nru a/drivers/scsi/amiga7xx.c b/drivers/scsi/amiga7xx.c
--- a/drivers/scsi/amiga7xx.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/amiga7xx.c	Wed Jun 18 23:42:06 2003
@@ -134,9 +134,22 @@
     return num;
 }
 
+static int amiga7xx_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static Scsi_Host_Template driver_template = {
 	.name			= "Amiga NCR53c710 SCSI",
 	.detect			= amiga7xx_detect,
+	.release		= amiga7xx_release,
 	.queuecommand		= NCR53c7xx_queue_command,
 	.abort			= NCR53c7xx_abort,
 	.reset			= NCR53c7xx_reset,
diff -Nru a/drivers/scsi/arm/acornscsi.c b/drivers/scsi/arm/acornscsi.c
--- a/drivers/scsi/arm/acornscsi.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/arm/acornscsi.c	Wed Jun 18 23:42:07 2003
@@ -2993,7 +2993,7 @@
 	AS_Host *ashost;
 	int ret = -ENOMEM;
 
-	host = scsi_register(&acornscsi_template, sizeof(AS_Host));
+	host = scsi_host_alloc(&acornscsi_template, sizeof(AS_Host));
 	if (!host)
 		goto out;
 
@@ -3060,7 +3060,7 @@
  err_2:
 	release_region(host->io_port + 0x800, 2);
  err_1:
-	scsi_unregister(host);
+	scsi_host_put(host);
  out:
 	return ret;
 }
@@ -3089,6 +3089,7 @@
 	msgqueue_free(&ashost->scsi.msgs);
 	queue_free(&ashost->queues.disconnected);
 	queue_free(&ashost->queues.issue);
+	scsi_host_put(host);
 }
 
 static const struct ecard_id acornscsi_cids[] = {
diff -Nru a/drivers/scsi/arm/arxescsi.c b/drivers/scsi/arm/arxescsi.c
--- a/drivers/scsi/arm/arxescsi.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/arm/arxescsi.c	Wed Jun 18 23:42:07 2003
@@ -264,7 +264,6 @@
 	.proc_info			= arxescsi_proc_info,
 	.name				= "ARXE SCSI card",
 	.info				= arxescsi_info,
-	.command			= fas216_command,
 	.queuecommand			= fas216_queue_command,
 	.eh_host_reset_handler		= fas216_eh_host_reset,
 	.eh_bus_reset_handler		= fas216_eh_bus_reset,
diff -Nru a/drivers/scsi/arm/cumana_1.c b/drivers/scsi/arm/cumana_1.c
--- a/drivers/scsi/arm/cumana_1.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/arm/cumana_1.c	Wed Jun 18 23:42:06 2003
@@ -262,7 +262,7 @@
 	struct Scsi_Host *host;
 	int ret = -ENOMEM;
 
-	host = scsi_register(&cumanascsi_template, sizeof(struct NCR5380_hostdata));
+	host = scsi_host_alloc(&cumanascsi_template, sizeof(struct NCR5380_hostdata));
 	if (!host)
 		goto out;
 
@@ -304,7 +304,7 @@
  out_release:
 	release_region(host->io_port, host->n_io_port);
  out_free:
-	scsi_unregister(host);
+	scsi_host_put(host);
  out:
 	return ret;
 }
@@ -318,7 +318,7 @@
 	scsi_remove_host(host);
 	free_irq(host->irq, host);
 	release_region(host->io_port, host->n_io_port);
-	scsi_unregister(host);
+	scsi_host_put(host);
 }
 
 static const struct ecard_id cumanascsi1_cids[] = {
diff -Nru a/drivers/scsi/arm/cumana_2.c b/drivers/scsi/arm/cumana_2.c
--- a/drivers/scsi/arm/cumana_2.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/arm/cumana_2.c	Wed Jun 18 23:42:08 2003
@@ -386,7 +386,6 @@
 	.proc_info			= cumanascsi_2_proc_info,
 	.name				= "Cumana SCSI II",
 	.info				= cumanascsi_2_info,
-	.command			= fas216_command,
 	.queuecommand			= fas216_queue_command,
 	.eh_host_reset_handler		= fas216_eh_host_reset,
 	.eh_bus_reset_handler		= fas216_eh_bus_reset,
diff -Nru a/drivers/scsi/arm/ecoscsi.c b/drivers/scsi/arm/ecoscsi.c
--- a/drivers/scsi/arm/ecoscsi.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/scsi/arm/ecoscsi.c	Wed Jun 18 23:42:09 2003
@@ -177,7 +177,7 @@
 static int __init ecoscsi_init(void)
 {
 
-	host = scsi_register(tpnt, sizeof(struct NCR5380_hostdata));
+	host = scsi_host_alloc(tpnt, sizeof(struct NCR5380_hostdata));
 	if (!host)
 		return 0;
 
@@ -211,7 +211,7 @@
 release_reg:
 	release_region(host->io_port, host->n_io_port);
 unregister_scsi:
-	scsi_unregister(host);
+	scsi_host_put(host);
 	return -ENODEV;
 }
 
@@ -224,7 +224,7 @@
 	if (shpnt->io_port)
 		release_region(shpnt->io_port, shpnt->n_io_port);
 
-	scsi_unregister(host);
+	scsi_host_put(host);
 	return 0;
 }
 
diff -Nru a/drivers/scsi/arm/eesox.c b/drivers/scsi/arm/eesox.c
--- a/drivers/scsi/arm/eesox.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/scsi/arm/eesox.c	Wed Jun 18 23:42:09 2003
@@ -492,7 +492,6 @@
 	.proc_info			= eesoxscsi_proc_info,
 	.name				= "EESOX SCSI",
 	.info				= eesoxscsi_info,
-	.command			= fas216_command,
 	.queuecommand			= fas216_queue_command,
 	.eh_host_reset_handler		= fas216_eh_host_reset,
 	.eh_bus_reset_handler		= fas216_eh_bus_reset,
diff -Nru a/drivers/scsi/arm/fas216.c b/drivers/scsi/arm/fas216.c
--- a/drivers/scsi/arm/fas216.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/arm/fas216.c	Wed Jun 18 23:42:07 2003
@@ -225,8 +225,7 @@
 	printk("    dma={ transfer_type=%X setup=%p pseudo=%p stop=%p }\n",
 		info->dma.transfer_type, info->dma.setup,
 		info->dma.pseudo, info->dma.stop);
-	printk("    internal_done=%X magic_end=%lX }\n",
-		info->internal_done, info->magic_end);
+	printk("    magic_end=%lX }\n", info->magic_end);
 }
 
 #ifdef CHECK_STRUCTURE
@@ -2253,74 +2252,6 @@
 	return result;
 }
 
-/**
- * fas216_internal_done - trigger restart of a waiting thread in fas216_command
- * @SCpnt: Command to wake
- *
- * Trigger restart of a waiting thread in fas216_command
- */
-static void fas216_internal_done(Scsi_Cmnd *SCpnt)
-{
-	FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
-
-	fas216_checkmagic(info);
-
-	info->internal_done = 1;
-}
-
-/**
- * fas216_command - queue a command for adapter to process.
- * @SCpnt: Command to queue
- *
- * Queue a command for adapter to process.
- * Returns: scsi result code.
- * Notes: io_request_lock is held, interrupts are disabled.
- */
-int fas216_command(Scsi_Cmnd *SCpnt)
-{
-	FAS216_Info *info = (FAS216_Info *)SCpnt->device->host->hostdata;
-
-	fas216_checkmagic(info);
-
-	/*
-	 * We should only be using this if we don't have an interrupt.
-	 * Provide some "incentive" to use the queueing code.
-	 */
-	if (info->scsi.irq != NO_IRQ)
-		BUG();
-
-	info->internal_done = 0;
-	fas216_queue_command(SCpnt, fas216_internal_done);
-
-	/*
-	 * This wastes time, since we can't return until the command is
-	 * complete. We can't sleep either since we may get re-entered!
-	 * However, we must re-enable interrupts, or else we'll be
-	 * waiting forever.
-	 */
-	spin_unlock_irq(info->host->host_lock);
-
-	while (!info->internal_done) {
-		/*
-		 * If we don't have an IRQ, then we must poll the card for
-		 * it's interrupt, and use that to call this driver's
-		 * interrupt routine.  That way, we keep the command
-		 * progressing.  Maybe we can add some inteligence here
-		 * and go to sleep if we know that the device is going
-		 * to be some time (eg, disconnected).
-		 */
-		if (fas216_readb(info, REG_STAT) & STAT_INT) {
-			spin_lock_irq(info->host->host_lock);
-			fas216_intr(info);
-			spin_unlock_irq(info->host->host_lock);
-		}
-	}
-
-	spin_lock_irq(info->host->host_lock);
-
-	return SCpnt->result;
-}
-
 /*
  * Error handler timeout function.  Indicate that we timed out,
  * and wake up any error handler process so it can continue.
@@ -2942,6 +2873,7 @@
 	scsi_remove_host(host);
 
 	fas216_writeb(info, REG_CMD, CMD_RESETCHIP);
+	scsi_host_put(host);
 }
 
 /**
diff -Nru a/drivers/scsi/arm/fas216.h b/drivers/scsi/arm/fas216.h
--- a/drivers/scsi/arm/fas216.h	Wed Jun 18 23:42:09 2003
+++ b/drivers/scsi/arm/fas216.h	Wed Jun 18 23:42:09 2003
@@ -310,8 +310,6 @@
 	} dma;
 
 	/* miscellaneous */
-	int			internal_done;		/* flag to indicate request done */
-
 	unsigned long		magic_end;
 } FAS216_Info;
 
@@ -336,13 +334,6 @@
  * Returns : 0 - success, else error
  */
 extern int fas216_queue_command (Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-
-/* Function: int fas216_command (Scsi_Cmnd *SCpnt)
- * Purpose : queue a command for adapter to process.
- * Params  : SCpnt - Command to queue
- * Returns : scsi result code
- */
-extern int fas216_command (Scsi_Cmnd *);
 
 /* Function: irqreturn_t fas216_intr (FAS216_Info *info)
  * Purpose : handle interrupts from the interface to progress a command
diff -Nru a/drivers/scsi/arm/oak.c b/drivers/scsi/arm/oak.c
--- a/drivers/scsi/arm/oak.c	Wed Jun 18 23:42:05 2003
+++ b/drivers/scsi/arm/oak.c	Wed Jun 18 23:42:05 2003
@@ -135,7 +135,7 @@
 	struct Scsi_Host *host;
 	int ret = -ENOMEM;
 
-	host = scsi_register(&oakscsi_template, sizeof(struct NCR5380_hostdata));
+	host = scsi_host_alloc(&oakscsi_template, sizeof(struct NCR5380_hostdata));
 	if (!host)
 		goto out;
 
@@ -163,7 +163,7 @@
 
 	release_region(host->io_port, host->n_io_port);
  unreg:
-	scsi_unregister(host);
+	scsi_host_put(host);
  out:
 	return ret;
 }
@@ -176,7 +176,7 @@
 	scsi_remove_host(host);
 
 	release_region(host->io_port, host->n_io_port);
-	scsi_unregister(host);
+	scsi_host_put(host);
 }
 
 static const struct ecard_id oakscsi_cids[] = {
diff -Nru a/drivers/scsi/arm/powertec.c b/drivers/scsi/arm/powertec.c
--- a/drivers/scsi/arm/powertec.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/arm/powertec.c	Wed Jun 18 23:42:08 2003
@@ -296,7 +296,6 @@
 	.proc_info			= powertecscsi_proc_info,
 	.name				= "PowerTec SCSI",
 	.info				= powertecscsi_info,
-	.command			= fas216_command,
 	.queuecommand			= fas216_queue_command,
 	.eh_host_reset_handler		= fas216_eh_host_reset,
 	.eh_bus_reset_handler		= fas216_eh_bus_reset,
diff -Nru a/drivers/scsi/atp870u.c b/drivers/scsi/atp870u.c
--- a/drivers/scsi/atp870u.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/atp870u.c	Wed Jun 18 23:42:07 2003
@@ -829,25 +829,6 @@
 
 }
 
-static void internal_done(Scsi_Cmnd * SCpnt)
-{
-	SCpnt->SCp.Status++;
-}
-
-static int atp870u_command(Scsi_Cmnd * SCpnt)
-{
-
-	atp870u_queuecommand(SCpnt, internal_done);
-
-	SCpnt->SCp.Status = 0;
-	while (!SCpnt->SCp.Status)
-	{
-		cpu_relax();
-		barrier();
-	}
-	return SCpnt->result;
-}
-
 static unsigned char fun_scam(struct atp_unit *dev, unsigned short int *val)
 {
 	unsigned int tmport;
@@ -2728,7 +2709,6 @@
 	.detect			= atp870u_detect,
 	.release		= atp870u_release,
 	.info			= atp870u_info,
-	.command		= atp870u_command,
 	.queuecommand		= atp870u_queuecommand,
 	.eh_abort_handler	= atp870u_abort,
 	.bios_param		= atp870u_biosparam,
diff -Nru a/drivers/scsi/atp870u.h b/drivers/scsi/atp870u.h
--- a/drivers/scsi/atp870u.h	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/atp870u.h	Wed Jun 18 23:42:06 2003
@@ -18,7 +18,6 @@
 #define MAX_SENSE 14
 
 static int atp870u_detect(Scsi_Host_Template *);
-static int atp870u_command(Scsi_Cmnd *);
 static int atp870u_queuecommand(Scsi_Cmnd *, void (*done) (Scsi_Cmnd *));
 static int atp870u_abort(Scsi_Cmnd *);
 static int atp870u_biosparam(struct scsi_device *, struct block_device *,
diff -Nru a/drivers/scsi/blz1230.c b/drivers/scsi/blz1230.c
--- a/drivers/scsi/blz1230.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/blz1230.c	Wed Jun 18 23:42:08 2003
@@ -334,7 +334,6 @@
 	.name			= "Blizzard1230 SCSI IV",
 	.detect			= blz1230_esp_detect,
 	.release		= blz1230_esp_release,
-	.command		= esp_command,
 	.queuecommand		= esp_queue,
 	.eh_abort_handler	= esp_abort,
 	.eh_bus_reset_handler	= esp_reset,
diff -Nru a/drivers/scsi/bvme6000.c b/drivers/scsi/bvme6000.c
--- a/drivers/scsi/bvme6000.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/bvme6000.c	Wed Jun 18 23:42:06 2003
@@ -51,9 +51,22 @@
     return 1;
 }
 
+static int mvme6000_scsi_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static Scsi_Host_Template driver_template = {
 	.name			= "BVME6000 NCR53c710 SCSI",
 	.detect			= bvme6000_scsi_detect,
+	.release		= bvme6000_scsi_release,
 	.queuecommand		= NCR53c7xx_queue_command,
 	.abort			= NCR53c7xx_abort,
 	.reset			= NCR53c7xx_reset,
diff -Nru a/drivers/scsi/constants.c b/drivers/scsi/constants.c
--- a/drivers/scsi/constants.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/constants.c	Wed Jun 18 23:42:08 2003
@@ -1004,16 +1004,14 @@
 #endif
 }
 
-void print_sense(const char * devclass, Scsi_Cmnd * SCpnt)
+void print_sense(const char *devclass, struct scsi_cmnd *cmd)
 {
-	print_sense_internal(devclass, SCpnt->sense_buffer,
-			     SCpnt->request);
+	print_sense_internal(devclass, cmd->sense_buffer, cmd->request);
 }
 
-void print_req_sense(const char * devclass, Scsi_Request * SRpnt)
+void print_req_sense(const char *devclass, struct scsi_request *sreq)
 {
-	print_sense_internal(devclass, SRpnt->sr_sense_buffer,
-			     SRpnt->sr_request);
+	print_sense_internal(devclass, sreq->sr_sense_buffer, sreq->sr_request);
 }
 
 #if (CONSTANTS & CONST_MSG) 
@@ -1116,13 +1114,13 @@
     return len;
 }
 
-void print_Scsi_Cmnd (Scsi_Cmnd *cmd) {
+void print_Scsi_Cmnd(struct scsi_cmnd *cmd) {
     printk("scsi%d : destination target %d, lun %d\n", 
 	   cmd->device->host->host_no, 
 	   cmd->device->id, 
 	   cmd->device->lun);
     printk("        command = ");
-    print_command (cmd->cmnd);
+    print_command(cmd->cmnd);
 }
 
 #if (CONSTANTS & CONST_HOST)
diff -Nru a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
--- a/drivers/scsi/dc395x.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/dc395x.c	Wed Jun 18 23:42:06 2003
@@ -5726,9 +5726,9 @@
 	/*
 	 *$$$$$$$$$$$  MEMORY ALLOCATE FOR ADAPTER CONTROL BLOCK $$$$$$$$$$$$
 	 */
-	host = scsi_register(host_template, sizeof(struct AdapterCtlBlk));
+	host = scsi_host_alloc(host_template, sizeof(struct AdapterCtlBlk));
 	if (!host) {
-		dprintkl(KERN_INFO, "pSH scsi_register ERROR\n");
+		dprintkl(KERN_INFO, "pSH scsi_host_alloc ERROR\n");
 		return 0;
 	}
 	DC395x_print_eeprom_settings(index);
@@ -5736,7 +5736,7 @@
 	pACB = (struct AdapterCtlBlk *) host->hostdata;
 
 	if (DC395x_initACB(host, io_port, irq, index)) {
-		scsi_unregister(host);
+		scsi_host_put(host);
 		return 0;
 	}
 	DC395x_print_config(pACB);
@@ -5755,7 +5755,7 @@
 
 	} else {
 		dprintkl(KERN_INFO, "DC395x_initAdapter initial ERROR\n");
-		scsi_unregister(host);
+		scsi_host_put(host);
 		host = NULL;
 	}
 	return host;
diff -Nru a/drivers/scsi/dec_esp.c b/drivers/scsi/dec_esp.c
--- a/drivers/scsi/dec_esp.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/dec_esp.c	Wed Jun 18 23:42:08 2003
@@ -109,13 +109,23 @@
 
 int dec_esp_detect(Scsi_Host_Template * tpnt);
 
+static int dec_esp_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static Scsi_Host_Template driver_template = {
 	.proc_name		= "esp",
 	.proc_info		= &esp_proc_info,
 	.name			= "NCR53C94",
 	.detect			= dec_esp_detect,
+	.release		= dec_esp_release,
 	.info			= esp_info,
-	.command		= esp_command,
 	.queuecommand		= esp_queue,
 	.eh_abort_handler	= esp_abort,
 	.eh_bus_reset_handler	= esp_reset,
diff -Nru a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
--- a/drivers/scsi/dpt_i2o.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/dpt_i2o.c	Wed Jun 18 23:42:08 2003
@@ -1949,26 +1949,6 @@
 	case I2ORESCANCMD:
 		adpt_rescan(pHba);
 		break;
-	case DPT_TARGET_BUSY & 0xFFFF:
-	case DPT_TARGET_BUSY:
-	{
-		TARGET_BUSY_T busy;
-		struct adpt_device* d;
-
-		if (copy_from_user((void*)&busy, (void*)arg, sizeof(TARGET_BUSY_T))) {
-			return -EFAULT;
-		}
-
-		d = adpt_find_device(pHba, busy.channel, busy.id, busy.lun);
-		if(d == NULL){
-			return -ENODEV;
-		}
-		busy.isBusy = ((d->pScsi_dev) && (0 != d->pScsi_dev->access_count)) ? 1 : 0;
-		if (copy_to_user ((char*)arg, &busy, sizeof(busy))) {
-			return -EFAULT;
-		}
-		break;
-	}
 	default:
 		return -EINVAL;
 	}
@@ -2492,10 +2472,6 @@
 			printk(KERN_WARNING"%s: Device (%d,%d,%d) offline\n",pHba->name,pDev->scsi_channel,pDev->scsi_id,pDev->scsi_lun);
 			if (pDev->pScsi_dev) {
 				pDev->pScsi_dev->online = FALSE;
-				if (pDev->pScsi_dev->access_count) {
-					// A drive that was mounted is no longer there... bad!
-					printk(KERN_WARNING"%s:Mounted drive taken offline\n",pHba->name);
-				}
 			}
 		}
 	}
diff -Nru a/drivers/scsi/dtc.c b/drivers/scsi/dtc.c
--- a/drivers/scsi/dtc.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/dtc.c	Wed Jun 18 23:42:08 2003
@@ -447,9 +447,20 @@
 
 #include "NCR5380.c"
 
+static int dtc_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static Scsi_Host_Template driver_template = {
 	.name				= "DTC 3180/3280 ",
 	.detect				= dtc_detect,
+	.release			= dtc_release,
 	.queuecommand			= dtc_queue_command,
 	.eh_abort_handler		= dtc_abort,
 	.eh_bus_reset_handler		= dtc_bus_reset,
diff -Nru a/drivers/scsi/eata.c b/drivers/scsi/eata.c
--- a/drivers/scsi/eata.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/scsi/eata.c	Wed Jun 18 23:42:09 2003
@@ -1,6 +1,36 @@
 /*
  *      eata.c - Low-level driver for EATA/DMA SCSI host adapters.
  *
+ *      03 Jun 2003 Rev. 8.10 for linux-2.5.70
+ *        + Update for new IRQ API.
+ *        + Use "goto" when appropriate.
+ *        + Drop eata.h.
+ *        + Update for new module_param API.
+ *        + Module parameters  can now be specified only in the
+ *          same format as the kernel boot options.
+ *
+ *             boot option    old module param 
+ *             -----------    ------------------
+ *             addr,...       io_port=addr,...
+ *             lc:[y|n]       linked_comm=[1|0]
+ *             mq:xx          max_queue_depth=xx
+ *             tm:[0|1|2]     tag_mode=[0|1|2]
+ *             et:[y|n]       ext_tran=[1|0]
+ *             rs:[y|n]       rev_scan=[1|0]
+ *             ip:[y|n]       isa_probe=[1|0]
+ *             ep:[y|n]       eisa_probe=[1|0]
+ *             pp:[y|n]       pci_probe=[1|0]
+ *
+ *          A valid example using the new parameter format is:
+ *          modprobe eata "eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n"
+ *
+ *          which is equivalent to the old format:
+ *          modprobe eata io_port=0x7410,0x230 linked_comm=1 tag_mode=0 \
+ *                        max_queue_depth=4 eisa_probe=0
+ *
+ *      12 Feb 2003 Rev. 8.04 for linux 2.5.60
+ *        + Release irq before calling scsi_register.
+ *
  *      12 Nov 2002 Rev. 8.02 for linux 2.5.47
  *        + Release driver_lock before calling scsi_register.
  *
@@ -279,7 +309,7 @@
  *          This driver is based on the CAM (Common Access Method Committee)
  *          EATA (Enhanced AT Bus Attachment) rev. 2.0A, using DMA protocol.
  *
- *  Copyright (C) 1994-2002 Dario Ballabio (ballabio_dario@emc.com)
+ *  Copyright (C) 1994-2003 Dario Ballabio (ballabio_dario@emc.com)
  *
  *  Alternate email: dario.ballabio@inwind.it, dario.ballabio@tiscalinet.it
  *
@@ -447,31 +477,8 @@
  *  the driver sets host->wish_block = TRUE for all ISA boards.
  */
 
-#include <linux/version.h>
-
-#define MAX_INT_PARAM 10
-
-#if defined(MODULE)
-#include <linux/module.h>
-
-MODULE_PARM(boot_options, "s");
-MODULE_PARM(io_port, "1-" __MODULE_STRING(MAX_INT_PARAM) "i");
-MODULE_PARM(linked_comm, "i");
-MODULE_PARM(link_statistics, "i");
-MODULE_PARM(max_queue_depth, "i");
-MODULE_PARM(tag_mode, "i");
-MODULE_PARM(ext_tran, "i");
-MODULE_PARM(rev_scan, "i");
-MODULE_PARM(isa_probe, "i");
-MODULE_PARM(eisa_probe, "i");
-MODULE_PARM(pci_probe, "i");
-MODULE_AUTHOR("Dario Ballabio");
-
-#endif
-
 #include <linux/config.h>
 #include <linux/string.h>
-#include <linux/sched.h>
 #include <linux/kernel.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
@@ -491,8 +498,31 @@
 #include "hosts.h"
 #include <asm/dma.h>
 #include <asm/irq.h>
-#include "eata.h"
 
+static int eata2x_detect(Scsi_Host_Template *);
+static int eata2x_release(struct Scsi_Host *);
+static int eata2x_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int eata2x_eh_abort(Scsi_Cmnd *);
+static int eata2x_eh_host_reset(Scsi_Cmnd *);
+static int eata2x_bios_param(struct scsi_device *, struct block_device *,
+                             sector_t, int *);
+static int eata2x_slave_configure(Scsi_Device *);
+
+static Scsi_Host_Template driver_template = {
+                .name                    = "EATA/DMA 2.0x rev. 8.10.00 ",
+                .detect                  = eata2x_detect,
+                .release                 = eata2x_release,
+                .queuecommand            = eata2x_queuecommand,
+                .eh_abort_handler        = eata2x_eh_abort,
+                .eh_device_reset_handler = NULL,
+                .eh_bus_reset_handler    = NULL,
+                .eh_host_reset_handler   = eata2x_eh_host_reset,
+                .bios_param              = eata2x_bios_param,
+                .slave_configure         = eata2x_slave_configure,
+                .this_id                 = 7,
+                .unchecked_isa_dma       = 1,
+                .use_clustering          = ENABLE_CLUSTERING
+                };
 #if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
 #error "Adjust your <asm/byteorder.h> defines"
 #endif
@@ -818,7 +848,6 @@
 static int link_statistics;
 static int ext_tran = FALSE;
 static int rev_scan = TRUE;
-static char *boot_options;
 
 #if defined(CONFIG_SCSI_EATA_TAGGED_QUEUE)
 static int tag_mode = TAG_SIMPLE;
@@ -856,6 +885,23 @@
 static int pci_probe = FALSE;
 #endif
 
+#define MAX_INT_PARAM 10
+#define MAX_BOOT_OPTIONS_SIZE 256
+static char boot_options[MAX_BOOT_OPTIONS_SIZE];
+
+#if defined(MODULE)
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+module_param_string(eata, boot_options, MAX_BOOT_OPTIONS_SIZE, 0);
+MODULE_PARM_DESC(eata, " equivalent to the \"eata=...\" kernel boot option." \
+"            Example: modprobe eata \"eata=0x7410,0x230,lc:y,tm:0,mq:4,ep:n\"");
+MODULE_AUTHOR("Dario Ballabio");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("EATA/DMA SCSI Driver");
+
+#endif
+
 static int eata2x_slave_configure(Scsi_Device *dev) {
    int j, tqd, utqd;
    char *tag_suffix, *link_suffix;
@@ -1011,19 +1057,20 @@
 
    sprintf(name, "%s%d", driver_name, j);
 
-   if(!request_region(port_base, REGION_SIZE, driver_name)) {
+   if (!request_region(port_base, REGION_SIZE, driver_name)) {
 #if defined(DEBUG_DETECT)
       printk("%s: address 0x%03lx in use, skipping probe.\n", name, port_base);
 #endif
-      return FALSE;
+      goto fail;
       }
 
+   spin_lock_irq(&driver_lock);
+
    if (do_dma(port_base, 0, READ_CONFIG_PIO)) {
 #if defined(DEBUG_DETECT)
       printk("%s: detect, do_dma failed at 0x%03lx.\n", name, port_base);
 #endif
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freelock;
       }
 
    /* Read the info structure */
@@ -1031,8 +1078,7 @@
 #if defined(DEBUG_DETECT)
       printk("%s: detect, read_pio failed at 0x%03lx.\n", name, port_base);
 #endif
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freelock;
       }
 
    info.data_len = DEV2H(info.data_len);
@@ -1048,15 +1094,13 @@
 #if defined(DEBUG_DETECT)
       printk("%s: signature 0x%04x discarded.\n", name, info.sign);
 #endif
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freelock;
       }
 
    if (info.data_len < EATA_2_0A_SIZE) {
       printk("%s: config structure size (%d bytes) too short, detaching.\n",
              name, info.data_len);
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freelock;
       }
    else if (info.data_len == EATA_2_0A_SIZE)
       protocol_rev = 'A';
@@ -1097,8 +1141,7 @@
    if (!info.haaval || info.ata) {
       printk("%s: address 0x%03lx, unusable %s board (%d%d), detaching.\n",
              name, port_base, bus_type, info.haaval, info.ata);
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freelock;
       }
 
    if (info.drqvld) {
@@ -1145,16 +1188,13 @@
              SA_INTERRUPT | ((subversion == ESA) ? SA_SHIRQ : 0),
              driver_name, (void *) &sha[j])) {
       printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freelock;
       }
 
    if (subversion == ISA && request_dma(dma_channel, driver_name)) {
       printk("%s: unable to allocate DMA channel %u, detaching.\n",
              name, dma_channel);
-      free_irq(irq, &sha[j]);
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freeirq;
       }
 
 #if defined(FORCE_CONFIG)
@@ -1166,8 +1206,7 @@
 
    if (!cf) {
       printk("%s: config, pci_alloc_consistent failed, detaching.\n", name);
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freedma;
       }
 
    /* Set board configuration */
@@ -1178,8 +1217,7 @@
    if (do_dma(port_base, cf_dma_addr, SET_CONFIG_DMA)) {
       printk("%s: busy timeout sending configuration, detaching.\n", name);
       pci_free_consistent(pdev, sizeof(struct eata_config), cf, cf_dma_addr);
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freedma;
       }
 
    }
@@ -1191,13 +1229,7 @@
 
    if (sh[j] == NULL) {
       printk("%s: unable to register host, detaching.\n", name);
-
-      free_irq(irq, &sha[j]);
-
-      if (subversion == ISA) free_dma(dma_channel);
-
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freedma;
       }
 
    sh[j]->io_port = port_base;
@@ -1268,6 +1300,8 @@
    if (dma_channel == NO_DMA) sprintf(dma_name, "%s", "BMST");
    else                       sprintf(dma_name, "DMA %u", dma_channel);
 
+   spin_unlock_irq(&driver_lock);
+
    for (i = 0; i < sh[j]->can_queue; i++)
       HD(j)->cp[i].cp_dma_addr = pci_map_single(HD(j)->pdev,
             &HD(j)->cp[i], sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL);
@@ -1277,15 +1311,13 @@
             sh[j]->sg_tablesize * sizeof(struct sg_list),
             (sh[j]->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC))) {
          printk("%s: kmalloc SGlist failed, mbox %d, detaching.\n", BN(j), i);
-         eata2x_release(sh[j]);
-         return FALSE;
+         goto release;
          }
 
    if (! (HD(j)->sp_cpu_addr = pci_alloc_consistent(HD(j)->pdev,
          sizeof(struct mssp), &HD(j)->sp_dma_addr))) {
       printk("%s: pci_alloc_consistent failed, detaching.\n", BN(j));
-      eata2x_release(sh[j]);
-      return FALSE;
+      goto release;
       }
 
    if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN)
@@ -1297,7 +1329,7 @@
       tag_mode = TAG_ORDERED;
 
    if (j == 0) {
-      printk("EATA/DMA 2.0x: Copyright (C) 1994-2002 Dario Ballabio.\n");
+      printk("EATA/DMA 2.0x: Copyright (C) 1994-2003 Dario Ballabio.\n");
       printk("%s config options -> tm:%d, lc:%c, mq:%d, rs:%c, et:%c, "\
              "ip:%c, ep:%c, pp:%c.\n", driver_name, tag_mode,
              YESNO(linked_comm), max_queue_depth, YESNO(rev_scan),
@@ -1342,6 +1374,20 @@
       }
 
    return TRUE;
+
+freedma:
+   if (subversion == ISA) free_dma(dma_channel);
+freeirq:
+   free_irq(irq, &sha[j]);
+freelock:
+   spin_unlock_irq(&driver_lock);
+   release_region(port_base, REGION_SIZE);
+fail:
+   return FALSE;
+
+release:
+   eata2x_release(sh[j]);
+   return FALSE;
 }
 
 static void internal_setup(char *str, int *ints) {
@@ -1440,11 +1486,9 @@
 static int eata2x_detect(Scsi_Host_Template *tpnt) {
    unsigned int j = 0, k;
 
-   spin_lock_irq(&driver_lock);
-
    tpnt->proc_name = "eata2x";
 
-   if(boot_options) option_setup(boot_options);
+   if(strlen(boot_options)) option_setup(boot_options);
 
 #if defined(MODULE)
    /* io_port could have been modified when loading as a module */
@@ -1478,7 +1522,6 @@
       }
 
    num_boards = j;
-   spin_unlock_irq(&driver_lock);
    return j;
 }
 
@@ -2091,7 +2134,7 @@
 
 }
 
-static void ihdlr(int irq, unsigned int j) {
+static irqreturn_t ihdlr(int irq, unsigned int j) {
    Scsi_Cmnd *SCpnt;
    unsigned int i, k, c, status, tstatus, reg;
    struct mssp *spp;
@@ -2101,7 +2144,7 @@
        panic("%s: ihdlr, irq %d, sh[j]->irq %d.\n", BN(j), irq, sh[j]->irq);
 
    /* Check if this board need to be serviced */
-   if (!(inb(sh[j]->io_port + REG_AUX_STATUS) & IRQ_ASSERTED)) return;
+   if (!(inb(sh[j]->io_port + REG_AUX_STATUS) & IRQ_ASSERTED)) goto none;
 
    HD(j)->iocount++;
 
@@ -2113,7 +2156,7 @@
       reg = inb(sh[j]->io_port + REG_STATUS);
       printk("%s: ihdlr, busy timeout error,  irq %d, reg 0x%x, count %d.\n",
              BN(j), irq, reg, HD(j)->iocount);
-      return;
+      goto none;
       }
 
    spp  = &HD(j)->sp;
@@ -2148,7 +2191,7 @@
       printk("%s: ihdlr, bad spp->cpp_index %d, irq %d, reg 0x%x, count %d.\n",
              BN(j), spp->cpp_index, irq, reg, HD(j)->iocount);
    if (spp->eoc == FALSE || spp->cpp_index < 0
-                         || spp->cpp_index >= sh[j]->can_queue) return;
+                         || spp->cpp_index >= sh[j]->can_queue) goto handled;
 
    /* Find the mailbox to be serviced on this board */
    i = spp->cpp_index;
@@ -2156,23 +2199,23 @@
    cpp = &(HD(j)->cp[i]);
 
 #if defined(DEBUG_GENERATE_ABORTS)
-   if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 500) < 3)) return;
+   if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 500) < 3)) goto handled;
 #endif
 
    if (HD(j)->cp_stat[i] == IGNORE) {
       HD(j)->cp_stat[i] = FREE;
-      return;
+      goto handled;
       }
    else if (HD(j)->cp_stat[i] == LOCKED) {
       HD(j)->cp_stat[i] = FREE;
       printk("%s: ihdlr, mbox %d unlocked, count %d.\n", BN(j), i,
              HD(j)->iocount);
-      return;
+      goto handled;
       }
    else if (HD(j)->cp_stat[i] == FREE) {
       printk("%s: ihdlr, mbox %d is free, count %d.\n", BN(j), i,
              HD(j)->iocount);
-      return;
+      goto handled;
       }
    else if (HD(j)->cp_stat[i] == IN_RESET)
       printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i);
@@ -2319,22 +2362,25 @@
    if (do_trace) printk("%s: ihdlr, exit, irq %d, count %d.\n", BN(j), irq,
                         HD(j)->iocount);
 
-   return;
+handled:
+   return IRQ_HANDLED;
+none:
+   return IRQ_NONE;
 }
 
 static irqreturn_t do_interrupt_handler(int irq, void *shap,
-					struct pt_regs *regs) {
+                                        struct pt_regs *regs) {
    unsigned int j;
    unsigned long spin_flags;
+   irqreturn_t ret;
 
    /* Check if the interrupt must be processed by this handler */
-   if ((j = (unsigned int)((char *)shap - sha)) >= num_boards)
-	return IRQ_NONE;
+   if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) return IRQ_NONE;
 
    spin_lock_irqsave(sh[j]->host_lock, spin_flags);
-   ihdlr(irq, j);
+   ret = ihdlr(irq, j);
    spin_unlock_irqrestore(sh[j]->host_lock, spin_flags);
-   return IRQ_HANDLED;
+   return ret;
 }
 
 static int eata2x_release(struct Scsi_Host *shpnt) {
@@ -2365,22 +2411,8 @@
    return FALSE;
 }
 
-static Scsi_Host_Template driver_template = {
-	.name              	= "EATA/DMA 2.0x rev. " EATA_VERSION " ",
-	.detect                  = eata2x_detect,
-	.release                 = eata2x_release,
-	.queuecommand            = eata2x_queuecommand,
-	.eh_abort_handler        = eata2x_eh_abort,
-	.eh_host_reset_handler   = eata2x_eh_host_reset,
-	.bios_param              = eata2x_bios_param,
-	.slave_configure	 = eata2x_slave_configure,
-	.this_id                 = 7,
-	.unchecked_isa_dma       = 1,
-	.use_clustering          = ENABLE_CLUSTERING,
-};
 #include "scsi_module.c"
 
 #ifndef MODULE
 __setup("eata=", option_setup);
 #endif /* end MODULE */
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/scsi/eata.h b/drivers/scsi/eata.h
--- a/drivers/scsi/eata.h	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,15 +0,0 @@
-/*
- *        eata.h - used by the low-level driver for EATA/DMA SCSI host adapters.
- */
-
-static int eata2x_detect(Scsi_Host_Template *);
-static int eata2x_release(struct Scsi_Host *);
-static int eata2x_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-static int eata2x_eh_abort(Scsi_Cmnd *);
-static int eata2x_eh_host_reset(Scsi_Cmnd *);
-static int eata2x_bios_param(struct scsi_device *, struct block_device *,
-                             sector_t, int *);
-static int eata2x_slave_configure(Scsi_Device *);
-
-#define EATA_VERSION "8.03.00"
-
diff -Nru a/drivers/scsi/esp.c b/drivers/scsi/esp.c
--- a/drivers/scsi/esp.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/scsi/esp.c	Wed Jun 18 23:42:09 2003
@@ -1871,15 +1871,6 @@
 	return 0;
 }
 
-/* Only queuing supported in this ESP driver. */
-static int esp_command(Scsi_Cmnd *SCpnt)
-{
-	struct esp *esp = (struct esp *) SCpnt->device->host->hostdata;
-
-	ESPLOG(("esp%d: esp_command() called...\n", esp->esp_id));
-	return -1;
-}
-
 /* Dump driver state. */
 static void esp_dump_cmd(Scsi_Cmnd *SCptr)
 {
@@ -4384,7 +4375,6 @@
 	SDptr->hostdata = NULL;
 }
 
-
 static Scsi_Host_Template driver_template = {
 	.proc_name		= "esp",
 	.proc_info		= esp_proc_info,
@@ -4394,7 +4384,6 @@
 	.slave_destroy		= esp_slave_destroy,
 	.release		= esp_release,
 	.info			= esp_info,
-	.command		= esp_command,
 	.queuecommand		= esp_queue,
 	.eh_abort_handler	= esp_abort,
 	.eh_bus_reset_handler	= esp_reset,
diff -Nru a/drivers/scsi/fd_mcs.c b/drivers/scsi/fd_mcs.c
--- a/drivers/scsi/fd_mcs.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/fd_mcs.c	Wed Jun 18 23:42:06 2003
@@ -1186,24 +1186,6 @@
 	return 0;
 }
 
-static void internal_done(Scsi_Cmnd * SCpnt)
-{
-	/* flag it done */
-	SCpnt->host_scribble = (unsigned char *) 1;
-}
-
-int fd_mcs_command(Scsi_Cmnd * SCpnt)
-{
-	fd_mcs_queue(SCpnt, internal_done);
-	/* host_scribble is used for status here */
-	SCpnt->host_scribble = NULL;
-	while (!SCpnt->host_scribble) {
-		cpu_relax();
-		barrier();
-	}
-	return SCpnt->result;
-}
-
 #if DEBUG_ABORT || DEBUG_RESET
 static void fd_mcs_print_info(Scsi_Cmnd * SCpnt)
 {
@@ -1431,7 +1413,6 @@
 	.detect				= fd_mcs_detect,
 	.release			= fd_mcs_release,
 	.info				= fd_mcs_info,
-	.command			= fd_mcs_command,
 	.queuecommand   		= fd_mcs_queue, 
 	.eh_abort_handler		= fd_mcs_abort,
 	.eh_bus_reset_handler		= fd_mcs_bus_reset,
diff -Nru a/drivers/scsi/fdomain.c b/drivers/scsi/fdomain.c
--- a/drivers/scsi/fdomain.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/fdomain.c	Wed Jun 18 23:42:08 2003
@@ -255,11 +255,6 @@
  be increased by changing this value to values which are close to 2.
  Please let me know if you try any different values.
 
- DO_DETECT: This activates some old scan code which was needed before the
- high level drivers got fixed.  If you are having trouble with the driver,
- turning this on should not hurt, and might help.  Please let me know if
- this is the case, since this code will be removed from future drivers.
-
  RESELECTION: This is no longer an option, since I gave up trying to
  implement it in version 4.x of this driver.  It did not improve
  performance at all and made the driver unstable (because I never found one
@@ -303,7 +298,6 @@
 #define DEBUG            0	/* Enable debugging output */
 #define ENABLE_PARITY    1	/* Enable SCSI Parity */
 #define FIFO_COUNT       2	/* Number of 512 byte blocks before INTR */
-#define DO_DETECT        0	/* Do device detection here (see scsi.c) */
 
 /* END OF USER DEFINABLE OPTIONS */
 
@@ -863,17 +857,6 @@
    int              retcode;
    struct Scsi_Host *shpnt;
    struct pci_dev *pdev = NULL;
-#if DO_DETECT
-   int i = 0;
-   int j = 0;
-   const int        buflen = 255;
-   Scsi_Cmnd        SCinit;
-   unsigned char    do_inquiry[] =       { INQUIRY, 0, 0, 0, buflen, 0 };
-   unsigned char    do_request_sense[] = { REQUEST_SENSE, 0, 0, 0, buflen, 0 };
-   unsigned char    do_read_capacity[] = { READ_CAPACITY,
-					   0, 0, 0, 0, 0, 0, 0, 0, 0 };
-   unsigned char    buf[buflen];
-#endif
 
    if (setup_called) {
 #if DEBUG_DETECT
@@ -984,59 +967,6 @@
    /* Log I/O ports with kernel */
    request_region( port_base, 0x10, "fdomain" );
 
-#if DO_DETECT
-
-   /* These routines are here because of the way the SCSI bus behaves after
-      a reset.  This appropriate behavior was not handled correctly by the
-      higher level SCSI routines when I first wrote this driver.  Now,
-      however, correct scan routines are part of scsi.c and these routines
-      are no longer needed.  However, this code is still good for
-      debugging.  */
-
-   SCinit.request_buffer  = SCinit.buffer = buf;
-   SCinit.request_bufflen = SCinit.bufflen = sizeof(buf)-1;
-   SCinit.use_sg          = 0;
-   SCinit.lun             = 0;
-
-   printk( "scsi: <fdomain> detection routine scanning for devices:\n" );
-   for (i = 0; i < 8; i++) {
-      SCinit.target = i;
-      if (i == tpnt->this_id)	/* Skip host adapter */
-	    continue;
-      memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
-      retcode = fdomain_16x0_command(&SCinit);
-      if (!retcode) {
-	 memcpy(SCinit.cmnd, do_inquiry, sizeof(do_inquiry));
-	 retcode = fdomain_16x0_command(&SCinit);
-	 if (!retcode) {
-	    printk( "     SCSI ID %d: ", i );
-	    for (j = 8; j < (buf[4] < 32 ? buf[4] : 32); j++)
-		  printk( "%c", buf[j] >= 20 ? buf[j] : ' ' );
-	    memcpy(SCinit.cmnd, do_read_capacity, sizeof(do_read_capacity));
-	    retcode = fdomain_16x0_command(&SCinit);
-	    if (!retcode) {
-	       unsigned long blocks, size, capacity;
-	       
-	       blocks = (buf[0] << 24) | (buf[1] << 16)
-		     | (buf[2] << 8) | buf[3];
-	       size = (buf[4] << 24) | (buf[5] << 16) | (buf[6] << 8) | buf[7];
-	       capacity = +( +(blocks / 1024L) * +(size * 10L)) / 1024L;
-	       
-	       printk( "%lu MB (%lu byte blocks)",
-		       ((capacity + 5L) / 10L), size );
-	    } else {
-	       memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
-	       retcode = fdomain_16x0_command(&SCinit);
-	    }
-	    printk ("\n" );
-	 } else {
-	    memcpy(SCinit.cmnd, do_request_sense, sizeof(do_request_sense));
-	    retcode = fdomain_16x0_command(&SCinit);
-	 }
-      }
-   }
-#endif
-
    return shpnt;
 }
 
@@ -1508,31 +1438,6 @@
    return 0;
 }
 
-/* The following code, which simulates the old-style command function, was
-   taken from Tommy Thorn's aha1542.c file.  This code is Copyright (C)
-   1992 Tommy Thorn. */
-
-static volatile int internal_done_flag    = 0;
-static volatile int internal_done_errcode = 0;
-
-static void internal_done(Scsi_Cmnd *SCpnt)
-{
-    internal_done_errcode = SCpnt->result;
-    ++internal_done_flag;
-}
-
-static int fdomain_16x0_command(Scsi_Cmnd *SCpnt)
-{
-    fdomain_16x0_queue(SCpnt, internal_done);
-
-    while (!internal_done_flag)
-	  cpu_relax();
-    internal_done_flag = 0;
-    return internal_done_errcode;
-}
-
-/* End of code derived from Tommy Thorn's work. */
-
 #if DEBUG_ABORT
 static void print_info(Scsi_Cmnd *SCpnt)
 {
@@ -1833,7 +1738,6 @@
 	.proc_name		= "fdomain",
 	.detect			= fdomain_16x0_detect,
 	.info			= fdomain_16x0_info,
-	.command		= fdomain_16x0_command,
 	.queuecommand		= fdomain_16x0_queue,
 	.eh_abort_handler	= fdomain_16x0_abort,
 	.eh_bus_reset_handler	= fdomain_16x0_bus_reset,
diff -Nru a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
--- a/drivers/scsi/hosts.c	Wed Jun 18 23:42:05 2003
+++ b/drivers/scsi/hosts.c	Wed Jun 18 23:42:05 2003
@@ -20,25 +20,15 @@
  *  September 04, 2002 Mike Anderson (andmike@us.ibm.com)
  */
 
-
-/*
- *  This file contains the medium level SCSI
- *  host interface initialization, as well as the scsi_hosts list of SCSI
- *  hosts currently present in the system.
- */
-
-#include <linux/config.h>
 #include <linux/module.h>
-#include <linux/blk.h>
+#include <linux/blkdev.h>
 #include <linux/kernel.h>
 #include <linux/string.h>
 #include <linux/mm.h>
 #include <linux/init.h>
-#include <linux/interrupt.h>
 #include <linux/list.h>
 #include <linux/completion.h>
 #include <linux/unistd.h>
-#include <asm/dma.h>
 
 #include "scsi.h"
 #include "hosts.h"
@@ -47,152 +37,7 @@
 #include "scsi_logging.h"
 
 
-static LIST_HEAD(scsi_host_list);
-static spinlock_t scsi_host_list_lock = SPIN_LOCK_UNLOCKED;
-
 static int scsi_host_next_hn;		/* host_no for next new host */
-static char *scsihosts;
-
-MODULE_PARM(scsihosts, "s");
-MODULE_PARM_DESC(scsihosts, "scsihosts=driver1,driver2,driver3");
-#ifndef MODULE
-int __init scsi_setup(char *str)
-{
-	scsihosts = str;
-	return 1;
-}
-
-__setup("scsihosts=", scsi_setup);
-#endif
-
-/**
-  * scsi_find_host_by_num - get a Scsi_Host by host no
-  *
-  * @host_no:	host number to locate
-  *
-  * Return value:
-  *	A pointer to located Scsi_Host or NULL.
-  **/
-static struct Scsi_Host *scsi_find_host_by_num(unsigned short host_no)
-{
-	struct Scsi_Host *shost, *shost_found = NULL;
-
-	spin_lock(&scsi_host_list_lock);
-	list_for_each_entry(shost, &scsi_host_list, sh_list) {
-		if (shost->host_no > host_no) {
-			/*
-			 * The list is sorted.
-			 */
-			break;
-		} else if (shost->host_no == host_no) {
-			shost_found = shost;
-			break;
-		}
-	}
-	spin_unlock(&scsi_host_list_lock);
-	return shost_found;
-}
-
-/**
- * scsi_alloc_hostnum - choose new SCSI host number based on host name.
- * @name:	String to store in name field
- *
- * Return value:
- *	Pointer to a new Scsi_Host_Name
- **/
-static int scsi_alloc_host_num(const char *name)
-{
-	int hostnum;
-	int namelen;
-	const char *start, *end;
-
-	if (name) {
-		hostnum = 0;
-		namelen = strlen(name);
-		start = scsihosts; 
-		while (1) {
-			int hostlen;
-
-			if (start && start[0] != '\0') {
-				end = strpbrk(start, ",:");
-				if (end) {
-					hostlen = (end - start);
-					end++;
-				} else
-					hostlen = strlen(start);
-				/*
-				 * Look for a match on the scsihosts list.
-				 */
-				if ((hostlen == namelen) && 
-				    (strncmp(name, start, hostlen) == 0) && 
-				    (!scsi_find_host_by_num(hostnum)))
-					return hostnum;
-				start = end;
-			} else  {
-				/*
-				 * Look for any unused numbers.
-				 */
-				if (!scsi_find_host_by_num(hostnum))
-					return hostnum;
-			}
-			hostnum++;
-		}
-	} else
-		return scsi_host_next_hn++;
-}
-
-
-/**
- * scsi_tp_for_each_host - call function for each scsi host off a template
- * @shost_tp:	a pointer to a scsi host template
- * @callback:	a pointer to callback function
- *
- * Return value:
- * 	0 on Success / 1 on Failure
- **/
-int scsi_tp_for_each_host(Scsi_Host_Template *shost_tp, int
-			    (*callback)(struct Scsi_Host *shost))
-{
-	struct list_head *lh, *lh_sf;
-	struct Scsi_Host *shost;
-
-	spin_lock(&scsi_host_list_lock);
-
-	list_for_each_safe(lh, lh_sf, &scsi_host_list) {
-		shost = list_entry(lh, struct Scsi_Host, sh_list);
-		if (shost->hostt == shost_tp) {
-			spin_unlock(&scsi_host_list_lock);
-			callback(shost);
-			spin_lock(&scsi_host_list_lock);
-		}
-	}
-
-	spin_unlock(&scsi_host_list_lock);
-
-	return 0;
-}
-
-/**
- * scsi_host_legacy_release - default release function for hosts
- * @shost: 
- * 
- * Description:
- * 	This is the default case for the release function.  Its completely
- *	useless for anything but old ISA adapters
- **/
-static int scsi_host_legacy_release(struct Scsi_Host *shost)
-{
-	if (shost->irq)
-		free_irq(shost->irq, NULL);
-#ifdef CONFIG_GENERIC_ISA_DMA
-	if (shost->dma_channel != 0xff)
-		free_dma(shost->dma_channel);
-#endif
-	if (shost->io_port && shost->n_io_port)
-		release_region(shost->io_port, shost->n_io_port);
-
-	return 0;
-}
 
 /**
  * scsi_remove_host - check a scsi host for release and release
@@ -217,9 +62,6 @@
 	scsi_forget_host(shost);
 	scsi_sysfs_remove_host(shost);
 
-	if (shost->hostt->release)
-		(*shost->hostt->release)(shost);
-
 	return 0;
 }
 
@@ -233,7 +75,7 @@
  **/
 int scsi_add_host(struct Scsi_Host *shost, struct device *dev)
 {
-	Scsi_Host_Template *sht = shost->hostt;
+	struct scsi_host_template *sht = shost->hostt;
 	int error;
 
 	printk(KERN_INFO "scsi%d : %s\n", shost->host_no,
@@ -243,34 +85,17 @@
 	if (!error) {
 		scsi_proc_host_add(shost);
 		scsi_scan_host(shost);
-	};
+	}
 			
 	return error;
 }
 
 /**
- * scsi_unregister - unregister a scsi host
- * @shost:	scsi host to be unregistered
- **/
-void scsi_unregister(struct Scsi_Host *shost)
-{
-	scsi_host_put(shost);
-}
-
-/**
  * scsi_free_sdev - free a scsi hosts resources
  * @shost:	scsi host to free 
  **/
 void scsi_free_shost(struct Scsi_Host *shost)
 {
-	/* Remove shost from scsi_host_list */
-	spin_lock(&scsi_host_list_lock);
-	list_del(&shost->sh_list);
-	spin_unlock(&scsi_host_list_lock);
-
-	/*
-	 * Next, kill the kernel error recovery thread for this host.
-	 */
 	if (shost->ehandler) {
 		DECLARE_COMPLETION(sem);
 		shost->eh_notify = &sem;
@@ -286,60 +111,58 @@
 }
 
 /**
- * scsi_register - register a scsi host adapter instance.
- * @shost_tp:	pointer to scsi host template
- * @xtr_bytes:	extra bytes to allocate for driver
+ * scsi_host_alloc - register a scsi host adapter instance.
+ * @sht:	pointer to scsi host template
+ * @privsize:	extra bytes to allocate for driver
  *
  * Note:
- * 	We call this when we come across a new host adapter. We only do
- * 	this once we are 100% sure that we want to use this host adapter -
- * 	it is a pain to reverse this, so we try to avoid it 
+ * 	Allocate a new Scsi_Host and perform basic initialization.
+ * 	The host is not published to the scsi midlayer until scsi_add_host
+ * 	is called.
  *
  * Return value:
  * 	Pointer to a new Scsi_Host
  **/
-extern int blk_nohighio;
-struct Scsi_Host * scsi_register(Scsi_Host_Template *shost_tp, int xtr_bytes)
+struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
 {
-	struct Scsi_Host *shost, *shost_scr;
-	int gfp_mask, rval;
-	DECLARE_COMPLETION(sem);
+	struct Scsi_Host *shost;
+	int gfp_mask = GFP_KERNEL, rval;
+	DECLARE_COMPLETION(complete);
+
+	if (sht->unchecked_isa_dma && privsize)
+		gfp_mask |= __GFP_DMA;
 
         /* Check to see if this host has any error handling facilities */
-        if(shost_tp->eh_strategy_handler == NULL &&
-           shost_tp->eh_abort_handler == NULL &&
-           shost_tp->eh_device_reset_handler == NULL &&
-           shost_tp->eh_bus_reset_handler == NULL &&
-           shost_tp->eh_host_reset_handler == NULL) {
-		printk(KERN_ERR "ERROR: SCSI host `%s' has no error handling\nERROR: This is not a safe way to run your SCSI host\nERROR: The error handling must be added to this driver\n", shost_tp->proc_name);
+        if (!sht->eh_strategy_handler && !sht->eh_abort_handler &&
+	    !sht->eh_device_reset_handler && !sht->eh_bus_reset_handler &&
+            !sht->eh_host_reset_handler) {
+		printk(KERN_ERR "ERROR: SCSI host `%s' has no error handling\n"
+				"ERROR: This is not a safe way to run your "
+				        "SCSI host\n"
+				"ERROR: The error handling must be added to "
+				"this driver\n", sht->proc_name);
 		dump_stack();
         }
-	if(shost_tp->shost_attrs == NULL)
-		/* if its not set in the template, use the default */
-		 shost_tp->shost_attrs = scsi_sysfs_shost_attrs;
-	if(shost_tp->sdev_attrs == NULL)
-		 shost_tp->sdev_attrs = scsi_sysfs_sdev_attrs;
-	gfp_mask = GFP_KERNEL;
-	if (shost_tp->unchecked_isa_dma && xtr_bytes)
-		gfp_mask |= __GFP_DMA;
-
-	shost = kmalloc(sizeof(struct Scsi_Host) + xtr_bytes, gfp_mask);
-	if (!shost) {
-		printk(KERN_ERR "%s: out of memory.\n", __FUNCTION__);
-		return NULL;
-	}
 
-	memset(shost, 0, sizeof(struct Scsi_Host) + xtr_bytes);
+	/* if its not set in the template, use the default */
+	if (!sht->shost_attrs)
+		 sht->shost_attrs = scsi_sysfs_shost_attrs;
+	if (!sht->sdev_attrs)
+		 sht->sdev_attrs = scsi_sysfs_sdev_attrs;
 
-	shost->host_no = scsi_alloc_host_num(shost_tp->proc_name);
+	shost = kmalloc(sizeof(struct Scsi_Host) + privsize, gfp_mask);
+	if (!shost)
+		return NULL;
+	memset(shost, 0, sizeof(struct Scsi_Host) + privsize);
 
 	spin_lock_init(&shost->default_lock);
 	scsi_assign_lock(shost, &shost->default_lock);
 	INIT_LIST_HEAD(&shost->my_devices);
 	INIT_LIST_HEAD(&shost->eh_cmd_q);
 	INIT_LIST_HEAD(&shost->starved_list);
-
 	init_waitqueue_head(&shost->host_wait);
+
+	shost->host_no = scsi_host_next_hn++; /* XXX(hch): still racy */
 	shost->dma_channel = 0xff;
 
 	/* These three are default values which can be overridden */
@@ -354,54 +177,29 @@
 	 * they actually do something sensible with such commands.
 	 */
 	shost->max_cmd_len = 12;
-	shost->hostt = shost_tp;
-	shost->host_blocked = 0;
-	shost->host_self_blocked = FALSE;
-	shost->max_host_blocked = shost_tp->max_host_blocked ? shost_tp->max_host_blocked : SCSI_DEFAULT_HOST_BLOCKED;
-
-#ifdef DEBUG
-	printk("%s: %x %x: %d\n", __FUNCTION_ (int)shost,
-	       (int)shost->hostt, xtr_bytes);
-#endif
+	shost->hostt = sht;
+	shost->this_id = sht->this_id;
+	shost->can_queue = sht->can_queue;
+	shost->sg_tablesize = sht->sg_tablesize;
+	shost->cmd_per_lun = sht->cmd_per_lun;
+	shost->unchecked_isa_dma = sht->unchecked_isa_dma;
+	shost->use_clustering = sht->use_clustering;
+	shost->use_blk_tcq = sht->use_blk_tcq;
+	shost->highmem_io = sht->highmem_io;
+
+	if (!sht->max_host_blocked)
+		shost->max_host_blocked = sht->max_host_blocked;
+	else
+		shost->max_host_blocked = SCSI_DEFAULT_HOST_BLOCKED;
 
 	/*
-	 * The next six are the default values which can be overridden if
-	 * need be
+	 * If the driver imposes no hard sector transfer limit, start at
+	 * machine infinity initially.
 	 */
-	shost->this_id = shost_tp->this_id;
-	shost->can_queue = shost_tp->can_queue;
-	shost->sg_tablesize = shost_tp->sg_tablesize;
-	shost->cmd_per_lun = shost_tp->cmd_per_lun;
-	shost->unchecked_isa_dma = shost_tp->unchecked_isa_dma;
-	shost->use_clustering = shost_tp->use_clustering;
-	if (!blk_nohighio)
-		shost->highmem_io = shost_tp->highmem_io;
-	if (!shost_tp->max_sectors) {
-		/*
-		 * Driver imposes no hard sector transfer limit.
-		 * start at machine infinity initially.
-		 */
+	if (sht->max_sectors)
+		shost->max_sectors = sht->max_sectors;
+	else
 		shost->max_sectors = SCSI_DEFAULT_MAX_SECTORS;
-	} else
-		shost->max_sectors = shost_tp->max_sectors;
-	shost->use_blk_tcq = shost_tp->use_blk_tcq;
-
-	spin_lock(&scsi_host_list_lock);
-	/*
-	 * FIXME When device naming is complete remove this step that
-	 * orders the scsi_host_list by host number and just do a
-	 * list_add_tail.
-	 */
-	list_for_each_entry(shost_scr, &scsi_host_list, sh_list) {
-		if (shost->host_no < shost_scr->host_no) {
-			__list_add(&shost->sh_list, shost_scr->sh_list.prev,
-				   &shost_scr->sh_list);
-			goto found;
-		}
-	}
-	list_add_tail(&shost->sh_list, &scsi_host_list);
-found:
-	spin_unlock(&scsi_host_list_lock);
 
 	rval = scsi_setup_command_freelist(shost);
 	if (rval)
@@ -409,85 +207,37 @@
 
 	scsi_sysfs_init_host(shost);
 
-	shost->eh_notify = &sem;
-	kernel_thread((int (*)(void *)) scsi_error_handler, (void *) shost, 0);
-	/*
-	 * Now wait for the kernel error thread to initialize itself
-	 * as it might be needed when we scan the bus.
-	 */
-	wait_for_completion(&sem);
+	shost->eh_notify = &complete;
+	/* XXX(hch): handle error return */
+	kernel_thread((int (*)(void *))scsi_error_handler, shost, 0);
+	wait_for_completion(&complete);
 	shost->eh_notify = NULL;
 	shost->hostt->present++;
 	return shost;
-
-fail:
-	spin_lock(&scsi_host_list_lock);
-	list_del(&shost->sh_list);
-	spin_unlock(&scsi_host_list_lock);
+ fail:
 	kfree(shost);
 	return NULL;
 }
 
-/**
- * scsi_register_host - register a low level host driver
- * @shost_tp:	pointer to a scsi host driver template
- *
- * Return value:
- * 	0 on Success / 1 on Failure.
- **/
-int scsi_register_host(Scsi_Host_Template *shost_tp)
+struct Scsi_Host *scsi_register(struct scsi_host_template *sht, int privsize)
 {
-	struct Scsi_Host *shost;
-
-	BUG_ON(!shost_tp->detect);
+	struct Scsi_Host *shost = scsi_host_alloc(sht, privsize);
 
-	if (!shost_tp->release) {
-		printk(KERN_WARNING
-		    "scsi HBA driver %s didn't set a release method, "
-		    "please fix the template\n", shost_tp->name);
-		shost_tp->release = &scsi_host_legacy_release;
+	if (!sht->detect) {
+		printk(KERN_WARNING "scsi_register() called on new-style "
+				    "template for driver %s\n", sht->name);
+		dump_stack();
 	}
 
-	shost_tp->detect(shost_tp);
-	if (!shost_tp->present)
-		return 0;
-
-	/*
-	 * XXX(hch) use scsi_tp_for_each_host() once it propagates
-	 *	    error returns properly.
-	 */
-	list_for_each_entry(shost, &scsi_host_list, sh_list)
-		if (shost->hostt == shost_tp)
-			if (scsi_add_host(shost, NULL))
-				goto out_of_space;
-
-	return 0;
-
-out_of_space:
-	scsi_unregister_host(shost_tp); /* easiest way to clean up?? */
-	return 1;
+	if (shost)
+		list_add_tail(&shost->sht_legacy_list, &sht->legacy_hosts);
+	return shost;
 }
 
-/**
- * scsi_unregister_host - unregister a low level host adapter driver
- * @shost_tp:	scsi host template to unregister.
- *
- * Description:
- * 	Similarly, this entry point should be called by a loadable module
- * 	if it is trying to remove a low level scsi driver from the system.
- *
- * Return value:
- * 	0 on Success / 1 on Failure
- *
- * Notes:
- * 	rmmod does not care what we return here the module will be
- * 	removed.
- **/
-int scsi_unregister_host(Scsi_Host_Template *shost_tp)
+void scsi_unregister(struct Scsi_Host *shost)
 {
-	scsi_tp_for_each_host(shost_tp, scsi_remove_host);
-	return 0;
-
+	list_del(&shost->sht_legacy_list);
+	scsi_host_put(shost);
 }
 
 /**
@@ -536,50 +286,6 @@
  **/
 void scsi_host_put(struct Scsi_Host *shost)
 {
-
 	class_device_put(&shost->class_dev);
 	put_device(&shost->host_gendev);
-}
-
-/**
- * scsi_host_init - set up the scsi host number list based on any entries
- * scsihosts.
- **/
-void __init scsi_host_init(void)
-{
-	char *shost_hn;
-
-	shost_hn = scsihosts;
-	while (shost_hn) {
-		scsi_host_next_hn++;
-		shost_hn = strpbrk(shost_hn, ":,");
-		if (shost_hn)
-			shost_hn++;
-	}
-}
-
-void scsi_host_busy_inc(struct Scsi_Host *shost, Scsi_Device *sdev)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(shost->host_lock, flags);
-	shost->host_busy++;
-	sdev->device_busy++;
-	spin_unlock_irqrestore(shost->host_lock, flags);
-}
-
-void scsi_host_busy_dec_and_test(struct Scsi_Host *shost, Scsi_Device *sdev)
-{
-	unsigned long flags;
-
-	spin_lock_irqsave(shost->host_lock, flags);
-	shost->host_busy--;
-	if (shost->in_recovery && shost->host_failed &&
-	    (shost->host_busy == shost->host_failed))
-	{
-		up(shost->eh_wait);
-		SCSI_LOG_ERROR_RECOVERY(5, printk("Waking error handler"
-					  " thread\n"));
-	}
-	spin_unlock_irqrestore(shost->host_lock, flags);
 }
diff -Nru a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h
--- a/drivers/scsi/hosts.h	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/hosts.h	Wed Jun 18 23:42:06 2003
@@ -28,519 +28,7 @@
 #include <linux/proc_fs.h>
 #include <linux/types.h>
 
-struct scsi_host_cmd_pool;
-
-
-/* It is senseless to set SG_ALL any higher than this - the performance
- *  does not get any better, and it wastes memory
- */
-#define SG_NONE 0
-#define SG_ALL 0xff
-
-#define DISABLE_CLUSTERING 0
-#define ENABLE_CLUSTERING 1
-
-/* The various choices mean:
- * NONE: Self evident.	Host adapter is not capable of scatter-gather.
- * ALL:	 Means that the host adapter module can do scatter-gather,
- *	 and that there is no limit to the size of the table to which
- *	 we scatter/gather data.
- * Anything else:  Indicates the maximum number of chains that can be
- *	 used in one scatter-gather request.
- */
-
-/*
- * The Scsi_Host_Template type has all that is needed to interface with a SCSI
- * host in a device independent matter.	 There is one entry for each different
- * type of host adapter that is supported on the system.
- */
-
-typedef struct	SHT
-{
-    /* Used with loadable modules so that we know when it is safe to unload */
-    struct module * module;
-
-    /* The pointer to the /proc/scsi directory entry */
-    struct proc_dir_entry *proc_dir;
-
-    /* proc-fs info function.
-     * Can be used to export driver statistics and other infos to the world
-     * outside the kernel ie. userspace and it also provides an interface
-     * to feed the driver with information. Check eata_dma_proc.c for reference
-     */
-    int (*proc_info)(struct Scsi_Host *, char *, char **, off_t, int, int);
-
-    /*
-     * The name pointer is a pointer to the name of the SCSI
-     * device detected.
-     */
-    const char *name;
-
-    /*
-     * The detect function shall return non zero on detection,
-     * indicating the number of host adapters of this particular
-     * type were found.	 It should also
-     * initialize all data necessary for this particular
-     * SCSI driver.  It is passed the host number, so this host
-     * knows where the first entry is in the scsi_hosts[] array.
-     *
-     * Note that the detect routine MUST not call any of the mid level
-     * functions to queue commands because things are not guaranteed
-     * to be set up yet.  The detect routine can send commands to
-     * the host adapter as long as the program control will not be
-     * passed to scsi.c in the processing of the command.  Note
-     * especially that scsi_malloc/scsi_free must not be called.
-     */
-    int (* detect)(struct SHT *);
-
-    /* Used with loadable modules to unload the host structures.  Note:
-     * there is a default action built into the modules code which may
-     * be sufficient for most host adapters.  Thus you may not have to supply
-     * this at all.
-     */
-    int (*release)(struct Scsi_Host *);
-
-    /*
-     * The info function will return whatever useful
-     * information the developer sees fit.  If not provided, then
-     * the name field will be used instead.
-     */
-    const char *(* info)(struct Scsi_Host *);
-
-    /*
-     * ioctl interface
-     */
-    int (*ioctl)(Scsi_Device *dev, int cmd, void *arg);
-
-    /*
-     * The command function takes a target, a command (this is a SCSI
-     * command formatted as per the SCSI spec, nothing strange), a
-     * data buffer pointer, and data buffer length pointer.  The return
-     * is a status int, bit fielded as follows :
-     * Byte What
-     * 0    SCSI status code
-     * 1    SCSI 1 byte message
-     * 2    host error return.
-     * 3    mid level error return
-     */
-    int (* command)(Scsi_Cmnd *);
-
-    /*
-     * The QueueCommand function works in a similar manner
-     * to the command function.	 It takes an additional parameter,
-     * void (* done)(int host, int code) which is passed the host
-     * # and exit result when the command is complete.
-     * Host number is the POSITION IN THE hosts array of THIS
-     * host adapter.
-     *
-     * if queuecommand returns 0, then the HBA has accepted the
-     * command.  The done() function must be called on the command
-     * when the driver has finished with it. (you may call done on the
-     * command before queuecommand returns, but in this case you
-     * *must* return 0 from queuecommand).
-     *
-     * queuecommand may also reject the command, in which case it may
-     * not touch the command and must not call done() for it.
-     *
-     * There are two possible rejection returns:
-     *
-     *   SCSI_MLQUEUE_DEVICE_BUSY: Block this device temporarily, but
-     *   allow commands to other devices serviced by this host.
-     *
-     *   SCSI_MLQUEUE_HOST_BUSY: Block all devices served by this
-     *   host temporarily.
-     *
-     *   for compatibility, any other non-zero return is treated the
-     *   same as SCSI_MLQUEUE_HOST_BUSY.
-     *
-     *   NOTE: "temporarily" means either until the next command for
-     *   this device/host completes, or a period of time determined by
-     *   I/O pressure in the system if there are no other outstanding
-     *   commands.
-     * */
-    int (* queuecommand)(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-
-    /*
-     * This is an error handling strategy routine.  You don't need to
-     * define one of these if you don't want to - there is a default
-     * routine that is present that should work in most cases.  For those
-     * driver authors that have the inclination and ability to write their
-     * own strategy routine, this is where it is specified.  Note - the
-     * strategy routine is *ALWAYS* run in the context of the kernel eh
-     * thread.  Thus you are guaranteed to *NOT* be in an interrupt handler
-     * when you execute this, and you are also guaranteed to *NOT* have any
-     * other commands being queued while you are in the strategy routine.
-     * When you return from this function, operations return to normal.
-     *
-     * See scsi_error.c scsi_unjam_host for additional comments about what
-     * this function should and should not be attempting to do.
-     */
-     int (*eh_strategy_handler)(struct Scsi_Host *);
-     int (*eh_abort_handler)(Scsi_Cmnd *);
-     int (*eh_device_reset_handler)(Scsi_Cmnd *);
-     int (*eh_bus_reset_handler)(Scsi_Cmnd *);
-     int (*eh_host_reset_handler)(Scsi_Cmnd *);
-
-    /*
-     * Old EH handlers, no longer used. Make them warn the user of old
-     * drivers by using a wrong type
-     */
-    int (*abort)(int);
-    int (*reset)(int,int);
-
-    /*
-     * slave_alloc()  -  Optional
-     * 
-     * Before the mid layer attempts to scan for a new device where none
-     * currently exists, it will call this entry in your driver.  Should
-     * your driver need to allocate any structs or perform any other init
-     * items in order to send commands to a currently unused target/lun
-     * combo, then this is where you can perform those allocations.  This
-     * is specifically so that drivers won't have to perform any kind of
-     * "is this a new device" checks in their queuecommand routine,
-     * thereby making the hot path a bit quicker.
-     *
-     * Return values: 0 on success, non-0 on failure
-     *
-     * Deallocation:  If we didn't find any devices at this ID, you will
-     * get an immediate call to slave_destroy().  If we find something here
-     * then you will get a call to slave_configure(), then the device will be
-     * used for however long it is kept around, then when the device is
-     * removed from the system (or * possibly at reboot time), you will
-     * then get a call to slave_detach().  This is assuming you implement
-     * slave_configure and slave_destroy.  However, if you allocate memory
-     * and hang it off the device struct, then you must implement the
-     * slave_destroy() routine at a minimum in order to avoid leaking memory
-     * each time a device is tore down.
-     */
-    int (* slave_alloc)(Scsi_Device *);
-
-    /*
-     * slave_configure()  -  Optional
-     * 
-     * Once the device has responded to an INQUIRY and we know the device
-     * is online, we call into the low level driver with the Scsi_Device *
-     * If the low level device driver implements this function, it *must*
-     * perform the task of setting the queue depth on the device.  All other
-     * tasks are optional and depend on what the driver supports and various
-     * implementation details.
-     * 
-     * Things currently recommended to be handled at this time include:
-     *
-     * 1.  Setting the device queue depth.  Proper setting of this is
-     *     described in the comments for scsi_adjust_queue_depth.
-     * 2.  Determining if the device supports the various synchronous
-     *     negotiation protocols.  The device struct will already have
-     *     responded to INQUIRY and the results of the standard items
-     *     will have been shoved into the various device flag bits, eg.
-     *     device->sdtr will be true if the device supports SDTR messages.
-     * 3.  Allocating command structs that the device will need.
-     * 4.  Setting the default timeout on this device (if needed).
-     * 5.  Anything else the low level driver might want to do on a device
-     *     specific setup basis...
-     * 6.  Return 0 on success, non-0 on error.  The device will be marked
-     *     as offline on error so that no access will occur.  If you return
-     *     non-0, your slave_detach routine will never get called for this
-     *     device, so don't leave any loose memory hanging around, clean
-     *     up after yourself before returning non-0
-     */
-    int (* slave_configure)(Scsi_Device *);
-
-    /*
-     * slave_destroy()  -  Optional
-     *
-     * Immediately prior to deallocating the device and after all activity
-     * has ceased the mid layer calls this point so that the low level driver
-     * may completely detach itself from the scsi device and vice versa.
-     * The low level driver is responsible for freeing any memory it allocated
-     * in the slave_alloc or slave_configure calls. 
-     */
-    void (* slave_destroy)(Scsi_Device *);
-
-    /*
-     * This function determines the bios parameters for a given
-     * harddisk.  These tend to be numbers that are made up by
-     * the host adapter.  Parameters:
-     * size, device, list (heads, sectors, cylinders)
-     */
-    int (* bios_param)(struct scsi_device *, struct block_device *,
-		    sector_t, int []);
-
-    /*
-     * This determines if we will use a non-interrupt driven
-     * or an interrupt driven scheme,  It is set to the maximum number
-     * of simultaneous commands a given host adapter will accept.
-     */
-    int can_queue;
-
-    /*
-     * In many instances, especially where disconnect / reconnect are
-     * supported, our host also has an ID on the SCSI bus.  If this is
-     * the case, then it must be reserved.  Please set this_id to -1 if
-     * your setup is in single initiator mode, and the host lacks an
-     * ID.
-     */
-    int this_id;
-
-    /*
-     * This determines the degree to which the host adapter is capable
-     * of scatter-gather.
-     */
-    short unsigned int sg_tablesize;
-
-    /*
-     * if the host adapter has limitations beside segment count
-     */
-    short unsigned int max_sectors;
-
-    /*
-     * True if this host adapter can make good use of linked commands.
-     * This will allow more than one command to be queued to a given
-     * unit on a given host.  Set this to the maximum number of command
-     * blocks to be provided for each device.  Set this to 1 for one
-     * command block per lun, 2 for two, etc.  Do not set this to 0.
-     * You should make sure that the host adapter will do the right thing
-     * before you try setting this above 1.
-     */
-    short cmd_per_lun;
-
-    /*
-     * present contains counter indicating how many boards of this
-     * type were found when we did the scan.
-     */
-    unsigned char present;
-
-    /*
-     * true if this host adapter uses unchecked DMA onto an ISA bus.
-     */
-    unsigned unchecked_isa_dma:1;
-
-    /*
-     * true if this host adapter can make good use of clustering.
-     * I originally thought that if the tablesize was large that it
-     * was a waste of CPU cycles to prepare a cluster list, but
-     * it works out that the Buslogic is faster if you use a smaller
-     * number of segments (i.e. use clustering).  I guess it is
-     * inefficient.
-     */
-    unsigned use_clustering:1;
-
-    /*
-     * True for emulated SCSI host adapters (e.g. ATAPI)
-     */
-    unsigned emulated:1;
-
-    unsigned highmem_io:1;
-
-    /* 
-     * True if the driver wishes to use the generic block layer
-     * tag queueing functions
-     */
-    unsigned use_blk_tcq:1;
-
-    /*
-     * Name of proc directory
-     */
-    char *proc_name;
-
-    /*
-     * countdown for host blocking with no commands outstanding
-     */
-    unsigned int max_host_blocked;
-
-    /*
-     * Default value for the blocking.  If the queue is empty, host_blocked
-     * counts down in the request_fn until it restarts host operations as
-     * zero is reached.  
-     *
-     * FIXME: This should probably be a value in the template */
-    #define SCSI_DEFAULT_HOST_BLOCKED	7
-
-    /*
-     * pointer to the sysfs class properties for this host
-     */
-    struct class_device_attribute **shost_attrs;
-
-    /*
-     * Pointer to the SCSI device properties for this host
-     */
-    struct device_attribute **sdev_attrs;
-
-} Scsi_Host_Template;
-
-/*
- * The scsi_hosts array is the array containing the data for all
- * possible <supported> scsi hosts.   This is similar to the
- * Scsi_Host_Template, except that we have one entry for each
- * actual physical host adapter on the system, stored as a linked
- * list.  Note that if there are 2 aha1542 boards, then there will
- * be two Scsi_Host entries, but only 1 Scsi_Host_Template entry.
- */
-
-struct Scsi_Host
-{
-/* private: */
-    /*
-     * This information is private to the scsi mid-layer.  Wrapping it in a
-     * struct private is a way of marking it in a sort of C++ type of way.
-     */
-    struct list_head      sh_list;
-    struct list_head	  my_devices;
-
-    struct scsi_host_cmd_pool *cmd_pool;
-    spinlock_t            free_list_lock;
-    struct list_head      free_list;   /* backup store of cmd structs */
-    struct list_head      starved_list;
-
-    spinlock_t		  default_lock;
-    spinlock_t		  *host_lock;
-
-    struct list_head	eh_cmd_q;
-    struct task_struct    * ehandler;  /* Error recovery thread. */
-    struct semaphore      * eh_wait;   /* The error recovery thread waits on
-                                          this. */
-    struct completion     * eh_notify; /* wait for eh to begin or end */
-    struct semaphore      * eh_action; /* Wait for specific actions on the
-                                          host. */
-    unsigned int            eh_active:1; /* Indicates the eh thread is awake and active if
-                                          this is true. */
-    unsigned int            eh_kill:1; /* set when killing the eh thread */
-    wait_queue_head_t       host_wait;
-    Scsi_Host_Template    * hostt;
-    volatile unsigned short host_busy;   /* commands actually active on low-level */
-    volatile unsigned short host_failed; /* commands that failed. */
-    
-/* public: */
-    unsigned short host_no;  /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */
-    int resetting; /* if set, it means that last_reset is a valid value */
-    unsigned long last_reset;
-
-    /*
-     *	These three parameters can be used to allow for wide scsi,
-     *	and for host adapters that support multiple busses
-     *	The first two should be set to 1 more than the actual max id
-     *	or lun (i.e. 8 for normal systems).
-     */
-    unsigned int max_id;
-    unsigned int max_lun;
-    unsigned int max_channel;
-
-    /* These parameters should be set by the detect routine */
-    unsigned long base;
-    unsigned long io_port;
-    unsigned char n_io_port;
-    unsigned char dma_channel;
-    unsigned int  irq;
-
-    /*
-     * This is a unique identifier that must be assigned so that we
-     * have some way of identifying each detected host adapter properly
-     * and uniquely.  For hosts that do not support more than one card
-     * in the system at one time, this does not need to be set.  It is
-     * initialized to 0 in scsi_register.
-     */
-    unsigned int unique_id;
-
-    /*
-     * The rest can be copied from the template, or specifically
-     * initialized, as required.
-     */
-
-    /*
-     * The maximum length of SCSI commands that this host can accept.
-     * Probably 12 for most host adapters, but could be 16 for others.
-     * For drivers that don't set this field, a value of 12 is
-     * assumed.  I am leaving this as a number rather than a bit
-     * because you never know what subsequent SCSI standards might do
-     * (i.e. could there be a 20 byte or a 24-byte command a few years
-     * down the road?).  
-     */
-    unsigned char max_cmd_len;
-
-    int this_id;
-    int can_queue;
-    short cmd_per_lun;
-    short unsigned int sg_tablesize;
-    short unsigned int max_sectors;
-
-    unsigned in_recovery:1;
-    unsigned unchecked_isa_dma:1;
-    unsigned use_clustering:1;
-    unsigned highmem_io:1;
-    unsigned use_blk_tcq:1;
-
-    /*
-     * Host has requested that no further requests come through for the
-     * time being.
-     */
-    unsigned host_self_blocked:1;
-    
-    /*
-     * Host uses correct SCSI ordering not PC ordering. The bit is
-     * set for the minority of drivers whose authors actually read the spec ;)
-     */
-    unsigned reverse_ordering:1;
-
-    /*
-     * Host has rejected a command because it was busy.
-     */
-    unsigned int host_blocked;
-
-    /*
-     * Value host_blocked counts down from
-     */
-    unsigned int max_host_blocked;
-
-    /* 
-     * Support for sysfs
-     */
-    struct device host_gendev;
-    struct class_device class_dev;
-
-    /*
-     * We should ensure that this is aligned, both for better performance
-     * and also because some compilers (m68k) don't automatically force
-     * alignment to a long boundary.
-     */
-    unsigned long hostdata[0]  /* Used for storage of host specific stuff */
-        __attribute__ ((aligned (sizeof(unsigned long))));
-};
-
-#define		dev_to_shost(d)		\
-	container_of(d, struct Scsi_Host, host_gendev)
-#define		class_to_shost(d)	\
-	container_of(d, struct Scsi_Host, class_dev)
-
-/*
- * These two functions are used to allocate and free a pseudo device
- * which will connect to the host adapter itself rather than any
- * physical device.  You must deallocate when you are done with the
- * thing.  This physical pseudo-device isn't real and won't be available
- * from any high-level drivers.
- */
-extern void scsi_free_host_dev(Scsi_Device *);
-extern Scsi_Device * scsi_get_host_dev(struct Scsi_Host *);
-
-extern void scsi_unblock_requests(struct Scsi_Host *);
-extern void scsi_block_requests(struct Scsi_Host *);
-extern void scsi_report_bus_reset(struct Scsi_Host *, int);
-extern void scsi_report_device_reset(struct Scsi_Host *, int, int);
-
-static inline void scsi_assign_lock(struct Scsi_Host *shost, spinlock_t *lock)
-{
-	shost->host_lock = lock;
-}
-
-static inline void scsi_set_device(struct Scsi_Host *shost,
-                                   struct device *dev)
-{
-        shost->host_gendev.parent = dev;
-}
-
-static inline struct device *scsi_get_device(struct Scsi_Host *shost)
-{
-        return shost->host_gendev.parent;
-}
+#include <scsi/scsi_host.h>
 
 struct scsi_driver {
 	struct module		*owner;
@@ -560,23 +48,6 @@
 #define scsi_unregister_interface(intf) \
 	class_interface_unregister(intf)
 
-/*
- * HBA allocation/freeing.
- */
-extern struct Scsi_Host * scsi_register(Scsi_Host_Template *, int);
-extern void scsi_unregister(struct Scsi_Host *);
-
-/*
- * HBA registration/unregistration.
- */
-extern int scsi_add_host(struct Scsi_Host *, struct device *);
-extern int scsi_remove_host(struct Scsi_Host *);
-
-/*
- * Legacy HBA template registration/unregistration.
- */
-extern int scsi_register_host(Scsi_Host_Template *);
-extern int scsi_unregister_host(Scsi_Host_Template *);
 
 /**
  * scsi_find_device - find a device given the host
@@ -585,9 +56,9 @@
  * @pun:	SCSI target number (physical unit number)
  * @lun:	SCSI Logical Unit Number
  **/
-static inline Scsi_Device *scsi_find_device(struct Scsi_Host *shost,
+static inline struct scsi_device *scsi_find_device(struct Scsi_Host *shost,
                                             int channel, int pun, int lun) {
-        Scsi_Device *sdev;
+        struct scsi_device *sdev;
 
 	list_for_each_entry (sdev, &shost->my_devices, siblings)
                 if (sdev->channel == channel && sdev->id == pun
@@ -595,7 +66,5 @@
                         return sdev;
         return NULL;
 }
-
-extern void scsi_sysfs_release_attributes(struct SHT *hostt);
 
 #endif
diff -Nru a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
--- a/drivers/scsi/ibmmca.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/ibmmca.c	Wed Jun 18 23:42:06 2003
@@ -1793,15 +1793,6 @@
 	return shpnt;
 }
 
-static int ibmmca_command(Scsi_Cmnd * cmd)
-{
-	ibmmca_queuecommand(cmd, internal_done);
-	cmd->SCp.Status = 0;
-	while (!cmd->SCp.Status)
-		barrier();
-	return cmd->result;
-}
-
 static int ibmmca_release(struct Scsi_Host *shpnt)
 {
 	release_region(shpnt->io_port, shpnt->n_io_port);
@@ -2490,7 +2481,6 @@
           .name           = "IBM SCSI-Subsystem",
           .detect         = ibmmca_detect,
           .release        = ibmmca_release,
-          .command        = ibmmca_command,
           .queuecommand   = ibmmca_queuecommand,
 	  .eh_abort_handler = ibmmca_abort,
 	  .eh_host_reset_handler = ibmmca_host_reset,
diff -Nru a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
--- a/drivers/scsi/ide-scsi.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/ide-scsi.c	Wed Jun 18 23:42:08 2003
@@ -612,7 +612,7 @@
 	drive->disk->fops = ide_fops;
 
 	scsi_remove_host(scsihost);
-	scsi_unregister(scsihost);
+	scsi_host_put(scsihost);
 	return 0;
 }
 
@@ -964,7 +964,7 @@
 	if (!strstr("ide-scsi", drive->driver_req) ||
 	    !drive->present ||
 	    drive->media == ide_disk ||
-	    !(host = scsi_register(&idescsi_template,sizeof(idescsi_scsi_t))))
+	    !(host = scsi_host_alloc(&idescsi_template,sizeof(idescsi_scsi_t))))
 		return 1;
 
 	host->max_id = 1;
@@ -984,7 +984,7 @@
 		ide_unregister_subdriver(drive);
 	}
 
-	scsi_unregister(host);
+	scsi_host_put(host);
 	return err;
 }
 
diff -Nru a/drivers/scsi/imm.c b/drivers/scsi/imm.c
--- a/drivers/scsi/imm.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/scsi/imm.c	Wed Jun 18 23:42:09 2003
@@ -113,7 +113,6 @@
 	.name				= "Iomega VPI2 (imm) interface",
 	.detect				= imm_detect,
 	.release			= imm_release,
-	.command			= imm_command,
 	.queuecommand			= imm_queuecommand,
 	.eh_abort_handler               = imm_abort,
 	.eh_bus_reset_handler           = imm_reset,
@@ -856,39 +855,6 @@
 	    return 0;
     }
     return 1;			/* FINISH_RETURN */
-}
-
-/* deprecated synchronous interface */
-int imm_command(Scsi_Cmnd * cmd)
-{
-    static int first_pass = 1;
-    int host_no = cmd->device->host->unique_id;
-
-    if (first_pass) {
-	printk("imm: using non-queuing interface\n");
-	first_pass = 0;
-    }
-    if (imm_hosts[host_no].cur_cmd) {
-	printk("IMM: bug in imm_command\n");
-	return 0;
-    }
-    imm_hosts[host_no].failed = 0;
-    imm_hosts[host_no].jstart = jiffies;
-    imm_hosts[host_no].cur_cmd = cmd;
-    cmd->result = DID_ERROR << 16;	/* default return code */
-    cmd->SCp.phase = 0;
-
-    imm_pb_claim(host_no);
-
-    while (imm_engine(&imm_hosts[host_no], cmd))
-	schedule();
-
-    if (cmd->SCp.phase)		/* Only disconnect if we have connected */
-	imm_disconnect(cmd->device->host->unique_id);
-
-    imm_pb_release(host_no);
-    imm_hosts[host_no].cur_cmd = 0;
-    return cmd->result;
 }
 
 /*
diff -Nru a/drivers/scsi/ini9100u.c b/drivers/scsi/ini9100u.c
--- a/drivers/scsi/ini9100u.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/ini9100u.c	Wed Jun 18 23:42:06 2003
@@ -147,7 +147,6 @@
 	.name		= i91u_REVID,
 	.detect		= i91u_detect,
 	.release	= i91u_release,
-	.command	= i91u_command,
 	.queuecommand	= i91u_queue,
 	.abort		= i91u_abort,
 	.reset		= i91u_reset,
@@ -555,15 +554,6 @@
 	i91uBuildSCB(pHCB, pSCB, SCpnt);
 	tul_exec_scb(pHCB, pSCB);	/* Start execute SCB            */
 	return (0);
-}
-
-/*
- *  We only support command in interrupt-driven fashion
- */
-int i91u_command(Scsi_Cmnd * SCpnt)
-{
-	printk("i91u: interrupt driven driver; use i91u_queue()\n");
-	return -1;
 }
 
 /*
diff -Nru a/drivers/scsi/inia100.c b/drivers/scsi/inia100.c
--- a/drivers/scsi/inia100.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/inia100.c	Wed Jun 18 23:42:06 2003
@@ -156,11 +156,11 @@
 
 	spin_lock_irqsave(&(pHCB->pSRB_lock), flags);
 
-	pSRB->next = NULL;	/* Pointer to next */
+	pSRB->SCp.ptr = NULL;	/* Pointer to next */
 	if (pHCB->pSRB_head == NULL)
 		pHCB->pSRB_head = pSRB;
 	else
-		pHCB->pSRB_tail->next = pSRB;	/* Pointer to next */
+		pHCB->pSRB_tail->SCp.ptr = (char *)pSRB;	/* Pointer to next */
 	pHCB->pSRB_tail = pSRB;
 	spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags);
 	return;
@@ -179,8 +179,8 @@
 	ULONG flags;
 	spin_lock_irqsave(&(pHCB->pSRB_lock), flags);
 	if ((pSRB = (Scsi_Cmnd *) pHCB->pSRB_head) != NULL) {
-		pHCB->pSRB_head = pHCB->pSRB_head->next;
-		pSRB->next = NULL;
+		pHCB->pSRB_head = (Scsi_Cmnd *) pHCB->pSRB_head->SCp.ptr;
+		pSRB->SCp.ptr = NULL;
 	}
 	spin_unlock_irqrestore(&(pHCB->pSRB_lock), flags);
 	return (pSRB);
diff -Nru a/drivers/scsi/ips.c b/drivers/scsi/ips.c
--- a/drivers/scsi/ips.c	Wed Jun 18 23:42:05 2003
+++ b/drivers/scsi/ips.c	Wed Jun 18 23:42:05 2003
@@ -725,7 +725,7 @@
    free_irq(ha->irq, ha);
 
    IPS_REMOVE_HOST(sh);
-   scsi_unregister(sh);
+   scsi_host_put(sh);
 
    ips_released_controllers++;
 
@@ -6732,7 +6732,7 @@
 ips_register_scsi( int index){
 	struct Scsi_Host *sh;
 	ips_ha_t *ha, *oldha = ips_ha[index];
-	sh = scsi_register(&ips_driver_template, sizeof(ips_ha_t));
+	sh = scsi_host_alloc(&ips_driver_template, sizeof(ips_ha_t));
 	if(!sh) {
 		IPS_PRINTK(KERN_WARNING, oldha->pcidev, "Unable to register controller with SCSI subsystem\n");
 		return -1;
@@ -6743,7 +6743,7 @@
 	/* Install the interrupt handler with the new ha */
 	if (request_irq(ha->irq, do_ipsintr, SA_SHIRQ, ips_name, ha)) {
 		IPS_PRINTK(KERN_WARNING, ha->pcidev, "Unable to install interrupt handler\n" );
-		scsi_unregister(sh);
+		scsi_host_put(sh);
 		return -1;
 	}
 
diff -Nru a/drivers/scsi/jazz_esp.c b/drivers/scsi/jazz_esp.c
--- a/drivers/scsi/jazz_esp.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/jazz_esp.c	Wed Jun 18 23:42:06 2003
@@ -139,6 +139,18 @@
     return 0;
 }
 
+static int jazz_esp_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 /************************************************************* DMA Functions */
 static int dma_bytes_sent(struct NCR_ESP *esp, int fifo_count)
 {
@@ -278,8 +290,8 @@
 	.proc_info		= &esp_proc_info,
 	.name			= "ESP 100/100a/200",
 	.detect			= jazz_esp_detect,
+	.release		= jazz_esp_release,
 	.info			= esp_info,
-	.command		= esp_command,
 	.queuecommand		= esp_queue,
 	.eh_abort_handler	= esp_abort,
 	.eh_bus_reset_handler	= esp_reset,
diff -Nru a/drivers/scsi/lasi700.c b/drivers/scsi/lasi700.c
--- a/drivers/scsi/lasi700.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/lasi700.c	Wed Jun 18 23:42:06 2003
@@ -31,19 +31,14 @@
  * machines for me to debug the driver on.
  */
 
-#ifndef __hppa__
-#error "lasi700 only compiles on hppa architecture"
-#endif
-
 #include <linux/kernel.h>
+#include <linux/module.h>
 #include <linux/init.h>
 #include <linux/types.h>
 #include <linux/stat.h>
 #include <linux/mm.h>
-#include <linux/blk.h>
+#include <linux/blkdev.h>
 #include <linux/sched.h>
-#include <linux/version.h>
-#include <linux/config.h>
 #include <linux/ioport.h>
 #include <linux/dma-mapping.h>
 
@@ -54,65 +49,27 @@
 #include <asm/parisc-device.h>
 #include <asm/delay.h>
 
-#include <linux/module.h>
-
 #include "scsi.h"
 #include "hosts.h"
 
 #include "lasi700.h"
 #include "53c700.h"
 
-#ifdef MODULE
-
-char *lasi700;			/* command line from insmod */
-
 MODULE_AUTHOR("James Bottomley");
 MODULE_DESCRIPTION("lasi700 SCSI Driver");
 MODULE_LICENSE("GPL");
-MODULE_PARM(lasi700, "s");
-
-#endif
 
-#ifdef MODULE
-#define ARG_SEP ' '
-#else
-#define ARG_SEP ','
-#endif
-
-static unsigned long __initdata opt_base;
-static int __initdata opt_irq;
-
-static int __init
-param_setup(char *string)
-{
-	char *pos = string, *next;
-
-	while(pos != NULL && (next = strchr(pos, ':')) != NULL) {
-		int val = (int)simple_strtoul(++next, NULL, 0);
-		
-		if(!strncmp(pos, "addr:", 5))
-			opt_base = val;
-		else if(!strncmp(pos, "irq:", 4))
-			opt_irq = val;
-
-		if((pos = strchr(pos, ARG_SEP)) != NULL)
-			pos++;
-	}
-	return 1;
-}
-
-#ifndef MODULE
-__setup("lasi700=", param_setup);
-#endif
-
-static Scsi_Host_Template __initdata *host_tpnt = NULL;
-static int __initdata host_count = 0;
 static struct parisc_device_id lasi700_scsi_tbl[] = {
 	LASI700_ID_TABLE,
 	LASI710_ID_TABLE,
 	{ 0 }
 };
 
+static Scsi_Host_Template lasi700_template = {
+	.name		= "LASI SCSI 53c700",
+	.proc_name	= "lasi700",
+	.this_id	= 7,
+};
 MODULE_DEVICE_TABLE(parisc, lasi700_scsi_tbl);
 
 static struct parisc_driver lasi700_driver = {
@@ -122,50 +79,36 @@
 };
 
 static int __init
-lasi700_detect(Scsi_Host_Template *tpnt)
-{
-	host_tpnt = tpnt;
-
-#ifdef MODULE
-	if(lasi700)
-		param_setup(lasi700);
-#endif
-
-	register_parisc_driver(&lasi700_driver);
-
-	return (host_count != 0);
-}
-
-static int __init
 lasi700_driver_callback(struct parisc_device *dev)
 {
 	unsigned long base = dev->hpa + LASI_SCSI_CORE_OFFSET;
-	char *driver_name;
+	struct NCR_700_Host_Parameters *hostdata;
 	struct Scsi_Host *host;
-	struct NCR_700_Host_Parameters *hostdata =
-		kmalloc(sizeof(struct NCR_700_Host_Parameters),
-			GFP_KERNEL);
-	if(dev->id.sversion == LASI_700_SVERSION) {
-		driver_name = "lasi700";
-	} else {
-		driver_name = "lasi710";
-	}
-	snprintf(dev->dev.name, sizeof(dev->dev.name), "%s", driver_name);
-	if(hostdata == NULL) {
+
+	snprintf(dev->dev.name, sizeof(dev->dev.name), "%s",
+		 (dev->id.sversion == LASI_700_SVERSION) ?
+		  "lasi700" : "lasi710");
+
+	hostdata = kmalloc(sizeof(*hostdata), GFP_KERNEL);
+	if (!hostdata) {
 		printk(KERN_ERR "%s: Failed to allocate host data\n",
-		       driver_name);
+		       dev->dev.name);
 		return 1;
 	}
 	memset(hostdata, 0, sizeof(struct NCR_700_Host_Parameters));
-	if(request_mem_region(base, 64, driver_name) == NULL) {
+
+	if (!request_mem_region(base, 64, dev->dev.name)) {
 		printk(KERN_ERR "%s: Failed to claim memory region\n",
-		       driver_name);
-		kfree(hostdata);
-		return 1;
+		       dev->dev.name);
+		goto out_kfree;
 	}
+
+	hostdata->dev = &dev->dev;
+	dma_set_mask(&dev->dev, 0xffffffffUL);
 	hostdata->base = base;
 	hostdata->differential = 0;
-	if(dev->id.sversion == LASI_700_SVERSION) {
+
+	if (dev->id.sversion == LASI_700_SVERSION) {
 		hostdata->clock = LASI700_CLOCK;
 		hostdata->force_le_on_be = 1;
 	} else {
@@ -174,26 +117,34 @@
 		hostdata->chip710 = 1;
 		hostdata->dmode_extra = DMODE_FC2;
 	}
-	hostdata->dev = &dev->dev;
-	dma_set_mask(&dev->dev, 0xffffffffUL);
-	if((host = NCR_700_detect(host_tpnt, hostdata)) == NULL) {
-		kfree(hostdata);
-		release_mem_region(host->base, 64);
-		return 1;
-	}
-	scsi_set_device(host, &dev->dev);
+
+	NCR_700_set_mem_mapped(hostdata);
+
+	host = NCR_700_detect(&lasi700_template, hostdata);
+	if (!host)
+		goto out_release_mem_region;
+
 	host->irq = dev->irq;
-	if(request_irq(dev->irq, NCR_700_intr, SA_SHIRQ, driver_name, host)) {
+	if (request_irq(dev->irq, NCR_700_intr, SA_SHIRQ,
+				dev->dev.name, host)) {
 		printk(KERN_ERR "%s: irq problem, detaching\n",
-		       driver_name);
-		scsi_unregister(host);
-		NCR_700_release(host);
-		return 1;
+		       dev->dev.name);
+		goto out_put_host;
 	}
-	host_count++;
+
+	scsi_add_host(host, &dev->dev);
 	return 0;
+
+ out_put_host:
+	scsi_host_put(host);
+ out_release_mem_region:
+	release_mem_region(base, 64);
+ out_kfree:
+	kfree(hostdata);
+	return 1;
 }
 
+#if 0
 static int
 lasi700_release(struct Scsi_Host *host)
 {
@@ -207,12 +158,12 @@
 	unregister_parisc_driver(&lasi700_driver);
 	return 1;
 }
+#endif
+
+static int __init
+lasi700_init(void)
+{
+	return register_parisc_driver(&lasi700_driver);
+}
 
-static Scsi_Host_Template driver_template = {
-	.name		= "LASI SCSI 53c700",
-	.proc_name	= "lasi700",
-	.detect		= lasi700_detect,
-	.release	= lasi700_release,
-	.this_id	= 7,
-};
-#include "scsi_module.c"
+module_init(lasi700_init);
diff -Nru a/drivers/scsi/mac_esp.c b/drivers/scsi/mac_esp.c
--- a/drivers/scsi/mac_esp.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/mac_esp.c	Wed Jun 18 23:42:07 2003
@@ -464,6 +464,16 @@
 	return chipspresent;
 }
 
+static int mac_esp_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 /*
  * I've been wondering what this is supposed to do, for some time. Talking 
  * to Allen Briggs: These machines have an extra register someplace where the
@@ -717,8 +727,8 @@
 	.proc_name		= "esp",
 	.name			= "Mac 53C9x SCSI",
 	.detect			= mac_esp_detect,
+	.release		= mac_esp_release,
 	.info			= esp_info,
-	/* .command		= esp_command, */
 	.queuecommand		= esp_queue,
 	.eh_abort_handler	= esp_abort,
 	.eh_bus_reset_handler	= esp_reset,
diff -Nru a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
--- a/drivers/scsi/megaraid.c	Wed Jun 18 23:42:05 2003
+++ b/drivers/scsi/megaraid.c	Wed Jun 18 23:42:05 2003
@@ -723,7 +723,7 @@
 {
 	dma_addr_t	prod_info_dma_handle;
 	mega_inquiry3	*inquiry3;
-	u8	raw_mbox[sizeof(mbox_t)];
+	u8	raw_mbox[sizeof(struct mbox_out)];
 	mbox_t	*mbox;
 	int	retval;
 
@@ -732,14 +732,14 @@
 	mbox = (mbox_t *)raw_mbox;
 
 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
-	memset(mbox, 0, sizeof(*mbox));
+	memset(&mbox->m_out, 0, sizeof(raw_mbox));
 
 	/*
 	 * Try to issue Inquiry3 command
 	 * if not succeeded, then issue MEGA_MBOXCMD_ADAPTERINQ command and
 	 * update enquiry3 structure
 	 */
-	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
 
 	inquiry3 = (mega_inquiry3 *)adapter->mega_buffer;
 
@@ -762,10 +762,10 @@
 
 		inq = &ext_inq->raid_inq;
 
-		mbox->xferaddr = (u32)dma_handle;
+		mbox->m_out.xferaddr = (u32)dma_handle;
 
 		/*issue old 0x04 command to adapter */
-		mbox->cmd = MEGA_MBOXCMD_ADPEXTINQ;
+		mbox->m_out.cmd = MEGA_MBOXCMD_ADPEXTINQ;
 
 		issue_scb_block(adapter, raw_mbox);
 
@@ -790,7 +790,7 @@
 				&adapter->product_info,
 				sizeof(mega_product_info), PCI_DMA_FROMDEVICE);
 
-		mbox->xferaddr = prod_info_dma_handle;
+		mbox->m_out.xferaddr = prod_info_dma_handle;
 
 		raw_mbox[0] = FC_NEW_CONFIG;	/* i.e. mbox->cmd=0xA1 */
 		raw_mbox[2] = NC_SUBOP_PRODUCT_INFO;	/* i.e. 0x0E */
@@ -1141,10 +1141,10 @@
 			memcpy(pthru->cdb, cmd->cmnd, cmd->cmd_len);
 
 			if( adapter->has_64bit_addr ) {
-				mbox->cmd = MEGA_MBOXCMD_PASSTHRU64;
+				mbox->m_out.cmd = MEGA_MBOXCMD_PASSTHRU64;
 			}
 			else {
-				mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
+				mbox->m_out.cmd = MEGA_MBOXCMD_PASSTHRU;
 			}
 
 			scb->dma_direction = PCI_DMA_FROMDEVICE;
@@ -1152,7 +1152,7 @@
 			pthru->numsgelements = mega_build_sglist(adapter, scb,
 				&pthru->dataxferaddr, &pthru->dataxferlen);
 
-			mbox->xferaddr = scb->pthru_dma_addr;
+			mbox->m_out.xferaddr = scb->pthru_dma_addr;
 
 			return scb;
 
@@ -1175,19 +1175,19 @@
 			mbox = (mbox_t *)scb->raw_mbox;
 
 			memset(mbox, 0, sizeof(scb->raw_mbox));
-			mbox->logdrv = ldrv_num;
+			mbox->m_out.logdrv = ldrv_num;
 
 			/*
 			 * A little hack: 2nd bit is zero for all scsi read
 			 * commands and is set for all scsi write commands
 			 */
 			if( adapter->has_64bit_addr ) {
-				mbox->cmd = (*cmd->cmnd & 0x02) ?
+				mbox->m_out.cmd = (*cmd->cmnd & 0x02) ?
 					MEGA_MBOXCMD_LWRITE64:
 					MEGA_MBOXCMD_LREAD64 ;
 			}
 			else {
-				mbox->cmd = (*cmd->cmnd & 0x02) ?
+				mbox->m_out.cmd = (*cmd->cmnd & 0x02) ?
 					MEGA_MBOXCMD_LWRITE:
 					MEGA_MBOXCMD_LREAD ;
 			}
@@ -1196,13 +1196,13 @@
 			 * 6-byte READ(0x08) or WRITE(0x0A) cdb
 			 */
 			if( cmd->cmd_len == 6 ) {
-				mbox->numsectors = (u32) cmd->cmnd[4];
-				mbox->lba =
+				mbox->m_out.numsectors = (u32) cmd->cmnd[4];
+				mbox->m_out.lba =
 					((u32)cmd->cmnd[1] << 16) |
 					((u32)cmd->cmnd[2] << 8) |
 					(u32)cmd->cmnd[3];
 
-				mbox->lba &= 0x1FFFFF;
+				mbox->m_out.lba &= 0x1FFFFF;
 
 #if MEGA_HAVE_STATS
 				/*
@@ -1213,11 +1213,11 @@
 				if (*cmd->cmnd == READ_6) {
 					adapter->nreads[ldrv_num%0x80]++;
 					adapter->nreadblocks[ldrv_num%0x80] +=
-						mbox->numsectors;
+						mbox->m_out.numsectors;
 				} else {
 					adapter->nwrites[ldrv_num%0x80]++;
 					adapter->nwriteblocks[ldrv_num%0x80] +=
-						mbox->numsectors;
+						mbox->m_out.numsectors;
 				}
 #endif
 			}
@@ -1226,10 +1226,10 @@
 			 * 10-byte READ(0x28) or WRITE(0x2A) cdb
 			 */
 			if( cmd->cmd_len == 10 ) {
-				mbox->numsectors =
+				mbox->m_out.numsectors =
 					(u32)cmd->cmnd[8] |
 					((u32)cmd->cmnd[7] << 8);
-				mbox->lba =
+				mbox->m_out.lba =
 					((u32)cmd->cmnd[2] << 24) |
 					((u32)cmd->cmnd[3] << 16) |
 					((u32)cmd->cmnd[4] << 8) |
@@ -1239,11 +1239,11 @@
 				if (*cmd->cmnd == READ_10) {
 					adapter->nreads[ldrv_num%0x80]++;
 					adapter->nreadblocks[ldrv_num%0x80] +=
-						mbox->numsectors;
+						mbox->m_out.numsectors;
 				} else {
 					adapter->nwrites[ldrv_num%0x80]++;
 					adapter->nwriteblocks[ldrv_num%0x80] +=
-						mbox->numsectors;
+						mbox->m_out.numsectors;
 				}
 #endif
 			}
@@ -1252,13 +1252,13 @@
 			 * 12-byte READ(0xA8) or WRITE(0xAA) cdb
 			 */
 			if( cmd->cmd_len == 12 ) {
-				mbox->lba =
+				mbox->m_out.lba =
 					((u32)cmd->cmnd[2] << 24) |
 					((u32)cmd->cmnd[3] << 16) |
 					((u32)cmd->cmnd[4] << 8) |
 					(u32)cmd->cmnd[5];
 
-				mbox->numsectors =
+				mbox->m_out.numsectors =
 					((u32)cmd->cmnd[6] << 24) |
 					((u32)cmd->cmnd[7] << 16) |
 					((u32)cmd->cmnd[8] << 8) |
@@ -1268,11 +1268,11 @@
 				if (*cmd->cmnd == READ_12) {
 					adapter->nreads[ldrv_num%0x80]++;
 					adapter->nreadblocks[ldrv_num%0x80] +=
-						mbox->numsectors;
+						mbox->m_out.numsectors;
 				} else {
 					adapter->nwrites[ldrv_num%0x80]++;
 					adapter->nwriteblocks[ldrv_num%0x80] +=
-						mbox->numsectors;
+						mbox->m_out.numsectors;
 				}
 #endif
 			}
@@ -1288,8 +1288,8 @@
 			}
 
 			/* Calculate Scatter-Gather info */
-			mbox->numsgelements = mega_build_sglist(adapter, scb,
-					(u32 *)&mbox->xferaddr, (u32 *)&seg);
+			mbox->m_out.numsgelements = mega_build_sglist(adapter, scb,
+					(u32 *)&mbox->m_out.xferaddr, (u32 *)&seg);
 
 			return scb;
 
@@ -1357,9 +1357,9 @@
 			epthru = mega_prepare_extpassthru(adapter, scb, cmd,
 					channel, target);
 
-			mbox->cmd = MEGA_MBOXCMD_EXTPTHRU;
+			mbox->m_out.cmd = MEGA_MBOXCMD_EXTPTHRU;
 
-			mbox->xferaddr = scb->epthru_dma_addr;
+			mbox->m_out.xferaddr = scb->epthru_dma_addr;
 
 		}
 		else {
@@ -1369,13 +1369,13 @@
 
 			/* Initialize mailbox */
 			if( adapter->has_64bit_addr ) {
-				mbox->cmd = MEGA_MBOXCMD_PASSTHRU64;
+				mbox->m_out.cmd = MEGA_MBOXCMD_PASSTHRU64;
 			}
 			else {
-				mbox->cmd = MEGA_MBOXCMD_PASSTHRU;
+				mbox->m_out.cmd = MEGA_MBOXCMD_PASSTHRU;
 			}
 
-			mbox->xferaddr = scb->pthru_dma_addr;
+			mbox->m_out.xferaddr = scb->pthru_dma_addr;
 
 		}
 		return scb;
@@ -1593,20 +1593,21 @@
 	volatile mbox_t		*mbox = adapter->mbox;
 	unsigned int	i = 0;
 
-	if(unlikely(mbox->busy)) {
+	if(unlikely(mbox->m_in.busy)) {
 		do {
 			udelay(1);
 			i++;
-		} while( mbox->busy && (i < max_mbox_busy_wait) );
+		} while( mbox->m_in.busy && (i < max_mbox_busy_wait) );
 
-		if(mbox->busy) return -1;
+		if(mbox->m_in.busy) return -1;
 	}
 
 	/* Copy mailbox data into host structure */
-	memcpy((char *)mbox, (char *)scb->raw_mbox, 16);
+	memcpy((char *)&mbox->m_out, (char *)scb->raw_mbox, 
+			sizeof(struct mbox_out));
 
-	mbox->cmdid = scb->idx;	/* Set cmdid */
-	mbox->busy = 1;		/* Set busy */
+	mbox->m_out.cmdid = scb->idx;	/* Set cmdid */
+	mbox->m_in.busy = 1;		/* Set busy */
 
 
 	/*
@@ -1614,14 +1615,14 @@
 	 */
 	atomic_inc(&adapter->pend_cmds);
 
-	switch (mbox->cmd) {
+	switch (mbox->m_out.cmd) {
 	case MEGA_MBOXCMD_LREAD64:
 	case MEGA_MBOXCMD_LWRITE64:
 	case MEGA_MBOXCMD_PASSTHRU64:
 	case MEGA_MBOXCMD_EXTPTHRU:
-		mbox64->xfer_segment_lo = mbox->xferaddr;
+		mbox64->xfer_segment_lo = mbox->m_out.xferaddr;
 		mbox64->xfer_segment_hi = 0;
-		mbox->xferaddr = 0xFFFFFFFF;
+		mbox->m_out.xferaddr = 0xFFFFFFFF;
 		break;
 	default:
 		mbox64->xfer_segment_lo = 0;
@@ -1634,8 +1635,8 @@
 	scb->state |= SCB_ISSUED;
 
 	if( likely(adapter->flag & BOARD_MEMMAP) ) {
-		mbox->poll = 0;
-		mbox->ack = 0;
+		mbox->m_in.poll = 0;
+		mbox->m_in.ack = 0;
 		WRINDOOR(adapter, adapter->mbox_dma | 0x1);
 	}
 	else {
@@ -1661,24 +1662,23 @@
 	volatile mbox_t *mbox = adapter->mbox;
 	u8	byte;
 
-	raw_mbox[0x1] = 0xFE;	/* Set cmdid */
-	raw_mbox[0xF] = 1;	/* Set busy */
-
 	/* Wait until mailbox is free */
 	if(mega_busywait_mbox (adapter))
 		goto bug_blocked_mailbox;
 
 	/* Copy mailbox data into host structure */
-	memcpy((char *) mbox, raw_mbox, 16);
+	memcpy((char *) mbox, raw_mbox, sizeof(struct mbox_out));
+	mbox->m_out.cmdid = 0xFE;
+	mbox->m_in.busy = 1;
 
 	switch (raw_mbox[0]) {
 	case MEGA_MBOXCMD_LREAD64:
 	case MEGA_MBOXCMD_LWRITE64:
 	case MEGA_MBOXCMD_PASSTHRU64:
 	case MEGA_MBOXCMD_EXTPTHRU:
-		mbox64->xfer_segment_lo = mbox->xferaddr;
+		mbox64->xfer_segment_lo = mbox->m_out.xferaddr;
 		mbox64->xfer_segment_hi = 0;
-		mbox->xferaddr = 0xFFFFFFFF;
+		mbox->m_out.xferaddr = 0xFFFFFFFF;
 		break;
 	default:
 		mbox64->xfer_segment_lo = 0;
@@ -1686,22 +1686,22 @@
 	}
 
 	if( likely(adapter->flag & BOARD_MEMMAP) ) {
-		mbox->poll = 0;
-		mbox->ack = 0;
-		mbox->numstatus = 0xFF;
-		mbox->status = 0xFF;
+		mbox->m_in.poll = 0;
+		mbox->m_in.ack = 0;
+		mbox->m_in.numstatus = 0xFF;
+		mbox->m_in.status = 0xFF;
 		WRINDOOR(adapter, adapter->mbox_dma | 0x1);
 
-		while((volatile u8)mbox->numstatus == 0xFF)
+		while((volatile u8)mbox->m_in.numstatus == 0xFF)
 			cpu_relax();
 
-		mbox->numstatus = 0xFF;
+		mbox->m_in.numstatus = 0xFF;
 
-		while( (volatile u8)mbox->poll != 0x77 )
+		while( (volatile u8)mbox->m_in.poll != 0x77 )
 			cpu_relax();
 
-		mbox->poll = 0;
-		mbox->ack = 0x77;
+		mbox->m_in.poll = 0;
+		mbox->m_in.ack = 0x77;
 
 		WRINDOOR(adapter, adapter->mbox_dma | 0x2);
 
@@ -1720,7 +1720,7 @@
 		irq_ack(adapter);
 	}
 
-	return mbox->status;
+	return mbox->m_in.status;
 
 bug_blocked_mailbox:
 	printk(KERN_WARNING "megaraid: Blocked mailbox......!!\n");
@@ -1767,19 +1767,20 @@
 		}
 		set_irq_state(adapter, byte);
 
-		while((nstatus = (volatile u8)adapter->mbox->numstatus)
+		while((nstatus = (volatile u8)adapter->mbox->m_in.numstatus)
 				== 0xFF)
 			cpu_relax();
-		adapter->mbox->numstatus = 0xFF;
+		adapter->mbox->m_in.numstatus = 0xFF;
 
-		status = adapter->mbox->status;
+		status = adapter->mbox->m_in.status;
 
 		/*
 		 * decrement the pending queue counter
 		 */
 		atomic_sub(nstatus, &adapter->pend_cmds);
 
-		memcpy(completed, (void *)adapter->mbox->completed, nstatus);
+		memcpy(completed, (void *)adapter->mbox->m_in.completed, 
+				nstatus);
 
 		/* Acknowledge interrupt */
 		irq_ack(adapter);
@@ -1843,20 +1844,21 @@
 		}
 		WROUTDOOR(adapter, 0x10001234);
 
-		while((nstatus = (volatile u8)adapter->mbox->numstatus)
+		while((nstatus = (volatile u8)adapter->mbox->m_in.numstatus)
 				== 0xFF) {
 			cpu_relax();
 		}
-		adapter->mbox->numstatus = 0xFF;
+		adapter->mbox->m_in.numstatus = 0xFF;
 
-		status = adapter->mbox->status;
+		status = adapter->mbox->m_in.status;
 
 		/*
 		 * decrement the pending queue counter
 		 */
 		atomic_sub(nstatus, &adapter->pend_cmds);
 
-		memcpy(completed, (void *)adapter->mbox->completed, nstatus);
+		memcpy(completed, (void *)adapter->mbox->m_in.completed, 
+				nstatus);
 
 		/* Acknowledge interrupt */
 		WRINDOOR(adapter, 0x2);
@@ -1986,7 +1988,7 @@
 #if MEGA_HAVE_STATS
 			{
 
-			int	logdrv = mbox->logdrv;
+			int	logdrv = mbox->m_out.logdrv;
 
 			islogical = adapter->logdrv_chan[cmd->channel];
 			/*
@@ -2065,8 +2067,8 @@
 				   SCSI_STATUS_CHECK_CONDITION */
 
 			/* set sense_buffer and result fields */
-			if( mbox->cmd == MEGA_MBOXCMD_PASSTHRU ||
-				mbox->cmd == MEGA_MBOXCMD_PASSTHRU64 ) {
+			if( mbox->m_out.cmd == MEGA_MBOXCMD_PASSTHRU ||
+				mbox->m_out.cmd == MEGA_MBOXCMD_PASSTHRU64 ) {
 
 				memcpy(cmd->sense_buffer, pthru->reqsensearea,
 						14);
@@ -2076,7 +2078,7 @@
 					(CHECK_CONDITION << 1);
 			}
 			else {
-				if (mbox->cmd == MEGA_MBOXCMD_EXTPTHRU) {
+				if (mbox->m_out.cmd == MEGA_MBOXCMD_EXTPTHRU) {
 
 					memcpy(cmd->sense_buffer,
 						epthru->reqsensearea, 14);
@@ -2233,7 +2235,7 @@
 static inline int
 mega_busywait_mbox (adapter_t *adapter)
 {
-	if (adapter->mbox->busy)
+	if (adapter->mbox->m_in.busy)
 		return __mega_busywait_mbox(adapter);
 	return 0;
 }
@@ -2245,7 +2247,7 @@
 	long counter;
 
 	for (counter = 0; counter < 10000; counter++) {
-		if (!mbox->busy)
+		if (!mbox->m_in.busy)
 			return 0;
 		udelay(100); yield();
 	}
@@ -2400,7 +2402,7 @@
 {
 	adapter_t	*adapter;
 	mbox_t	*mbox;
-	u_char	raw_mbox[sizeof(mbox_t)];
+	u_char	raw_mbox[sizeof(struct mbox_out)];
 	char	buf[12] = { 0 };
 
 	adapter = (adapter_t *)host->hostdata;
@@ -2409,7 +2411,7 @@
 	printk(KERN_NOTICE "megaraid: being unloaded...");
 
 	/* Flush adapter cache */
-	memset(mbox, 0, sizeof(*mbox));
+	memset(&mbox->m_out, 0, sizeof(raw_mbox));
 	raw_mbox[0] = FLUSH_ADAPTER;
 
 	irq_disable(adapter);
@@ -2419,7 +2421,7 @@
 	issue_scb_block(adapter, raw_mbox);
 
 	/* Flush disks cache */
-	memset(mbox, 0, sizeof(*mbox));
+	memset(&mbox->m_out, 0, sizeof(raw_mbox));
 	raw_mbox[0] = FLUSH_SYSTEM;
 
 	/* Issue a blocking (interrupts disabled) command to the card */
@@ -2569,35 +2571,6 @@
 	return buffer;
 }
 
-volatile static int internal_done_flag = 0;
-volatile static int internal_done_errcode = 0;
-
-static DECLARE_WAIT_QUEUE_HEAD (internal_wait);
-
-static void internal_done (Scsi_Cmnd *cmd)
-{
-	internal_done_errcode = cmd->result;
-	internal_done_flag++;
-	wake_up (&internal_wait);
-}
-
-/* shouldn't be used, but included for completeness */
-
-static int
-megaraid_command (Scsi_Cmnd *cmd)
-{
-	internal_done_flag = 0;
-
-	/* Queue command, and wait until it has completed */
-	megaraid_queue (cmd, internal_done);
-
-	while (!internal_done_flag)
-		interruptible_sleep_on (&internal_wait);
-
-	return internal_done_errcode;
-}
-
-
 /*
  * Abort a previous SCSI request. Only commands on the pending list can be
  * aborted. All the commands issued to the F/W must complete.
@@ -2979,16 +2952,24 @@
 	int	len = 0;
 
 	len = sprintf(page, "Contents of Mail Box Structure\n");
-	len += sprintf(page+len, "  Fw Command   = 0x%02x\n", mbox->cmd);
-	len += sprintf(page+len, "  Cmd Sequence = 0x%02x\n", mbox->cmdid);
-	len += sprintf(page+len, "  No of Sectors= %04d\n", mbox->numsectors);
-	len += sprintf(page+len, "  LBA          = 0x%02x\n", mbox->lba);
-	len += sprintf(page+len, "  DTA          = 0x%08x\n", mbox->xferaddr);
-	len += sprintf(page+len, "  Logical Drive= 0x%02x\n", mbox->logdrv);
+	len += sprintf(page+len, "  Fw Command   = 0x%02x\n", 
+			mbox->m_out.cmd);
+	len += sprintf(page+len, "  Cmd Sequence = 0x%02x\n", 
+			mbox->m_out.cmdid);
+	len += sprintf(page+len, "  No of Sectors= %04d\n", 
+			mbox->m_out.numsectors);
+	len += sprintf(page+len, "  LBA          = 0x%02x\n", 
+			mbox->m_out.lba);
+	len += sprintf(page+len, "  DTA          = 0x%08x\n", 
+			mbox->m_out.xferaddr);
+	len += sprintf(page+len, "  Logical Drive= 0x%02x\n", 
+			mbox->m_out.logdrv);
 	len += sprintf(page+len, "  No of SG Elmt= 0x%02x\n",
-			mbox->numsgelements);
-	len += sprintf(page+len, "  Busy         = %01x\n", mbox->busy);
-	len += sprintf(page+len, "  Status       = 0x%02x\n", mbox->status);
+			mbox->m_out.numsgelements);
+	len += sprintf(page+len, "  Busy         = %01x\n", 
+			mbox->m_in.busy);
+	len += sprintf(page+len, "  Status       = 0x%02x\n", 
+			mbox->m_in.status);
 
 	*eof = 1;
 
@@ -3881,7 +3862,7 @@
 {
 	adapter_t *adapter;
 	struct Scsi_Host *host;
-	u8 raw_mbox[sizeof(mbox_t)];
+	u8 raw_mbox[sizeof(struct mbox_out)];
 	mbox_t *mbox;
 	int i,j;
 
@@ -3897,7 +3878,7 @@
 		mbox = (mbox_t *)raw_mbox;
 
 		/* Flush adapter cache */
-		memset(mbox, 0, sizeof(*mbox));
+		memset(&mbox->m_out, 0, sizeof(raw_mbox));
 		raw_mbox[0] = FLUSH_ADAPTER;
 
 		irq_disable(adapter);
@@ -3910,7 +3891,7 @@
 		issue_scb_block(adapter, raw_mbox);
 
 		/* Flush disks cache */
-		memset(mbox, 0, sizeof(*mbox));
+		memset(&mbox->m_out, 0, sizeof(raw_mbox));
 		raw_mbox[0] = FLUSH_SYSTEM;
 
 		issue_scb_block(adapter, raw_mbox);
@@ -4643,17 +4624,17 @@
 static int
 mega_is_bios_enabled(adapter_t *adapter)
 {
-	unsigned char	raw_mbox[sizeof(mbox_t)];
+	unsigned char	raw_mbox[sizeof(struct mbox_out)];
 	mbox_t	*mbox;
 	int	ret;
 
 	mbox = (mbox_t *)raw_mbox;
 
-	memset(mbox, 0, sizeof(*mbox));
+	memset(&mbox->m_out, 0, sizeof(raw_mbox));
 
 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
 
-	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
 
 	raw_mbox[0] = IS_BIOS_ENABLED;
 	raw_mbox[2] = GET_BIOS;
@@ -4676,13 +4657,13 @@
 static void
 mega_enum_raid_scsi(adapter_t *adapter)
 {
-	unsigned char raw_mbox[sizeof(mbox_t)];
+	unsigned char raw_mbox[sizeof(struct mbox_out)];
 	mbox_t *mbox;
 	int i;
 
 	mbox = (mbox_t *)raw_mbox;
 
-	memset(mbox, 0, sizeof(*mbox));
+	memset(&mbox->m_out, 0, sizeof(raw_mbox));
 
 	/*
 	 * issue command to find out what channels are raid/scsi
@@ -4692,7 +4673,7 @@
 
 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
 
-	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
 
 	/*
 	 * Non-ROMB firware fail this command, so all channels
@@ -4731,7 +4712,7 @@
 mega_get_boot_drv(adapter_t *adapter)
 {
 	struct private_bios_data	*prv_bios_data;
-	unsigned char	raw_mbox[sizeof(mbox_t)];
+	unsigned char	raw_mbox[sizeof(struct mbox_out)];
 	mbox_t	*mbox;
 	u16	cksum = 0;
 	u8	*cksum_p;
@@ -4740,14 +4721,14 @@
 
 	mbox = (mbox_t *)raw_mbox;
 
-	memset(mbox, 0, sizeof(raw_mbox));
+	memset(&mbox->m_out, 0, sizeof(raw_mbox));
 
 	raw_mbox[0] = BIOS_PVT_DATA;
 	raw_mbox[2] = GET_BIOS_PVT_DATA;
 
 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
 
-	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
 
 	adapter->boot_ldrv_enabled = 0;
 	adapter->boot_ldrv = 0;
@@ -4797,13 +4778,13 @@
 static int
 mega_support_random_del(adapter_t *adapter)
 {
-	unsigned char raw_mbox[sizeof(mbox_t)];
+	unsigned char raw_mbox[sizeof(struct mbox_out)];
 	mbox_t *mbox;
 	int rval;
 
 	mbox = (mbox_t *)raw_mbox;
 
-	memset(mbox, 0, sizeof(*mbox));
+	memset(&mbox->m_out, 0, sizeof(raw_mbox));
 
 	/*
 	 * issue command
@@ -4826,13 +4807,13 @@
 static int
 mega_support_ext_cdb(adapter_t *adapter)
 {
-	unsigned char raw_mbox[sizeof(mbox_t)];
+	unsigned char raw_mbox[sizeof(struct mbox_out)];
 	mbox_t *mbox;
 	int rval;
 
 	mbox = (mbox_t *)raw_mbox;
 
-	memset(mbox, 0, sizeof(*mbox));
+	memset(&mbox->m_out, 0, sizeof(raw_mbox));
 	/*
 	 * issue command to find out if controller supports extended CDBs.
 	 */
@@ -4944,7 +4925,7 @@
 static void
 mega_get_max_sgl(adapter_t *adapter)
 {
-	unsigned char	raw_mbox[sizeof(mbox_t)];
+	unsigned char	raw_mbox[sizeof(struct mbox_out)];
 	mbox_t	*mbox;
 
 	mbox = (mbox_t *)raw_mbox;
@@ -4953,7 +4934,7 @@
 
 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
 
-	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
 
 	raw_mbox[0] = MAIN_MISC_OPCODE;
 	raw_mbox[2] = GET_MAX_SG_SUPPORT;
@@ -4989,7 +4970,7 @@
 static int
 mega_support_cluster(adapter_t *adapter)
 {
-	unsigned char	raw_mbox[sizeof(mbox_t)];
+	unsigned char	raw_mbox[sizeof(struct mbox_out)];
 	mbox_t	*mbox;
 
 	mbox = (mbox_t *)raw_mbox;
@@ -4998,7 +4979,7 @@
 
 	memset((void *)adapter->mega_buffer, 0, MEGA_BUFFER_SIZE);
 
-	mbox->xferaddr = (u32)adapter->buf_dma_handle;
+	mbox->m_out.xferaddr = (u32)adapter->buf_dma_handle;
 
 	/*
 	 * Try to get the initiator id. This command will succeed iff the
@@ -5367,7 +5348,6 @@
 	.detect =			megaraid_detect,
 	.release =			megaraid_release,
 	.info =				megaraid_info,
-	.command =			megaraid_command,
 	.queuecommand =			megaraid_queue,	
 	.bios_param =			megaraid_biosparam,
 	.max_sectors =			MAX_SECTORS_PER_IO,
diff -Nru a/drivers/scsi/megaraid.h b/drivers/scsi/megaraid.h
--- a/drivers/scsi/megaraid.h	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/megaraid.h	Wed Jun 18 23:42:07 2003
@@ -120,8 +120,7 @@
 
 #define NVIRT_CHAN		4	/* # of virtual channels to represent
 					   up to 60 logical drives */
-
-typedef struct {
+struct mbox_out {
 	/* 0x0 */ u8 cmd;
 	/* 0x1 */ u8 cmdid;
 	/* 0x2 */ u16 numsectors;
@@ -130,12 +129,20 @@
 	/* 0xC */ u8 logdrv;
 	/* 0xD */ u8 numsgelements;
 	/* 0xE */ u8 resvd;
+} __attribute__ ((packed));
+
+struct mbox_in {
 	/* 0xF */ volatile u8 busy;
 	/* 0x10 */ volatile u8 numstatus;
 	/* 0x11 */ volatile u8 status;
 	/* 0x12 */ volatile u8 completed[MAX_FIRMWARE_STATUS];
 	volatile u8 poll;
 	volatile u8 ack;
+} __attribute__ ((packed));
+
+typedef struct {
+	struct mbox_out	m_out;
+	struct mbox_in	m_in;
 } __attribute__ ((packed)) mbox_t;
 
 typedef struct {
@@ -1001,7 +1008,6 @@
 static void mega_free_scb(adapter_t *, scb_t *);
 
 static int megaraid_release (struct Scsi_Host *);
-static int megaraid_command (Scsi_Cmnd *);
 static int megaraid_abort(Scsi_Cmnd *);
 static int megaraid_reset(Scsi_Cmnd *);
 static int megaraid_abort_and_reset(adapter_t *, Scsi_Cmnd *, int);
diff -Nru a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
--- a/drivers/scsi/mesh.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/mesh.c	Wed Jun 18 23:42:08 2003
@@ -2047,11 +2047,8 @@
 	.name				= "MESH",
 	.detect				= mesh_detect,
 	.release			= mesh_release,
-	.command			= NULL,
 	.queuecommand			= mesh_queue,
 	.eh_abort_handler		= mesh_abort,
-	.eh_device_reset_handler	= NULL,
-	.eh_bus_reset_handler		= NULL,
 	.eh_host_reset_handler		= mesh_host_reset,
 	.can_queue			= 20,
 	.this_id			= 7,
diff -Nru a/drivers/scsi/mvme16x.c b/drivers/scsi/mvme16x.c
--- a/drivers/scsi/mvme16x.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/mvme16x.c	Wed Jun 18 23:42:08 2003
@@ -53,9 +53,22 @@
     return 1;
 }
 
+static int mvme16x_scsi_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static Scsi_Host_Template driver_template = {
 	.name			= "MVME16x NCR53c710 SCSI",
 	.detect			= mvme16x_scsi_detect,
+	.release		= mvme16x_scsi_release,
 	.queuecommand		= NCR53c7xx_queue_command,
 	.abort			= NCR53c7xx_abort,
 	.reset			= NCR53c7xx_reset,
diff -Nru a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
--- a/drivers/scsi/nsp32.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/nsp32.c	Wed Jun 18 23:42:07 2003
@@ -1621,7 +1621,7 @@
 	/*
 	 * register this HBA as SCSI device
 	 */
-	host = scsi_register(&nsp32_template, sizeof(nsp32_hw_data));
+	host = scsi_host_alloc(&nsp32_template, sizeof(nsp32_hw_data));
 	if (host == NULL) {
 		nsp32_msg (KERN_ERR, "failed to scsi register");
 		goto err;
@@ -1840,7 +1840,7 @@
 	kfree(data->lunt_list);
 
  scsi_unregister:
-	scsi_unregister(host);
+	scsi_host_put(host);
 
  err:
 	return 1;
diff -Nru a/drivers/scsi/pas16.c b/drivers/scsi/pas16.c
--- a/drivers/scsi/pas16.c	Wed Jun 18 23:42:05 2003
+++ b/drivers/scsi/pas16.c	Wed Jun 18 23:42:05 2003
@@ -600,9 +600,22 @@
 
 #include "NCR5380.c"
 
+static int pas16_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static Scsi_Host_Template driver_template = {
 	.name           = "Pro Audio Spectrum-16 SCSI",
 	.detect         = pas16_detect,
+	.release        = pas16_release,
 	.queuecommand   = pas16_queue_command,
 	.eh_abort_handler = pas16_abort,
 	.eh_bus_reset_handler = pas16_bus_reset,
diff -Nru a/drivers/scsi/pci2000.c b/drivers/scsi/pci2000.c
--- a/drivers/scsi/pci2000.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/pci2000.c	Wed Jun 18 23:42:08 2003
@@ -612,41 +612,6 @@
 	return 0;
 	}
 /****************************************************************
- *	Name:	internal_done :LOCAL
- *
- *	Description:	Done handler for non-queued commands
- *
- *	Parameters:		SCpnt - Pointer to SCSI command structure.
- *
- *	Returns:		Nothing.
- *
- ****************************************************************/
-static void internal_done (Scsi_Cmnd * SCpnt)
-	{
-	SCpnt->SCp.Status++;
-	}
-/****************************************************************
- *	Name:	Pci2000_Command
- *
- *	Description:	Process a command from the SCSI manager.
- *
- *	Parameters:		SCpnt - Pointer to SCSI command structure.
- *
- *	Returns:		Status code.
- *
- ****************************************************************/
-int Pci2000_Command (Scsi_Cmnd *SCpnt)
-	{
-	DEB(printk("pci2000_command: ..calling pci2000_queuecommand\n"));
-
-	Pci2000_QueueCommand (SCpnt, internal_done);
-
-    SCpnt->SCp.Status = 0;
-	while (!SCpnt->SCp.Status)
-		barrier ();
-	return SCpnt->result;
-	}
-/****************************************************************
  *	Name:	Pci2000_Detect
  *
  *	Description:	Detect and initialize our boards.
@@ -856,7 +821,6 @@
 	.name		= "PCI-2000 SCSI Intelligent Disk Controller",
 	.detect		= Pci2000_Detect,
 	.release	= Pci2000_Release,
-	.command	= Pci2000_Command,
 	.queuecommand	= Pci2000_QueueCommand,
 	.abort		= Pci2000_Abort,
 	.reset		= Pci2000_Reset,
diff -Nru a/drivers/scsi/pci2220i.c b/drivers/scsi/pci2220i.c
--- a/drivers/scsi/pci2220i.c	Wed Jun 18 23:42:05 2003
+++ b/drivers/scsi/pci2220i.c	Wed Jun 18 23:42:05 2003
@@ -2307,28 +2307,6 @@
 		}
 	return 0;
 	}
-static void internal_done(Scsi_Cmnd *SCpnt)
-	{
-	SCpnt->SCp.Status++;
-	}
-/****************************************************************
- *	Name:	Pci2220i_Command
- *
- *	Description:	Process a command from the SCSI manager.
- *
- *	Parameters:		SCpnt - Pointer to SCSI command structure.
- *
- *	Returns:		Status code.
- *
- ****************************************************************/
-int Pci2220i_Command (Scsi_Cmnd *SCpnt)
-	{
-	Pci2220i_QueueCommand (SCpnt, internal_done);
-    SCpnt->SCp.Status = 0;
-	while (!SCpnt->SCp.Status)
-		barrier ();
-	return SCpnt->result;
-	}
 /****************************************************************
  *	Name:			ReadFlash
  *
@@ -2924,7 +2902,6 @@
 	.name			= "PCI-2220I/PCI-2240I",
 	.detect			= Pci2220i_Detect,
 	.release		= Pci2220i_Release,
-	.command		= Pci2220i_Command,
 	.queuecommand		= Pci2220i_QueueCommand,
 	.abort			= Pci2220i_Abort,
 	.reset			= Pci2220i_Reset,
diff -Nru a/drivers/scsi/pcmcia/nsp_cs.c b/drivers/scsi/pcmcia/nsp_cs.c
--- a/drivers/scsi/pcmcia/nsp_cs.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/scsi/pcmcia/nsp_cs.c	Wed Jun 18 23:42:09 2003
@@ -1222,7 +1222,7 @@
 	DEBUG(0, "%s: this_id=%d\n", __FUNCTION__, sht->this_id);
 
 	request_region(data->BaseAddress, data->NumAddress, "nsp_cs");
-	host		  = scsi_register(sht, 0);
+	host		  = scsi_host_alloc(sht, 0);
 	if(host == NULL)
 		return NULL;
 
diff -Nru a/drivers/scsi/ppa.c b/drivers/scsi/ppa.c
--- a/drivers/scsi/ppa.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/ppa.c	Wed Jun 18 23:42:07 2003
@@ -103,7 +103,6 @@
 	.name				= "Iomega VPI0 (ppa) interface",
 	.detect				= ppa_detect,
 	.release			= ppa_release,
-	.command			= ppa_command,
 	.queuecommand			= ppa_queuecommand,
 	.eh_abort_handler		= ppa_abort,
 	.eh_bus_reset_handler		= ppa_reset,
@@ -759,39 +758,6 @@
 	    return 0;
     }
     return 1;			/* FINISH_RETURN */
-}
-
-/* deprecated synchronous interface */
-int ppa_command(Scsi_Cmnd * cmd)
-{
-    static int first_pass = 1;
-    int host_no = cmd->device->host->unique_id;
-
-    if (first_pass) {
-	printk("ppa: using non-queuing interface\n");
-	first_pass = 0;
-    }
-    if (ppa_hosts[host_no].cur_cmd) {
-	printk("PPA: bug in ppa_command\n");
-	return 0;
-    }
-    ppa_hosts[host_no].failed = 0;
-    ppa_hosts[host_no].jstart = jiffies;
-    ppa_hosts[host_no].cur_cmd = cmd;
-    cmd->result = DID_ERROR << 16;	/* default return code */
-    cmd->SCp.phase = 0;
-
-    ppa_pb_claim(host_no);
-
-    while (ppa_engine(&ppa_hosts[host_no], cmd))
-	schedule();
-
-    if (cmd->SCp.phase)		/* Only disconnect if we have connected */
-	ppa_disconnect(cmd->device->host->unique_id);
-
-    ppa_pb_release(host_no);
-    ppa_hosts[host_no].cur_cmd = 0;
-    return cmd->result;
 }
 
 /*
diff -Nru a/drivers/scsi/psi240i.c b/drivers/scsi/psi240i.c
--- a/drivers/scsi/psi240i.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/psi240i.c	Wed Jun 18 23:42:08 2003
@@ -496,31 +496,6 @@
 	return 0;
 	}
 
-static void internal_done(Scsi_Cmnd * SCpnt)
-	{
-	SCpnt->SCp.Status++;
-	}
-/****************************************************************
- *	Name:	Psi240i_Command
- *
- *	Description:	Process a command from the SCSI manager.
- *
- *	Parameters:		SCpnt - Pointer to SCSI command structure.
- *
- *	Returns:		Status code.
- *
- ****************************************************************/
-int Psi240i_Command (Scsi_Cmnd *SCpnt)
-	{
-	DEB(printk("psi240i_command: ..calling psi240i_queuecommand\n"));
-
-	Psi240i_QueueCommand (SCpnt, internal_done);
-
-    SCpnt->SCp.Status = 0;
-	while (!SCpnt->SCp.Status)
-		barrier ();
-	return SCpnt->result;
-	}
 /***************************************************************************
  *	Name:			ReadChipMemory
  *
@@ -655,6 +630,17 @@
 		}
 	return count;
 	}
+
+static int Psi240i_Release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 /****************************************************************
  *	Name:	Psi240i_Abort
  *
@@ -722,7 +708,7 @@
 	.proc_name		= "psi240i", 
 	.name			= "PSI-240I EIDE Disk Controller",
 	.detect			= Psi240i_Detect,
-	.command		= Psi240i_Command,
+	.release		= Psi240i_Release,
 	.queuecommand		= Psi240i_QueueCommand,
 	.abort	  		= Psi240i_Abort,
 	.reset	  		= Psi240i_Reset,
diff -Nru a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c
--- a/drivers/scsi/qlogicfas.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/scsi/qlogicfas.c	Wed Jun 18 23:42:09 2003
@@ -544,46 +544,6 @@
 
 #if QL_USE_IRQ
 
-static void qlidone(Scsi_Cmnd * cmd)
-{
-}				/* null function */
-
-#endif
-
-/*
- *	Synchronous command processing
- */
- 
-static int qlogicfas_command(Scsi_Cmnd * cmd)
-{
-	int k;
-#if QL_USE_IRQ
-	if (qlirq >= 0) {
-		qlogicfas_queuecommand(cmd, qlidone);
-		while (qlcmd != NULL)
-		{
-			cpu_relax();
-			barrier();
-		}
-		return cmd->result;
-	}
-#endif
-
-	/*
-	 *	Non-irq version
-	 */
-	 
-	if (cmd->device->id == qinitid)
-		return (DID_BAD_TARGET << 16);
-	ql_icmd(cmd);
-	if ((k = ql_wai()))
-		return (k << 16);
-	return ql_pcmd(cmd);
-
-}
-
-#if QL_USE_IRQ
-
 /*
  *	Queued command
  */
@@ -739,6 +699,18 @@
 	return (__qlogicfas_detect(sht) != NULL);
 }
 
+static int qlogicfas_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 /* 
  *	Return bios parameters 
  */
@@ -826,8 +798,8 @@
 	.name			= "qlogicfas",
 	.proc_name		= "qlogicfas",
 	.detect			= qlogicfas_detect,
+	.release		= qlogicfas_release,
 	.info			= qlogicfas_info,
-	.command		= qlogicfas_command,
 	.queuecommand		= qlogicfas_queuecommand,
 	.eh_abort_handler	= qlogicfas_abort,
 	.eh_bus_reset_handler	= qlogicfas_bus_reset,
diff -Nru a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c
--- a/drivers/scsi/scsi.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/scsi.c	Wed Jun 18 23:42:07 2003
@@ -38,6 +38,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
@@ -82,7 +83,6 @@
  * Data declarations.
  */
 unsigned long scsi_pid;
-struct scsi_cmnd *last_cmnd;
 static unsigned long serial_number;
 
 /*
@@ -108,26 +108,6 @@
 	"Enclosure        ",
 };
 
-MODULE_PARM(scsi_logging_level, "i");
-MODULE_PARM_DESC(scsi_logging_level, "SCSI logging level; should be zero or nonzero");
-
-#ifndef MODULE
-static int __init scsi_logging_setup(char *str)
-{
-	int tmp;
-
-	if (get_option(&str, &tmp) == 1) {
-		scsi_logging_level = (tmp ? ~0 : 0);
-		return 1;
-	} else {
-		printk(KERN_INFO "scsi_logging_setup : usage scsi_logging_level=n "
-		       "(n should be 0 or non-zero)\n");
-		return 0;
-	}
-}
-__setup("scsi_logging=", scsi_logging_setup);
-#endif
-
 /*
  * Function:    scsi_allocate_request
  *
@@ -460,29 +440,18 @@
 		goto out;
 	}
 
-	if (host->can_queue) {
-		SCSI_LOG_MLQUEUE(3, printk("queuecommand : routine at %p\n",
-					   host->hostt->queuecommand));
+	SCSI_LOG_MLQUEUE(3, printk("queuecommand : routine at %p\n",
+				   host->hostt->queuecommand));
 
-		spin_lock_irqsave(host->host_lock, flags);
-		rtn = host->hostt->queuecommand(cmd, scsi_done);
-		spin_unlock_irqrestore(host->host_lock, flags);
-		if (rtn) {
-			scsi_queue_insert(cmd,
+	spin_lock_irqsave(host->host_lock, flags);
+	rtn = host->hostt->queuecommand(cmd, scsi_done);
+	spin_unlock_irqrestore(host->host_lock, flags);
+	if (rtn) {
+		scsi_queue_insert(cmd,
 				(rtn == SCSI_MLQUEUE_DEVICE_BUSY) ?
-					rtn : SCSI_MLQUEUE_HOST_BUSY);
-			SCSI_LOG_MLQUEUE(3,
-			    printk("queuecommand : request rejected\n"));
-		}
-	} else {
-		SCSI_LOG_MLQUEUE(3, printk("command() :  routine at %p\n",
-					host->hostt->command));
-
-		spin_lock_irqsave(host->host_lock, flags);
-		cmd->result = host->hostt->command(cmd);
-		scsi_done(cmd);
-		spin_unlock_irqrestore(host->host_lock, flags);
-		rtn = 0;
+				 rtn : SCSI_MLQUEUE_HOST_BUSY);
+		SCSI_LOG_MLQUEUE(3,
+		    printk("queuecommand : request rejected\n"));
 	}
 
  out:
@@ -752,16 +721,8 @@
 	struct scsi_device *sdev = cmd->device;
 	struct Scsi_Host *shost = sdev->host;
 	struct scsi_request *sreq;
-	unsigned long flags;
 
-	scsi_host_busy_dec_and_test(shost, sdev);
-
-	/*
-	 * XXX(hch): We really want a nice helper for this..
-	 */
-	spin_lock_irqsave(&sdev->sdev_lock, flags);
-	sdev->device_busy--;
-	spin_unlock_irqrestore(&sdev->sdev_lock, flags);
+	scsi_device_unbusy(sdev);
 
         /*
          * Clear the flags which say that the device/host is no longer
@@ -983,6 +944,9 @@
 MODULE_DESCRIPTION("SCSI core");
 MODULE_LICENSE("GPL");
 
+module_param(scsi_logging_level, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(scsi_logging_level, "a bit mask of logging levels");
+
 static int __init init_scsi(void)
 {
 	int error, i;
@@ -1003,7 +967,6 @@
 	for (i = 0; i < NR_CPUS; i++)
 		INIT_LIST_HEAD(&done_q[i]);
 
-	scsi_host_init();
 	devfs_mk_dir("scsi");
 	open_softirq(SCSI_SOFTIRQ, scsi_softirq, NULL);
 	printk(KERN_NOTICE "SCSI subsystem initialized\n");
diff -Nru a/drivers/scsi/scsi.h b/drivers/scsi/scsi.h
--- a/drivers/scsi/scsi.h	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/scsi.h	Wed Jun 18 23:42:06 2003
@@ -16,6 +16,12 @@
 #define _SCSI_H
 
 #include <linux/config.h>	    /* for CONFIG_SCSI_LOGGING */
+
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+#include <scsi/scsi_eh.h>
+#include <scsi/scsi_request.h>
+#include <scsi/scsi_tcq.h>
 #include <scsi/scsi.h>
 
 /*
@@ -112,19 +118,6 @@
 #define SOFT_ERROR      0x2005
 #define ADD_TO_MLQUEUE  0x2006
 
-/*
- * These are the values that scsi_cmd->state can take.
- */
-#define SCSI_STATE_TIMEOUT         0x1000
-#define SCSI_STATE_FINISHED        0x1001
-#define SCSI_STATE_FAILED          0x1002
-#define SCSI_STATE_QUEUED          0x1003
-#define SCSI_STATE_UNUSED          0x1006
-#define SCSI_STATE_DISCONNECTING   0x1008
-#define SCSI_STATE_INITIALIZING    0x1009
-#define SCSI_STATE_BHQUEUE         0x100a
-#define SCSI_STATE_MLQUEUE         0x100b
-
 #define IDENTIFY_BASE       0x80
 #define IDENTIFY(can_disconnect, lun)   (IDENTIFY_BASE |\
 		     ((can_disconnect) ?  0x40 : 0) |\
@@ -169,9 +162,6 @@
 #define DRIVER_MASK         0x0f
 #define SUGGEST_MASK        0xf0
 
-#define MAX_COMMAND_SIZE    16
-#define SCSI_SENSE_BUFFERSIZE   64
-
 /*
  *  SCSI command sets
  */
@@ -204,96 +194,20 @@
 #define ASKED_FOR_SENSE 0x20
 #define SYNC_RESET      0x40
 
-/*
- * This specifies "machine infinity" for host templates which don't
- * limit the transfer size.  Note this limit represents an absolute
- * maximum, and may be over the transfer limits allowed for individual
- * devices (e.g. 256 for SCSI-1)
- */
-#define SCSI_DEFAULT_MAX_SECTORS	1024
-
-/*
- * This is the crap from the old error handling code.  We have it in a special
- * place so that we can more easily delete it later on.
- */
-#include "scsi_obsolete.h"
-
-/*
- * Forward-declaration of structs for prototypes.
- */
 struct Scsi_Host;
+struct scsi_cmnd;
+struct scsi_device;
 struct scsi_target;
 struct scatterlist;
 
 /*
- * Add some typedefs so that we can prototyope a bunch of the functions.
- */
-typedef struct scsi_device Scsi_Device;
-typedef struct scsi_cmnd Scsi_Cmnd;
-typedef struct scsi_request Scsi_Request;
-
-/*
- * These are the error handling functions defined in scsi_error.c
- */
-extern void scsi_add_timer(Scsi_Cmnd * SCset, int timeout,
-			   void (*complete) (Scsi_Cmnd *));
-extern int scsi_delete_timer(Scsi_Cmnd * SCset);
-extern int scsi_block_when_processing_errors(Scsi_Device *);
-extern void scsi_sleep(int);
-
-/*
- * Prototypes for functions in scsicam.c
- */
-extern int  scsi_partsize(unsigned char *buf, unsigned long capacity,
-                    unsigned int *cyls, unsigned int *hds,
-                    unsigned int *secs);
-
-/*
- * Prototypes for functions in scsi_lib.c
- */
-extern void scsi_io_completion(Scsi_Cmnd * SCpnt, int good_sectors,
-			       int block_sectors);
-
-/*
- * Prototypes for functions in scsi.c
- */
-extern struct scsi_cmnd *scsi_get_command(struct scsi_device *dev, int flags);
-extern void scsi_put_command(struct scsi_cmnd *cmd);
-extern void scsi_adjust_queue_depth(Scsi_Device *, int, int);
-extern int scsi_track_queue_full(Scsi_Device *, int);
-extern int scsi_device_get(struct scsi_device *);
-extern void scsi_device_put(struct scsi_device *);
-extern void scsi_set_device_offline(struct scsi_device *);
-
-/*
- * Newer request-based interfaces.
- */
-extern Scsi_Request *scsi_allocate_request(Scsi_Device *);
-extern void scsi_release_request(Scsi_Request *);
-extern void scsi_wait_req(Scsi_Request *, const void *cmnd,
-			  void *buffer, unsigned bufflen,
-			  int timeout, int retries);
-extern void scsi_do_req(Scsi_Request *, const void *cmnd,
-			void *buffer, unsigned bufflen,
-			void (*done) (struct scsi_cmnd *),
-			int timeout, int retries);
-
-/*
- * Prototypes for functions in scsi_scan.c
- */
-extern struct scsi_device *scsi_add_device(struct Scsi_Host *,
-		uint, uint, uint);
-extern int scsi_remove_device(struct scsi_device *);
-extern u64 scsi_calculate_bounce_limit(struct Scsi_Host *);
-
-/*
  * Prototypes for functions in constants.c
  * Some of these used to live in constants.h
  */
-extern void print_Scsi_Cmnd (Scsi_Cmnd *);
+extern void print_Scsi_Cmnd(struct scsi_cmnd *);
 extern void print_command(unsigned char *);
-extern void print_sense(const char *, Scsi_Cmnd *);
-extern void print_req_sense(const char *, Scsi_Request *);
+extern void print_sense(const char *, struct scsi_cmnd *);
+extern void print_req_sense(const char *, struct scsi_request *);
 extern void print_driverbyte(int scsiresult);
 extern void print_hostbyte(int scsiresult);
 extern void print_status(unsigned char status);
@@ -301,286 +215,6 @@
 extern const char *scsi_sense_key_string(unsigned char);
 extern const char *scsi_extd_sense_format(unsigned char, unsigned char);
 
-
-/*
- *  The scsi_device struct contains what we know about each given scsi
- *  device.
- *
- * FIXME(eric) - One of the great regrets that I have is that I failed to
- * define these structure elements as something like sdev_foo instead of foo.
- * This would make it so much easier to grep through sources and so forth.
- * I propose that all new elements that get added to these structures follow
- * this convention.  As time goes on and as people have the stomach for it,
- * it should be possible to go back and retrofit at least some of the elements
- * here with with the prefix.
- */
-
-struct scsi_device {
-	struct class_device	sdev_classdev;
-	/*
-	 * This information is private to the scsi mid-layer.
-	 */
-	struct list_head    siblings;   /* list of all devices on this host */
-	struct list_head    same_target_siblings; /* just the devices sharing same target id */
-	struct Scsi_Host *host;
-	request_queue_t *request_queue;
-	volatile unsigned short device_busy;	/* commands actually active on low-level */
-	spinlock_t sdev_lock;           /* also the request queue_lock */
-	spinlock_t list_lock;
-	struct list_head cmd_list;	/* queue of in use SCSI Command structures */
-	struct list_head starved_entry;
-        Scsi_Cmnd *current_cmnd;	/* currently active command */
-	unsigned short queue_depth;	/* How deep of a queue we want */
-	unsigned short last_queue_full_depth; /* These two are used by */
-	unsigned short last_queue_full_count; /* scsi_track_queue_full() */
-	unsigned long last_queue_full_time;/* don't let QUEUE_FULLs on the same
-					   jiffie count on our counter, they
-					   could all be from the same event. */
-
-	unsigned int id, lun, channel;
-
-	unsigned int manufacturer;	/* Manufacturer of device, for using 
-					 * vendor-specific cmd's */
-	unsigned sector_size;	/* size in bytes */
-
-	int access_count;	/* Count of open channels/mounts */
-
-	void *hostdata;		/* available to low-level driver */
-	char devfs_name[256];	/* devfs junk */
-	char type;
-	char scsi_level;
-	unsigned char inquiry_len;	/* valid bytes in 'inquiry' */
-	unsigned char * inquiry;	/* INQUIRY response data */
-	char * vendor;		/* [back_compat] point into 'inquiry' ... */
-	char * model;		/* ... after scan; point to static string */
-	char * rev;		/* ... "nullnullnullnull" before scan */
-	unsigned char current_tag;	/* current tag */
-//	unsigned char sync_min_period;	/* Not less than this period */
-//	unsigned char sync_max_offset;	/* Not greater than this offset */
-	struct scsi_target      *sdev_target;   /* used only for single_lun */
-
-	unsigned online:1;
-	unsigned writeable:1;
-	unsigned removable:1;
-	unsigned random:1;
-	unsigned changed:1;	/* Data invalid due to media change */
-	unsigned busy:1;	/* Used to prevent races */
-	unsigned lockable:1;	/* Able to prevent media removal */
-	unsigned locked:1;      /* Media removal disabled */
-	unsigned borken:1;	/* Tell the Seagate driver to be 
-				 * painfully slow on this device */
-	unsigned disconnect:1;	/* can disconnect */
-	unsigned soft_reset:1;	/* Uses soft reset option */
-	unsigned sdtr:1;	/* Device supports SDTR messages */
-	unsigned wdtr:1;	/* Device supports WDTR messages */
-	unsigned ppr:1;		/* Device supports PPR messages */
-	unsigned tagged_supported:1;	/* Supports SCSI-II tagged queuing */
-	unsigned tagged_queue:1;/* This is going away!!!!  Look at simple_tags
-				   instead!!!  Please fix your driver now!! */
-	unsigned simple_tags:1;	/* simple queue tag messages are enabled */
-	unsigned ordered_tags:1;/* ordered queue tag messages are enabled */
-	unsigned single_lun:1;	/* Indicates we should only allow I/O to
-				 * one of the luns for the device at a 
-				 * time. */
-	unsigned was_reset:1;	/* There was a bus reset on the bus for 
-				 * this device */
-	unsigned expecting_cc_ua:1; /* Expecting a CHECK_CONDITION/UNIT_ATTN
-				     * because we did a bus reset. */
-	unsigned use_10_for_rw:1; /* first try 10-byte read / write */
-	unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */
-	unsigned remap:1;	/* support remapping  */
-//	unsigned sync:1;	/* Sync transfer state, managed by host */
-//	unsigned wide:1;	/* WIDE transfer state, managed by host */
-	unsigned no_start_on_add:1;	/* do not issue start on add */
-
-	unsigned int device_blocked;	/* Device returned QUEUE_FULL. */
-
-	unsigned int max_device_blocked; /* what device_blocked counts down from  */
-  	/* default value if the device doesn't override */
-	#define SCSI_DEFAULT_DEVICE_BLOCKED	3
-
-	struct device sdev_driverfs_dev;
-};
-#define	to_scsi_device(d)	\
-	container_of(d, struct scsi_device, sdev_driverfs_dev)
-
-
-typedef struct scsi_pointer {
-	char *ptr;		/* data pointer */
-	int this_residual;	/* left in this buffer */
-	struct scatterlist *buffer;	/* which buffer */
-	int buffers_residual;	/* how many buffers left */
-
-        dma_addr_t dma_handle;
-
-	volatile int Status;
-	volatile int Message;
-	volatile int have_data_in;
-	volatile int sent_command;
-	volatile int phase;
-} Scsi_Pointer;
-
-/*
- * This is essentially a slimmed down version of Scsi_Cmnd.  The point of
- * having this is that requests that are injected into the queue as result
- * of things like ioctls and character devices shouldn't be using a
- * Scsi_Cmnd until such a time that the command is actually at the head
- * of the queue and being sent to the driver.
- */
-struct scsi_request {
-	int     sr_magic;
-	int     sr_result;	/* Status code from lower level driver */
-	unsigned char sr_sense_buffer[SCSI_SENSE_BUFFERSIZE];		/* obtained by REQUEST SENSE
-						 * when CHECK CONDITION is
-						 * received on original command 
-						 * (auto-sense) */
-
-	struct Scsi_Host *sr_host;
-	Scsi_Device *sr_device;
-	Scsi_Cmnd *sr_command;
-	struct request *sr_request;	/* A copy of the command we are
-				   working on */
-	unsigned sr_bufflen;	/* Size of data buffer */
-	void *sr_buffer;		/* Data buffer */
-	int sr_allowed;
-	unsigned char sr_data_direction;
-	unsigned char sr_cmd_len;
-	unsigned char sr_cmnd[MAX_COMMAND_SIZE];
-	void (*sr_done) (struct scsi_cmnd *);	/* Mid-level done function */
-	int sr_timeout_per_command;
-	unsigned short sr_use_sg;	/* Number of pieces of scatter-gather */
-	unsigned short sr_sglist_len;	/* size of malloc'd scatter-gather list */
-	unsigned sr_underflow;	/* Return error if less than
-				   this amount is transferred */
- 	void * upper_private_data;	/* reserved for owner (usually upper
- 					   level driver) of this request */
-};
-
-/*
- * FIXME(eric) - one of the great regrets that I have is that I failed to
- * define these structure elements as something like sc_foo instead of foo.
- * This would make it so much easier to grep through sources and so forth.
- * I propose that all new elements that get added to these structures follow
- * this convention.  As time goes on and as people have the stomach for it,
- * it should be possible to go back and retrofit at least some of the elements
- * here with with the prefix.
- */
-struct scsi_cmnd {
-	int     sc_magic;
-
-	struct scsi_device *device;
-	unsigned short state;
-	unsigned short owner;
-	Scsi_Request *sc_request;
-
-	struct list_head list;  /* scsi_cmnd participates in queue lists */
-
-	struct list_head eh_entry; /* entry for the host eh_cmd_q */
-	int eh_state;		/* Used for state tracking in error handlr */
-	int eh_eflags;		/* Used by error handlr */
-	void (*done) (struct scsi_cmnd *);	/* Mid-level done function */
-	/*
-	   A SCSI Command is assigned a nonzero serial_number when internal_cmnd
-	   passes it to the driver's queue command function.  The serial_number
-	   is cleared when scsi_done is entered indicating that the command has
-	   been completed.  If a timeout occurs, the serial number at the moment
-	   of timeout is copied into serial_number_at_timeout.  By subsequently
-	   comparing the serial_number and serial_number_at_timeout fields
-	   during abort or reset processing, we can detect whether the command
-	   has already completed.  This also detects cases where the command has
-	   completed and the SCSI Command structure has already being reused
-	   for another command, so that we can avoid incorrectly aborting or
-	   resetting the new command.
-	 */
-
-	unsigned long serial_number;
-	unsigned long serial_number_at_timeout;
-
-	int retries;
-	int allowed;
-	int timeout_per_command;
-	int timeout_total;
-	int timeout;
-
-	/*
-	 * We handle the timeout differently if it happens when a reset, 
-	 * abort, etc are in process. 
-	 */
-	unsigned volatile char internal_timeout;
-
-	unsigned char cmd_len;
-	unsigned char old_cmd_len;
-	unsigned char sc_data_direction;
-	unsigned char sc_old_data_direction;
-
-	/* These elements define the operation we are about to perform */
-	unsigned char cmnd[MAX_COMMAND_SIZE];
-	unsigned request_bufflen;	/* Actual request size */
-
-	struct timer_list eh_timeout;	/* Used to time out the command. */
-	void *request_buffer;		/* Actual requested buffer */
-
-	/* These elements define the operation we ultimately want to perform */
-	unsigned char data_cmnd[MAX_COMMAND_SIZE];
-	unsigned short old_use_sg;	/* We save  use_sg here when requesting
-					 * sense info */
-	unsigned short use_sg;	/* Number of pieces of scatter-gather */
-	unsigned short sglist_len;	/* size of malloc'd scatter-gather list */
-	unsigned short abort_reason;	/* If the mid-level code requests an
-					 * abort, this is the reason. */
-	unsigned bufflen;	/* Size of data buffer */
-	void *buffer;		/* Data buffer */
-
-	unsigned underflow;	/* Return error if less than
-				   this amount is transferred */
-	unsigned old_underflow;	/* save underflow here when reusing the
-				 * command for error handling */
-
-	unsigned transfersize;	/* How much we are guaranteed to
-				   transfer with each SCSI transfer
-				   (ie, between disconnect / 
-				   reconnects.   Probably == sector
-				   size */
-
-	int resid;		/* Number of bytes requested to be
-				   transferred less actual number
-				   transferred (0 if not supported) */
-
-	struct request *request;	/* The command we are
-				   	   working on */
-
-	unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE];		/* obtained by REQUEST SENSE
-						 * when CHECK CONDITION is
-						 * received on original command 
-						 * (auto-sense) */
-
-	unsigned flags;
-
-	/* Low-level done function - can be used by low-level driver to point
-	 *        to completion function.  Not used by mid/upper level code. */
-	void (*scsi_done) (struct scsi_cmnd *);
-
-	/*
-	 * The following fields can be written to by the host specific code. 
-	 * Everything else should be left alone. 
-	 */
-
-	Scsi_Pointer SCp;	/* Scratchpad used by some host adapters */
-
-	unsigned char *host_scribble;	/* The host adapter is allowed to
-					   * call scsi_malloc and get some memory
-					   * and hang it here.     The host adapter
-					   * is also expected to call scsi_free
-					   * to release this memory.  (The memory
-					   * obtained by scsi_malloc is guaranteed
-					   * to be at an address < 16Mb). */
-
-	int result;		/* Status code from lower level driver */
-
-	unsigned char tag;	/* SCSI-II queued command tag */
-	unsigned long pid;	/* Process ID, starts at 0 */
-};
-
 /*
  * Definitions and prototypes used for scsi mid-level queue.
  */
@@ -588,104 +222,18 @@
 #define SCSI_MLQUEUE_DEVICE_BUSY 0x1056
 #define SCSI_MLQUEUE_EH_RETRY    0x1057
 
-/*
- * Reset request from external source
- */
-#define SCSI_TRY_RESET_DEVICE	1
-#define SCSI_TRY_RESET_BUS	2
-#define SCSI_TRY_RESET_HOST	3
-
-extern int scsi_reset_provider(Scsi_Device *, int);
-
-#define MSG_SIMPLE_TAG	0x20
-#define MSG_HEAD_TAG	0x21
-#define MSG_ORDERED_TAG	0x22
-
-#define SCSI_NO_TAG	(-1)    /* identify no tag in use */
-
-/**
- * scsi_activate_tcq - turn on tag command queueing
- * @SDpnt:	device to turn on TCQ for
- * @depth:	queue depth
- *
- * Notes:
- *	Eventually, I hope depth would be the maximum depth
- *	the device could cope with and the real queue depth
- *	would be adjustable from 0 to depth.
- **/
-static inline void scsi_activate_tcq(Scsi_Device *SDpnt, int depth) {
-        if(SDpnt->tagged_supported) {
-		if(!blk_queue_tagged(SDpnt->request_queue))
-			blk_queue_init_tags(SDpnt->request_queue, depth);
-		scsi_adjust_queue_depth(SDpnt, MSG_ORDERED_TAG, depth);
-        }
-}
-
-/**
- * scsi_deactivate_tcq - turn off tag command queueing
- * @SDpnt:	device to turn off TCQ for
- **/
-static inline void scsi_deactivate_tcq(Scsi_Device *SDpnt, int depth) {
-	if(blk_queue_tagged(SDpnt->request_queue))
-		blk_queue_free_tags(SDpnt->request_queue);
-	scsi_adjust_queue_depth(SDpnt, 0, depth);
-}
-
-/**
- * scsi_populate_tag_msg - place a tag message in a buffer
- * @SCpnt:	pointer to the Scsi_Cmnd for the tag
- * @msg:	pointer to the area to place the tag
- *
- * Notes:
- *	designed to create the correct type of tag message for the 
- *	particular request.  Returns the size of the tag message.
- *	May return 0 if TCQ is disabled for this device.
- **/
-static inline int scsi_populate_tag_msg(Scsi_Cmnd *SCpnt, char *msg) {
-        struct request *req = SCpnt->request;
-
-        if(!blk_rq_tagged(req))
-                return 0;
-
-	if (req->flags & REQ_HARDBARRIER)
-                *msg++ = MSG_ORDERED_TAG;
-        else
-                *msg++ = MSG_SIMPLE_TAG;
-
-        *msg++ = SCpnt->request->tag;
-
-        return 2;
-}
-
-/**
- * scsi_find_tag - find a tagged command by device
- * @SDpnt:	pointer to the ScSI device
- * @tag:	the tag number
- *
- * Notes:
- *	Only works with tags allocated by the generic blk layer.
- **/
-static inline Scsi_Cmnd *scsi_find_tag(Scsi_Device *SDpnt, int tag) {
-
-        struct request *req;
-
-        if(tag == SCSI_NO_TAG)
-                /* single command, look in space */
-                return SDpnt->current_cmnd;
-
-        req = blk_queue_find_tag(SDpnt->request_queue, tag);
-
-        if(req == NULL)
-                return NULL;
-
-        return (Scsi_Cmnd *)req->special;
-}
-
-int scsi_set_medium_removal(Scsi_Device *dev, char state);
-
 extern int scsi_sysfs_modify_sdev_attribute(struct device_attribute ***dev_attrs,
 					    struct device_attribute *attr);
 extern int scsi_sysfs_modify_shost_attribute(struct class_device_attribute ***class_attrs,
 					     struct class_device_attribute *attr);
+
+/*
+ * This is the crap from the old error handling code.  We have it in a special
+ * place so that we can more easily delete it later on.
+ */
+#include "scsi_obsolete.h"
+
+/* obsolete typedef junk. */
+#include "scsi_typedefs.h"
 
 #endif /* _SCSI_H */
diff -Nru a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
--- a/drivers/scsi/scsi_debug.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/scsi_debug.c	Wed Jun 18 23:42:07 2003
@@ -1681,7 +1681,7 @@
 
 	sdbg_host = to_sdebug_host(dev);
 
-        hpnt = scsi_register(&sdebug_driver_template, sizeof(sdbg_host));
+        hpnt = scsi_host_alloc(&sdebug_driver_template, sizeof(sdbg_host));
         if (NULL == hpnt) {
                 printk(KERN_ERR "%s: scsi_register failed\n", __FUNCTION__);
                 error = -ENODEV;
@@ -1700,7 +1700,7 @@
         if (error) {
                 printk(KERN_ERR "%s: scsi_add_host failed\n", __FUNCTION__);
                 error = -ENODEV;
-		scsi_unregister(hpnt);
+		scsi_host_put(hpnt);
         }
 
 
@@ -1726,8 +1726,6 @@
                 return -EBUSY;
         }
 
-        scsi_unregister(sdbg_host->shost);
-
         list_for_each_safe(lh, lh_sf, &sdbg_host->dev_info_list) {
                 sdbg_devinfo = list_entry(lh, struct sdebug_dev_info,
                                           dev_list);
@@ -1735,5 +1733,6 @@
                 kfree(sdbg_devinfo);
         }
 
+        scsi_host_put(sdbg_host->shost);
         return 0;
 }
diff -Nru a/drivers/scsi/scsi_devinfo.c b/drivers/scsi/scsi_devinfo.c
--- a/drivers/scsi/scsi_devinfo.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/scsi_devinfo.c	Wed Jun 18 23:42:06 2003
@@ -3,6 +3,7 @@
 #include <linux/init.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/proc_fs.h>
 #include <linux/seq_file.h>
 
@@ -23,9 +24,9 @@
 
 
 static const char spaces[] = "                "; /* 16 of them */
-static char *scsi_dev_flags;
 static unsigned scsi_default_dev_flags;
 static LIST_HEAD(scsi_dev_info_list);
+static __init char scsi_dev_flags[256];
 
 /*
  * scsi_static_device_list: deprecated list of devices that require
@@ -180,6 +181,7 @@
 	{"SGI", "TP9400", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
 	{"SGI", "TP9500", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
 	{"MYLEX", "DACARMRB", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
+	{"XYRATEX", "RS", "*", BLIST_SPARSELUN | BLIST_LARGELUN},
 	{ NULL, NULL, NULL, 0 },
 };
 
@@ -450,35 +452,15 @@
 	return err;
 }
 
-MODULE_PARM(scsi_dev_flags, "s");
-MODULE_PARM_DESC(scsi_dev_flags,
-	 "Given scsi_dev_flags=vendor:model:flags, add a black/white list"
-	 " entry for vendor and model with an integer value of flags"
+module_param_string(dev_flags, scsi_dev_flags, sizeof(scsi_dev_flags), 0);
+MODULE_PARM_DESC(dev_flags,
+	 "Given scsi_dev_flags=vendor:model:flags[,v:m:f] add black/white"
+	 " list entries for vendor and model with an integer value of flags"
 	 " to the scsi device info list");
-MODULE_PARM(scsi_default_dev_flags, "i");
-MODULE_PARM_DESC(scsi_default_dev_flags,
-		 "scsi default device flag integer value");
 
-static int __init setup_scsi_dev_flags(char *str)
-{
-	scsi_dev_flags = str;
-	return 1;
-}
-
-static int __init setup_scsi_default_dev_flags(char *str)
-{
-	unsigned int tmp;
-	if (get_option(&str, &tmp) == 1) {
-		scsi_default_dev_flags = tmp;
-		printk(KERN_WARNING "%s %d\n", __FUNCTION__,
-		       scsi_default_dev_flags);
-		return 1;
-	} else {
-		printk(KERN_WARNING "%s: usage scsi_default_dev_flags=intr\n",
-		       __FUNCTION__);
-		return 0;
-	}
-}
+module_param_named(default_dev_flags, scsi_default_dev_flags, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(default_dev_flags,
+		 "scsi default device flag integer value");
 
 /**
  * scsi_dev_info_list_delete: called from scsi.c:exit_scsi to remove
@@ -540,6 +522,3 @@
 		scsi_exit_devinfo();
 	return error;
 }
-
-__setup("scsi_dev_flags=", setup_scsi_dev_flags);
-__setup("scsi_default_dev_flags=", setup_scsi_default_dev_flags);
diff -Nru a/drivers/scsi/scsi_error.c b/drivers/scsi/scsi_error.c
--- a/drivers/scsi/scsi_error.c	Wed Jun 18 23:42:05 2003
+++ b/drivers/scsi/scsi_error.c	Wed Jun 18 23:42:05 2003
@@ -44,6 +44,16 @@
 #define BUS_RESET_SETTLE_TIME   10*HZ
 #define HOST_RESET_SETTLE_TIME  10*HZ
 
+/* called with shost->host_lock held */
+void scsi_eh_wakeup(struct Scsi_Host *shost)
+{
+	if (shost->host_busy == shost->host_failed) {
+		up(shost->eh_wait);
+		SCSI_LOG_ERROR_RECOVERY(5,
+				printk("Waking error handler thread\n"));
+	}
+}
+
 /**
  * scsi_eh_scmd_add - add scsi cmd to error handling.
  * @scmd:	scmd to run eh on.
@@ -76,14 +86,8 @@
 	list_add_tail(&scmd->eh_entry, &shost->eh_cmd_q);
 	shost->in_recovery = 1;
 	shost->host_failed++;
-	if (shost->host_busy == shost->host_failed) {
-		up(shost->eh_wait);
-		SCSI_LOG_ERROR_RECOVERY(5, printk("Waking error handler"
-					  " thread\n"));
-	}
-
+	scsi_eh_wakeup(shost);
 	spin_unlock_irqrestore(shost->host_lock, flags);
-
 	return 1;
 }
 
@@ -431,6 +435,7 @@
 static int scsi_send_eh_cmnd(struct scsi_cmnd *scmd, int timeout)
 {
 	struct Scsi_Host *host = scmd->device->host;
+	DECLARE_MUTEX_LOCKED(sem);
 	unsigned long flags;
 	int rtn = SUCCESS;
 
@@ -444,71 +449,53 @@
 		scmd->cmnd[1] = (scmd->cmnd[1] & 0x1f) |
 			(scmd->device->lun << 5 & 0xe0);
 
-	if (host->can_queue) {
-		DECLARE_MUTEX_LOCKED(sem);
+	scsi_add_timer(scmd, timeout, scsi_eh_times_out);
 
-		scsi_add_timer(scmd, timeout, scsi_eh_times_out);
+	/*
+	 * set up the semaphore so we wait for the command to complete.
+	 */
+	scmd->device->host->eh_action = &sem;
+	scmd->request->rq_status = RQ_SCSI_BUSY;
 
-		/*
-		 * set up the semaphore so we wait for the command to complete.
-		 */
-		scmd->device->host->eh_action = &sem;
-		scmd->request->rq_status = RQ_SCSI_BUSY;
+	spin_lock_irqsave(scmd->device->host->host_lock, flags);
+	host->hostt->queuecommand(scmd, scsi_eh_done);
+	spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 
-		spin_lock_irqsave(scmd->device->host->host_lock, flags);
-		host->hostt->queuecommand(scmd, scsi_eh_done);
-		spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
+	down(&sem);
 
-		down(&sem);
+	scmd->device->host->eh_action = NULL;
 
-		scmd->device->host->eh_action = NULL;
+	/*
+	 * see if timeout.  if so, tell the host to forget about it.
+	 * in other words, we don't want a callback any more.
+	 */
+	if (scsi_eh_eflags_chk(scmd, SCSI_EH_REC_TIMEOUT)) {
+		scsi_eh_eflags_clr(scmd,  SCSI_EH_REC_TIMEOUT);
+		scmd->owner = SCSI_OWNER_LOWLEVEL;
 
 		/*
-		 * see if timeout.  if so, tell the host to forget about it.
-		 * in other words, we don't want a callback any more.
+		 * as far as the low level driver is
+		 * concerned, this command is still active, so
+		 * we must give the low level driver a chance
+		 * to abort it. (db) 
+		 *
+		 * FIXME(eric) - we are not tracking whether we could
+		 * abort a timed out command or not.  not sure how
+		 * we should treat them differently anyways.
 		 */
-		if (scsi_eh_eflags_chk(scmd, SCSI_EH_REC_TIMEOUT)) {
-			scsi_eh_eflags_clr(scmd,  SCSI_EH_REC_TIMEOUT);
-                        scmd->owner = SCSI_OWNER_LOWLEVEL;
-
-			/*
-			 * as far as the low level driver is
-			 * concerned, this command is still active, so
-			 * we must give the low level driver a chance
-			 * to abort it. (db) 
-			 *
-			 * FIXME(eric) - we are not tracking whether we could
-			 * abort a timed out command or not.  not sure how
-			 * we should treat them differently anyways.
-			 */
-			spin_lock_irqsave(scmd->device->host->host_lock, flags);
-			if (scmd->device->host->hostt->eh_abort_handler)
-				scmd->device->host->hostt->eh_abort_handler(scmd);
-			spin_unlock_irqrestore(scmd->device->host->host_lock,
-					       flags);
+		spin_lock_irqsave(scmd->device->host->host_lock, flags);
+		if (scmd->device->host->hostt->eh_abort_handler)
+			scmd->device->host->hostt->eh_abort_handler(scmd);
+		spin_unlock_irqrestore(scmd->device->host->host_lock, flags);
 			
-			scmd->request->rq_status = RQ_SCSI_DONE;
-			scmd->owner = SCSI_OWNER_ERROR_HANDLER;
+		scmd->request->rq_status = RQ_SCSI_DONE;
+		scmd->owner = SCSI_OWNER_ERROR_HANDLER;
 			
-			rtn = FAILED;
-		}
-		SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd: %p, rtn:%x\n",
-						  __FUNCTION__, scmd, rtn));
-	} else {
-		int temp;
-
-		/*
-		 * we damn well had better never use this code.  there is no
-		 * timeout protection here, since we would end up waiting in
-		 * the actual low level driver, we don't know how to wake it up.
-		 */
-		spin_lock_irqsave(host->host_lock, flags);
-		temp = host->hostt->command(scmd);
-		spin_unlock_irqrestore(host->host_lock, flags);
-
-		scmd->result = temp;
-		/* fall through to code below to examine status. */
+		rtn = FAILED;
 	}
+
+	SCSI_LOG_ERROR_RECOVERY(3, printk("%s: scmd: %p, rtn:%x\n",
+					  __FUNCTION__, scmd, rtn));
 
 	/*
 	 * now examine the actual status codes to see whether the command
diff -Nru a/drivers/scsi/scsi_ioctl.c b/drivers/scsi/scsi_ioctl.c
--- a/drivers/scsi/scsi_ioctl.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/scsi/scsi_ioctl.c	Wed Jun 18 23:42:09 2003
@@ -90,75 +90,70 @@
  * The output area is then filled in starting from the command byte. 
  */
 
-static int ioctl_internal_command(Scsi_Device * dev, char *cmd,
+static int ioctl_internal_command(struct scsi_device *sdev, char *cmd,
 				  int timeout, int retries)
 {
+	struct scsi_request *sreq;
 	int result;
-	Scsi_Request *SRpnt;
-	Scsi_Device *SDpnt;
 
+	SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", *cmd));
 
-	SCSI_LOG_IOCTL(1, printk("Trying ioctl with scsi command %d\n", cmd[0]));
-	if (NULL == (SRpnt = scsi_allocate_request(dev))) {
+	sreq = scsi_allocate_request(sdev);
+	if (!sreq) {
 		printk("SCSI internal ioctl failed, no memory\n");
 		return -ENOMEM;
 	}
 
-	SRpnt->sr_data_direction = SCSI_DATA_NONE;
-        scsi_wait_req(SRpnt, cmd, NULL, 0, timeout, retries);
+	sreq->sr_data_direction = SCSI_DATA_NONE;
+        scsi_wait_req(sreq, cmd, NULL, 0, timeout, retries);
 
-	SCSI_LOG_IOCTL(2, printk("Ioctl returned  0x%x\n", SRpnt->sr_result));
+	SCSI_LOG_IOCTL(2, printk("Ioctl returned  0x%x\n", sreq->sr_result));
 
-	if (driver_byte(SRpnt->sr_result) != 0)
-		switch (SRpnt->sr_sense_buffer[2] & 0xf) {
+	if (driver_byte(sreq->sr_result)) {
+		switch (sreq->sr_sense_buffer[2] & 0xf) {
 		case ILLEGAL_REQUEST:
 			if (cmd[0] == ALLOW_MEDIUM_REMOVAL)
-				dev->lockable = 0;
+				sdev->lockable = 0;
 			else
 				printk("SCSI device (ioctl) reports ILLEGAL REQUEST.\n");
 			break;
 		case NOT_READY:	/* This happens if there is no disc in drive */
-			if (dev->removable && (cmd[0] != TEST_UNIT_READY)) {
+			if (sdev->removable && (cmd[0] != TEST_UNIT_READY)) {
 				printk(KERN_INFO "Device not ready.  Make sure there is a disc in the drive.\n");
 				break;
 			}
 		case UNIT_ATTENTION:
-			if (dev->removable) {
-				dev->changed = 1;
-				SRpnt->sr_result = 0;	/* This is no longer considered an error */
-				/* gag this error, VFS will log it anyway /axboe */
-				/* printk(KERN_INFO "Disc change detected.\n"); */
+			if (sdev->removable) {
+				sdev->changed = 1;
+				sreq->sr_result = 0;	/* This is no longer considered an error */
 				break;
 			}
 		default:	/* Fall through for non-removable media */
 			printk("SCSI error: host %d id %d lun %d return code = %x\n",
-			       dev->host->host_no,
-			       dev->id,
-			       dev->lun,
-			       SRpnt->sr_result);
+			       sdev->host->host_no,
+			       sdev->id,
+			       sdev->lun,
+			       sreq->sr_result);
 			printk("\tSense class %x, sense error %x, extended sense %x\n",
-			       sense_class(SRpnt->sr_sense_buffer[0]),
-			       sense_error(SRpnt->sr_sense_buffer[0]),
-			       SRpnt->sr_sense_buffer[2] & 0xf);
+			       sense_class(sreq->sr_sense_buffer[0]),
+			       sense_error(sreq->sr_sense_buffer[0]),
+			       sreq->sr_sense_buffer[2] & 0xf);
 
 		}
+	}
 
-	result = SRpnt->sr_result;
-
+	result = sreq->sr_result;
 	SCSI_LOG_IOCTL(2, printk("IOCTL Releasing command\n"));
-	SDpnt = SRpnt->sr_device;
-	scsi_release_request(SRpnt);
-	SRpnt = NULL;
-
+	scsi_release_request(sreq);
 	return result;
 }
 
-int scsi_set_medium_removal(Scsi_Device *dev, char state)
+int scsi_set_medium_removal(struct scsi_device *sdev, char state)
 {
 	char scsi_cmd[MAX_COMMAND_SIZE];
 	int ret;
 
-	if (!dev->removable || !dev->lockable)
+	if (!sdev->removable || !sdev->lockable)
 	       return 0;
 
 	scsi_cmd[0] = ALLOW_MEDIUM_REMOVAL;
@@ -168,11 +163,10 @@
 	scsi_cmd[4] = state;
 	scsi_cmd[5] = 0;
 
-	ret = ioctl_internal_command(dev, scsi_cmd, IOCTL_NORMAL_TIMEOUT, NORMAL_RETRIES);
-
+	ret = ioctl_internal_command(sdev, scsi_cmd,
+			IOCTL_NORMAL_TIMEOUT, NORMAL_RETRIES);
 	if (ret == 0)
-		dev->locked = state == SCSI_REMOVAL_PREVENT;
-
+		sdev->locked = (state == SCSI_REMOVAL_PREVENT);
 	return ret;
 }
 
@@ -209,13 +203,13 @@
  */
 #define OMAX_SB_LEN 16		/* Old sense buffer length */
 
-int scsi_ioctl_send_command(Scsi_Device * dev, Scsi_Ioctl_Command * sic)
+int scsi_ioctl_send_command(struct scsi_device *sdev,
+			    struct scsi_ioctl_command *sic)
 {
 	char *buf;
 	unsigned char cmd[MAX_COMMAND_SIZE];
 	char *cmd_in;
-	Scsi_Request *SRpnt;
-	Scsi_Device *SDpnt;
+	struct scsi_request *sreq;
 	unsigned char opcode;
 	unsigned int inlen, outlen, cmdlen;
 	unsigned int needed, buf_needed;
@@ -225,7 +219,7 @@
 	if (!sic)
 		return -EINVAL;
 
-	if (dev->host->unchecked_isa_dma)
+	if (sdev->host->unchecked_isa_dma)
 		gfp_mask |= GFP_DMA;
 
 	/*
@@ -259,11 +253,11 @@
 		buf_needed = (buf_needed + 511) & ~511;
 		if (buf_needed > MAX_BUF)
 			buf_needed = MAX_BUF;
-		buf = (char *) kmalloc(buf_needed, gfp_mask);
+		buf = kmalloc(buf_needed, gfp_mask);
 		if (!buf)
 			return -ENOMEM;
 		memset(buf, 0, buf_needed);
-		if( inlen == 0 ) {
+		if (inlen == 0) {
 			data_direction = SCSI_DATA_READ;
 		} else if (outlen == 0 ) {
 			data_direction = SCSI_DATA_WRITE;
@@ -327,62 +321,34 @@
 		break;
 	}
 
-#ifndef DEBUG_NO_CMD
-
-
-	SRpnt = scsi_allocate_request(dev);
-        if( SRpnt == NULL )
-        {
+	sreq = scsi_allocate_request(sdev);
+        if (sreq) {
                 result = -EINTR;
                 goto error;
         }
 
-	SRpnt->sr_data_direction = data_direction;
-        scsi_wait_req(SRpnt, cmd, buf, needed, timeout, retries);
+	sreq->sr_data_direction = data_direction;
+        scsi_wait_req(sreq, cmd, buf, needed, timeout, retries);
 
 	/* 
 	 * If there was an error condition, pass the info back to the user. 
 	 */
-
-	result = SRpnt->sr_result;
-
-	if (SRpnt->sr_result) {
-		int sb_len = sizeof(SRpnt->sr_sense_buffer);
+	result = sreq->sr_result;
+	if (result) {
+		int sb_len = sizeof(sreq->sr_sense_buffer);
 
 		sb_len = (sb_len > OMAX_SB_LEN) ? OMAX_SB_LEN : sb_len;
-		if (copy_to_user(cmd_in, SRpnt->sr_sense_buffer, sb_len))
+		if (copy_to_user(cmd_in, sreq->sr_sense_buffer, sb_len))
 			result = -EFAULT;
 	} else {
 		if (copy_to_user(cmd_in, buf, outlen))
 			result = -EFAULT;
 	}	
 
-	SDpnt = SRpnt->sr_device;
-	scsi_release_request(SRpnt);
-	SRpnt = NULL;
-
+	scsi_release_request(sreq);
 error:
-	if (buf)
-		kfree(buf);
-
-
+	kfree(buf);
 	return result;
-#else
-	{
-		int i;
-		printk("scsi_ioctl : device %d.  command = ", dev->id);
-		for (i = 0; i < cmdlen; ++i)
-			printk("%02x ", cmd[i]);
-		printk("\nbuffer =");
-		for (i = 0; i < 20; ++i)
-			printk("%02x ", buf[i]);
-		printk("\n");
-		printk("inlen = %d, outlen = %d, cmdlen = %d\n",
-		       inlen, outlen, cmdlen);
-		printk("buffer = %d, cmd_in = %d\n", buffer, cmd_in);
-	}
-	return 0;
-#endif
 }
 
 /*
@@ -395,14 +361,13 @@
  *                  device)
  *          any copy_to_user() error on failure there
  */
-static int
-scsi_ioctl_get_pci(Scsi_Device * sdev, void *arg)
+static int scsi_ioctl_get_pci(struct scsi_device *sdev, void *arg)
 {
 	struct device *dev = scsi_get_device(sdev->host);
 
-        if (!dev) return -ENXIO;
-        return copy_to_user(arg, dev->bus_id,
-                            sizeof(dev->bus_id));
+        if (!dev)
+		return -ENXIO;
+        return copy_to_user(arg, dev->bus_id, sizeof(dev->bus_id));
 }
 
 
@@ -411,12 +376,12 @@
  * not take a major/minor number as the dev field.  Rather, it takes
  * a pointer to a scsi_devices[] element, a structure. 
  */
-int scsi_ioctl(Scsi_Device * dev, int cmd, void *arg)
+int scsi_ioctl(struct scsi_device *sdev, int cmd, void *arg)
 {
 	char scsi_cmd[MAX_COMMAND_SIZE];
 
 	/* No idea how this happens.... */
-	if (!dev)
+	if (!sdev)
 		return -ENXIO;
 
 	/*
@@ -425,24 +390,24 @@
 	 * may try and take the device offline, in which case all further
 	 * access to the device is prohibited.
 	 */
-	if (!scsi_block_when_processing_errors(dev)) {
+	if (!scsi_block_when_processing_errors(sdev))
 		return -ENODEV;
-	}
 
 	switch (cmd) {
 	case SCSI_IOCTL_GET_IDLUN:
-		if (verify_area(VERIFY_WRITE, arg, sizeof(Scsi_Idlun)))
+		if (verify_area(VERIFY_WRITE, arg, sizeof(struct scsi_idlun)))
 			return -EFAULT;
 
-		__put_user((dev->id & 0xff)
-			 + ((dev->lun & 0xff) << 8)
-			 + ((dev->channel & 0xff) << 16)
-			 + ((dev->host->host_no & 0xff) << 24),
-			 &((Scsi_Idlun *) arg)->dev_id);
-		__put_user(dev->host->unique_id, &((Scsi_Idlun *) arg)->host_unique_id);
+		__put_user((sdev->id & 0xff)
+			 + ((sdev->lun & 0xff) << 8)
+			 + ((sdev->channel & 0xff) << 16)
+			 + ((sdev->host->host_no & 0xff) << 24),
+			 &((struct scsi_idlun *)arg)->dev_id);
+		__put_user(sdev->host->unique_id,
+			 &((struct scsi_idlun *)arg)->host_unique_id);
 		return 0;
 	case SCSI_IOCTL_GET_BUS_NUMBER:
-		return put_user(dev->host->host_no, (int *) arg);
+		return put_user(sdev->host->host_no, (int *)arg);
 	/*
 	 * The next two ioctls either need to go or need to be changed to
 	 * pass tagged queueing changes through the low level drivers.
@@ -454,61 +419,56 @@
 	case SCSI_IOCTL_TAGGED_ENABLE:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
-		if (!dev->tagged_supported)
+		if (!sdev->tagged_supported)
 			return -EINVAL;
-		dev->tagged_queue = 1;
-		dev->current_tag = 1;
+		sdev->tagged_queue = 1;
+		sdev->current_tag = 1;
 		return 0;
 	case SCSI_IOCTL_TAGGED_DISABLE:
 		if (!capable(CAP_SYS_ADMIN))
 			return -EACCES;
-		if (!dev->tagged_supported)
+		if (!sdev->tagged_supported)
 			return -EINVAL;
-		dev->tagged_queue = 0;
-		dev->current_tag = 0;
+		sdev->tagged_queue = 0;
+		sdev->current_tag = 0;
 		return 0;
 	case SCSI_IOCTL_PROBE_HOST:
-		return ioctl_probe(dev->host, arg);
+		return ioctl_probe(sdev->host, arg);
 	case SCSI_IOCTL_SEND_COMMAND:
 		if (!capable(CAP_SYS_ADMIN) || !capable(CAP_SYS_RAWIO))
 			return -EACCES;
-		return scsi_ioctl_send_command((Scsi_Device *) dev,
-					     (Scsi_Ioctl_Command *) arg);
+		return scsi_ioctl_send_command(sdev,
+				(struct scsi_ioctl_command *)arg);
 	case SCSI_IOCTL_DOORLOCK:
-		return scsi_set_medium_removal(dev, SCSI_REMOVAL_PREVENT);
+		return scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
 	case SCSI_IOCTL_DOORUNLOCK:
-		return scsi_set_medium_removal(dev, SCSI_REMOVAL_ALLOW);
+		return scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
 	case SCSI_IOCTL_TEST_UNIT_READY:
 		scsi_cmd[0] = TEST_UNIT_READY;
 		scsi_cmd[1] = 0;
 		scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
 		scsi_cmd[4] = 0;
-		return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
+		return ioctl_internal_command(sdev, scsi_cmd,
 				   IOCTL_NORMAL_TIMEOUT, NORMAL_RETRIES);
-		break;
 	case SCSI_IOCTL_START_UNIT:
 		scsi_cmd[0] = START_STOP;
 		scsi_cmd[1] = 0;
 		scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
 		scsi_cmd[4] = 1;
-		return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
+		return ioctl_internal_command(sdev, scsi_cmd,
 				     START_STOP_TIMEOUT, NORMAL_RETRIES);
-		break;
 	case SCSI_IOCTL_STOP_UNIT:
 		scsi_cmd[0] = START_STOP;
 		scsi_cmd[1] = 0;
 		scsi_cmd[2] = scsi_cmd[3] = scsi_cmd[5] = 0;
 		scsi_cmd[4] = 0;
-		return ioctl_internal_command((Scsi_Device *) dev, scsi_cmd,
+		return ioctl_internal_command(sdev, scsi_cmd,
 				     START_STOP_TIMEOUT, NORMAL_RETRIES);
-		break;
         case SCSI_IOCTL_GET_PCI:
-                return scsi_ioctl_get_pci(dev, arg);
-                break;
+                return scsi_ioctl_get_pci(sdev, arg);
 	default:
-		if (dev->host->hostt->ioctl)
-			return dev->host->hostt->ioctl(dev, cmd, arg);
-		return -EINVAL;
+		if (sdev->host->hostt->ioctl)
+			return sdev->host->hostt->ioctl(sdev, cmd, arg);
 	}
 	return -EINVAL;
 }
@@ -518,13 +478,13 @@
  * fs segment fiddling.
  */
 
-int kernel_scsi_ioctl(Scsi_Device * dev, int cmd, void *arg)
+int kernel_scsi_ioctl(struct scsi_device *sdev, int cmd, void *arg)
 {
 	mm_segment_t oldfs;
 	int tmp;
 	oldfs = get_fs();
 	set_fs(get_ds());
-	tmp = scsi_ioctl(dev, cmd, arg);
+	tmp = scsi_ioctl(sdev, cmd, arg);
 	set_fs(oldfs);
 	return tmp;
 }
diff -Nru a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
--- a/drivers/scsi/scsi_lib.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/scsi_lib.c	Wed Jun 18 23:42:07 2003
@@ -95,7 +95,6 @@
 {
 	struct Scsi_Host *host = cmd->device->host;
 	struct scsi_device *device = cmd->device;
-	unsigned long flags;
 
 	SCSI_LOG_MLQUEUE(1,
 		 printk("Inserting command %p into mlqueue\n", cmd));
@@ -134,10 +133,7 @@
 	 * Decrement the counters, since these commands are no longer
 	 * active on the host/device.
 	 */
-	spin_lock_irqsave(device->request_queue->queue_lock, flags);
-	device->device_busy--;
-	spin_unlock_irqrestore(device->request_queue->queue_lock, flags);
-	scsi_host_busy_dec_and_test(host, device);
+	scsi_device_unbusy(device);
 
 	/*
 	 * Insert this command at the head of the queue for it's device.
@@ -314,6 +310,21 @@
 	cmd->underflow = cmd->old_underflow;
 }
 
+void scsi_device_unbusy(struct scsi_device *sdev)
+{
+	struct Scsi_Host *shost = sdev->host;
+	unsigned long flags;
+
+	spin_lock_irqsave(shost->host_lock, flags);
+	shost->host_busy--;
+	if (unlikely(shost->in_recovery && shost->host_failed))
+		scsi_eh_wakeup(shost);
+	spin_unlock(shost->host_lock);
+	spin_lock(&sdev->sdev_lock);
+	sdev->device_busy--;
+	spin_unlock_irqrestore(&sdev->sdev_lock, flags);
+}
+
 /*
  * Called for single_lun devices on IO completion. Clear starget_sdev_user,
  * and call blk_run_queue for all the scsi_devices on the target -
@@ -730,17 +741,6 @@
 	 * can choose a block to remap, etc.
 	 */
 	if (driver_byte(result) != 0) {
-		if (suggestion(result) == SUGGEST_REMAP) {
-#ifdef REMAP
-			/*
-			 * Not yet implemented.  A read will fail after being remapped,
-			 * a write will call the strategy routine again.
-			 */
-			if (cmd->device->remap) {
-				result = 0;
-			}
-#endif
-		}
 		if ((cmd->sense_buffer[0] & 0x7f) == 0x70) {
 			/*
 			 * If the device is in the process of becoming ready,
@@ -944,6 +944,18 @@
 		} else
 			cmd = req->special;
 	} else if (req->flags & (REQ_CMD | REQ_BLOCK_PC)) {
+		/*
+		 * Just check to see if the device is online.  If
+		 * it isn't, we refuse to process ordinary commands
+		 * (we will allow specials just in case someone needs
+		 * to send a command to an offline device without bringing
+		 * it back online)
+		 */
+		if(!sdev->online) {
+			printk(KERN_ERR "scsi%d (%d:%d): rejecting I/O to offline device\n",
+			       sdev->host->host_no, sdev->id, sdev->lun);
+			return BLKPREP_KILL;
+		}
 		/*
 		 * Now try and find a command block that we can use.
 		 */
diff -Nru a/drivers/scsi/scsi_module.c b/drivers/scsi/scsi_module.c
--- a/drivers/scsi/scsi_module.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/scsi_module.c	Wed Jun 18 23:42:06 2003
@@ -1,71 +1,73 @@
 /*
- *  scsi_module.c Copyright (1994, 1995) Eric Youngdale.
+ * Copyright (C) 2003 Christoph Hellwig.
+ *	Released under GPL v2.
  *
- * Support for loading low-level scsi drivers using the linux kernel loadable
- * module interface.
+ * Support for old-style host templates.
  *
- * To use, the host adapter should first define and initialize the variable
- * driver_template (datatype Scsi_Host_Template), and then include this file.
- * This should also be wrapped in a #ifdef MODULE/#endif.
- *
- * The low -level driver must also define a release function which will
- * free any irq assignments, release any dma channels, release any I/O
- * address space that might be reserved, and otherwise clean up after itself.
- * The idea is that the same driver should be able to be reloaded without
- * any difficulty.  This makes debugging new drivers easier, as you should
- * be able to load the driver, test it, unload, modify and reload.
- *
- * One *very* important caveat.  If the driver may need to do DMA on the
- * ISA bus, you must have unchecked_isa_dma set in the device template,
- * even if this might be changed during the detect routine.  This is
- * because the shpnt structure will be allocated in a special way so that
- * it will be below the appropriate DMA limit - thus if your driver uses
- * the hostdata field of shpnt, and the board must be able to access this
- * via DMA, the shpnt structure must be in a DMA accessible region of
- * memory.  This comment would be relevant for something like the buslogic
- * driver where there are many boards, only some of which do DMA onto the
- * ISA bus.  There is no convenient way of specifying whether the host
- * needs to be in a ISA DMA accessible region of memory when you call
- * scsi_register.
+ * NOTE:  Do not use this for new drivers ever.
  */
 
-#include <linux/module.h>
 #include <linux/init.h>
+#include <linux/kernel.h>
+#include <linux/module.h>
+
+#include "scsi.h"
+#include "hosts.h"
+
 
 static int __init init_this_scsi_driver(void)
 {
-	driver_template.module = THIS_MODULE;
-	scsi_register_host(&driver_template);
-	if (driver_template.present)
-		return 0;
-
-	scsi_unregister_host(&driver_template);
-	return -ENODEV;
+	struct scsi_host_template *sht = &driver_template;
+	struct Scsi_Host *shost;
+	struct list_head *l;
+	int error;
+
+	if (!sht->release) {
+		printk(KERN_ERR
+		    "scsi HBA driver %s didn't set a release method.\n",
+		    sht->name);
+		return -EINVAL;
+	}
+
+	sht->module = THIS_MODULE;
+	INIT_LIST_HEAD(&sht->legacy_hosts);
+
+	sht->detect(sht);
+	if (!sht->present)
+		return -ENODEV;
+
+	list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list) {
+		error = scsi_add_host(shost, NULL);
+		if (error)
+			goto fail;
+	}
+	return 0;
+ fail:
+	l = &shost->sht_legacy_list;
+	while ((l = l->prev) != &sht->legacy_hosts)
+		scsi_remove_host(list_entry(l, struct Scsi_Host, sht_legacy_list));
+	return error;
 }
 
 static void __exit exit_this_scsi_driver(void)
 {
-	scsi_unregister_host(&driver_template);
+	struct scsi_host_template *sht = &driver_template;
+	struct Scsi_Host *shost, *s;
+
+	list_for_each_entry(shost, &sht->legacy_hosts, sht_legacy_list)
+		scsi_remove_host(shost);
+	list_for_each_entry_safe(shost, s, &sht->legacy_hosts, sht_legacy_list)
+		sht->release(shost);
+
+	if (list_empty(&sht->legacy_hosts))
+		return;
+
+	printk(KERN_WARNING "%s did not call scsi_unregister\n", sht->name);
+	dump_stack();
+
+	list_for_each_entry_safe(shost, s, &sht->legacy_hosts, sht_legacy_list)
+		scsi_unregister(shost);
 }
 
 module_init(init_this_scsi_driver);
 module_exit(exit_this_scsi_driver);
-
-/*
- * Overrides for Emacs so that we almost follow Linus's tabbing style.
- * Emacs will notice this stuff at the end of the file and automatically
- * adjust the settings for this buffer only.  This must remain at the end
- * of the file.
- * ---------------------------------------------------------------------------
- * Local variables:
- * c-indent-level: 4
- * c-brace-imaginary-offset: 0
- * c-brace-offset: -4
- * c-argdecl-indent: 4
- * c-label-offset: -4
- * c-continued-statement-offset: 4
- * c-continued-brace-offset: 0
- * indent-tabs-mode: nil
- * tab-width: 8
- * End:
- */
diff -Nru a/drivers/scsi/scsi_priv.h b/drivers/scsi/scsi_priv.h
--- a/drivers/scsi/scsi_priv.h	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/scsi_priv.h	Wed Jun 18 23:42:08 2003
@@ -52,13 +52,6 @@
 };
 
 
-/* hosts.c */
-extern void scsi_host_busy_inc(struct Scsi_Host *, Scsi_Device *);
-extern void scsi_host_busy_dec_and_test(struct Scsi_Host *, Scsi_Device *);
-extern struct Scsi_Host *scsi_host_lookup(unsigned short);
-extern void scsi_host_put(struct Scsi_Host *);
-extern void scsi_host_init(void);
-
 /* scsi.c */
 extern int scsi_dispatch_cmd(struct scsi_cmnd *cmd);
 extern int scsi_setup_command_freelist(struct Scsi_Host *shost);
@@ -80,11 +73,13 @@
 extern void scsi_times_out(struct scsi_cmnd *cmd);
 extern void scsi_error_handler(void *host);
 extern int scsi_decide_disposition(struct scsi_cmnd *cmd);
+extern void scsi_eh_wakeup(struct Scsi_Host *shost);
 extern int scsi_eh_scmd_add(struct scsi_cmnd *, int);
 
 /* scsi_lib.c */
 extern int scsi_maybe_unblock_host(struct scsi_device *sdev);
 extern void scsi_setup_cmd_retry(struct scsi_cmnd *cmd);
+extern void scsi_device_unbusy(struct scsi_device *sdev);
 extern int scsi_queue_insert(struct scsi_cmnd *cmd, int reason);
 extern void scsi_next_command(struct scsi_cmnd *cmd);
 extern void scsi_run_host_queues(struct Scsi_Host *shost);
@@ -107,12 +102,11 @@
 #endif /* CONFIG_PROC_FS */
 
 /* scsi_scan.c */
-extern void scsi_scan_host(struct Scsi_Host *shost);
-extern void scsi_forget_host(struct Scsi_Host *shost);
+extern void scsi_scan_host(struct Scsi_Host *);
+extern void scsi_forget_host(struct Scsi_Host *);
 extern void scsi_free_sdev(struct scsi_device *);
 extern void scsi_free_shost(struct Scsi_Host *);
-extern void scsi_host_get(struct Scsi_Host *);
-extern void scsi_rescan_device(struct device *dev);
+extern void scsi_rescan_device(struct device *);
 
 /* scsi_sysfs.c */
 extern int scsi_device_register(struct scsi_device *);
diff -Nru a/drivers/scsi/scsi_proc.c b/drivers/scsi/scsi_proc.c
--- a/drivers/scsi/scsi_proc.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/scsi_proc.c	Wed Jun 18 23:42:06 2003
@@ -42,48 +42,15 @@
 EXPORT_SYMBOL(proc_scsi);
 
 
-/* Used if the driver currently has no own support for /proc/scsi */
-static int generic_proc_info(char *buffer, char **start, off_t offset,
-			     int count, const char *(*info)(struct Scsi_Host *),
-			     struct Scsi_Host *shost)
-{
-	int len, pos, begin = 0;
-	static const char noprocfs[] =
-		"The driver does not yet support the proc-fs\n";
-
-	if (info && shost)
-		len = sprintf(buffer, "%s\n", info(shost));
-	else
-		len = sprintf(buffer, "%s\n", noprocfs);
-
-	pos = len;
-	if (pos < offset) {
-		len = 0;
-		begin = pos;
-	}
-
-	*start = buffer + (offset - begin);
-	len -= (offset - begin);
-	if (len > count)
-		len = count;
-
-	return len;
-}
-
 static int proc_scsi_read(char *buffer, char **start, off_t offset,
 			  int length, int *eof, void *data)
 {
 	struct Scsi_Host *shost = data;
 	int n;
 
-	if (shost->hostt->proc_info == NULL)
-		n = generic_proc_info(buffer, start, offset, length,
-				      shost->hostt->info, shost);
-	else
-		n = shost->hostt->proc_info(shost, buffer, start, offset,
-					   length, 0);
-
+	n = shost->hostt->proc_info(shost, buffer, start, offset, length, 0);
 	*eof = (n < length);
+
 	return n;
 }
 
@@ -95,8 +62,6 @@
 	char *page;
 	char *start;
     
-	if (!shost->hostt->proc_info)
-		return -ENOSYS;
 	if (count > PROC_BLOCK_SIZE)
 		return -EOVERFLOW;
 
@@ -114,10 +79,13 @@
 
 void scsi_proc_host_add(struct Scsi_Host *shost)
 {
-	Scsi_Host_Template *sht = shost->hostt;
+	struct scsi_host_template *sht = shost->hostt;
 	struct proc_dir_entry *p;
 	char name[10];
 
+	if (!sht->proc_info)
+		return;
+
 	if (!sht->proc_dir) {
 		sht->proc_dir = proc_mkdir(sht->proc_name, proc_scsi);
         	if (!sht->proc_dir) {
@@ -130,27 +98,29 @@
 
 	sprintf(name,"%d", shost->host_no);
 	p = create_proc_read_entry(name, S_IFREG | S_IRUGO | S_IWUSR,
-			shost->hostt->proc_dir, proc_scsi_read, shost);
+			sht->proc_dir, proc_scsi_read, shost);
 	if (!p) {
 		printk(KERN_ERR "%s: Failed to register host %d in"
 		       "%s\n", __FUNCTION__, shost->host_no,
-		       shost->hostt->proc_name);
+		       sht->proc_name);
 		return;
 	} 
 
 	p->write_proc = proc_scsi_write_proc;
 	p->owner = shost->hostt->module;
-
 }
 
 void scsi_proc_host_rm(struct Scsi_Host *shost)
 {
+	struct scsi_host_template *sht = shost->hostt;
 	char name[10];
 
-	sprintf(name,"%d", shost->host_no);
-	remove_proc_entry(name, shost->hostt->proc_dir);
-	if (!shost->hostt->present)
-		remove_proc_entry(shost->hostt->proc_name, proc_scsi);
+	if (sht->proc_info) {
+		sprintf(name,"%d", shost->host_no);
+		remove_proc_entry(name, sht->proc_dir);
+		if (!sht->present)
+			remove_proc_entry(sht->proc_name, proc_scsi);
+	}
 }
 
 static int proc_print_scsidevice(struct device *dev, void *data)
@@ -244,8 +214,8 @@
 	return error;
 }
 
-static int proc_scsi_write(struct file *file, const char* buf,
-                           size_t length, loff_t *ppos)
+static ssize_t proc_scsi_write(struct file *file, const char __user *buf,
+			       size_t length, loff_t *ppos)
 {
 	int host, channel, id, lun;
 	char *buffer, *p;
diff -Nru a/drivers/scsi/scsi_scan.c b/drivers/scsi/scsi_scan.c
--- a/drivers/scsi/scsi_scan.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/scsi_scan.c	Wed Jun 18 23:42:08 2003
@@ -27,6 +27,7 @@
 
 #include <linux/config.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/init.h>
 #include <linux/blk.h>
 
@@ -72,29 +73,9 @@
 static unsigned int max_scsi_luns = 1;
 #endif
 
-#ifdef MODULE
-MODULE_PARM(max_scsi_luns, "i");
-MODULE_PARM_DESC(max_scsi_luns,
+module_param_named(max_luns, max_scsi_luns, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(max_luns,
 		 "last scsi LUN (should be between 1 and 2^32-1)");
-#else
-
-static int __init scsi_luns_setup(char *str)
-{
-	unsigned int tmp;
-
-	if (get_option(&str, &tmp) == 1) {
-		max_scsi_luns = tmp;
-		return 1;
-	} else {
-		printk(KERN_WARNING "scsi_luns_setup: usage max_scsi_luns=n "
-		       "(n should be between 1 and 2^32-1)\n");
-		return 0;
-	}
-}
-
-__setup("max_scsi_luns=", scsi_luns_setup);
-
-#endif
 
 #ifdef CONFIG_SCSI_REPORT_LUNS
 /*
@@ -106,29 +87,10 @@
  */
 static unsigned int max_scsi_report_luns = 128;
 
-#ifdef MODULE
-MODULE_PARM(max_scsi_report_luns, "i");
-MODULE_PARM_DESC(max_scsi_report_luns,
+module_param_named(max_report_luns, max_scsi_report_luns, int, S_IRUGO|S_IWUSR);
+MODULE_PARM_DESC(max_report_luns,
 		 "REPORT LUNS maximum number of LUNS received (should be"
 		 " between 1 and 16384)");
-#else
-static int __init scsi_report_luns_setup(char *str)
-{
-	unsigned int tmp;
-
-	if (get_option(&str, &tmp) == 1) {
-		max_scsi_report_luns = tmp;
-		return 1;
-	} else {
-		printk(KERN_WARNING "scsi_report_luns_setup: usage"
-		       " max_scsi_report_luns=n (n should be between 1"
-		       " and 16384)\n");
-		return 0;
-	}
-}
-
-__setup("max_scsi_report_luns=", scsi_report_luns_setup);
-#endif
 #endif
 
 /**
@@ -141,7 +103,8 @@
  *     @sreq to unlock a device, storing the (unused) results into result.
  *     Called for BLIST_KEY devices.
  **/
-static void scsi_unlock_floptical(Scsi_Request *sreq, unsigned char *result)
+static void scsi_unlock_floptical(struct scsi_request *sreq,
+				  unsigned char *result)
 {
 	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
 
@@ -154,8 +117,7 @@
 	scsi_cmd[5] = 0;
 	sreq->sr_cmd_len = 0;
 	sreq->sr_data_direction = SCSI_DATA_READ;
-	scsi_wait_req(sreq, (void *) scsi_cmd, (void *) result, 0x2a /* size */,
-		      SCSI_TIMEOUT, 3);
+	scsi_wait_req(sreq, scsi_cmd, result, 0x2a /* size */, SCSI_TIMEOUT, 3);
 }
 
 /**
@@ -354,10 +316,10 @@
  *     are copied to the Scsi_Device at @sreq->sr_device (sdev);
  *     any flags value is stored in *@bflags.
  **/
-static void scsi_probe_lun(Scsi_Request *sreq, char *inq_result,
+static void scsi_probe_lun(struct scsi_request *sreq, char *inq_result,
 			   int *bflags)
 {
-	Scsi_Device *sdev = sreq->sr_device;	/* a bit ugly */
+	struct scsi_device *sdev = sreq->sr_device;	/* a bit ugly */
 	unsigned char scsi_cmd[MAX_COMMAND_SIZE];
 	int possible_inq_resp_len;
 
@@ -522,7 +484,7 @@
  *     SCSI_SCAN_NO_RESPONSE: could not allocate or setup a Scsi_Device
  *     SCSI_SCAN_LUN_PRESENT: a new Scsi_Device was allocated and initialized
  **/
-static int scsi_add_lun(Scsi_Device *sdev, char *inq_result, int *bflags)
+static int scsi_add_lun(struct scsi_device *sdev, char *inq_result, int *bflags)
 {
 	struct scsi_device *sdev_sibling;
 	struct scsi_target *starget;
@@ -578,8 +540,6 @@
 	default:
 		printk(KERN_INFO "scsi: unknown device type %d\n", sdev->type);
 	}
-
-	sdev->random = (sdev->type == TYPE_TAPE) ? 0 : 1;
 
 	scsi_set_name(sdev, inq_result);
 
diff -Nru a/drivers/scsi/scsi_syms.c b/drivers/scsi/scsi_syms.c
--- a/drivers/scsi/scsi_syms.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/scsi_syms.c	Wed Jun 18 23:42:07 2003
@@ -31,10 +31,12 @@
  */
 EXPORT_SYMBOL(scsi_register_driver);
 EXPORT_SYMBOL(scsi_register_interface);
-EXPORT_SYMBOL(scsi_register_host);
-EXPORT_SYMBOL(scsi_unregister_host);
+EXPORT_SYMBOL(scsi_host_alloc);
 EXPORT_SYMBOL(scsi_add_host);
 EXPORT_SYMBOL(scsi_remove_host);
+EXPORT_SYMBOL(scsi_host_get);
+EXPORT_SYMBOL(scsi_host_put);
+EXPORT_SYMBOL(scsi_host_lookup);
 EXPORT_SYMBOL(scsi_register);
 EXPORT_SYMBOL(scsi_unregister);
 EXPORT_SYMBOL(scsicam_bios_param);
diff -Nru a/drivers/scsi/scsi_sysfs.c b/drivers/scsi/scsi_sysfs.c
--- a/drivers/scsi/scsi_sysfs.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/scsi_sysfs.c	Wed Jun 18 23:42:06 2003
@@ -487,7 +487,7 @@
 }
 EXPORT_SYMBOL(scsi_sysfs_modify_sdev_attribute);
 
-void scsi_sysfs_release_attributes(struct SHT *hostt)
+void scsi_sysfs_release_attributes(struct scsi_host_template *hostt)
 {
 	if(hostt->sdev_attrs != scsi_sysfs_sdev_attrs)
 		kfree(hostt->sdev_attrs);
diff -Nru a/drivers/scsi/scsi_typedefs.h b/drivers/scsi/scsi_typedefs.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/scsi/scsi_typedefs.h	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,6 @@
+
+typedef struct scsi_host_template Scsi_Host_Template;
+typedef struct scsi_device Scsi_Device;
+typedef struct scsi_cmnd Scsi_Cmnd;
+typedef struct scsi_request Scsi_Request;
+typedef struct scsi_pointer Scsi_Pointer;
diff -Nru a/drivers/scsi/sd.c b/drivers/scsi/sd.c
--- a/drivers/scsi/sd.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/sd.c	Wed Jun 18 23:42:08 2003
@@ -76,6 +76,7 @@
 	struct scsi_driver *driver;	/* always &sd_template */
 	struct scsi_device *device;
 	struct gendisk	*disk;
+	unsigned int	openers;	/* protected by BKL for now, yuck */
 	sector_t	capacity;	/* size in 512-byte sectors */
 	u32		index;
 	u8		media_present;
@@ -87,7 +88,7 @@
 static unsigned long sd_index_bits[SD_DISKS / BITS_PER_LONG];
 static spinlock_t sd_index_lock = SPIN_LOCK_UNLOCKED;
 
-static void sd_init_onedisk(struct scsi_disk * sdkp, struct gendisk *disk);
+static int sd_revalidate_disk(struct gendisk *disk);
 static void sd_rw_intr(struct scsi_cmnd * SCpnt);
 
 static int sd_probe(struct device *);
@@ -95,7 +96,6 @@
 static void sd_shutdown(struct device *dev);
 static void sd_rescan(struct device *);
 static int sd_init_command(struct scsi_cmnd *);
-static int sd_synchronize_cache(struct scsi_disk *, int);
 static void sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
 		 struct scsi_request *SRpnt, unsigned char *buffer);
 
@@ -396,9 +396,10 @@
 	if (!sdev->online)
 		goto error_out;
 
-	if (sdev->removable && sdev->access_count == 1)
+	if (!sdkp->openers++ && sdev->removable) {
 		if (scsi_block_when_processing_errors(sdev))
 			scsi_set_medium_removal(sdev, SCSI_REMOVAL_PREVENT);
+	}
 
 	return 0;
 
@@ -421,13 +422,15 @@
 static int sd_release(struct inode *inode, struct file *filp)
 {
 	struct gendisk *disk = inode->i_bdev->bd_disk;
-	struct scsi_device *sdev = scsi_disk(disk)->device;
+	struct scsi_disk *sdkp = scsi_disk(disk);
+	struct scsi_device *sdev = sdkp->device;
 
 	SCSI_LOG_HLQUEUE(3, printk("sd_release: disk=%s\n", disk->disk_name));
 
-	if (sdev->removable && sdev->access_count == 1)
+	if (!--sdkp->openers && sdev->removable) {
 		if (scsi_block_when_processing_errors(sdev))
 			scsi_set_medium_removal(sdev, SCSI_REMOVAL_ALLOW);
+	}
 
 	/*
 	 * XXX and what if there are packets in flight and this close()
@@ -566,7 +569,7 @@
 	 * UNIT ATTENTION, or with same cartridge - GOOD STATUS.
 	 *
 	 * Drives that auto spin down. eg iomega jaz 1G, will be started
-	 * by sd_spinup_disk() from sd_init_onedisk(), which happens whenever
+	 * by sd_spinup_disk() from sd_revalidate_disk(), which happens whenever
 	 * sd_revalidate() is called.
 	 */
 	retval = -ENODEV;
@@ -632,15 +635,6 @@
 	kfree(buffer);
 }
 
-static int sd_revalidate_disk(struct gendisk *disk)
-{
-	struct scsi_disk *sdkp = scsi_disk(disk);
-
-	sd_init_onedisk(sdkp, disk);
-	set_capacity(disk, sdkp->capacity);
-	return 0;
-}
-
 static struct block_device_operations sd_fops = {
 	.owner			= THIS_MODULE,
 	.open			= sd_open,
@@ -772,7 +766,7 @@
 }
 
 /*
- * spinup disk - called only in sd_init_onedisk()
+ * spinup disk - called only in sd_revalidate_disk()
  */
 static void
 sd_spinup_disk(struct scsi_disk *sdkp, char *diskname,
@@ -856,7 +850,7 @@
 				SRpnt->sr_sense_buffer[0] = 0;
 				SRpnt->sr_sense_buffer[2] = 0;
 
-				SRpnt->sr_data_direction = SCSI_DATA_READ;
+				SRpnt->sr_data_direction = SCSI_DATA_NONE;
 				scsi_wait_req(SRpnt, (void *)cmd, 
 					      (void *) buffer, 0/*512*/, 
 					      SD_TIMEOUT, SD_MAX_RETRIES);
@@ -892,7 +886,7 @@
 }
 
 /*
- * read disk capacity - called only in sd_init_onedisk()
+ * read disk capacity
  */
 static void
 sd_read_capacity(struct scsi_disk *sdkp, char *diskname,
@@ -1105,7 +1099,7 @@
 }
 
 /*
- * read write protect setting, if possible - called only in sd_init_onedisk()
+ * read write protect setting, if possible - called only in sd_revalidate_disk()
  * called with buffer of length 512
  */
 static void
@@ -1147,7 +1141,7 @@
 }
 
 /*
- * sd_read_cache_type - called only from sd_init_onedisk()
+ * sd_read_cache_type - called only from sd_revalidate_disk()
  * called with buffer of length 512
  */
 static void
@@ -1206,71 +1200,69 @@
 }
 
 /**
- *	sd_init_onedisk - called the first time a new disk is seen,
+ *	sd_revalidate_disk - called the first time a new disk is seen,
  *	performs disk spin up, read_capacity, etc.
- *	@sdkp: pointer to associated struct scsi_disk object
- *	@dsk_nr: disk number within this driver (e.g. 0->/dev/sda,
- *	1->/dev/sdb, etc)
- *
- *	Note: this function is local to this driver.
+ *	@disk: struct gendisk we care about
  **/
-static void
-sd_init_onedisk(struct scsi_disk * sdkp, struct gendisk *disk)
+static int sd_revalidate_disk(struct gendisk *disk)
 {
+	struct scsi_disk *sdkp = scsi_disk(disk);
+	struct scsi_device *sdp = sdkp->device;
+	struct scsi_request *sreq;
 	unsigned char *buffer;
-	struct scsi_device *sdp;
-	struct scsi_request *SRpnt;
 
-	SCSI_LOG_HLQUEUE(3, printk("sd_init_onedisk: disk=%s\n", disk->disk_name));
+	SCSI_LOG_HLQUEUE(3, printk("sd_revalidate_disk: disk=%s\n", disk->disk_name));
 
 	/*
 	 * If the device is offline, don't try and read capacity or any
 	 * of the other niceties.
 	 */
-	sdp = sdkp->device;
-	if (sdp->online == FALSE)
-		return;
+	if (!sdp->online)
+		goto out;
 
-	SRpnt = scsi_allocate_request(sdp);
-	if (!SRpnt) {
-		printk(KERN_WARNING "(sd_init_onedisk:) Request allocation "
+	sreq = scsi_allocate_request(sdp);
+	if (!sreq) {
+		printk(KERN_WARNING "(sd_revalidate_disk:) Request allocation "
 		       "failure.\n");
-		return;
+		goto out;
 	}
 
-	buffer = kmalloc(512, GFP_KERNEL | GFP_DMA);
+	buffer = kmalloc(512, GFP_KERNEL | __GFP_DMA);
 	if (!buffer) {
-		printk(KERN_WARNING "(sd_init_onedisk:) Memory allocation "
+		printk(KERN_WARNING "(sd_revalidate_disk:) Memory allocation "
 		       "failure.\n");
-		goto leave;
+		goto out_release_request;
 	}
 
 	/* defaults, until the device tells us otherwise */
+	sdp->sector_size = 512;
 	sdkp->capacity = 0;
-	sdkp->device->sector_size = 512;
 	sdkp->media_present = 1;
 	sdkp->write_prot = 0;
 	sdkp->WCE = 0;
 	sdkp->RCD = 0;
 
-	sd_spinup_disk(sdkp, disk->disk_name, SRpnt, buffer);
+	sd_spinup_disk(sdkp, disk->disk_name, sreq, buffer);
 
-	if (sdkp->media_present)
-		sd_read_capacity(sdkp, disk->disk_name, SRpnt, buffer);
-	
-	if (sdp->removable && sdkp->media_present)
-		sd_read_write_protect_flag(sdkp, disk->disk_name, SRpnt, buffer);
-	/* without media there is no reason to ask;
-	   moreover, some devices react badly if we do */
-	if (sdkp->media_present)
-		sd_read_cache_type(sdkp, disk->disk_name, SRpnt, buffer);
+	/*
+	 * Without media there is no reason to ask; moreover, some devices
+	 * react badly if we do.
+	 */
+	if (sdkp->media_present) {
+		sd_read_capacity(sdkp, disk->disk_name, sreq, buffer);
+		if (sdp->removable)
+			sd_read_write_protect_flag(sdkp, disk->disk_name,
+					sreq, buffer);
+		sd_read_cache_type(sdkp, disk->disk_name, sreq, buffer);
+	}
 		
-	SRpnt->sr_device->remap = 1;
-
- leave:
-	scsi_release_request(SRpnt);
-
+	set_capacity(disk, sdkp->capacity);
 	kfree(buffer);
+
+ out_release_request: 
+	scsi_release_request(sreq);
+ out:
+	return 0;
 }
 
 /**
@@ -1329,6 +1321,7 @@
 	sdkp->driver = &sd_template;
 	sdkp->disk = gd;
 	sdkp->index = index;
+	sdkp->openers = 0;
 
 	gd->major = sd_major(index >> 4);
 	gd->first_minor = (index & 15) << 4;
@@ -1344,16 +1337,16 @@
 
 	strcpy(gd->devfs_name, sdp->devfs_name);
 
-	sd_init_onedisk(sdkp, gd);
+	gd->private_data = &sdkp->driver;
+
+	sd_revalidate_disk(gd);
 
 	gd->driverfs_dev = &sdp->sdev_driverfs_dev;
 	gd->flags = GENHD_FL_DRIVERFS;
 	if (sdp->removable)
 		gd->flags |= GENHD_FL_REMOVABLE;
-	gd->private_data = &sdkp->driver;
 	gd->queue = sdkp->device->request_queue;
 
-	set_capacity(gd, sdkp->capacity);
 	dev_set_drvdata(dev, sdkp);
 	add_disk(gd);
 
@@ -1400,16 +1393,57 @@
 	return 0;
 }
 
+/*
+ * Send a SYNCHRONIZE CACHE instruction down to the device through
+ * the normal SCSI command structure.  Wait for the command to
+ * complete.
+ */
 static void sd_shutdown(struct device *dev)
 {
+	struct scsi_device *sdp = to_scsi_device(dev);
 	struct scsi_disk *sdkp = dev_get_drvdata(dev);
+	struct scsi_request *sreq;
+	int retries, res;
 
-	if (sdkp->WCE) {
-		printk(KERN_NOTICE "Synchronizing SCSI cache: ");
-		sd_synchronize_cache(sdkp, 1);
-		printk("\n");
+	if (!sdp->online || !sdkp->WCE)
+		return;
+
+	printk(KERN_NOTICE "Synchronizing SCSI cache for disk %s: ",
+			sdkp->disk->disk_name);
+
+	sreq = scsi_allocate_request(sdp);
+	if (!sreq) {
+		printk("FAILED\n  No memory for request\n");
+		return;
 	}
-}
+
+	sreq->sr_data_direction = SCSI_DATA_NONE;
+	for (retries = 3; retries > 0; --retries) {
+		unsigned char cmd[10] = { 0 };
+
+		cmd[0] = SYNCHRONIZE_CACHE;
+		/*
+		 * Leave the rest of the command zero to indicate
+		 * flush everything.
+		 */
+		scsi_wait_req(sreq, cmd, NULL, 0, SD_TIMEOUT, SD_MAX_RETRIES);
+		if (sreq->sr_result == 0)
+			break;
+	}
+
+	res = sreq->sr_result;
+	if (res) {
+		printk(KERN_WARNING "FAILED\n  status = %x, message = %02x, "
+				    "host = %d, driver = %02x\n  ",
+				    status_byte(res), msg_byte(res),
+				    host_byte(res), driver_byte(res));
+			if (driver_byte(res) & DRIVER_SENSE)
+				print_req_sense("sd", sreq);
+	}
+	
+	scsi_release_request(sreq);
+	printk("\n");
+}	
 
 /**
  *	init_sd - entry point for this driver (both when built in or when
@@ -1447,60 +1481,6 @@
 	scsi_unregister_driver(&sd_template.gendrv);
 	for (i = 0; i < SD_MAJORS; i++)
 		unregister_blkdev(sd_major(i), "sd");
-}
-
-/* send a SYNCHRONIZE CACHE instruction down to the device through the
- * normal SCSI command structure.  Wait for the command to complete (must
- * have user context) */
-static int sd_synchronize_cache(struct scsi_disk *sdkp, int verbose)
-{
-	struct scsi_request *SRpnt;
-	struct scsi_device *SDpnt = sdkp->device;
-	int retries, the_result;
-
-	if (!SDpnt->online)
-		return 0;
-
-	if (verbose)
-		printk("%s ", sdkp->disk->disk_name);
-
-	SRpnt = scsi_allocate_request(SDpnt);
-	if(!SRpnt) {
-		if(verbose)
-			printk("FAILED\n  No memory for request\n");
-		return 0;
-	}
-
-	SRpnt->sr_data_direction = SCSI_DATA_NONE;
-
-	for(retries = 3; retries > 0; --retries) {
-		unsigned char cmd[10] = { 0 };
-
-		cmd[0] = SYNCHRONIZE_CACHE;
-		/* leave the rest of the command zero to indicate 
-		 * flush everything */
-		scsi_wait_req(SRpnt, (void *)cmd, NULL, 0,
-			      SD_TIMEOUT, SD_MAX_RETRIES);
-
-		if(SRpnt->sr_result == 0)
-			break;
-	}
-
-	the_result = SRpnt->sr_result;
-	if(verbose) {
-		if(the_result != 0) {
-			printk("FAILED\n  status = %x, message = %02x, host = %d, driver = %02x\n  ",
-			       status_byte(the_result),
-			       msg_byte(the_result),
-			       host_byte(the_result),
-			       driver_byte(the_result));
-			if (driver_byte(the_result) & DRIVER_SENSE)
-				print_req_sense("sd", SRpnt);
-
-		}
-	}
-	scsi_release_request(SRpnt);
-	return (the_result == 0);
 }
 
 MODULE_LICENSE("GPL");
diff -Nru a/drivers/scsi/seagate.c b/drivers/scsi/seagate.c
--- a/drivers/scsi/seagate.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/seagate.c	Wed Jun 18 23:42:07 2003
@@ -729,13 +729,6 @@
 	return 0;
 }
 
-static int seagate_st0x_command(Scsi_Cmnd * SCpnt)
-{
-	return internal_command (SCpnt->device->id, SCpnt->device->lun, SCpnt->cmnd,
-				 SCpnt->request_buffer, SCpnt->request_bufflen,
-				 (int) NO_RECONNECT);
-}
-
 static int internal_command (unsigned char target, unsigned char lun,
 		  const void *cmnd, void *buff, int bufflen, int reselect)
 {
@@ -1704,7 +1697,6 @@
 	.detect         	= seagate_st0x_detect,
 	.release        	= seagate_st0x_release,
 	.info           	= seagate_st0x_info,
-	.command        	= seagate_st0x_command,
 	.queuecommand   	= seagate_st0x_queue_command,
 	.eh_abort_handler	= seagate_st0x_abort,
 	.eh_bus_reset_handler	= seagate_st0x_bus_reset,
diff -Nru a/drivers/scsi/sim710.c b/drivers/scsi/sim710.c
--- a/drivers/scsi/sim710.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/sim710.c	Wed Jun 18 23:42:08 2003
@@ -121,6 +121,7 @@
 	hostdata->differential = differential;
 	hostdata->clock = clock;
 	hostdata->chip710 = 1;
+	NCR_700_set_io_mapped(hostdata);
 
 	/* and register the chip */
 	if((host = NCR_700_detect(&sim710_driver_template, hostdata)) == NULL) {
@@ -143,7 +144,7 @@
 	return 0;
 
  out_unregister:
-	scsi_unregister(host);
+	scsi_host_put(host);
  out_release:
 	release_region(host->base, 64);
  out_free:
@@ -294,12 +295,17 @@
 	unsigned char irq, differential = 0, scsi_id = 7;
 
 	if(strcmp(edev->id.sig, "HWP0C80") == 0) {
+		__u8 val;
 		eisa_irqs =  eisa_hwp_irqs;
 		irq_index = (inb(io_addr + 0xc85) & 0x7) - 1;
-#if 0
-		/* this doesn't seem to work at the moment */
-		scsi_id = ffs(inb(io_addr + 0x4));
-#endif
+
+		val = inb(io_addr + 0x4);
+		scsi_id = ffs(val) - 1;
+
+		if(scsi_id > 7 || (val & ~(1<<scsi_id)) != 0) {
+			printk(KERN_ERR "sim710.c, EISA card %s has incorrect scsi_id, setting to 7\n", dev->name);
+			scsi_id = 7;
+		}
 	} else {
 		eisa_irqs = eisa_cpq_irqs;
 		irq_index = inb(io_addr + 0xc88) & 0x07;
diff -Nru a/drivers/scsi/sr.c b/drivers/scsi/sr.c
--- a/drivers/scsi/sr.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/sr.c	Wed Jun 18 23:42:06 2003
@@ -524,7 +524,6 @@
 	sprintf(cd->cdi.name, "sr%d", minor);
 
 	sdev->sector_size = 2048;	/* A guess, just in case */
-	sdev->remap = 1;
 
 	/* FIXME: need to handle a get_capabilities failure properly ?? */
 	get_capabilities(cd);
diff -Nru a/drivers/scsi/st.c b/drivers/scsi/st.c
--- a/drivers/scsi/st.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/st.c	Wed Jun 18 23:42:08 2003
@@ -3674,22 +3674,6 @@
 
 #endif
 
-/* Driverfs file support */
-static ssize_t st_device_kdev_read(struct device *dev, char *page)
-{
-	kdev_t kdev; 
-	kdev.value=(unsigned long)dev->driver_data;
-	return sprintf(page, "%x\n",kdev.value);
-}
-static DEVICE_ATTR(kdev,S_IRUGO,st_device_kdev_read,NULL);
-
-static ssize_t st_device_type_read(struct device *ev, char * page)
-{
-	return sprintf (page, "CHR\n");
-}
-static DEVICE_ATTR(type,S_IRUGO,st_device_type_read,NULL);
-
-
 static struct file_operations st_fops =
 {
 	.owner =	THIS_MODULE,
diff -Nru a/drivers/scsi/sun3x_esp.c b/drivers/scsi/sun3x_esp.c
--- a/drivers/scsi/sun3x_esp.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/scsi/sun3x_esp.c	Wed Jun 18 23:42:08 2003
@@ -413,7 +413,6 @@
 	.slave_alloc		= esp_slave_alloc,
 	.slave_destroy		= esp_slave_destroy,
 	.info			= esp_info,
-	.command		= esp_command,
 	.queuecommand		= esp_queue,
 	.eh_abort_handler	= esp_abort,
 	.eh_bus_reset_handler	= esp_reset,
diff -Nru a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
--- a/drivers/scsi/sym53c416.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/sym53c416.c	Wed Jun 18 23:42:06 2003
@@ -787,20 +787,6 @@
 	return 0;
 }
 
-static void internal_done(Scsi_Cmnd *SCpnt)
-{
-	SCpnt->SCp.Status++;
-}
-
-static int sym53c416_command(Scsi_Cmnd *SCpnt)
-{
-	sym53c416_queuecommand(SCpnt, internal_done);
-	SCpnt->SCp.Status = 0;
-	while(!SCpnt->SCp.Status)
-		barrier();
-	return SCpnt->result;
-}
-
 static int sym53c416_abort(Scsi_Cmnd *SCpnt)
 {
 	return FAILED;
@@ -880,7 +866,6 @@
 	.name =			"Symbios Logic 53c416",
 	.detect =		sym53c416_detect,
 	.info =			sym53c416_info,	
-	.command =		sym53c416_command,
 	.queuecommand =		sym53c416_queuecommand,
 	.eh_abort_handler =	sym53c416_abort,
 	.eh_host_reset_handler =sym53c416_host_reset,
diff -Nru a/drivers/scsi/t128.c b/drivers/scsi/t128.c
--- a/drivers/scsi/t128.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/scsi/t128.c	Wed Jun 18 23:42:09 2003
@@ -280,6 +280,16 @@
     return count;
 }
 
+static int t128_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 /*
  * Function : int t128_biosparam(Disk * disk, struct block_device *dev, int *ip)
  *
@@ -403,6 +413,7 @@
 static Scsi_Host_Template driver_template = {
 	.name           = "Trantor T128/T128F/T228",
 	.detect         = t128_detect,
+	.release        = t128_release,
 	.queuecommand   = t128_queue_command,
 	.eh_abort_handler = t128_abort,
 	.eh_bus_reset_handler    = t128_bus_reset,
diff -Nru a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
--- a/drivers/scsi/u14-34f.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/scsi/u14-34f.c	Wed Jun 18 23:42:06 2003
@@ -1,6 +1,36 @@
 /*
  *      u14-34f.c - Low-level driver for UltraStor 14F/34F SCSI host adapters.
  *
+ *      03 Jun 2003 Rev. 8.10 for linux-2.5.70
+ *        + Update for new IRQ API.
+ *        + Use "goto" when appropriate.
+ *        + Drop u14-34f.h.
+ *        + Update for new module_param API.
+ *        + Module parameters  can now be specified only in the
+ *          same format as the kernel boot options.
+ *
+ *             boot option    old module param 
+ *             -----------    ------------------
+ *             addr,...       io_port=addr,...
+ *             lc:[y|n]       linked_comm=[1|0]
+ *             mq:xx          max_queue_depth=xx
+ *             tm:[0|1|2]     tag_mode=[0|1|2]
+ *             et:[y|n]       ext_tran=[1|0]
+ *             of:[y|n]       have_old_firmware=[1|0]
+ *
+ *          A valid example using the new parameter format is:
+ *          modprobe u14-34f "u14-34f=0x340,0x330,lc:y,tm:0,mq:4"
+ *
+ *          which is equivalent to the old format:
+ *          modprobe u14-34f io_port=0x340,0x330 linked_comm=1 tag_mode=0 \
+ *                        max_queue_depth=4
+ *
+ *          With actual module code, u14-34f and u14_34f are equivalent
+ *          as module parameter names.
+ *
+ *      12 Feb 2003 Rev. 8.04 for linux 2.5.60
+ *        + Release irq before calling scsi_register.
+ *
  *      12 Nov 2002 Rev. 8.02 for linux 2.5.47
  *        + Release driver_lock before calling scsi_register.
  *
@@ -221,7 +251,7 @@
  *
  *          Multiple U14F and/or U34F host adapters are supported.
  *
- *  Copyright (C) 1994-2002 Dario Ballabio (ballabio_dario@emc.com)
+ *  Copyright (C) 1994-2003 Dario Ballabio (ballabio_dario@emc.com)
  *
  *  Alternate email: dario.ballabio@inwind.it, dario.ballabio@tiscalinet.it
  *
@@ -375,31 +405,8 @@
  *  the driver sets host->wish_block = TRUE for all ISA boards.
  */
 
-#include <linux/version.h>
-
-#ifndef LinuxVersionCode
-#define LinuxVersionCode(v, p, s) (((v)<<16)+((p)<<8)+(s))
-#endif
-
-#define MAX_INT_PARAM 10
-
-#if defined(MODULE)
-#include <linux/module.h>
-
-MODULE_PARM(boot_options, "s");
-MODULE_PARM(io_port, "1-" __MODULE_STRING(MAX_INT_PARAM) "i");
-MODULE_PARM(linked_comm, "i");
-MODULE_PARM(have_old_firmware, "i");
-MODULE_PARM(link_statistics, "i");
-MODULE_PARM(max_queue_depth, "i");
-MODULE_PARM(tag_mode, "i");
-MODULE_PARM(ext_tran, "i");
-MODULE_AUTHOR("Dario Ballabio");
-
-#endif
-
+#include <linux/config.h>
 #include <linux/string.h>
-#include <linux/interrupt.h>
 #include <linux/kernel.h>
 #include <linux/ioport.h>
 #include <linux/delay.h>
@@ -408,20 +415,42 @@
 #include <asm/byteorder.h>
 #include <linux/proc_fs.h>
 #include <linux/blk.h>
+#include <linux/interrupt.h>
 #include <linux/stat.h>
-#include <linux/config.h>
 #include <linux/pci.h>
 #include <linux/init.h>
 #include <linux/ctype.h>
 #include <linux/spinlock.h>
 #include <scsi/scsicam.h>
-
+#include "scsi.h"
+#include "hosts.h"
 #include <asm/dma.h>
 #include <asm/irq.h>
 
-#include "scsi.h"
-#include "hosts.h"
-#include "u14-34f.h"
+static int u14_34f_detect(Scsi_Host_Template *);
+static int u14_34f_release(struct Scsi_Host *);
+static int u14_34f_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
+static int u14_34f_eh_abort(Scsi_Cmnd *);
+static int u14_34f_eh_host_reset(Scsi_Cmnd *);
+static int u14_34f_bios_param(struct scsi_device *, struct block_device *,
+                              sector_t, int *);
+static int u14_34f_slave_configure(Scsi_Device *);
+
+static Scsi_Host_Template driver_template = {
+                .name                    = "UltraStor 14F/34F rev. 8.10.00 ",
+                .detect                  = u14_34f_detect,
+                .release                 = u14_34f_release,
+                .queuecommand            = u14_34f_queuecommand,
+                .eh_abort_handler        = u14_34f_eh_abort,
+                .eh_device_reset_handler = NULL,
+                .eh_bus_reset_handler    = NULL,
+                .eh_host_reset_handler   = u14_34f_eh_host_reset,
+                .bios_param              = u14_34f_bios_param,
+                .slave_configure         = u14_34f_slave_configure,
+                .this_id                 = 7,
+                .unchecked_isa_dma       = 1,
+                .use_clustering          = ENABLE_CLUSTERING
+                };
 
 #if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
 #error "Adjust your <asm/byteorder.h> defines"
@@ -610,7 +639,6 @@
 static int setup_done = FALSE;
 static int link_statistics;
 static int ext_tran = FALSE;
-static char *boot_options;
 
 #if defined(HAVE_OLD_UX4F_FIRMWARE)
 static int have_old_firmware = TRUE;
@@ -636,6 +664,24 @@
 static int max_queue_depth = MAX_CMD_PER_LUN;
 #endif
 
+#define MAX_INT_PARAM 10
+#define MAX_BOOT_OPTIONS_SIZE 256
+static char boot_options[MAX_BOOT_OPTIONS_SIZE];
+
+#if defined(MODULE)
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+
+module_param_string(u14_34f, boot_options, MAX_BOOT_OPTIONS_SIZE, 0);
+MODULE_PARM_DESC(u14_34f, " equivalent to the \"u14-34f=...\" kernel boot " \
+"option." \
+"      Example: modprobe u14-34f \"u14_34f=0x340,0x330,lc:y,tm:0,mq:4\"");
+MODULE_AUTHOR("Dario Ballabio");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("UltraStor 14F/34F SCSI Driver");
+
+#endif
+
 static int u14_34f_slave_configure(Scsi_Device *dev) {
    int j, tqd, utqd;
    char *tag_suffix, *link_suffix;
@@ -802,24 +848,20 @@
 
    sprintf(name, "%s%d", driver_name, j);
 
-   if(!request_region(port_base, REGION_SIZE, driver_name)) {
+   if (!request_region(port_base, REGION_SIZE, driver_name)) {
 #if defined(DEBUG_DETECT)
       printk("%s: address 0x%03lx in use, skipping probe.\n", name, port_base);
 #endif
-      return FALSE;
+      goto fail;
       }
 
-   if (inb(port_base + REG_PRODUCT_ID1) != PRODUCT_ID1) {
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
-      }
+   spin_lock_irq(&driver_lock);
+
+   if (inb(port_base + REG_PRODUCT_ID1) != PRODUCT_ID1) goto freelock;
 
    in_byte = inb(port_base + REG_PRODUCT_ID2);
 
-   if ((in_byte & 0xf0) != PRODUCT_ID2) {
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
-      }
+   if ((in_byte & 0xf0) != PRODUCT_ID2) goto freelock;
 
    *(char *)&config_1 = inb(port_base + REG_CONFIG1);
    *(char *)&config_2 = inb(port_base + REG_CONFIG2);
@@ -833,16 +875,13 @@
              SA_INTERRUPT | ((subversion == ESA) ? SA_SHIRQ : 0),
              driver_name, (void *) &sha[j])) {
       printk("%s: unable to allocate IRQ %u, detaching.\n", name, irq);
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freelock;
       }
 
    if (subversion == ISA && request_dma(dma_channel, driver_name)) {
       printk("%s: unable to allocate DMA channel %u, detaching.\n",
              name, dma_channel);
-      free_irq(irq, &sha[j]);
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freeirq;
       }
 
    if (have_old_firmware) tpnt->use_clustering = DISABLE_CLUSTERING;
@@ -853,13 +892,7 @@
 
    if (sh[j] == NULL) {
       printk("%s: unable to register host, detaching.\n", name);
-
-      free_irq(irq, &sha[j]);
-
-      if (subversion == ISA) free_dma(dma_channel);
-
-      release_region(port_base, REGION_SIZE);
-      return FALSE;
+      goto freedma;
       }
 
    sh[j]->io_port = port_base;
@@ -938,6 +971,8 @@
    if (dma_channel == NO_DMA) sprintf(dma_name, "%s", "BMST");
    else                       sprintf(dma_name, "DMA %u", dma_channel);
 
+   spin_unlock_irq(&driver_lock);
+
    for (i = 0; i < sh[j]->can_queue; i++)
       HD(j)->cp[i].cp_dma_addr = pci_map_single(HD(j)->pdev,
             &HD(j)->cp[i], sizeof(struct mscp), PCI_DMA_BIDIRECTIONAL);
@@ -947,8 +982,7 @@
             sh[j]->sg_tablesize * sizeof(struct sg_list),
             (sh[j]->unchecked_isa_dma ? GFP_DMA : 0) | GFP_ATOMIC))) {
          printk("%s: kmalloc SGlist failed, mbox %d, detaching.\n", BN(j), i);
-         u14_34f_release(sh[j]);
-         return FALSE;
+         goto release;
          }
 
    if (max_queue_depth > MAX_TAGGED_CMD_PER_LUN)
@@ -960,7 +994,7 @@
       tag_mode = TAG_ORDERED;
 
    if (j == 0) {
-      printk("UltraStor 14F/34F: Copyright (C) 1994-2002 Dario Ballabio.\n");
+      printk("UltraStor 14F/34F: Copyright (C) 1994-2003 Dario Ballabio.\n");
       printk("%s config options -> of:%c, tm:%d, lc:%c, mq:%d, et:%c.\n",
              driver_name, YESNO(have_old_firmware), tag_mode,
              YESNO(linked_comm), max_queue_depth, YESNO(ext_tran));
@@ -979,6 +1013,20 @@
              BN(j), i, sh[j]->this_id);
 
    return TRUE;
+
+freedma:
+   if (subversion == ISA) free_dma(dma_channel);
+freeirq:
+   free_irq(irq, &sha[j]);
+freelock:
+   spin_unlock_irq(&driver_lock);
+   release_region(port_base, REGION_SIZE);
+fail:
+   return FALSE;
+
+release:
+   u14_34f_release(sh[j]);
+   return FALSE;
 }
 
 static void internal_setup(char *str, int *ints) {
@@ -1034,13 +1082,10 @@
 
 static int u14_34f_detect(Scsi_Host_Template *tpnt) {
    unsigned int j = 0, k;
-   unsigned long spin_flags;
-
-   spin_lock_irqsave(&driver_lock, spin_flags);
 
    tpnt->proc_name = "u14-34f";
 
-   if(boot_options) option_setup(boot_options);
+   if(strlen(boot_options)) option_setup(boot_options);
 
 #if defined(MODULE)
    /* io_port could have been modified when loading as a module */
@@ -1060,7 +1105,6 @@
       }
 
    num_boards = j;
-   spin_unlock_irqrestore(&driver_lock, spin_flags);
    return j;
 }
 
@@ -1680,7 +1724,7 @@
 
 }
 
-static void ihdlr(int irq, unsigned int j) {
+static irqreturn_t ihdlr(int irq, unsigned int j) {
    Scsi_Cmnd *SCpnt;
    unsigned int i, k, c, status, tstatus, reg, ret;
    struct mscp *spp, *cpp;
@@ -1689,7 +1733,7 @@
        panic("%s: ihdlr, irq %d, sh[j]->irq %d.\n", BN(j), irq, sh[j]->irq);
 
    /* Check if this board need to be serviced */
-   if (!((reg = inb(sh[j]->io_port + REG_SYS_INTR)) & IRQ_ASSERTED)) return;
+   if (!((reg = inb(sh[j]->io_port + REG_SYS_INTR)) & IRQ_ASSERTED)) goto none;
 
    HD(j)->iocount++;
 
@@ -1701,7 +1745,7 @@
       outb(CMD_CLR_INTR, sh[j]->io_port + REG_SYS_INTR);
       printk("%s: ihdlr, busy timeout error,  irq %d, reg 0x%x, count %d.\n",
              BN(j), irq, reg, HD(j)->iocount);
-      return;
+      goto none;
       }
 
    ret = inl(sh[j]->io_port + REG_ICM);
@@ -1721,23 +1765,23 @@
    spp = cpp;
 
 #if defined(DEBUG_GENERATE_ABORTS)
-   if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 500) < 3)) return;
+   if ((HD(j)->iocount > 500) && ((HD(j)->iocount % 500) < 3)) goto handled;
 #endif
 
    if (HD(j)->cp_stat[i] == IGNORE) {
       HD(j)->cp_stat[i] = FREE;
-      return;
+      goto handled;
       }
    else if (HD(j)->cp_stat[i] == LOCKED) {
       HD(j)->cp_stat[i] = FREE;
       printk("%s: ihdlr, mbox %d unlocked, count %d.\n", BN(j), i,
              HD(j)->iocount);
-      return;
+      goto handled;
       }
    else if (HD(j)->cp_stat[i] == FREE) {
       printk("%s: ihdlr, mbox %d is free, count %d.\n", BN(j), i,
              HD(j)->iocount);
-      return;
+      goto handled;
       }
    else if (HD(j)->cp_stat[i] == IN_RESET)
       printk("%s: ihdlr, mbox %d is in reset.\n", BN(j), i);
@@ -1887,23 +1931,25 @@
    if (do_trace) printk("%s: ihdlr, exit, irq %d, count %d.\n", BN(j), irq,
                         HD(j)->iocount);
 
-   return;
+handled:
+   return IRQ_HANDLED;
+none:
+   return IRQ_NONE;
 }
 
 static irqreturn_t do_interrupt_handler(int irq, void *shap,
-					struct pt_regs *regs)
-{
+                                        struct pt_regs *regs) {
    unsigned int j;
    unsigned long spin_flags;
+   irqreturn_t ret;
 
    /* Check if the interrupt must be processed by this handler */
-   if ((j = (unsigned int)((char *)shap - sha)) >= num_boards)
-	   return IRQ_NONE;
+   if ((j = (unsigned int)((char *)shap - sha)) >= num_boards) return IRQ_NONE;
 
    spin_lock_irqsave(sh[j]->host_lock, spin_flags);
-   ihdlr(irq, j);
+   ret = ihdlr(irq, j);
    spin_unlock_irqrestore(sh[j]->host_lock, spin_flags);
-   return IRQ_HANDLED;
+   return ret;
 }
 
 static int u14_34f_release(struct Scsi_Host *shpnt) {
@@ -1930,22 +1976,8 @@
    return FALSE;
 }
 
-static Scsi_Host_Template driver_template = {
-	.name         = "UltraStor 14F/34F rev. " U14_34F_VERSION " ",
-	.detect                  = u14_34f_detect,
-	.release                 = u14_34f_release,
-	.queuecommand            = u14_34f_queuecommand,
-	.eh_abort_handler        = u14_34f_eh_abort,
-	.eh_host_reset_handler   = u14_34f_eh_host_reset,
-	.bios_param              = u14_34f_bios_param,
-	.slave_configure         = u14_34f_slave_configure,
-	.this_id                 = 7,
-	.unchecked_isa_dma       = 1, 
-	.use_clustering          = ENABLE_CLUSTERING,
-};
 #include "scsi_module.c"
 
 #ifndef MODULE
 __setup("u14-34f=", option_setup);
 #endif /* end MODULE */
-MODULE_LICENSE("GPL");
diff -Nru a/drivers/scsi/u14-34f.h b/drivers/scsi/u14-34f.h
--- a/drivers/scsi/u14-34f.h	Wed Jun 18 23:42:09 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,14 +0,0 @@
-/*
- *   u14-34f.h - used by the low-level driver for UltraStor 14F/34F
- */
-
-static int u14_34f_detect(Scsi_Host_Template *);
-static int u14_34f_release(struct Scsi_Host *);
-static int u14_34f_queuecommand(Scsi_Cmnd *, void (*done)(Scsi_Cmnd *));
-static int u14_34f_eh_abort(Scsi_Cmnd *);
-static int u14_34f_eh_host_reset(Scsi_Cmnd *);
-static int u14_34f_bios_param(struct scsi_device *, struct block_device *,
-                              sector_t, int *);
-static int u14_34f_slave_configure(Scsi_Device *);
-
-#define U14_34F_VERSION "8.03.00"
diff -Nru a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c
--- a/drivers/scsi/ultrastor.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/scsi/ultrastor.c	Wed Jun 18 23:42:07 2003
@@ -643,6 +643,18 @@
 	return ultrastor_14f_detect(tpnt) || ultrastor_24f_detect(tpnt);
 }
 
+static int ultrastor_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->dma_channel != 0xff)
+		free_dma(shost->dma_channel);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
+
 static const char *ultrastor_info(struct Scsi_Host * shpnt)
 {
     static char buf[64];
@@ -1177,6 +1189,7 @@
 static Scsi_Host_Template driver_template = {
 	.name              = "UltraStor 14F/24F/34F",
 	.detect            = ultrastor_detect,
+	.release	   = ultrastor_release,
 	.info              = ultrastor_info,
 	.queuecommand      = ultrastor_queuecommand,
 	.eh_abort_handler  = ultrastor_abort,
diff -Nru a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
--- a/drivers/scsi/wd7000.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/scsi/wd7000.c	Wed Jun 18 23:42:09 2003
@@ -1031,14 +1031,6 @@
 	return (scsierr | (hosterr << 16));
 }
 
-
-static void wd7000_scsi_done(Scsi_Cmnd * SCpnt)
-{
-	dprintk("wd7000_scsi_done: 0x%06lx\n", (long) SCpnt);
-	SCpnt->SCp.phase = 0;
-}
-
-
 #define wd7000_intr_ack(host)   outb (0, host->iobase + ASC_INTR_ACK)
 
 static void wd7000_intr_handle(int irq, void *dev_id, struct pt_regs *regs)
@@ -1188,20 +1180,6 @@
 	return 0;
 }
 
-
-static int wd7000_command(Scsi_Cmnd * SCpnt)
-{
-	wd7000_queuecommand(SCpnt, wd7000_scsi_done);
-
-	while (SCpnt->SCp.phase > 0) {
-		cpu_relax();
-		barrier();	/* phase counts scbs down to 0 */
-	}
-
-	return (SCpnt->result);
-}
-
-
 static int wd7000_diagnostics(Adapter * host, int code)
 {
 	static IcbDiag icb = { ICB_OP_DIAGNOSTICS };
@@ -1616,6 +1594,15 @@
 	return (present);
 }
 
+static int wd7000_release(struct Scsi_Host *shost)
+{
+	if (shost->irq)
+		free_irq(shost->irq, NULL);
+	if (shost->io_port && shost->n_io_port)
+		release_region(shost->io_port, shost->n_io_port);
+	scsi_unregister(shost);
+	return 0;
+}
 
 /*
  *  I have absolutely NO idea how to do an abort with the WD7000...
@@ -1722,7 +1709,7 @@
 	.proc_info		= wd7000_proc_info,
 	.name			= "Western Digital WD-7000",
 	.detect			= wd7000_detect,
-	.command		= wd7000_command,
+	.release		= wd7000_release,
 	.queuecommand		= wd7000_queuecommand,
 	.eh_bus_reset_handler	= wd7000_bus_reset,
 	.eh_device_reset_handler = wd7000_device_reset,
diff -Nru a/drivers/serial/Kconfig b/drivers/serial/Kconfig
--- a/drivers/serial/Kconfig	Wed Jun 18 23:42:09 2003
+++ b/drivers/serial/Kconfig	Wed Jun 18 23:42:09 2003
@@ -77,7 +77,15 @@
 	  a module, say M here and read <file:Documentation/modules.txt>.
 	  If unsure, say N.
 
-config SERIAL_HCDP
+config SERIAL_8250_ACPI
+	bool "8250/16550 device discovery via ACPI namespace"
+	default y if IA64
+	depends on ACPI_BUS
+	---help---
+	  If you wish to enable serial port discovery via the ACPI
+	  namespace, say Y here.  If unsure, say N.
+
+config SERIAL_8250_HCDP
 	bool "8250/16550 device discovery support via EFI HCDP table"
 	depends on IA64
 	---help---
diff -Nru a/drivers/serial/Makefile b/drivers/serial/Makefile
--- a/drivers/serial/Makefile	Wed Jun 18 23:42:07 2003
+++ b/drivers/serial/Makefile	Wed Jun 18 23:42:07 2003
@@ -8,7 +8,8 @@
 serial-8250-$(CONFIG_GSC) += 8250_gsc.o
 serial-8250-$(CONFIG_PCI) += 8250_pci.o
 serial-8250-$(CONFIG_PNP) += 8250_pnp.o
-serial-8250-$(CONFIG_SERIAL_HCDP) += 8250_hcdp.o
+serial-8250-$(CONFIG_SERIAL_8250_HCDP) += 8250_hcdp.o
+serial-8250-$(CONFIG_SERIAL_8250_ACPI) += 8250_acpi.o
 
 obj-$(CONFIG_SERIAL_CORE) += core.o
 obj-$(CONFIG_SERIAL_21285) += 21285.o
diff -Nru a/drivers/usb/Makefile.lib b/drivers/usb/Makefile.lib
--- a/drivers/usb/Makefile.lib	Wed Jun 18 23:42:05 2003
+++ b/drivers/usb/Makefile.lib	Wed Jun 18 23:42:05 2003
@@ -1,3 +1,4 @@
+obj-$(CONFIG_USB_AX8817X)	+= crc32.o
 obj-$(CONFIG_USB_CATC)		+= crc32.o
 obj-$(CONFIG_USB_SPEEDTOUCH)	+= crc32.o
 obj-$(CONFIG_USB_USBNET)	+= crc32.o
diff -Nru a/drivers/usb/class/audio.c b/drivers/usb/class/audio.c
--- a/drivers/usb/class/audio.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/usb/class/audio.c	Wed Jun 18 23:42:09 2003
@@ -541,7 +541,7 @@
 			pgrem = rem;
 		memcpy((db->sgbuf[db->wrptr >> PAGE_SHIFT]) + (db->wrptr & (PAGE_SIZE-1)), buffer, pgrem);
 		size -= pgrem;
-		(char *)buffer += pgrem;
+		buffer += pgrem;
 		db->wrptr += pgrem;
 		if (db->wrptr >= db->dmasize)
 			db->wrptr = 0;
@@ -564,14 +564,14 @@
 			pgrem = rem;
 		memcpy(buffer, (db->sgbuf[db->rdptr >> PAGE_SHIFT]) + (db->rdptr & (PAGE_SIZE-1)), pgrem);
 		size -= pgrem;
-		(char *)buffer += pgrem;
+		buffer += pgrem;
 		db->rdptr += pgrem;
 		if (db->rdptr >= db->dmasize)
 			db->rdptr = 0;
 	}
 }
 
-static int dmabuf_copyin_user(struct dmabuf *db, unsigned int ptr, const void *buffer, unsigned int size)
+static int dmabuf_copyin_user(struct dmabuf *db, unsigned int ptr, const void __user *buffer, unsigned int size)
 {
 	unsigned int pgrem, rem;
 
@@ -589,14 +589,14 @@
 		if (copy_from_user((db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), buffer, pgrem))
 			return -EFAULT;
 		size -= pgrem;
-		(char *)buffer += pgrem;
+		buffer += pgrem;
 		ptr += pgrem;
 		if (ptr >= db->dmasize)
 			ptr = 0;
 	}
 }
 
-static int dmabuf_copyout_user(struct dmabuf *db, unsigned int ptr, void *buffer, unsigned int size)
+static int dmabuf_copyout_user(struct dmabuf *db, unsigned int ptr, void __user *buffer, unsigned int size)
 {
 	unsigned int pgrem, rem;
 
@@ -614,7 +614,7 @@
 		if (copy_to_user(buffer, (db->sgbuf[ptr >> PAGE_SHIFT]) + (ptr & (PAGE_SIZE-1)), pgrem))
 			return -EFAULT;
 		size -= pgrem;
-		(char *)buffer += pgrem;
+		buffer += pgrem;
 		ptr += pgrem;
 		if (ptr >= db->dmasize)
 			ptr = 0;
@@ -2010,7 +2010,7 @@
 		strncpy(info.id, "USB_AUDIO", sizeof(info.id));
 		strncpy(info.name, "USB Audio Class Driver", sizeof(info.name));
 		info.modify_counter = ms->modcnt;
-		if (copy_to_user((void *)arg, &info, sizeof(info)))
+		if (copy_to_user((void __user *)arg, &info, sizeof(info)))
 			return -EFAULT;
 		return 0;
 	}
@@ -2018,7 +2018,7 @@
 		_old_mixer_info info;
 		strncpy(info.id, "USB_AUDIO", sizeof(info.id));
 		strncpy(info.name, "USB Audio Class Driver", sizeof(info.name));
-		if (copy_to_user((void *)arg, &info, sizeof(info)))
+		if (copy_to_user((void __user *)arg, &info, sizeof(info)))
 			return -EFAULT;
 		return 0;
 	}
@@ -2140,7 +2140,7 @@
 
 /* --------------------------------------------------------------------- */
 
-static ssize_t usb_audio_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t usb_audio_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 {
 	struct usb_audiodev *as = (struct usb_audiodev *)file->private_data;
 	DECLARE_WAITQUEUE(wait, current);
@@ -2208,7 +2208,7 @@
 	return ret;
 }
 
-static ssize_t usb_audio_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t usb_audio_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
 	struct usb_audiodev *as = (struct usb_audiodev *)file->private_data;
 	DECLARE_WAITQUEUE(wait, current);
@@ -2507,7 +2507,7 @@
 		abinfo.fragstotal = as->usbout.dma.numfrag;
 		abinfo.fragments = abinfo.bytes >> as->usbout.dma.fragshift;      
 		spin_unlock_irqrestore(&as->lock, flags);
-		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+		return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 
 	case SNDCTL_DSP_GETISPACE:
 		if (!(file->f_mode & FMODE_READ))
@@ -2520,7 +2520,7 @@
 		abinfo.fragstotal = as->usbin.dma.numfrag;
 		abinfo.fragments = abinfo.bytes >> as->usbin.dma.fragshift;      
 		spin_unlock_irqrestore(&as->lock, flags);
-		return copy_to_user((void *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
+		return copy_to_user((void __user *)arg, &abinfo, sizeof(abinfo)) ? -EFAULT : 0;
 		
 	case SNDCTL_DSP_NONBLOCK:
 		file->f_flags |= O_NONBLOCK;
@@ -2544,7 +2544,7 @@
 		if (as->usbin.dma.mapped)
 			as->usbin.dma.count &= as->usbin.dma.fragsize-1;
 		spin_unlock_irqrestore(&as->lock, flags);
-		if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+		if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo)))
 			return -EFAULT;
 		return 0;
 
@@ -2558,7 +2558,7 @@
 		if (as->usbout.dma.mapped)
 			as->usbout.dma.count &= as->usbout.dma.fragsize-1;
 		spin_unlock_irqrestore(&as->lock, flags);
-		if (copy_to_user((void *)arg, &cinfo, sizeof(cinfo)))
+		if (copy_to_user((void __user *)arg, &cinfo, sizeof(cinfo)))
 			return -EFAULT;
 		return 0;
 
diff -Nru a/drivers/usb/class/bluetty.c b/drivers/usb/class/bluetty.c
--- a/drivers/usb/class/bluetty.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/usb/class/bluetty.c	Wed Jun 18 23:42:08 2003
@@ -484,7 +484,7 @@
 			retval = -ENOMEM;
 			goto exit;
 		}
-		if (copy_from_user (temp_buffer, buf, count)) {
+		if (copy_from_user (temp_buffer, (void __user *)buf, count)) {
 			retval = -EFAULT;
 			goto exit;
 		}
diff -Nru a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
--- a/drivers/usb/class/cdc-acm.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/usb/class/cdc-acm.c	Wed Jun 18 23:42:08 2003
@@ -388,7 +388,7 @@
 	count = (count > acm->writesize) ? acm->writesize : count;
 
 	if (from_user) {
-		if (copy_from_user(acm->writeurb->transfer_buffer, buf, count))
+		if (copy_from_user(acm->writeurb->transfer_buffer, (void __user *)buf, count))
 			return -EFAULT;
 	} else
 		memcpy(acm->writeurb->transfer_buffer, buf, count);
@@ -548,7 +548,7 @@
 	struct usb_host_config *cfacm;
 	struct usb_host_interface *ifcom, *ifdata;
 	struct usb_endpoint_descriptor *epctrl, *epread, *epwrite;
-	int readsize, ctrlsize, minor, i;
+	int readsize, ctrlsize, minor, i, j;
 	unsigned char *buf;
 
 	dev = interface_to_usbdev (intf);
@@ -558,120 +558,123 @@
 
 		dbg("probing config %d", cfacm->desc.bConfigurationValue);
 
-		if (cfacm->desc.bNumInterfaces != 2 ||
-		    usb_interface_claimed(cfacm->interface + 0) ||
-		    usb_interface_claimed(cfacm->interface + 1))
+		for (j = 0; j < cfacm->desc.bNumInterfaces - 1; j++) {
+		    
+			if (usb_interface_claimed(cfacm->interface + j) ||
+			    usb_interface_claimed(cfacm->interface + j + 1))
 			continue;
 
-		ifcom = cfacm->interface[0].altsetting + 0;
-		ifdata = cfacm->interface[1].altsetting + 0;
+			ifcom = cfacm->interface[j].altsetting + 0;
+			ifdata = cfacm->interface[j + 1].altsetting + 0;
 
-		if (ifdata->desc.bInterfaceClass != 10 || ifdata->desc.bNumEndpoints < 2) {
-			ifcom = cfacm->interface[1].altsetting + 0;
-			ifdata = cfacm->interface[0].altsetting + 0;
-			if (ifdata->desc.bInterfaceClass != 10 || ifdata->desc.bNumEndpoints < 2)
+			if (ifdata->desc.bInterfaceClass != 10 || ifdata->desc.bNumEndpoints < 2) {
+				ifcom = cfacm->interface[j + 1].altsetting + 0;
+				ifdata = cfacm->interface[j].altsetting + 0;
+				if (ifdata->desc.bInterfaceClass != 10 || ifdata->desc.bNumEndpoints < 2)
+					continue;
+			}
+
+			if (ifcom->desc.bInterfaceClass != 2 || ifcom->desc.bInterfaceSubClass != 2 ||
+			    ifcom->desc.bInterfaceProtocol < 1 || ifcom->desc.bInterfaceProtocol > 6 ||
+			    ifcom->desc.bNumEndpoints < 1)
 				continue;
-		}
-
-		if (ifcom->desc.bInterfaceClass != 2 || ifcom->desc.bInterfaceSubClass != 2 ||
-		    ifcom->desc.bInterfaceProtocol != 1 || ifcom->desc.bNumEndpoints < 1)
-			continue;
-
-		epctrl = &ifcom->endpoint[0].desc;
-		epread = &ifdata->endpoint[0].desc;
-		epwrite = &ifdata->endpoint[1].desc;
-
-		if ((epctrl->bEndpointAddress & 0x80) != 0x80 || (epctrl->bmAttributes & 3) != 3 ||
-		   (epread->bmAttributes & 3) != 2 || (epwrite->bmAttributes & 3) != 2 ||
-		   ((epread->bEndpointAddress & 0x80) ^ (epwrite->bEndpointAddress & 0x80)) != 0x80)
-			continue;
-
-		if ((epread->bEndpointAddress & 0x80) != 0x80) {
-			epread = &ifdata->endpoint[1].desc;
-			epwrite = &ifdata->endpoint[0].desc;
-		}
 
-		usb_set_configuration(dev, cfacm->desc.bConfigurationValue);
-
-		for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
-		if (acm_table[minor]) {
-			err("no more free acm devices");
-			return -ENODEV;
-		}
-
-		if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) {
-			err("out of memory");
-			return -ENOMEM;
-		}
-		memset(acm, 0, sizeof(struct acm));
-
-		ctrlsize = epctrl->wMaxPacketSize;
-		readsize = epread->wMaxPacketSize;
-		acm->writesize = epwrite->wMaxPacketSize;
-		acm->iface = cfacm->interface;
-		acm->minor = minor;
-		acm->dev = dev;
-
-		INIT_WORK(&acm->work, acm_softint, acm);
-
-		if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) {
-			err("out of memory");
-			kfree(acm);
-			return -ENOMEM;
-		}
+			epctrl = &ifcom->endpoint[0].desc;
+			epread = &ifdata->endpoint[0].desc;
+			epwrite = &ifdata->endpoint[1].desc;
+
+			if ((epctrl->bEndpointAddress & 0x80) != 0x80 || (epctrl->bmAttributes & 3) != 3 ||
+			   (epread->bmAttributes & 3) != 2 || (epwrite->bmAttributes & 3) != 2 ||
+			   ((epread->bEndpointAddress & 0x80) ^ (epwrite->bEndpointAddress & 0x80)) != 0x80)
+				continue;
 
-		acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL);
-		if (!acm->ctrlurb) {
-			err("out of memory");
-			kfree(acm);
-			kfree(buf);
-			return -ENOMEM;
+			if ((epread->bEndpointAddress & 0x80) != 0x80) {
+				epread = &ifdata->endpoint[1].desc;
+				epwrite = &ifdata->endpoint[0].desc;
+			}
+
+			usb_set_configuration(dev, cfacm->desc.bConfigurationValue);
+
+			for (minor = 0; minor < ACM_TTY_MINORS && acm_table[minor]; minor++);
+			if (acm_table[minor]) {
+				err("no more free acm devices");
+				return -ENODEV;
+			}
+
+			if (!(acm = kmalloc(sizeof(struct acm), GFP_KERNEL))) {
+				err("out of memory");
+				return -ENOMEM;
+			}
+			memset(acm, 0, sizeof(struct acm));
+
+			ctrlsize = epctrl->wMaxPacketSize;
+			readsize = epread->wMaxPacketSize;
+			acm->writesize = epwrite->wMaxPacketSize;
+			acm->iface = cfacm->interface + j;
+			acm->minor = minor;
+			acm->dev = dev;
+
+			INIT_WORK(&acm->work, acm_softint, acm);
+
+			if (!(buf = kmalloc(ctrlsize + readsize + acm->writesize, GFP_KERNEL))) {
+				err("out of memory");
+				kfree(acm);
+				return -ENOMEM;
+			}
+
+			acm->ctrlurb = usb_alloc_urb(0, GFP_KERNEL);
+			if (!acm->ctrlurb) {
+				err("out of memory");
+				kfree(acm);
+				kfree(buf);
+				return -ENOMEM;
+			}
+			acm->readurb = usb_alloc_urb(0, GFP_KERNEL);
+			if (!acm->readurb) {
+				err("out of memory");
+				usb_free_urb(acm->ctrlurb);
+				kfree(acm);
+				kfree(buf);
+				return -ENOMEM;
+			}
+			acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
+			if (!acm->writeurb) {
+				err("out of memory");
+				usb_free_urb(acm->readurb);
+				usb_free_urb(acm->ctrlurb);
+				kfree(acm);
+				kfree(buf);
+				return -ENOMEM;
+			}
+
+			usb_fill_int_urb(acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress),
+				buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
+
+			usb_fill_bulk_urb(acm->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
+				buf += ctrlsize, readsize, acm_read_bulk, acm);
+			acm->readurb->transfer_flags |= URB_NO_FSBR;
+
+			usb_fill_bulk_urb(acm->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
+				buf += readsize, acm->writesize, acm_write_bulk, acm);
+			acm->writeurb->transfer_flags |= URB_NO_FSBR;
+
+			info("ttyACM%d: USB ACM device", minor);
+
+			acm_set_control(acm, acm->ctrlout);
+
+			acm->line.speed = cpu_to_le32(9600);
+			acm->line.databits = 8;
+			acm_set_line(acm, &acm->line);
+
+			usb_driver_claim_interface(&acm_driver, acm->iface + 0, acm);
+			usb_driver_claim_interface(&acm_driver, acm->iface + 1, acm);
+
+			tty_register_device(acm_tty_driver, minor, &intf->dev);
+
+			acm_table[minor] = acm;
+			usb_set_intfdata (intf, acm);
+			return 0;
 		}
-		acm->readurb = usb_alloc_urb(0, GFP_KERNEL);
-		if (!acm->readurb) {
-			err("out of memory");
-			usb_free_urb(acm->ctrlurb);
-			kfree(acm);
-			kfree(buf);
-			return -ENOMEM;
-		}
-		acm->writeurb = usb_alloc_urb(0, GFP_KERNEL);
-		if (!acm->writeurb) {
-			err("out of memory");
-			usb_free_urb(acm->readurb);
-			usb_free_urb(acm->ctrlurb);
-			kfree(acm);
-			kfree(buf);
-			return -ENOMEM;
-		}
-
-		usb_fill_int_urb(acm->ctrlurb, dev, usb_rcvintpipe(dev, epctrl->bEndpointAddress),
-			buf, ctrlsize, acm_ctrl_irq, acm, epctrl->bInterval);
-
-		usb_fill_bulk_urb(acm->readurb, dev, usb_rcvbulkpipe(dev, epread->bEndpointAddress),
-			buf += ctrlsize, readsize, acm_read_bulk, acm);
-		acm->readurb->transfer_flags |= URB_NO_FSBR;
-
-		usb_fill_bulk_urb(acm->writeurb, dev, usb_sndbulkpipe(dev, epwrite->bEndpointAddress),
-			buf += readsize, acm->writesize, acm_write_bulk, acm);
-		acm->writeurb->transfer_flags |= URB_NO_FSBR;
-
-		info("ttyACM%d: USB ACM device", minor);
-
-		acm_set_control(acm, acm->ctrlout);
-
-		acm->line.speed = cpu_to_le32(9600);
-		acm->line.databits = 8;
-		acm_set_line(acm, &acm->line);
-
-		usb_driver_claim_interface(&acm_driver, acm->iface + 0, acm);
-		usb_driver_claim_interface(&acm_driver, acm->iface + 1, acm);
-
-		tty_register_device(acm_tty_driver, minor, &intf->dev);
-
-		acm_table[minor] = acm;
-		usb_set_intfdata (intf, acm);
-		return 0;
 	}
 
 	return -EIO;
diff -Nru a/drivers/usb/class/usb-midi.c b/drivers/usb/class/usb-midi.c
--- a/drivers/usb/class/usb-midi.c	Wed Jun 18 23:42:05 2003
+++ b/drivers/usb/class/usb-midi.c	Wed Jun 18 23:42:05 2003
@@ -642,7 +642,7 @@
  *
  **/
 
-static ssize_t usb_midi_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t usb_midi_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 {
 	struct usb_mididev *m = (struct usb_mididev *)file->private_data;
 	struct midi_in_endpoint *ep = m->min.ep;
@@ -725,7 +725,7 @@
  *
  **/
 
-static ssize_t usb_midi_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t usb_midi_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
 	struct usb_mididev *m = (struct usb_mididev *)file->private_data;
 	ssize_t ret;
diff -Nru a/drivers/usb/class/usblp.c b/drivers/usb/class/usblp.c
--- a/drivers/usb/class/usblp.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/usb/class/usblp.c	Wed Jun 18 23:42:06 2003
@@ -296,13 +296,13 @@
 	}
 
 	status = *usblp->statusbuf;
-	if (~status & LP_PERRORP) {
+
+	if (~status & LP_PERRORP)
 		newerr = 3;
-		if (status & LP_POUTPA)
-			newerr = 1;
-		if (~status & LP_PSELECD)
-			newerr = 2;
-	}
+	if (status & LP_POUTPA)
+		newerr = 1;
+	if (~status & LP_PSELECD)
+		newerr = 2;
 
 	if (newerr != err)
 		info("usblp%d: %s", usblp->minor, usblp_messages[newerr]);
@@ -426,7 +426,7 @@
 {
 	struct usblp *usblp = file->private_data;
 	int length, err, i;
-	unsigned char lpstatus, newChannel;
+	unsigned char newChannel;
 	int status;
 	int twoints[2];
 	int retval = 0;
@@ -455,7 +455,7 @@
 				if (length > _IOC_SIZE(cmd))
 					length = _IOC_SIZE(cmd); /* truncate */
 
-				if (copy_to_user((unsigned char *) arg,
+				if (copy_to_user((void __user *) arg,
 						usblp->device_id_string,
 						(unsigned long) length)) {
 					retval = -EFAULT;
@@ -479,7 +479,7 @@
 						twoints[1] |= (1<<i);
 				}
 
-				if (copy_to_user((unsigned char *)arg,
+				if (copy_to_user((void __user *)arg,
 						(unsigned char *)twoints,
 						sizeof(twoints))) {
 					retval = -EFAULT;
@@ -540,7 +540,7 @@
 
 				twoints[0] = usblp->dev->bus->busnum;
 				twoints[1] = usblp->dev->devnum;
-				if (copy_to_user((unsigned char *)arg,
+				if (copy_to_user((void __user *)arg,
 						(unsigned char *)twoints,
 						sizeof(twoints))) {
 					retval = -EFAULT;
@@ -560,7 +560,7 @@
 
 				twoints[0] = usblp->dev->descriptor.idVendor;
 				twoints[1] = usblp->dev->descriptor.idProduct;
-				if (copy_to_user((unsigned char *)arg,
+				if (copy_to_user((void __user *)arg,
 						(unsigned char *)twoints,
 						sizeof(twoints))) {
 					retval = -EFAULT;
@@ -578,13 +578,13 @@
 		switch (cmd) {
 
 			case LPGETSTATUS:
-				if (usblp_read_status(usblp, &lpstatus)) {
+				if (usblp_read_status(usblp, usblp->statusbuf)) {
 					err("usblp%d: failed reading printer status", usblp->minor);
 					retval = -EIO;
 					goto done;
 				}
-				status = lpstatus;
-				if (copy_to_user ((int *)arg, &status, sizeof(int)))
+				status = *usblp->statusbuf;
+				if (copy_to_user ((void __user *)arg, &status, sizeof(int)))
 					retval = -EFAULT;
 				break;
 
@@ -597,7 +597,7 @@
 	return retval;
 }
 
-static ssize_t usblp_write(struct file *file, const char *buffer, size_t count, loff_t *ppos)
+static ssize_t usblp_write(struct file *file, const char __user *buffer, size_t count, loff_t *ppos)
 {
 	DECLARE_WAITQUEUE(wait, current);
 	struct usblp *usblp = file->private_data;
@@ -682,7 +682,7 @@
 	return count;
 }
 
-static ssize_t usblp_read(struct file *file, char *buffer, size_t count, loff_t *ppos)
+static ssize_t usblp_read(struct file *file, char __user *buffer, size_t count, loff_t *ppos)
 {
 	struct usblp *usblp = file->private_data;
 	DECLARE_WAITQUEUE(wait, current);
@@ -858,8 +858,8 @@
 	}
 
 	usblp->writebuf = usblp->readbuf = NULL;
-	usblp->writeurb->transfer_flags = URB_NO_DMA_MAP;
-	usblp->readurb->transfer_flags = URB_NO_DMA_MAP;
+	usblp->writeurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
+	usblp->readurb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
 	/* Malloc write & read buffers.  We somewhat wastefully
 	 * malloc both regardless of bidirectionality, because the
 	 * alternate setting can be changed later via an ioctl. */
diff -Nru a/drivers/usb/core/hcd.c b/drivers/usb/core/hcd.c
--- a/drivers/usb/core/hcd.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/core/hcd.c	Wed Jun 18 23:42:07 2003
@@ -459,7 +459,8 @@
 	/* rh_timer protected by hcd_data_lock */
 	if (hcd->rh_timer.data
 			|| urb->status != -EINPROGRESS
-			|| urb->transfer_buffer_length < len) {
+			|| urb->transfer_buffer_length < len
+			|| !HCD_IS_RUNNING (hcd->state)) {
 		dev_dbg (hcd->controller,
 				"not queuing rh status urb, stat %d\n",
 				urb->status);
@@ -489,11 +490,10 @@
 	local_irq_save (flags);
 	spin_lock (&urb->lock);
 
-	/* do nothing if the hc is gone or the urb's been unlinked */
+	/* do nothing if the urb's been unlinked */
 	if (!urb->dev
 			|| urb->status != -EINPROGRESS
-			|| (hcd = urb->dev->bus->hcpriv) == 0
-			|| !HCD_IS_RUNNING (hcd->state)) {
+			|| (hcd = urb->dev->bus->hcpriv) == 0) {
 		spin_unlock (&urb->lock);
 		local_irq_restore (flags);
 		return;
@@ -1027,7 +1027,8 @@
 		 * valid and usb_buffer_{sync,unmap}() not be needed, since
 		 * they could clobber root hub response data.
 		 */
-		urb->transfer_flags |= URB_NO_DMA_MAP;
+		urb->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP
+					| URB_NO_SETUP_DMA_MAP);
 		status = rh_urb_enqueue (hcd, urb);
 		goto done;
 	}
@@ -1035,15 +1036,16 @@
 	/* lower level hcd code should use *_dma exclusively,
 	 * unless it uses pio or talks to another transport.
 	 */
-	if (!(urb->transfer_flags & URB_NO_DMA_MAP)
-			&& hcd->controller->dma_mask) {
-		if (usb_pipecontrol (urb->pipe))
+	if (hcd->controller->dma_mask) {
+		if (usb_pipecontrol (urb->pipe)
+			&& !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
 			urb->setup_dma = dma_map_single (
 					hcd->controller,
 					urb->setup_packet,
 					sizeof (struct usb_ctrlrequest),
 					DMA_TO_DEVICE);
-		if (urb->transfer_buffer_length != 0)
+		if (urb->transfer_buffer_length != 0
+			&& !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
 			urb->transfer_dma = dma_map_single (
 					hcd->controller,
 					urb->transfer_buffer,
@@ -1410,12 +1412,14 @@
 	// It would catch exit/unlink paths for all urbs.
 
 	/* lower level hcd code should use *_dma exclusively */
-	if (!(urb->transfer_flags & URB_NO_DMA_MAP)) {
-		if (usb_pipecontrol (urb->pipe))
+	if (hcd->controller->dma_mask) {
+		if (usb_pipecontrol (urb->pipe)
+			&& !(urb->transfer_flags & URB_NO_SETUP_DMA_MAP))
 			pci_unmap_single (hcd->pdev, urb->setup_dma,
 					sizeof (struct usb_ctrlrequest),
 					PCI_DMA_TODEVICE);
-		if (urb->transfer_buffer_length != 0)
+		if (urb->transfer_buffer_length != 0
+			&& !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP))
 			pci_unmap_single (hcd->pdev, urb->transfer_dma,
 					urb->transfer_buffer_length,
 					usb_pipein (urb->pipe)
diff -Nru a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
--- a/drivers/usb/core/hub.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/core/hub.c	Wed Jun 18 23:42:07 2003
@@ -461,7 +461,7 @@
 	usb_fill_int_urb(hub->urb, dev, pipe, *hub->buffer, maxp, hub_irq,
 		hub, endpoint->bInterval);
 	hub->urb->transfer_dma = hub->buffer_dma;
-	hub->urb->transfer_flags |= URB_NO_DMA_MAP;
+	hub->urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 	ret = usb_submit_urb(hub->urb, GFP_KERNEL);
 	if (ret) {
 		message = "couldn't submit status urb";
diff -Nru a/drivers/usb/core/message.c b/drivers/usb/core/message.c
--- a/drivers/usb/core/message.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/usb/core/message.c	Wed Jun 18 23:42:06 2003
@@ -344,7 +344,8 @@
 	if (!io->urbs)
 		goto nomem;
 
-	urb_flags = URB_ASYNC_UNLINK | URB_NO_DMA_MAP | URB_NO_INTERRUPT;
+	urb_flags = URB_ASYNC_UNLINK | URB_NO_TRANSFER_DMA_MAP
+			| URB_NO_INTERRUPT;
 	if (usb_pipein (pipe))
 		urb_flags |= URB_SHORT_NOT_OK;
 
diff -Nru a/drivers/usb/core/urb.c b/drivers/usb/core/urb.c
--- a/drivers/usb/core/urb.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/core/urb.c	Wed Jun 18 23:42:07 2003
@@ -297,7 +297,7 @@
 
 	/* enforce simple/standard policy */
 	allowed = URB_ASYNC_UNLINK;	// affects later unlinks
-	allowed |= URB_NO_DMA_MAP;
+	allowed |= (URB_NO_TRANSFER_DMA_MAP | URB_NO_SETUP_DMA_MAP);
 	allowed |= URB_NO_INTERRUPT;
 	switch (temp) {
 	case PIPE_BULK:
diff -Nru a/drivers/usb/core/usb.c b/drivers/usb/core/usb.c
--- a/drivers/usb/core/usb.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/core/usb.c	Wed Jun 18 23:42:07 2003
@@ -1234,7 +1234,7 @@
 }
 
 /**
- * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_DMA_MAP
+ * usb_buffer_alloc - allocate dma-consistent buffer for URB_NO_xxx_DMA_MAP
  * @dev: device the buffer will be used with
  * @size: requested buffer size
  * @mem_flags: affect whether allocation may block
@@ -1245,9 +1245,9 @@
  * specified device.  Such cpu-space buffers are returned along with the DMA
  * address (through the pointer provided).
  *
- * These buffers are used with URB_NO_DMA_MAP set in urb->transfer_flags to
- * avoid behaviors like using "DMA bounce buffers", or tying down I/O mapping
- * hardware for long idle periods.  The implementation varies between
+ * These buffers are used with URB_NO_xxx_DMA_MAP set in urb->transfer_flags
+ * to avoid behaviors like using "DMA bounce buffers", or tying down I/O
+ * mapping hardware for long idle periods.  The implementation varies between
  * platforms, depending on details of how DMA will work to this device.
  * Using these buffers also helps prevent cacheline sharing problems on
  * architectures where CPU caches are not DMA-coherent.
@@ -1291,17 +1291,17 @@
 
 /**
  * usb_buffer_map - create DMA mapping(s) for an urb
- * @urb: urb whose transfer_buffer will be mapped
+ * @urb: urb whose transfer_buffer/setup_packet will be mapped
  *
  * Return value is either null (indicating no buffer could be mapped), or
- * the parameter.  URB_NO_DMA_MAP is added to urb->transfer_flags if the
- * operation succeeds.  If the device is connected to this system through
- * a non-DMA controller, this operation always succeeds.
+ * the parameter.  URB_NO_TRANSFER_DMA_MAP and URB_NO_SETUP_DMA_MAP are
+ * added to urb->transfer_flags if the operation succeeds.  If the device
+ * is connected to this system through a non-DMA controller, this operation
+ * always succeeds.
  *
  * This call would normally be used for an urb which is reused, perhaps
  * as the target of a large periodic transfer, with usb_buffer_dmasync()
- * calls to synchronize memory and dma state.  It may not be used for
- * control requests.
+ * calls to synchronize memory and dma state.
  *
  * Reverse the effect of this call with usb_buffer_unmap().
  */
@@ -1311,7 +1311,6 @@
 	struct device		*controller;
 
 	if (!urb
-			|| usb_pipecontrol (urb->pipe)
 			|| !urb->dev
 			|| !(bus = urb->dev->bus)
 			|| !(controller = bus->controller))
@@ -1322,17 +1321,23 @@
 			urb->transfer_buffer, urb->transfer_buffer_length,
 			usb_pipein (urb->pipe)
 				? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+		if (usb_pipecontrol (urb->pipe))
+			urb->setup_dma = dma_map_single (controller,
+					urb->setup_packet,
+					sizeof (struct usb_ctrlrequest),
+					DMA_TO_DEVICE);
 	// FIXME generic api broken like pci, can't report errors
 	// if (urb->transfer_dma == DMA_ADDR_INVALID) return 0;
 	} else
 		urb->transfer_dma = ~0;
-	urb->transfer_flags |= URB_NO_DMA_MAP;
+	urb->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP
+				| URB_NO_SETUP_DMA_MAP);
 	return urb;
 }
 
 /**
  * usb_buffer_dmasync - synchronize DMA and CPU view of buffer(s)
- * @urb: urb whose transfer_buffer will be synchronized
+ * @urb: urb whose transfer_buffer/setup_packet will be synchronized
  */
 void usb_buffer_dmasync (struct urb *urb)
 {
@@ -1340,17 +1345,23 @@
 	struct device		*controller;
 
 	if (!urb
-			|| !(urb->transfer_flags & URB_NO_DMA_MAP)
+			|| !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
 			|| !urb->dev
 			|| !(bus = urb->dev->bus)
 			|| !(controller = bus->controller))
 		return;
 
-	if (controller->dma_mask)
+	if (controller->dma_mask) {
 		dma_sync_single (controller,
 			urb->transfer_dma, urb->transfer_buffer_length,
 			usb_pipein (urb->pipe)
 				? DMA_FROM_DEVICE : DMA_TO_DEVICE);
+		if (usb_pipecontrol (urb->pipe))
+			dma_sync_single (controller,
+					urb->setup_dma,
+					sizeof (struct usb_ctrlrequest),
+					DMA_TO_DEVICE);
+	}
 }
 
 /**
@@ -1365,18 +1376,25 @@
 	struct device		*controller;
 
 	if (!urb
-			|| !(urb->transfer_flags & URB_NO_DMA_MAP)
+			|| !(urb->transfer_flags & URB_NO_TRANSFER_DMA_MAP)
 			|| !urb->dev
 			|| !(bus = urb->dev->bus)
 			|| !(controller = bus->controller))
 		return;
 
-	if (controller->dma_mask)
+	if (controller->dma_mask) {
 		dma_unmap_single (controller,
 			urb->transfer_dma, urb->transfer_buffer_length,
 			usb_pipein (urb->pipe)
 				? DMA_FROM_DEVICE : DMA_TO_DEVICE);
-	urb->transfer_flags &= ~URB_NO_DMA_MAP;
+		if (usb_pipecontrol (urb->pipe))
+			dma_unmap_single (controller,
+					urb->setup_dma,
+					sizeof (struct usb_ctrlrequest),
+					DMA_TO_DEVICE);
+	}
+	urb->transfer_flags &= ~(URB_NO_TRANSFER_DMA_MAP
+				| URB_NO_SETUP_DMA_MAP);
 }
 
 /**
@@ -1391,7 +1409,7 @@
  *
  * The caller is responsible for placing the resulting DMA addresses from
  * the scatterlist into URB transfer buffer pointers, and for setting the
- * URB_NO_DMA_MAP transfer flag in each of those URBs.
+ * URB_NO_TRANSFER_DMA_MAP transfer flag in each of those URBs.
  *
  * Top I/O rates come from queuing URBs, instead of waiting for each one
  * to complete before starting the next I/O.   This is particularly easy
diff -Nru a/drivers/usb/gadget/net2280.c b/drivers/usb/gadget/net2280.c
--- a/drivers/usb/gadget/net2280.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/usb/gadget/net2280.c	Wed Jun 18 23:42:06 2003
@@ -2222,7 +2222,7 @@
 			/* hw handles device features */
 			if (u.r.bRequestType != USB_RECIP_ENDPOINT)
 				goto delegate;
-			if (u.r.wIndex != 0 /* HALT feature */
+			if (u.r.wValue != 0 /* HALT feature */
 					|| u.r.wLength != 0)
 				goto do_stall;
 			if ((e = get_ep_by_addr (dev, u.r.wIndex)) == 0)
@@ -2239,7 +2239,7 @@
 			/* hw handles device features */
 			if (u.r.bRequestType != USB_RECIP_ENDPOINT)
 				goto delegate;
-			if (u.r.wIndex != 0 /* HALT feature */
+			if (u.r.wValue != 0 /* HALT feature */
 					|| u.r.wLength != 0)
 				goto do_stall;
 			if ((e = get_ep_by_addr (dev, u.r.wIndex)) == 0)
diff -Nru a/drivers/usb/host/ehci-dbg.c b/drivers/usb/host/ehci-dbg.c
--- a/drivers/usb/host/ehci-dbg.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/usb/host/ehci-dbg.c	Wed Jun 18 23:42:08 2003
@@ -115,19 +115,28 @@
 #ifdef	DEBUG
 
 static void __attribute__((__unused__))
+dbg_qtd (char *label, struct ehci_hcd *ehci, struct ehci_qtd *qtd)
+{
+	ehci_dbg (ehci, "%s td %p n%08x %08x t%08x p0=%08x\n", label, qtd,
+		cpu_to_le32p (&qtd->hw_next),
+		cpu_to_le32p (&qtd->hw_alt_next),
+		cpu_to_le32p (&qtd->hw_token),
+		cpu_to_le32p (&qtd->hw_buf [0]));
+	if (qtd->hw_buf [1])
+		ehci_dbg (ehci, "  p1=%08x p2=%08x p3=%08x p4=%08x\n",
+			cpu_to_le32p (&qtd->hw_buf [1]),
+			cpu_to_le32p (&qtd->hw_buf [2]),
+			cpu_to_le32p (&qtd->hw_buf [3]),
+			cpu_to_le32p (&qtd->hw_buf [4]));
+}
+
+static void __attribute__((__unused__))
 dbg_qh (char *label, struct ehci_hcd *ehci, struct ehci_qh *qh)
 {
-	dbg ("%s %p n%08x info1 %x info2 %x hw_curr %x qtd_next %x", label,
+	ehci_dbg (ehci, "%s qh %p n%08x info %x %x qtd %x\n", label,
 		qh, qh->hw_next, qh->hw_info1, qh->hw_info2,
-		qh->hw_current, qh->hw_qtd_next);
-	dbg ("  alt+nak+t= %x, token= %x, page0= %x, page1= %x",
-		qh->hw_alt_next, qh->hw_token,
-		qh->hw_buf [0], qh->hw_buf [1]);
-	if (qh->hw_buf [2]) {
-		dbg ("  page2= %x, page3= %x, page4= %x",
-			qh->hw_buf [2], qh->hw_buf [3],
-			qh->hw_buf [4]);
-	}
+		qh->hw_current);
+	dbg_qtd ("overlay", ehci, (struct ehci_qtd *) &qh->hw_qtd_next);
 }
 
 static int __attribute__((__unused__))
@@ -284,8 +293,7 @@
 		return '*';
 	if (token & QTD_STS_HALT)
 		return '-';
-	if (QTD_PID (token) != 1 /* not IN: OUT or SETUP */
-			|| QTD_LENGTH (token) == 0)
+	if (!IS_SHORT_READ (token))
 		return ' ';
 	/* tries to advance through hw_alt_next */
 	return '/';
@@ -307,11 +315,14 @@
 	char			*next = *nextp;
 	char			mark;
 
-	mark = token_mark (qh->hw_token);
+	if (qh->hw_qtd_next == EHCI_LIST_END)	/* NEC does this */
+		mark = '@';
+	else
+		mark = token_mark (qh->hw_token);
 	if (mark == '/') {	/* qh_alt_next controls qh advance? */
 		if ((qh->hw_alt_next & QTD_MASK) == ehci->async->hw_alt_next)
 			mark = '#';	/* blocked */
-		else if (qh->hw_alt_next & cpu_to_le32 (0x01))
+		else if (qh->hw_alt_next == EHCI_LIST_END)
 			mark = '.';	/* use hw_qtd_next */
 		/* else alt_next points to some other qtd */
 	}
@@ -324,7 +335,7 @@
 			(scratch >> 8) & 0x000f,
 			scratch, cpu_to_le32p (&qh->hw_info2),
 			cpu_to_le32p (&qh->hw_token), mark,
-			(cpu_to_le32 (0x8000000) & qh->hw_token)
+			(__constant_cpu_to_le32 (QTD_TOGGLE) & qh->hw_token)
 				? "data0" : "data1",
 			(cpu_to_le32p (&qh->hw_alt_next) >> 1) & 0x0f);
 	size -= temp;
@@ -390,6 +401,8 @@
 	char			*next;
 	struct ehci_qh		*qh;
 
+	*buf = 0;
+
 	pdev = container_of (dev, struct pci_dev, dev);
 	ehci = container_of (pci_get_drvdata (pdev), struct ehci_hcd, hcd);
 	next = buf;
@@ -412,7 +425,7 @@
 	}
 	spin_unlock_irqrestore (&ehci->lock, flags);
 
-	return PAGE_SIZE - size;
+	return strlen (buf);
 }
 static DEVICE_ATTR (async, S_IRUGO, show_async, NULL);
 
@@ -548,7 +561,8 @@
 	/* Capability Registers */
 	i = readw (&ehci->caps->hci_version);
 	temp = snprintf (next, size,
-		"EHCI %x.%02x, hcd state %d (version " DRIVER_VERSION ")\n",
+		"%s\nEHCI %x.%02x, hcd state %d (driver " DRIVER_VERSION ")\n",
+		pdev->dev.name,
 		i >> 8, i & 0x0ff, ehci->hcd.state);
 	size -= temp;
 	next += temp;
diff -Nru a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
--- a/drivers/usb/host/ehci-hcd.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/usb/host/ehci-hcd.c	Wed Jun 18 23:42:08 2003
@@ -39,13 +39,10 @@
 #include <linux/interrupt.h>
 #include <linux/reboot.h>
 #include <linux/usb.h>
+#include <linux/moduleparam.h>
 
 #include <linux/version.h>
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,32)
-#include "../hcd.h"
-#else
 #include "../core/hcd.h"
-#endif
 
 #include <asm/byteorder.h>
 #include <asm/io.h>
@@ -94,11 +91,11 @@
  * 2001-June	Works with usb-storage and NEC EHCI on 2.4
  */
 
-#define DRIVER_VERSION "2003-Jan-22"
+#define DRIVER_VERSION "2003-Jun-13"
 #define DRIVER_AUTHOR "David Brownell"
 #define DRIVER_DESC "USB 2.0 'Enhanced' Host Controller (EHCI) Driver"
 
-static const char	hcd_name [] = "ehci-hcd";
+static const char	hcd_name [] = "ehci_hcd";
 
 
 // #define EHCI_VERBOSE_DEBUG
@@ -123,7 +120,7 @@
 
 /* Initial IRQ latency:  lower than default */
 static int log2_irq_thresh = 0;		// 0 to 6
-MODULE_PARM (log2_irq_thresh, "i");
+module_param (log2_irq_thresh, int, S_IRUGO);
 MODULE_PARM_DESC (log2_irq_thresh, "log2 IRQ latency, 1-64 microframes");
 
 #define	INTR_MASK (STS_IAA | STS_FATAL | STS_ERR | STS_INT)
@@ -434,7 +431,7 @@
 	pci_set_mwi (ehci->hcd.pdev);
 
 	/* clear interrupt enables, set irq latency */
-	temp = readl (&ehci->regs->command) & 0xff;
+	temp = readl (&ehci->regs->command) & 0x0fff;
 	if (log2_irq_thresh < 0 || log2_irq_thresh > 6)
 		log2_irq_thresh = 0;
 	temp |= 1 << (16 + log2_irq_thresh);
@@ -1020,7 +1017,8 @@
 	if (usb_disabled())
 		return -ENODEV;
 
-	dbg ("block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd",
+	pr_debug ("%s: block sizes: qh %Zd qtd %Zd itd %Zd sitd %Zd\n",
+		hcd_name,
 		sizeof (struct ehci_qh), sizeof (struct ehci_qtd),
 		sizeof (struct ehci_itd), sizeof (struct ehci_sitd));
 
diff -Nru a/drivers/usb/host/ehci-q.c b/drivers/usb/host/ehci-q.c
--- a/drivers/usb/host/ehci-q.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/usb/host/ehci-q.c	Wed Jun 18 23:42:08 2003
@@ -88,7 +88,6 @@
 static inline void
 qh_update (struct ehci_hcd *ehci, struct ehci_qh *qh, struct ehci_qtd *qtd)
 {
-	qh->hw_current = 0;
 	qh->hw_qtd_next = QTD_NEXT (qtd->qtd_dma);
 	qh->hw_alt_next = EHCI_LIST_END;
 
@@ -99,8 +98,6 @@
 
 /*-------------------------------------------------------------------------*/
 
-#define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1)
-
 static void qtd_copy_status (
 	struct ehci_hcd *ehci,
 	struct urb *urb,
@@ -279,16 +276,15 @@
 		/* hardware copies qtd out of qh overlay */
 		rmb ();
 		token = le32_to_cpu (qtd->hw_token);
-		stopped = stopped
-			|| (HALT_BIT & qh->hw_token) != 0
-			|| (ehci->hcd.state == USB_STATE_HALT);
 
 		/* always clean up qtds the hc de-activated */
 		if ((token & QTD_STS_ACTIVE) == 0) {
 
-			/* magic dummy for short reads; won't advance */
-			if (IS_SHORT_READ (token)
-					&& !(token & QTD_STS_HALT)
+			if ((token & QTD_STS_HALT) != 0) {
+				stopped = 1;
+
+			/* magic dummy for some short reads; qh won't advance */
+			} else if (IS_SHORT_READ (token)
 					&& (qh->hw_alt_next & QTD_MASK)
 						== ehci->async->hw_alt_next) {
 				stopped = 1;
@@ -296,10 +292,13 @@
 			}
 
 		/* stop scanning when we reach qtds the hc is using */
-		} else if (likely (!stopped)) {
+		} else if (likely (!stopped
+				&& HCD_IS_RUNNING (ehci->hcd.state))) {
 			break;
 
 		} else {
+			stopped = 1;
+
 			/* ignore active urbs unless some previous qtd
 			 * for the urb faulted (including short read) or
 			 * its urb was canceled.  we may patch qh or qtds.
@@ -358,12 +357,20 @@
 	qh->qh_state = state;
 
 	/* update qh after fault cleanup */
-	if (unlikely ((HALT_BIT & qh->hw_token) != 0)) {
-		qh_update (ehci, qh,
-			list_empty (&qh->qtd_list)
-				? qh->dummy
-				: list_entry (qh->qtd_list.next,
-					struct ehci_qtd, qtd_list));
+	if (unlikely (stopped != 0)
+			/* some EHCI 0.95 impls will overlay dummy qtds */ 
+			|| qh->hw_qtd_next == EHCI_LIST_END) {
+		if (list_empty (&qh->qtd_list))
+			end = qh->dummy;
+		else {
+			end = list_entry (qh->qtd_list.next,
+					struct ehci_qtd, qtd_list);
+			/* first qtd may already be partially processed */
+			if (cpu_to_le32 (end->qtd_dma) == qh->hw_current)
+				end = 0;
+		}
+		if (end)
+			qh_update (ehci, qh, end);
 	}
 
 	return count;
@@ -683,12 +690,11 @@
 
 	/* NOTE:  if (PIPE_INTERRUPT) { scheduler sets s-mask } */
 
-	/* init as halted, toggle clear, advance to dummy */
+	/* init as live, toggle clear, advance to dummy */
 	qh->qh_state = QH_STATE_IDLE;
 	qh->hw_info1 = cpu_to_le32 (info1);
 	qh->hw_info2 = cpu_to_le32 (info2);
 	qh_update (ehci, qh, qh->dummy);
-	qh->hw_token = cpu_to_le32 (QTD_STS_HALT);
 	usb_settoggle (urb->dev, usb_pipeendpoint (urb->pipe), !is_input, 1);
 	return qh;
 }
@@ -787,11 +793,6 @@
 				}
 			}
 		}
-
-		/* FIXME:  changing config or interface setting is not
-		 * supported yet.  preferred fix is for usbcore to tell
-		 * us to clear out each endpoint's state, but...
-		 */
 
 		/* usb_clear_halt() means qh data toggle gets reset */
 		if (unlikely (!usb_gettoggle (urb->dev,
diff -Nru a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
--- a/drivers/usb/host/ehci.h	Wed Jun 18 23:42:09 2003
+++ b/drivers/usb/host/ehci.h	Wed Jun 18 23:42:09 2003
@@ -290,7 +290,10 @@
 	size_t			length;			/* length of buffer */
 } __attribute__ ((aligned (32)));
 
-#define QTD_MASK cpu_to_le32 (~0x1f)	/* mask NakCnt+T in qh->hw_alt_next */
+/* mask NakCnt+T in qh->hw_alt_next */
+#define QTD_MASK __constant_cpu_to_le32 (~0x1f)
+
+#define IS_SHORT_READ(token) (QTD_LENGTH (token) != 0 && QTD_PID (token) == 1)
 
 /*-------------------------------------------------------------------------*/
 
diff -Nru a/drivers/usb/image/hpusbscsi.c b/drivers/usb/image/hpusbscsi.c
--- a/drivers/usb/image/hpusbscsi.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/usb/image/hpusbscsi.c	Wed Jun 18 23:42:09 2003
@@ -104,7 +104,7 @@
 		goto out_free_controlurb;
 
 	/* In host->hostdata we store a pointer to desc */
-	new->host = scsi_register(&hpusbscsi_scsi_host_template, sizeof(new));
+	new->host = scsi_host_alloc(&hpusbscsi_scsi_host_template, sizeof(new));
 	if (!new->host)
 		goto out_unlink_controlurb;
 
@@ -137,7 +137,7 @@
 
 	scsi_remove_host(desc->host);
 	usb_unlink_urb(desc->controlurb);
-	scsi_unregister(desc->host);
+	scsi_host_put(desc->host);
 
 	usb_free_urb(desc->controlurb);
 	usb_free_urb(desc->dataurb);
diff -Nru a/drivers/usb/image/microtek.c b/drivers/usb/image/microtek.c
--- a/drivers/usb/image/microtek.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/usb/image/microtek.c	Wed Jun 18 23:42:09 2003
@@ -811,7 +811,7 @@
 		MTS_WARNING( "will this work? Image data EP is not usually %d\n",
 			     (int)new_desc->ep_image );
 
-	new_desc->host = scsi_register(&mts_scsi_host_template,
+	new_desc->host = scsi_host_alloc(&mts_scsi_host_template,
 			sizeof(new_desc));
 	if (!new_desc->host)
 		goto out_free_urb;
@@ -838,7 +838,7 @@
 
 	scsi_remove_host(desc->host);
 	usb_unlink_urb(desc->urb);
-	scsi_unregister(desc->host);
+	scsi_host_put(desc->host);
 
 	usb_free_urb(desc->urb);
 	kfree(desc);
diff -Nru a/drivers/usb/input/aiptek.c b/drivers/usb/input/aiptek.c
--- a/drivers/usb/input/aiptek.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/usb/input/aiptek.c	Wed Jun 18 23:42:08 2003
@@ -330,7 +330,7 @@
 			 aiptek->data, aiptek->features->pktlen,
 			 aiptek->features->irq, aiptek, endpoint->bInterval);
 	aiptek->irq->transfer_dma = aiptek->data_dma;
-	aiptek->irq->transfer_flags |= URB_NO_DMA_MAP;
+	aiptek->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 	input_register_device(&aiptek->dev);
 
diff -Nru a/drivers/usb/input/hid-core.c b/drivers/usb/input/hid-core.c
--- a/drivers/usb/input/hid-core.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/input/hid-core.c	Wed Jun 18 23:42:07 2003
@@ -1518,7 +1518,7 @@
 			usb_fill_int_urb(hid->urbin, dev, pipe, hid->inbuf, 0,
 					 hid_irq_in, hid, endpoint->bInterval);
 			hid->urbin->transfer_dma = hid->inbuf_dma;
-			hid->urbin->transfer_flags |= URB_NO_DMA_MAP;
+			hid->urbin->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 		} else {
 			if (hid->urbout)
 				continue;
@@ -1528,7 +1528,7 @@
 			usb_fill_bulk_urb(hid->urbout, dev, pipe, hid->outbuf, 0,
 					  hid_irq_out, hid);
 			hid->urbout->transfer_dma = hid->outbuf_dma;
-			hid->urbout->transfer_flags |= URB_NO_DMA_MAP;
+			hid->urbout->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 		}
 	}
 
@@ -1577,7 +1577,8 @@
 			     hid->ctrlbuf, 1, hid_ctrl, hid);
 	hid->urbctrl->setup_dma = hid->cr_dma;
 	hid->urbctrl->transfer_dma = hid->ctrlbuf_dma;
-	hid->urbctrl->transfer_flags |= URB_NO_DMA_MAP;
+	hid->urbctrl->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP
+				| URB_NO_SETUP_DMA_MAP);
 
 	return hid;
 
diff -Nru a/drivers/usb/input/kbtab.c b/drivers/usb/input/kbtab.c
--- a/drivers/usb/input/kbtab.c	Wed Jun 18 23:42:05 2003
+++ b/drivers/usb/input/kbtab.c	Wed Jun 18 23:42:05 2003
@@ -181,7 +181,7 @@
 			 kbtab->data, 8,
 			 kbtab_irq, kbtab, endpoint->bInterval);
 	kbtab->irq->transfer_dma = kbtab->data_dma;
-	kbtab->irq->transfer_flags |= URB_NO_DMA_MAP;
+	kbtab->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 	input_register_device(&kbtab->dev);
 
diff -Nru a/drivers/usb/input/powermate.c b/drivers/usb/input/powermate.c
--- a/drivers/usb/input/powermate.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/input/powermate.c	Wed Jun 18 23:42:07 2003
@@ -180,7 +180,7 @@
 			     (void *) pm->configcr, 0, 0,
 			     powermate_config_complete, pm);
 	pm->config->setup_dma = pm->configcr_dma;
-	pm->config->transfer_flags |= URB_NO_DMA_MAP;
+	pm->config->transfer_flags |= URB_NO_SETUP_DMA_MAP;
 
 	if (usb_submit_urb(pm->config, GFP_ATOMIC))
 		printk(KERN_ERR "powermate: usb_submit_urb(config) failed");
@@ -355,7 +355,7 @@
 			 POWERMATE_PAYLOAD_SIZE, powermate_irq,
 			 pm, endpoint->bInterval);
 	pm->irq->transfer_dma = pm->data_dma;
-	pm->irq->transfer_flags |= URB_NO_DMA_MAP;
+	pm->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 	/* register our interrupt URB with the USB system */
 	if (usb_submit_urb(pm->irq, GFP_KERNEL)) {
diff -Nru a/drivers/usb/input/usbkbd.c b/drivers/usb/input/usbkbd.c
--- a/drivers/usb/input/usbkbd.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/usb/input/usbkbd.c	Wed Jun 18 23:42:09 2003
@@ -282,7 +282,7 @@
 			 kbd->new, (maxp > 8 ? 8 : maxp),
 			 usb_kbd_irq, kbd, endpoint->bInterval);
 	kbd->irq->transfer_dma = kbd->new_dma;
-	kbd->irq->transfer_flags |= URB_NO_DMA_MAP;
+	kbd->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 	kbd->cr->bRequestType = USB_TYPE_CLASS | USB_RECIP_INTERFACE;
 	kbd->cr->bRequest = 0x09;
@@ -325,7 +325,8 @@
 			     usb_kbd_led, kbd);
 	kbd->led->setup_dma = kbd->cr_dma;
 	kbd->led->transfer_dma = kbd->leds_dma;
-	kbd->led->transfer_flags |= URB_NO_DMA_MAP;
+	kbd->led->transfer_flags |= (URB_NO_TRANSFER_DMA_MAP
+				| URB_NO_SETUP_DMA_MAP);
 
 	input_register_device(&kbd->dev);
 
diff -Nru a/drivers/usb/input/usbmouse.c b/drivers/usb/input/usbmouse.c
--- a/drivers/usb/input/usbmouse.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/usb/input/usbmouse.c	Wed Jun 18 23:42:09 2003
@@ -207,7 +207,7 @@
 			 (maxp > 8 ? 8 : maxp),
 			 usb_mouse_irq, mouse, endpoint->bInterval);
 	mouse->irq->transfer_dma = mouse->data_dma;
-	mouse->irq->transfer_flags |= URB_NO_DMA_MAP;
+	mouse->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 	input_register_device(&mouse->dev);
 	printk(KERN_INFO "input: %s on %s\n", mouse->name, path);
diff -Nru a/drivers/usb/input/wacom.c b/drivers/usb/input/wacom.c
--- a/drivers/usb/input/wacom.c	Wed Jun 18 23:42:05 2003
+++ b/drivers/usb/input/wacom.c	Wed Jun 18 23:42:05 2003
@@ -590,7 +590,7 @@
 			 wacom->data, wacom->features->pktlen,
 			 wacom->features->irq, wacom, endpoint->bInterval);
 	wacom->irq->transfer_dma = wacom->data_dma;
-	wacom->irq->transfer_flags |= URB_NO_DMA_MAP;
+	wacom->irq->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 	input_register_device(&wacom->dev);
 
diff -Nru a/drivers/usb/input/xpad.c b/drivers/usb/input/xpad.c
--- a/drivers/usb/input/xpad.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/input/xpad.c	Wed Jun 18 23:42:07 2003
@@ -259,7 +259,7 @@
 			 xpad->idata, XPAD_PKT_LEN, xpad_irq_in,
 			 xpad, ep_irq_in->bInterval);
 	xpad->irq_in->transfer_dma = xpad->idata_dma;
-	xpad->irq_in->transfer_flags |= URB_NO_DMA_MAP;
+	xpad->irq_in->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 	
 	xpad->udev = udev;
 	
diff -Nru a/drivers/usb/misc/auerswald.c b/drivers/usb/misc/auerswald.c
--- a/drivers/usb/misc/auerswald.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/misc/auerswald.c	Wed Jun 18 23:42:07 2003
@@ -149,8 +149,8 @@
 /* External data structures / Interface                              */
 typedef struct
 {
-        char *buf;               /* return buffer for string contents */
-        unsigned int bsize;      /* size of return buffer */
+	char __user *buf;	/* return buffer for string contents */
+	unsigned int bsize;	/* size of return buffer */
 } audevinfo_t,*paudevinfo_t;
 
 /* IO controls */
@@ -1548,7 +1548,7 @@
 	/* get a string descriptor for the device */
 	case IOCTL_AU_DEVINFO:
 		dbg ("IOCTL_AU_DEVINFO");
-                if (copy_from_user (&devinfo, (void *) arg, sizeof (audevinfo_t))) {
+                if (copy_from_user (&devinfo, (void __user *) arg, sizeof (audevinfo_t))) {
         		ret = -EFAULT;
 	        	break;
                 }
@@ -1578,7 +1578,7 @@
 }
 
 /* Read data from the device */
-static ssize_t auerchar_read (struct file *file, char *buf, size_t count, loff_t * ppos)
+static ssize_t auerchar_read (struct file *file, char __user *buf, size_t count, loff_t * ppos)
 {
         unsigned long flags;
 	pauerchar_t ccp = (pauerchar_t) file->private_data;
@@ -1708,7 +1708,7 @@
 
 
 /* Write a data block into the right service channel of the device */
-static ssize_t auerchar_write (struct file *file, const char *buf, size_t len, loff_t *ppos)
+static ssize_t auerchar_write (struct file *file, const char __user *buf, size_t len, loff_t *ppos)
 {
 	pauerchar_t ccp = (pauerchar_t) file->private_data;
         pauerswald_t cp = NULL;
diff -Nru a/drivers/usb/misc/brlvger.c b/drivers/usb/misc/brlvger.c
--- a/drivers/usb/misc/brlvger.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/misc/brlvger.c	Wed Jun 18 23:42:07 2003
@@ -109,9 +109,9 @@
 static void brlvger_disconnect(struct usb_interface *intf);
 static int brlvger_open(struct inode *inode, struct file *file);
 static int brlvger_release(struct inode *inode, struct file *file);
-static ssize_t brlvger_write(struct file *file, const char *buffer,
+static ssize_t brlvger_write(struct file *file, const char __user *buffer,
 			     size_t count, loff_t *pos);
-static ssize_t brlvger_read(struct file *file, char *buffer,
+static ssize_t brlvger_read(struct file *file, char __user *buffer,
 			    size_t count, loff_t *unused_pos);
 static int brlvger_ioctl(struct inode *inode, struct file *file,
 			 unsigned cmd, unsigned long arg);
@@ -546,7 +546,7 @@
 }
 
 static ssize_t
-brlvger_write(struct file *file, const char *buffer,
+brlvger_write(struct file *file, const char __user *buffer,
 	      size_t count, loff_t *pos)
 {
 	struct brlvger_priv *priv = file->private_data;
@@ -655,7 +655,7 @@
 }
 
 static ssize_t
-brlvger_read(struct file *file, char *buffer,
+brlvger_read(struct file *file, char __user *buffer,
 	     size_t count, loff_t *unused_pos)
 {
 	struct brlvger_priv *priv = file->private_data;
@@ -719,7 +719,7 @@
 		memcpy(&vi.fwver, priv->fwver, BRLVGER_FWVER_SIZE);
 		memcpy(&vi.serialnum, priv->serialnum, BRLVGER_SERIAL_SIZE);
 
-		if(copy_to_user((void *)arg, &vi, sizeof(vi)))
+		if(copy_to_user((void __user *)arg, &vi, sizeof(vi)))
 			return -EFAULT;
 		return 0;
 	}
diff -Nru a/drivers/usb/misc/rio500.c b/drivers/usb/misc/rio500.c
--- a/drivers/usb/misc/rio500.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/usb/misc/rio500.c	Wed Jun 18 23:42:08 2003
@@ -111,7 +111,7 @@
 {
 	struct RioCommand rio_cmd;
 	struct rio_usb_data *rio = &rio_instance;
-	void *data;
+	void __user *data;
 	unsigned char *buffer;
 	int result, requesttype;
 	int retries;
@@ -129,7 +129,7 @@
 
 	switch (cmd) {
 	case RIO_RECV_COMMAND:
-		data = (void *) arg;
+		data = (void __user *) arg;
 		if (data == NULL)
 			break;
 		if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
@@ -199,7 +199,7 @@
 		break;
 
 	case RIO_SEND_COMMAND:
-		data = (void *) arg;
+		data = (void __user *) arg;
 		if (data == NULL)
 			break;
 		if (copy_from_user(&rio_cmd, data, sizeof(struct RioCommand))) {
@@ -266,7 +266,7 @@
 }
 
 static ssize_t
-write_rio(struct file *file, const char *buffer,
+write_rio(struct file *file, const char __user *buffer,
 	  size_t count, loff_t * ppos)
 {
 	struct rio_usb_data *rio = &rio_instance;
@@ -352,7 +352,7 @@
 }
 
 static ssize_t
-read_rio(struct file *file, char *buffer, size_t count, loff_t * ppos)
+read_rio(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
 {
 	struct rio_usb_data *rio = &rio_instance;
 	ssize_t read_count;
diff -Nru a/drivers/usb/misc/rio500_usb.h b/drivers/usb/misc/rio500_usb.h
--- a/drivers/usb/misc/rio500_usb.h	Wed Jun 18 23:42:06 2003
+++ b/drivers/usb/misc/rio500_usb.h	Wed Jun 18 23:42:06 2003
@@ -32,6 +32,6 @@
 	int requesttype;
 	int value;
 	int index;
-	void *buffer;
+	void __user *buffer;
 	int timeout;
 };
diff -Nru a/drivers/usb/misc/speedtch.c b/drivers/usb/misc/speedtch.c
--- a/drivers/usb/misc/speedtch.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/usb/misc/speedtch.c	Wed Jun 18 23:42:09 2003
@@ -61,6 +61,7 @@
 
 #include <asm/semaphore.h>
 #include <linux/module.h>
+#include <linux/moduleparam.h>
 #include <linux/kernel.h>
 #include <linux/sched.h>
 #include <linux/timer.h>
@@ -102,12 +103,43 @@
 #define SPEEDTOUCH_VENDORID		0x06b9
 #define SPEEDTOUCH_PRODUCTID		0x4061
 
-#define UDSL_NUM_RCV_URBS		1
-#define UDSL_NUM_SND_URBS		1
-#define UDSL_NUM_RCV_BUFS		(2*UDSL_NUM_RCV_URBS)
-#define UDSL_NUM_SND_BUFS		(2*UDSL_NUM_SND_URBS)
-#define UDSL_RCV_BUF_SIZE		32 /* ATM cells */
-#define UDSL_SND_BUF_SIZE		64 /* ATM cells */
+#define UDSL_MAX_RCV_URBS		4
+#define UDSL_MAX_SND_URBS		4
+#define UDSL_MAX_RCV_BUFS		8
+#define UDSL_MAX_SND_BUFS		8
+#define UDSL_MAX_RCV_BUF_SIZE		1024 /* ATM cells */
+#define UDSL_MAX_SND_BUF_SIZE		1024 /* ATM cells */
+#define UDSL_DEFAULT_RCV_URBS		1
+#define UDSL_DEFAULT_SND_URBS		1
+#define UDSL_DEFAULT_RCV_BUFS		2
+#define UDSL_DEFAULT_SND_BUFS		2
+#define UDSL_DEFAULT_RCV_BUF_SIZE	64 /* ATM cells */
+#define UDSL_DEFAULT_SND_BUF_SIZE	64 /* ATM cells */
+
+static unsigned int num_rcv_urbs = UDSL_DEFAULT_RCV_URBS;
+static unsigned int num_snd_urbs = UDSL_DEFAULT_SND_URBS;
+static unsigned int num_rcv_bufs = UDSL_DEFAULT_RCV_BUFS;
+static unsigned int num_snd_bufs = UDSL_DEFAULT_SND_BUFS;
+static unsigned int rcv_buf_size = UDSL_DEFAULT_RCV_BUF_SIZE;
+static unsigned int snd_buf_size = UDSL_DEFAULT_SND_BUF_SIZE;
+
+module_param (num_rcv_urbs, uint, 0444);
+MODULE_PARM_DESC (num_rcv_urbs, "Number of urbs used for reception (range: 0-" __MODULE_STRING (UDSL_MAX_RCV_URBS) ", default: " __MODULE_STRING (UDSL_DEFAULT_RCV_URBS) ")");
+
+module_param (num_snd_urbs, uint, 0444);
+MODULE_PARM_DESC (num_snd_urbs, "Number of urbs used for transmission (range: 0-" __MODULE_STRING (UDSL_MAX_SND_URBS) ", default: " __MODULE_STRING (UDSL_DEFAULT_SND_URBS) ")");
+
+module_param (num_rcv_bufs, uint, 0444);
+MODULE_PARM_DESC (num_rcv_bufs, "Number of buffers used for reception (range: 0-" __MODULE_STRING (UDSL_MAX_RCV_BUFS) ", default: " __MODULE_STRING (UDSL_DEFAULT_RCV_BUFS) ")");
+
+module_param (num_snd_bufs, uint, 0444);
+MODULE_PARM_DESC (num_snd_bufs, "Number of buffers used for transmission (range: 0-" __MODULE_STRING (UDSL_MAX_SND_BUFS) ", default: " __MODULE_STRING (UDSL_DEFAULT_SND_BUFS) ")");
+
+module_param (rcv_buf_size, uint, 0444);
+MODULE_PARM_DESC (rcv_buf_size, "Size of the buffers used for reception (range: 0-" __MODULE_STRING (UDSL_MAX_RCV_BUF_SIZE) ", default: " __MODULE_STRING (UDSL_DEFAULT_RCV_BUF_SIZE) ")");
+
+module_param (snd_buf_size, uint, 0444);
+MODULE_PARM_DESC (snd_buf_size, "Size of the buffers used for transmission (range: 0-" __MODULE_STRING (UDSL_MAX_SND_BUF_SIZE) ", default: " __MODULE_STRING (UDSL_DEFAULT_SND_BUF_SIZE) ")");
 
 #define UDSL_IOCTL_LINE_UP		1
 #define UDSL_IOCTL_LINE_DOWN		2
@@ -196,8 +228,8 @@
 	struct list_head vcc_list;
 
 	/* receive */
-	struct udsl_receiver receivers [UDSL_NUM_RCV_URBS];
-	struct udsl_receive_buffer receive_buffers [UDSL_NUM_RCV_BUFS];
+	struct udsl_receiver receivers [UDSL_MAX_RCV_URBS];
+	struct udsl_receive_buffer receive_buffers [UDSL_MAX_RCV_BUFS];
 
 	spinlock_t receive_lock;
 	struct list_head spare_receivers;
@@ -207,8 +239,8 @@
 	struct list_head spare_receive_buffers;
 
 	/* send */
-	struct udsl_sender senders [UDSL_NUM_SND_URBS];
-	struct udsl_send_buffer send_buffers [UDSL_NUM_SND_BUFS];
+	struct udsl_sender senders [UDSL_MAX_SND_URBS];
+	struct udsl_send_buffer send_buffers [UDSL_MAX_SND_BUFS];
 
 	struct sk_buff_head sndqueue;
 
@@ -503,7 +535,7 @@
 
 	vdbg ("udsl_complete_receive: urb 0x%p, status %d, actual_length %d, filled_cells %u, rcv 0x%p, buf 0x%p", urb, urb->status, urb->actual_length, buf->filled_cells, rcv, buf);
 
-	BUG_ON (buf->filled_cells > UDSL_RCV_BUF_SIZE);
+	BUG_ON (buf->filled_cells > rcv_buf_size);
 
 	/* may not be in_interrupt() */
 	spin_lock_irqsave (&instance->receive_lock, flags);
@@ -541,7 +573,7 @@
 				   instance->usb_dev,
 				   usb_rcvbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_IN),
 				   buf->base,
-				   UDSL_RCV_BUF_SIZE * ATM_CELL_SIZE,
+				   rcv_buf_size * ATM_CELL_SIZE,
 				   udsl_complete_receive,
 				   rcv);
 
@@ -626,11 +658,11 @@
 				   instance->usb_dev,
 				   usb_sndbulkpipe (instance->usb_dev, UDSL_ENDPOINT_DATA_OUT),
 				   buf->base,
-				   (UDSL_SND_BUF_SIZE - buf->free_cells) * ATM_CELL_SIZE,
+				   (snd_buf_size - buf->free_cells) * ATM_CELL_SIZE,
 				   udsl_complete_send,
 				   snd);
 
-		vdbg ("udsl_process_send: submitting urb 0x%p (%d cells), snd 0x%p, buf 0x%p", snd->urb, UDSL_SND_BUF_SIZE - buf->free_cells, snd, buf);
+		vdbg ("udsl_process_send: submitting urb 0x%p (%d cells), snd 0x%p, buf 0x%p", snd->urb, snd_buf_size - buf->free_cells, snd, buf);
 
 		if ((err = usb_submit_urb(snd->urb, GFP_ATOMIC)) < 0) {
 			dbg ("udsl_process_send: urb submission failed (%d)!", err);
@@ -662,7 +694,7 @@
 		spin_unlock_irq (&instance->send_lock);
 
 		buf->free_start = buf->base;
-		buf->free_cells = UDSL_SND_BUF_SIZE;
+		buf->free_cells = snd_buf_size;
 
 		instance->current_buffer = buf;
 	}
@@ -676,7 +708,7 @@
 		instance->current_buffer = NULL;
 	}
 
-	vdbg ("udsl_process_send: buffer contains %d cells, %d left", UDSL_SND_BUF_SIZE - buf->free_cells, buf->free_cells);
+	vdbg ("udsl_process_send: buffer contains %d cells, %d left", snd_buf_size - buf->free_cells, buf->free_cells);
 
 	if (!UDSL_SKB (skb)->num_cells) {
 		struct atm_vcc *vcc = UDSL_SKB (skb)->atm_data.vcc;
@@ -1039,7 +1071,7 @@
 	INIT_LIST_HEAD (&instance->filled_send_buffers);
 
 	/* receive init */
-	for (i = 0; i < UDSL_NUM_RCV_URBS; i++) {
+	for (i = 0; i < num_rcv_urbs; i++) {
 		struct udsl_receiver *rcv = &(instance->receivers [i]);
 
 		if (!(rcv->urb = usb_alloc_urb (0, GFP_KERNEL))) {
@@ -1052,10 +1084,10 @@
 		list_add (&rcv->list, &instance->spare_receivers);
 	}
 
-	for (i = 0; i < UDSL_NUM_RCV_BUFS; i++) {
+	for (i = 0; i < num_rcv_bufs; i++) {
 		struct udsl_receive_buffer *buf = &(instance->receive_buffers [i]);
 
-		if (!(buf->base = kmalloc (UDSL_RCV_BUF_SIZE * ATM_CELL_SIZE, GFP_KERNEL))) {
+		if (!(buf->base = kmalloc (rcv_buf_size * ATM_CELL_SIZE, GFP_KERNEL))) {
 			dbg ("udsl_usb_probe: no memory for receive buffer %d!", i);
 			goto fail;
 		}
@@ -1064,7 +1096,7 @@
 	}
 
 	/* send init */
-	for (i = 0; i < UDSL_NUM_SND_URBS; i++) {
+	for (i = 0; i < num_snd_urbs; i++) {
 		struct udsl_sender *snd = &(instance->senders [i]);
 
 		if (!(snd->urb = usb_alloc_urb (0, GFP_KERNEL))) {
@@ -1077,10 +1109,10 @@
 		list_add (&snd->list, &instance->spare_senders);
 	}
 
-	for (i = 0; i < UDSL_NUM_SND_BUFS; i++) {
+	for (i = 0; i < num_snd_bufs; i++) {
 		struct udsl_send_buffer *buf = &(instance->send_buffers [i]);
 
-		if (!(buf->base = kmalloc (UDSL_SND_BUF_SIZE * ATM_CELL_SIZE, GFP_KERNEL))) {
+		if (!(buf->base = kmalloc (snd_buf_size * ATM_CELL_SIZE, GFP_KERNEL))) {
 			dbg ("udsl_usb_probe: no memory for send buffer %d!", i);
 			goto fail;
 		}
@@ -1139,16 +1171,16 @@
 	return 0;
 
 fail:
-	for (i = 0; i < UDSL_NUM_SND_BUFS; i++)
+	for (i = 0; i < num_snd_bufs; i++)
 		kfree (instance->send_buffers [i].base);
 
-	for (i = 0; i < UDSL_NUM_SND_URBS; i++)
+	for (i = 0; i < num_snd_urbs; i++)
 		usb_free_urb (instance->senders [i].urb);
 
-	for (i = 0; i < UDSL_NUM_RCV_BUFS; i++)
+	for (i = 0; i < num_rcv_bufs; i++)
 		kfree (instance->receive_buffers [i].base);
 
-	for (i = 0; i < UDSL_NUM_RCV_URBS; i++)
+	for (i = 0; i < num_rcv_urbs; i++)
 		usb_free_urb (instance->receivers [i].urb);
 
 	kfree (instance);
@@ -1175,7 +1207,7 @@
 	/* receive finalize */
 	tasklet_disable (&instance->receive_tasklet);
 
-	for (i = 0; i < UDSL_NUM_RCV_URBS; i++)
+	for (i = 0; i < num_rcv_urbs; i++)
 		if ((result = usb_unlink_urb (instance->receivers [i].urb)) < 0)
 			dbg ("udsl_usb_disconnect: usb_unlink_urb on receive urb %d returned %d", i, result);
 
@@ -1184,13 +1216,13 @@
 		count = 0;
 		spin_lock_irq (&instance->receive_lock);
 		list_for_each (pos, &instance->spare_receivers)
-			if (++count > UDSL_NUM_RCV_URBS)
+			if (++count > num_rcv_urbs)
 				panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
 		spin_unlock_irq (&instance->receive_lock);
 
 		dbg ("udsl_usb_disconnect: found %u spare receivers", count);
 
-		if (count == UDSL_NUM_RCV_URBS)
+		if (count == num_rcv_urbs)
 			break;
 
 		set_current_state (TASK_RUNNING);
@@ -1203,16 +1235,16 @@
 
 	tasklet_enable (&instance->receive_tasklet);
 
-	for (i = 0; i < UDSL_NUM_RCV_URBS; i++)
+	for (i = 0; i < num_rcv_urbs; i++)
 		usb_free_urb (instance->receivers [i].urb);
 
-	for (i = 0; i < UDSL_NUM_RCV_BUFS; i++)
+	for (i = 0; i < num_rcv_bufs; i++)
 		kfree (instance->receive_buffers [i].base);
 
 	/* send finalize */
 	tasklet_disable (&instance->send_tasklet);
 
-	for (i = 0; i < UDSL_NUM_SND_URBS; i++)
+	for (i = 0; i < num_snd_urbs; i++)
 		if ((result = usb_unlink_urb (instance->senders [i].urb)) < 0)
 			dbg ("udsl_usb_disconnect: usb_unlink_urb on send urb %d returned %d", i, result);
 
@@ -1221,13 +1253,13 @@
 		count = 0;
 		spin_lock_irq (&instance->send_lock);
 		list_for_each (pos, &instance->spare_senders)
-			if (++count > UDSL_NUM_SND_URBS)
+			if (++count > num_snd_urbs)
 				panic (__FILE__ ": memory corruption detected at line %d!\n", __LINE__);
 		spin_unlock_irq (&instance->send_lock);
 
 		dbg ("udsl_usb_disconnect: found %u spare senders", count);
 
-		if (count == UDSL_NUM_SND_URBS)
+		if (count == num_snd_urbs)
 			break;
 
 		set_current_state (TASK_RUNNING);
@@ -1241,10 +1273,10 @@
 
 	tasklet_enable (&instance->send_tasklet);
 
-	for (i = 0; i < UDSL_NUM_SND_URBS; i++)
+	for (i = 0; i < num_snd_urbs; i++)
 		usb_free_urb (instance->senders [i].urb);
 
-	for (i = 0; i < UDSL_NUM_SND_BUFS; i++)
+	for (i = 0; i < num_snd_bufs; i++)
 		kfree (instance->send_buffers [i].base);
 
 	wmb ();
@@ -1269,6 +1301,11 @@
 		printk (KERN_ERR __FILE__ ": unusable with this kernel!\n");
 		return -EIO;
 	}
+
+	if ((num_rcv_urbs > UDSL_MAX_RCV_URBS) || (num_snd_urbs > UDSL_MAX_SND_URBS) ||
+	    (num_rcv_bufs > UDSL_MAX_RCV_BUFS) || (num_snd_bufs > UDSL_MAX_SND_BUFS) ||
+	    (rcv_buf_size > UDSL_MAX_RCV_BUF_SIZE) || (snd_buf_size > UDSL_MAX_SND_BUF_SIZE))
+		return -EINVAL;
 
 	return usb_register (&udsl_usb_driver);
 }
diff -Nru a/drivers/usb/misc/tiglusb.c b/drivers/usb/misc/tiglusb.c
--- a/drivers/usb/misc/tiglusb.c	Wed Jun 18 23:42:05 2003
+++ b/drivers/usb/misc/tiglusb.c	Wed Jun 18 23:42:05 2003
@@ -155,7 +155,7 @@
 }
 
 static ssize_t
-tiglusb_read (struct file *filp, char *buf, size_t count, loff_t * f_pos)
+tiglusb_read (struct file *filp, char __user *buf, size_t count, loff_t * f_pos)
 {
 	ptiglusb_t s = (ptiglusb_t) filp->private_data;
 	ssize_t ret = 0;
@@ -208,7 +208,7 @@
 }
 
 static ssize_t
-tiglusb_write (struct file *filp, const char *buf, size_t count, loff_t * f_pos)
+tiglusb_write (struct file *filp, const char __user *buf, size_t count, loff_t * f_pos)
 {
 	ptiglusb_t s = (ptiglusb_t) filp->private_data;
 	ssize_t ret = 0;
diff -Nru a/drivers/usb/misc/usblcd.c b/drivers/usb/misc/usblcd.c
--- a/drivers/usb/misc/usblcd.c	Wed Jun 18 23:42:05 2003
+++ b/drivers/usb/misc/usblcd.c	Wed Jun 18 23:42:05 2003
@@ -88,12 +88,12 @@
 		i = (lcd->lcd_dev)->descriptor.bcdDevice;
 		sprintf(buf,"%1d%1d.%1d%1d",(i & 0xF000)>>12,(i & 0xF00)>>8,
 			(i & 0xF0)>>4,(i & 0xF));
-		if (copy_to_user((void *)arg,buf,strlen(buf))!=0)
+		if (copy_to_user((void __user *)arg,buf,strlen(buf))!=0)
 			return -EFAULT;
 		break;
 	case IOCTL_GET_DRV_VERSION:
 		sprintf(buf,DRIVER_VERSION);
-		if (copy_to_user((void *)arg,buf,strlen(buf))!=0)
+		if (copy_to_user((void __user *)arg,buf,strlen(buf))!=0)
 			return -EFAULT;
 		break;
 	default:
@@ -105,7 +105,7 @@
 }
 
 static ssize_t
-write_lcd(struct file *file, const char *buffer,
+write_lcd(struct file *file, const char __user *buffer,
 	  size_t count, loff_t * ppos)
 {
 	struct lcd_usb_data *lcd = &lcd_instance;
@@ -171,7 +171,7 @@
 }
 
 static ssize_t
-read_lcd(struct file *file, char *buffer, size_t count, loff_t * ppos)
+read_lcd(struct file *file, char __user *buffer, size_t count, loff_t * ppos)
 {
 	struct lcd_usb_data *lcd = &lcd_instance;
 	ssize_t read_count;
diff -Nru a/drivers/usb/misc/usbtest.c b/drivers/usb/misc/usbtest.c
--- a/drivers/usb/misc/usbtest.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/usb/misc/usbtest.c	Wed Jun 18 23:42:09 2003
@@ -107,7 +107,7 @@
 	urb->interval = (udev->speed == USB_SPEED_HIGH)
 			? (INTERRUPT_RATE << 3)
 			: INTERRUPT_RATE;
-	urb->transfer_flags = URB_NO_DMA_MAP;
+	urb->transfer_flags = URB_NO_TRANSFER_DMA_MAP;
 	if (usb_pipein (pipe))
 		urb->transfer_flags |= URB_SHORT_NOT_OK;
 	urb->transfer_buffer = usb_buffer_alloc (udev, bytes, SLAB_KERNEL,
diff -Nru a/drivers/usb/net/Kconfig b/drivers/usb/net/Kconfig
--- a/drivers/usb/net/Kconfig	Wed Jun 18 23:42:08 2003
+++ b/drivers/usb/net/Kconfig	Wed Jun 18 23:42:08 2003
@@ -7,6 +7,27 @@
 comment "Networking support is needed for USB Networking device support"
 	depends on USB && !NET
 
+config USB_AX8817X
+	tristate "USB ASIX AX8817X Ethernet device support (EXPERIMENTAL)"
+	depends on USB && NET && EXPERIMENTAL
+	---help---
+	  Say Y if you want to use one of the following 10/100Mps USB
+	  Ethernet devices based on the ASIX AX88172 chip.  Supported
+	  devices are:
+		ASIX AX88172
+		D-Link DUB-E100
+		Hawking UF200
+		Netgear FA120
+
+	  This driver makes the adapter appear as a normal Ethernet interface,
+	  typically on eth0, if it is the only ethernet device, or perhaps on
+	  eth1, if you have a PCI or ISA ethernet card installed.
+
+	  This code is also available as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want).
+	  The module will be called ax8817x.o. If you want to compile it as a
+	  module, say M here and read <file:Documentation/modules.txt>.
+
 config USB_CATC
 	tristate "USB CATC NetMate-based Ethernet device support (EXPERIMENTAL)"
 	depends on USB && NET && EXPERIMENTAL
@@ -191,7 +212,8 @@
 	help
 	  Choose this option to support the "usb-eth" networking driver
 	  used by most of the ARM Linux community with device controllers
-	  such as the SA-11x0 and PXA-25x UDCs.
+	  such as the SA-11x0 and PXA-25x UDCs, or the tftp capabilities
+	  in some PXA versions of the "blob" boot loader.
 
 	  Although the ROMs shipped with Sharp Zaurus products use a
 	  different link level framing protocol, you can have them use
diff -Nru a/drivers/usb/net/Makefile b/drivers/usb/net/Makefile
--- a/drivers/usb/net/Makefile	Wed Jun 18 23:42:05 2003
+++ b/drivers/usb/net/Makefile	Wed Jun 18 23:42:05 2003
@@ -2,6 +2,7 @@
 # Makefile for USB Network drivers
 #
 
+obj-$(CONFIG_USB_AX8817X)	+= ax8817x.o
 obj-$(CONFIG_USB_CATC)		+= catc.o
 obj-$(CONFIG_USB_KAWETH)	+= kaweth.o
 obj-$(CONFIG_USB_PEGASUS)	+= pegasus.o
diff -Nru a/drivers/usb/net/Makefile.mii b/drivers/usb/net/Makefile.mii
--- a/drivers/usb/net/Makefile.mii	Wed Jun 18 23:42:08 2003
+++ b/drivers/usb/net/Makefile.mii	Wed Jun 18 23:42:08 2003
@@ -2,4 +2,5 @@
 # Makefile for USB Network drivers which require generic MII code.
 #
 
+obj-$(CONFIG_USB_AX8817X)	+= mii.o
 obj-$(CONFIG_USB_PEGASUS)	+= mii.o
diff -Nru a/drivers/usb/net/ax8817x.c b/drivers/usb/net/ax8817x.c
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/drivers/usb/net/ax8817x.c	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,1341 @@
+/*
+ * ASIX AX8817x USB 2.0 10/100/HomePNA Ethernet controller driver
+ *
+ * $Id: ax8817x.c,v 1.11 2003/06/15 19:00:02 dhollis Exp $
+ *
+ * Copyright (c) 2002-2003 TiVo Inc.
+ *
+ * This software may be used and distributed according to the terms
+ * of the GNU General Public License, incorporated herein by reference.
+ *
+ * History 
+ *
+ *	2003-06-15 - Dave Hollis <dhollis@davehollis.com>  2.0.0
+ *		* Remove crc32 inline function, use core kernel instead
+ *		* Set sane defaults for rx_buffers
+ *		* Fix ethtool GETDRVINFO bits - use strlcpy and
+ *		  usb_make_path
+ *
+ *	2003-06-05 - Dave Hollis <dhollis@davehollis.com>  0.10.0
+ *		* Port to 2.5 series kernels
+ *		* Remove #if 0 blocks that are confirmed
+ *		  unnecessary
+ *		* Re-did tx routines based off pegasus driver.
+ *		  This resolved hard crashes and greatly simplified
+ *		  things.
+ *		* Redo mii/ethtool routines
+ *
+ *	2003-05-31 - Dave Hollis <dhollis@davehollis.com>  0.9.8
+ *		* Don't stop/start the queue in start_xmit
+ *		* Swallow URB status upon hard removal
+ *		* Cleanup remaining comments (kill // style)
+ *
+ *	2003-05-29 - Dave Hollis <dhollis@davehollis.com>  0.9.7
+ *		* Set module owner
+ *		* Follow-up on suggestions from David Brownell &
+ *		  Oliver Neukum which should help with robustness
+ *		* Use ether_crc from stock kernel if available
+ *
+ *	2003-05-28 - Dave Hollis <dhollis@davehollis.com>  0.9.6
+ *		* Added basic ethtool & mii support
+ *
+ *	2003-05-28 - Dave Hollis <dhollis@davehollis.com>  0.9.5
+ *		* Workout devrequest change to usb_ctrlrequest structure
+ *		* Replace FILL_BULK_URB macros to non-deprecated 
+ *		  usb_fill_bulk_urb macros
+ *		* Replace printks with equivalent macros
+ *		* Use defines for module description, version, author to
+ *		  simplify future changes
+ *
+ * Known Issues
+ *
+ * Todo
+ *	Fix mii/ethtool output
+*/
+
+#include <linux/slab.h>
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/usb.h>
+
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/ethtool.h>
+#include <linux/skbuff.h>
+#include <linux/mii.h>
+#include <linux/crc32.h>
+#include <asm/uaccess.h>
+#include <linux/version.h>
+
+/* Version Information */
+#define DRIVER_VERSION "v2.0.0"
+#define DRIVER_AUTHOR "TiVo, Inc."
+#define DRIVER_DESC "ASIX AX8817x USB Ethernet driver"
+#define DRIVER_NAME "ax8817x"
+
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_LICENSE("GPL");
+
+#define AX_REQ_READ         ( USB_DIR_IN | USB_TYPE_VENDOR | USB_RECIP_DEVICE )
+#define AX_REQ_WRITE        ( USB_DIR_OUT | USB_TYPE_VENDOR | USB_RECIP_DEVICE )
+
+#define AX_CMD_SET_SW_MII           0x06
+#define AX_CMD_READ_MII_REG         0x07
+#define AX_CMD_WRITE_MII_REG        0x08
+#define AX_CMD_SET_HW_MII           0x0a
+#define AX_CMD_WRITE_RX_CTL         0x10
+#define AX_CMD_WRITE_MULTI_FILTER   0x16
+#define AX_CMD_READ_NODE_ID         0x17
+#define AX_CMD_READ_PHY_ID          0x19
+#define AX_CMD_WRITE_MEDIUM_MODE    0x1b
+#define AX_CMD_WRITE_GPIOS          0x1f
+
+#define AX_RX_MAX                   ETH_FRAME_LEN
+#define AX_TIMEOUT_CMD              ( HZ / 10 )
+#define AX_TIMEOUT_TX               ( HZ * 2 )
+#define AX_MAX_MCAST                64
+
+#define AX_DRV_STATE_INITIALIZING   0x00
+#define AX_DRV_STATE_RUNNING        0x01
+#define AX_DRV_STATE_EXITING        0x02
+
+#define AX_PHY_STATE_INITIALIZING   0x00
+#define AX_PHY_STATE_NO_LINK        0x01
+#define AX_PHY_STATE_POLLING_1      0x02
+#define AX_PHY_STATE_POLLING_2      0x03
+#define AX_PHY_STATE_POLLING_3      0x04
+#define AX_PHY_STATE_POLLING_4      0x05
+#define AX_PHY_STATE_SETTING_MAC    0x06
+#define AX_PHY_STATE_LINK           0x07
+#define AX_PHY_STATE_ABORT_POLL     0x08
+#define AX_PHY_STATE_ABORTING       0x09
+
+#define AX_MAX_PHY_RETRY            50
+
+#define AX_RX_URBS_DEFAULT	    2
+
+static int n_rx_urbs = AX_RX_URBS_DEFAULT;
+
+MODULE_PARM(n_rx_urbs, "i");
+MODULE_PARM_DESC(n_rx_urbs,
+		 "Number of rx buffers to queue at once (def 2)");
+
+struct ax8817x_info;
+struct ax_cmd_req;
+typedef int (*ax_cmd_callback_t) (struct ax8817x_info *,
+				  struct ax_cmd_req *);
+
+struct ax_cmd_req {
+	struct list_head list;
+	ax_cmd_callback_t cmd_callback;
+	void *priv;
+	int status;
+	void *data;
+	int data_size;
+	int timeout;
+	struct usb_ctrlrequest devreq;
+};
+
+struct ax8817x_info {
+	struct usb_device *usb;
+	struct net_device *net;
+	struct net_device_stats stats;
+	struct mii_if_info mii;
+	struct urb **rx_urbs;
+	struct urb *int_urb;
+	struct urb *tx_urb;
+	u8 *int_buf;
+	struct urb *ctl_urb;
+	struct list_head ctl_queue;
+	spinlock_t ctl_lock;
+	atomic_t rx_refill_cnt;
+	struct ax_cmd_req phy_req;
+	u8 phy_id;
+	u8 phy_state;
+	u8 drv_state;
+};
+
+
+const struct usb_device_id ax8817x_id_table[] __devinitdata = {
+	/* Linksys USB200M */
+      {USB_DEVICE(0x077b, 0x2226), driver_info:0x00130103},
+	/* Hawking UF200, TRENDnet TU2-ET100 */
+      {USB_DEVICE(0x07b8, 0x420a), driver_info:0x001f1d1f},
+	/* NETGEAR FA120 */
+      {USB_DEVICE(0x0846, 0x1040), driver_info:0x00130103},
+	/* D-Link DUB-E100 */
+      {USB_DEVICE(0x2001, 0x1a00), driver_info:0x009f9d9f},
+
+	{}
+};
+
+MODULE_DEVICE_TABLE(usb, ax8817x_id_table);
+
+
+static void ax_run_ctl_queue(struct ax8817x_info *, struct ax_cmd_req *,
+			     int);
+static void ax_rx_callback(struct urb *, struct pt_regs *);
+
+static void ax_ctl_callback(struct urb *urb, struct pt_regs *regs)
+{
+	struct ax8817x_info *ax_info =
+	    (struct ax8817x_info *) urb->context;
+
+	ax_run_ctl_queue(ax_info, NULL,
+			 urb->status ? urb->status : urb->actual_length);
+}
+
+/* 
+ * Queue a new ctl request, or dequeue the first in the list
+*/
+static void ax_run_ctl_queue(struct ax8817x_info *ax_info,
+			     struct ax_cmd_req *req, int status)
+{
+	struct ax_cmd_req *next_req = NULL;
+	struct ax_cmd_req *last_req = NULL;
+	unsigned long flags;
+
+	/* Need to lock around queue list manipulation */
+	spin_lock_irqsave(&ax_info->ctl_lock, flags);
+
+	if (req == NULL) {
+		last_req =
+		    list_entry(ax_info->ctl_queue.next, struct ax_cmd_req,
+			       list);
+	} else {
+		if (list_empty(&ax_info->ctl_queue)) {
+			next_req = req;
+		}
+
+		req->status = -EINPROGRESS;
+		list_add_tail(&req->list, &ax_info->ctl_queue);
+	}
+
+	while (1) {
+		if (last_req != NULL) {
+			/* dequeue completed entry */
+			list_del(&last_req->list);
+
+			last_req->status = status;
+			if (last_req->cmd_callback(ax_info, last_req)) {
+				/* requeue if told to do so */
+				last_req->status = -EINPROGRESS;
+				list_add_tail(&last_req->list,
+					      &ax_info->ctl_queue);
+			}
+
+			if (list_empty(&ax_info->ctl_queue)) {
+				next_req = NULL;
+			} else {
+				next_req =
+				    list_entry(ax_info->ctl_queue.next,
+					       struct ax_cmd_req, list);
+			}
+		}
+
+		spin_unlock_irqrestore(&ax_info->ctl_lock, flags);
+
+		if (next_req == NULL) {
+			break;
+		}
+
+		/* XXX: do something with timeout */
+		usb_fill_control_urb(ax_info->ctl_urb, ax_info->usb,
+				     next_req->devreq.
+				     bRequestType & USB_DIR_IN ?
+				     usb_rcvctrlpipe(ax_info->usb,
+						     0) :
+				     usb_sndctrlpipe(ax_info->usb, 0),
+				     (void *) &next_req->devreq,
+				     next_req->data, next_req->data_size,
+				     ax_ctl_callback, ax_info);
+
+		status = usb_submit_urb(ax_info->ctl_urb, GFP_ATOMIC);
+		if (status >= 0) {
+			break;
+		}
+
+		last_req = next_req;
+
+		spin_lock_irqsave(&ax_info->ctl_lock, flags);
+	}
+}
+
+static int ax_sync_cmd_callback(struct ax8817x_info *unused,
+				struct ax_cmd_req *req)
+{
+	wait_queue_head_t *wq = (wait_queue_head_t *) req->priv;
+
+	wake_up(wq);
+
+	return 0;
+}
+
+static int ax_async_cmd_callback(struct ax8817x_info *unused,
+				 struct ax_cmd_req *req)
+{
+	if (req->status < 0) {
+		err("%s: Async command %d failed: %d\n", __FUNCTION__,
+		    req->devreq.bRequest, req->status);
+	}
+
+	/* Nothing else to do here, just need to free the request (and its
+	   allocated data) */
+	if (req->data != NULL) {
+		kfree(req->data);
+	}
+	kfree(req);
+
+	return 0;
+}
+
+/*
+ * This is mostly the same as usb_control_msg(), except that it is able
+ * to queue control messages
+*/
+static int ax_control_msg(struct ax8817x_info *ax_info, u8 requesttype,
+			  u8 request, u16 value, u16 index, void *data,
+			  u16 size, int timeout)
+{
+	struct ax_cmd_req *req;
+	DECLARE_WAIT_QUEUE_HEAD(wq);
+	DECLARE_WAITQUEUE(wait, current);
+	int ret;
+
+	req = kmalloc(sizeof(struct ax_cmd_req), GFP_KERNEL);
+	if (req == NULL) {
+		return -ENOMEM;
+	}
+
+	req->devreq.bRequestType = requesttype;
+	req->devreq.bRequest = request;
+	req->devreq.wValue = cpu_to_le16(value);
+	req->devreq.wIndex = cpu_to_le16(index);
+	req->devreq.wLength = cpu_to_le16(size);
+	req->data = data;
+	req->data_size = size;
+	req->timeout = timeout;
+
+	req->priv = &wq;
+	set_current_state(TASK_UNINTERRUPTIBLE);
+	add_wait_queue(&wq, &wait);
+
+	req->cmd_callback = ax_sync_cmd_callback;
+
+	ax_run_ctl_queue(ax_info, req, 0);
+	schedule();
+
+	ret = req->status;
+
+	kfree(req);
+
+	return ret;
+}
+
+/*
+ * Same, but can be used asynchronously, may fail, and returns no exit
+ * status
+*/
+static void ax_control_msg_async(struct ax8817x_info *ax_info,
+				 u8 requesttype, u8 request, u16 value,
+				 u16 index, void *data, u16 size,
+				 int timeout)
+{
+	struct ax_cmd_req *req;
+
+	req = kmalloc(sizeof(struct ax_cmd_req), GFP_ATOMIC);
+	if (req == NULL) {
+		/* There's not much else we can do here... */
+		err("%s: Failed alloc\n", __FUNCTION__);
+		return;
+	}
+
+	req->devreq.bRequestType = requesttype;
+	req->devreq.bRequest = request;
+	req->devreq.wValue = cpu_to_le16(value);
+	req->devreq.wIndex = cpu_to_le16(index);
+	req->devreq.wLength = cpu_to_le16(size);
+	req->data = data;
+	req->data_size = size;
+	req->timeout = timeout;
+
+	req->cmd_callback = ax_async_cmd_callback;
+
+	ax_run_ctl_queue(ax_info, req, 0);
+}
+
+static inline int ax_read_cmd(struct ax8817x_info *ax_info, u8 cmd,
+			      u16 value, u16 index, u16 size, void *data)
+{
+	return ax_control_msg(ax_info, AX_REQ_READ, cmd, value, index,
+			      data, size, AX_TIMEOUT_CMD);
+}
+
+static inline int ax_write_cmd(struct ax8817x_info *ax_info, u8 cmd,
+			       u16 value, u16 index, u16 size, void *data)
+{
+	return ax_control_msg(ax_info, AX_REQ_WRITE, cmd, value, index,
+			      data, size, AX_TIMEOUT_CMD);
+}
+
+static inline void ax_write_cmd_async(struct ax8817x_info *ax_info, u8 cmd,
+				      u16 value, u16 index, u16 size,
+				      void *data)
+{
+	ax_control_msg_async(ax_info, AX_REQ_WRITE, cmd, value, index,
+			     data, size, AX_TIMEOUT_CMD);
+}
+
+static int ax_refill_rx_urb(struct ax8817x_info *ax_info, struct urb *urb)
+{
+	struct sk_buff *skb;
+	int ret;
+
+	skb = dev_alloc_skb(AX_RX_MAX + 2);
+	if (skb != NULL) {
+		skb_reserve(skb, 2);	/* for IP header alignment */
+		skb->dev = ax_info->net;
+
+		usb_fill_bulk_urb(urb, ax_info->usb,
+				  usb_rcvbulkpipe(ax_info->usb, 3),
+				  skb->data, AX_RX_MAX, ax_rx_callback,
+				  skb);
+
+		ret = usb_submit_urb(urb, GFP_ATOMIC);
+		if (ret < 0) {
+			err("Failed submit rx URB (%d)\n", ret);
+			dev_kfree_skb_irq(skb);
+			urb->context = NULL;
+		} else {
+			ret = 0;
+		}
+	} else {
+		/* this just means we're low on memory at the moment. Try to
+		   handle it gracefully. */
+		urb->context = NULL;
+		ret = 1;
+	}
+
+	return ret;
+}
+
+static int ax_phy_cmd_callback(struct ax8817x_info *ax_info,
+			       struct ax_cmd_req *req)
+{
+	int full_duplex;
+	int flow_control;
+	u16 mii_data_le;
+
+	if (req->status < 0) {
+		err("%s: Failed at state %d: %d\n", __FUNCTION__,
+		    ax_info->phy_state, req->status);
+		/* Not sure what else we can do, so just bail */
+		ax_info->phy_state = AX_PHY_STATE_ABORTING;
+	}
+
+	switch (ax_info->phy_state) {
+		/* Now that we're in software MII mode, read the BMSR */
+	case AX_PHY_STATE_POLLING_1:
+		ax_info->phy_state = AX_PHY_STATE_POLLING_2;
+		req->devreq.bRequestType = AX_REQ_READ;
+		req->devreq.bRequest = AX_CMD_READ_MII_REG;
+		req->devreq.wValue = cpu_to_le16(ax_info->phy_id);
+		req->devreq.wIndex = cpu_to_le16(MII_BMSR);
+		req->devreq.wLength = cpu_to_le16(2);
+		req->data_size = 2;
+		req->priv = 0;	/* This is the retry count */
+		return 1;
+
+		/* Done reading BMSR */
+	case AX_PHY_STATE_POLLING_2:
+		mii_data_le = *(u16 *) req->data;
+		if ((mii_data_le &
+		     cpu_to_le16(BMSR_LSTATUS | BMSR_ANEGCAPABLE))
+		    == cpu_to_le16(BMSR_LSTATUS | BMSR_ANEGCAPABLE)) {
+			if (mii_data_le & cpu_to_le16(BMSR_ANEGCOMPLETE)) {
+				/* Autonegotiation done, go on to read LPA */
+				ax_info->phy_state =
+				    AX_PHY_STATE_POLLING_3;
+				req->devreq.wIndex = cpu_to_le16(MII_LPA);
+				return 1;
+			} else if ((long) req->priv++ < AX_MAX_PHY_RETRY) {
+				/* Reread BMSR if it's still autonegotiating. This is
+				   probably unnecessary logic, I've never seen it take
+				   more than 1 try... */
+				return 1;
+			}
+			/* else fall through to abort */
+		}
+		/* XXX: should probably handle auto-neg failure better,
+		   by reverting to manual setting of something safe. (?) */
+
+		ax_info->phy_state = AX_PHY_STATE_ABORT_POLL;
+		/* and then fall through to set hw MII */
+
+		/* Got what we needed from PHY, set back to hardware MII mode
+		   (Do same for abort in mid-poll) */
+	case AX_PHY_STATE_POLLING_3:
+	case AX_PHY_STATE_ABORT_POLL:
+		ax_info->phy_state += 1;
+		req->devreq.bRequestType = AX_REQ_WRITE;
+		req->devreq.bRequest = AX_CMD_SET_HW_MII;
+		req->devreq.wValue = cpu_to_le16(0);
+		req->devreq.wIndex = cpu_to_le16(0);
+		req->devreq.wLength = cpu_to_le16(0);
+		req->data_size = 0;
+		return 1;
+
+		/* The end result, set the right duplex and flow control mode in the
+		   MAC (based on the PHY's LPA reg, which should still be in the data
+		   buffer) */
+	case AX_PHY_STATE_POLLING_4:
+		mii_data_le = *(u16 *) req->data;
+		ax_info->phy_state = AX_PHY_STATE_SETTING_MAC;
+		req->devreq.bRequest = AX_CMD_WRITE_MEDIUM_MODE;
+		full_duplex = mii_data_le & cpu_to_le16(LPA_DUPLEX);
+		flow_control = full_duplex &&
+		    (mii_data_le & cpu_to_le16(0x0400));
+		req->devreq.wValue = cpu_to_le16(0x04) |
+		    (full_duplex ? cpu_to_le16(0x02) : 0) |
+		    (flow_control ? cpu_to_le16(0x10) : 0);
+		info("%s: Link established, %s duplex, flow control %sabled\n", ax_info->net->name, full_duplex ? "full" : "half", flow_control ? "en" : "dis");
+		return 1;
+
+		/* All done */
+	case AX_PHY_STATE_SETTING_MAC:
+		ax_info->phy_state = AX_PHY_STATE_LINK;
+		netif_carrier_on(ax_info->net);
+		return 0;
+
+	default:
+		err("%s: Unknown state %d\n", __FUNCTION__,
+		    ax_info->phy_state);
+		/* fall through */
+	case AX_PHY_STATE_ABORTING:
+		ax_info->phy_state = AX_PHY_STATE_NO_LINK;
+		return 0;
+	}
+}
+
+static void ax_int_callback(struct urb *urb, struct pt_regs *regs)
+{
+	struct ax8817x_info *ax_info =
+	    (struct ax8817x_info *) urb->context;
+	u8 phy_link;
+
+	if (ax_info->drv_state == AX_DRV_STATE_EXITING ||
+	    urb->actual_length < 3) {
+		return;
+	}
+
+	/* Ignore the first PHY link report, it will sometimes be reported as
+	   link active, even though we just told the PHY to reset. If it
+	   really has link, we'll pick it up next int callback.
+	 */
+	if (ax_info->phy_state == AX_PHY_STATE_INITIALIZING) {
+		netif_carrier_off(ax_info->net);
+		ax_info->phy_state = AX_PHY_STATE_NO_LINK;
+		return;
+	}
+
+	/* Assume we're only interested in the primary PHY for now. */
+	phy_link = ax_info->int_buf[2] & 1;
+
+	if (phy_link ==
+	    (ax_info->phy_state == AX_PHY_STATE_NO_LINK) ? 0 : 1) {
+		/* Common case, no change */
+		return;
+	}
+
+	if (phy_link == 0) {
+		netif_carrier_off(ax_info->net);
+		/* Abort an in-progress poll of the PHY if necessary */
+		switch (ax_info->phy_state) {
+		case AX_PHY_STATE_POLLING_1:
+		case AX_PHY_STATE_POLLING_2:
+		case AX_PHY_STATE_POLLING_3:
+			ax_info->phy_state = AX_PHY_STATE_ABORT_POLL;
+			break;
+
+		case AX_PHY_STATE_POLLING_4:
+		case AX_PHY_STATE_SETTING_MAC:
+			ax_info->phy_state = AX_PHY_STATE_ABORTING;
+			break;
+
+		case AX_PHY_STATE_LINK:
+			ax_info->phy_state = AX_PHY_STATE_NO_LINK;
+			break;
+
+		default:
+			/* If we're already aborting, continue aborting */
+			break;
+		}
+	} else {
+		/* Note that we only fall into this case if previous phy_state was
+		   AX_PHY_STATE_NO_LINK. When the link is reported active while
+		   we're still polling, or when we're aborting, the logic above
+		   will just return, and we'll check again next int callback. */
+
+		ax_info->phy_state = AX_PHY_STATE_POLLING_1;
+		ax_info->phy_req.devreq.bRequestType = AX_REQ_WRITE;
+		ax_info->phy_req.devreq.bRequest = AX_CMD_SET_SW_MII;
+		ax_info->phy_req.devreq.wValue = cpu_to_le16(0);
+		ax_info->phy_req.devreq.wIndex = cpu_to_le16(0);
+		ax_info->phy_req.devreq.wLength = cpu_to_le16(0);
+		ax_info->phy_req.data_size = 0;
+		ax_info->phy_req.timeout = AX_TIMEOUT_CMD;
+		ax_info->phy_req.cmd_callback = ax_phy_cmd_callback;
+
+		ax_run_ctl_queue(ax_info, &ax_info->phy_req, 0);
+	}
+}
+
+static void ax_rx_callback(struct urb *urb, struct pt_regs *regs)
+{
+	struct sk_buff *skb = (struct sk_buff *) urb->context;
+	struct net_device *net = skb->dev;
+	struct ax8817x_info *ax_info = (struct ax8817x_info *) net->priv;
+	int ret, len, refill;
+
+	switch (urb->status) {
+	case 0:
+		break;
+
+	default:
+		err("%s: URB status %d\n", __FUNCTION__, urb->status);
+		/* It's not clear that we can do much in this case, the rx pipe
+		   doesn't ever seem to stall, so if we got -ETIMEDOUT, that
+		   usually means the device was unplugged, and we just haven't
+		   noticed yet.
+		   Just fall through and free skb without resubmitting urb. */
+	case -ENOENT:		/* */
+	case -ECONNRESET:	/* Async unlink */
+	case -ESHUTDOWN:	/* Hardware gone */
+	case -EILSEQ:		/* Get this when you yank it out on UHCI */
+	case -ETIMEDOUT:	/* OHCI */
+	case -EPROTO:		/* EHCI */
+	case -EPIPE:
+		dev_kfree_skb_any(skb);
+		urb->context = NULL;
+		return;
+	}
+
+	if (ax_info->drv_state == AX_DRV_STATE_INITIALIZING) {
+		/* Not really expecting this to ever happen, since we haven't yet
+		   enabled receive in the rx_ctl register, but ya never know... */
+		goto refill_same;
+	} else if (ax_info->drv_state == AX_DRV_STATE_EXITING) {
+		dev_kfree_skb_any(skb);
+		urb->context = NULL;
+		return;
+	}
+
+	len = urb->actual_length;
+	if (len == 0) {
+		/* this shouldn't happen... */
+		goto refill_same;
+	}
+
+	refill = ax_refill_rx_urb(ax_info, urb);
+
+	if (refill == 0
+	    || atomic_read(&ax_info->rx_refill_cnt) < n_rx_urbs) {
+		/* Send the receive buffer up the network stack */
+		skb_put(skb, len);
+		skb->protocol = eth_type_trans(skb, net);
+		net->last_rx = jiffies;
+		ax_info->stats.rx_packets++;
+		ax_info->stats.rx_bytes += len;
+
+		netif_rx(skb);
+
+		if (refill == 0) {
+			int i;
+
+			/* This is the common case. This URB got refilled OK, and
+			   no other URBs need to be refilled. */
+			if (atomic_read(&ax_info->rx_refill_cnt) == 0) {
+				return;
+			}
+
+			for (i = 0; i < n_rx_urbs; i++) {
+				struct urb *urb = ax_info->rx_urbs[i];
+
+				if (urb->context == NULL) {
+					if (ax_refill_rx_urb(ax_info, urb)
+					    == 0) {
+						atomic_dec(&ax_info->
+							   rx_refill_cnt);
+					} else {
+						break;
+					}
+				}
+			}
+		} else {
+			/* remember to refill this one later */
+			atomic_inc(&ax_info->rx_refill_cnt);
+		}
+
+		return;
+	} else {
+		ax_info->stats.rx_dropped++;
+		if (refill < 0) {
+			/* the error code was already printk'ed in ax_refill_rx_urb()
+			   so just note the consequences here: */
+			warn("Halting rx due to error\n");
+			return;
+		}
+
+		/* fall through to resubmit this URB with the existing skb
+		   will try to reallocate skb's on next rx callback */
+	}
+
+refill_same:
+	usb_fill_bulk_urb(urb, ax_info->usb,
+			  usb_rcvbulkpipe(ax_info->usb, 3), skb->data,
+			  AX_RX_MAX, ax_rx_callback, skb);
+
+	ret = usb_submit_urb(urb, GFP_ATOMIC);
+	if (ret < 0) {
+		err("Failed submit rx URB (%d)\n", ret);
+	}
+}
+
+static int ax8817x_open(struct net_device *net)
+{
+	struct ax8817x_info *ax_info = (struct ax8817x_info *) net->priv;
+	u8 buf[4];
+	int i, ret;
+
+	ret = ax_write_cmd(ax_info, AX_CMD_WRITE_RX_CTL, 0x80, 0, 0, buf);
+	if (ret < 0) {
+		return ret;
+	}
+
+	ret = 0;
+
+	ax_info->tx_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (ax_info->tx_urb == NULL) {
+		err("Error allocating tx_urb!");
+		ret = -ENOMEM;
+	}
+
+	atomic_set(&ax_info->rx_refill_cnt, 0);
+
+	for (i = 0; i < n_rx_urbs && ret == 0; i++) {
+		struct urb *urb = ax_info->rx_urbs[i];
+
+		if (urb == NULL) {
+			urb = ax_info->rx_urbs[i] =
+			    usb_alloc_urb(0, GFP_KERNEL);
+			if (urb == NULL) {
+				ret = -ENOMEM;
+				break;
+			}
+			if (n_rx_urbs > 1) {
+				urb->transfer_flags |= URB_NO_INTERRUPT;	/* FIXME: Was USB_QUEUE_BULK */
+			}
+		}
+		ret = ax_refill_rx_urb(ax_info, urb);
+		if (ret == 1) {
+			atomic_inc(&ax_info->rx_refill_cnt);
+			ret = 0;
+		}
+	}
+
+	/* XXX: should handle the case where we couldn't allocate any skb's
+	   better. They get allocated with GFP_ATOMIC, so they may all fail... */
+	if (ret == 0 && atomic_read(&ax_info->rx_refill_cnt) < n_rx_urbs) {
+		netif_start_queue(net);
+	} else {
+		/* Error: clean up anything we allocated and bail. */
+		usb_free_urb(ax_info->tx_urb);
+
+		for (i = 0; i < n_rx_urbs; i++) {
+			struct urb *urb = ax_info->rx_urbs[i];
+
+			if (urb != NULL) {
+				/* skb gets freed in the URB callback */
+				usb_unlink_urb(urb);
+				usb_free_urb(urb);
+			}
+		}
+
+		err("%s: Failed start rx queue (%d)\n", __FUNCTION__, ret);
+	}
+	return ret;
+}
+
+static int ax8817x_stop(struct net_device *net)
+{
+	struct ax8817x_info *ax_info = (struct ax8817x_info *) net->priv;
+	u8 buf[4];
+	int i, ret;
+
+	netif_stop_queue(net);
+
+	ret = ax_write_cmd(ax_info, AX_CMD_WRITE_RX_CTL, 0x80, 0, 0, buf);
+	if (ret < 0 && ax_info->drv_state != AX_DRV_STATE_EXITING) {
+		err("%s: Failed cmd (%d)\n", __FUNCTION__, ret);
+	}
+	if (ax_info->tx_urb != NULL) {
+		usb_unlink_urb(ax_info->tx_urb);
+		usb_free_urb(ax_info->tx_urb);
+		ax_info->tx_urb = NULL;
+	}
+
+	for (i = 0; i < n_rx_urbs; i++) {
+		struct urb *urb = ax_info->rx_urbs[i];
+		if (urb != NULL) {
+			/* skb gets freed in the URB callback */
+			usb_unlink_urb(urb);
+			usb_free_urb(urb);
+			ax_info->rx_urbs[i] = NULL;
+		}
+	}
+
+	return 0;
+}
+
+static void write_bulk_callback(struct urb *urb, struct pt_regs *regs)
+{
+	struct ax8817x_info *ax_info = urb->context;
+
+	if (!ax_info || (ax_info->drv_state == AX_DRV_STATE_EXITING))
+		return;
+
+	if (!netif_device_present(ax_info->net))
+		return;
+
+	if (urb->status)
+		info("%s: TX status %d", ax_info->net->name, urb->status);
+
+	ax_info->net->trans_start = jiffies;
+	netif_wake_queue(ax_info->net);
+}
+
+static int ax8817x_start_xmit(struct sk_buff *skb, struct net_device *net)
+{
+	struct ax8817x_info *ax_info = net->priv;
+	int res;
+
+	netif_stop_queue(net);
+
+	ax_info->tx_urb->transfer_flags |= URB_ZERO_PACKET;
+	usb_fill_bulk_urb(ax_info->tx_urb, ax_info->usb,
+			  usb_sndbulkpipe(ax_info->usb, 2),
+			  skb->data, skb->len, write_bulk_callback,
+			  ax_info);
+	if ((res = usb_submit_urb(ax_info->tx_urb, GFP_ATOMIC))) {
+		warn("Failed tx_urb %d", res);
+		ax_info->stats.tx_errors++;
+		netif_start_queue(net);
+	} else {
+		ax_info->stats.tx_packets++;
+		ax_info->stats.tx_bytes += skb->len;
+		net->trans_start = jiffies;
+	}
+	dev_kfree_skb(skb);
+
+	return 0;
+}
+
+static void ax8817x_tx_timeout(struct net_device *net)
+{
+	struct ax8817x_info *ax_info = net->priv;
+
+	if (!ax_info)
+		return;
+
+	warn("%s: Tx timed out.", net->name);
+	ax_info->tx_urb->transfer_flags |= URB_ASYNC_UNLINK;
+	usb_unlink_urb(ax_info->tx_urb);
+	ax_info->stats.tx_errors++;
+}
+
+static struct net_device_stats *ax8817x_stats(struct net_device *net)
+{
+	struct ax8817x_info *ax_info = (struct ax8817x_info *) net->priv;
+
+	return &ax_info->stats;
+}
+
+static void ax8817x_set_multicast(struct net_device *net)
+{
+	struct ax8817x_info *ax_info = (struct ax8817x_info *) net->priv;
+	u8 rx_ctl = 0x8c;
+
+	if (net->flags & IFF_PROMISC) {
+		rx_ctl |= 0x01;
+	} else if (net->flags & IFF_ALLMULTI
+		   || net->mc_count > AX_MAX_MCAST) {
+		rx_ctl |= 0x02;
+	} else if (net->mc_count == 0) {
+		/* just broadcast and directed */
+	} else {
+		struct dev_mc_list *mc_list = net->mc_list;
+		u8 *multi_filter;
+		u32 crc_bits;
+		int i;
+
+		multi_filter = kmalloc(8, GFP_ATOMIC);
+		if (multi_filter == NULL) {
+			/* Oops, couldn't allocate a DMA buffer for setting the multicast
+			   filter. Try all multi mode, although the ax_write_cmd_async
+			   will almost certainly fail, too... (but it will printk). */
+			rx_ctl |= 0x02;
+		} else {
+			memset(multi_filter, 0, 8);
+
+			/* Build the multicast hash filter. */
+			for (i = 0; i < net->mc_count; i++) {
+				crc_bits =
+				    ether_crc(ETH_ALEN,
+					      mc_list->dmi_addr) >> 26;
+				multi_filter[crc_bits >> 3] |=
+				    1 << (crc_bits & 7);
+				mc_list = mc_list->next;
+			}
+
+			ax_write_cmd_async(ax_info,
+					   AX_CMD_WRITE_MULTI_FILTER, 0, 0,
+					   8, multi_filter);
+
+			rx_ctl |= 0x10;
+		}
+	}
+
+	ax_write_cmd_async(ax_info, AX_CMD_WRITE_RX_CTL, rx_ctl, 0, 0,
+			   NULL);
+}
+
+static int read_mii_word(struct ax8817x_info *ax_info, __u8 phy, __u8 indx,
+			 __u16 * regd)
+{
+	int ret;
+
+	ax_write_cmd(ax_info, AX_CMD_SET_SW_MII, 0, 0, 0, NULL);
+	ret =
+	    ax_read_cmd(ax_info, AX_CMD_READ_MII_REG, phy, indx, 2, regd);
+	ax_write_cmd(ax_info, AX_CMD_SET_HW_MII, 0, 0, 0, NULL);
+
+	return 0;
+}
+
+static int write_mii_word(struct ax8817x_info *ax_info, __u8 phy,
+			  __u8 indx, __u16 regd)
+{
+	warn("write_mii_word - not implemented!");
+	return 0;
+}
+
+static int mdio_read(struct net_device *dev, int phy_id, int loc)
+{
+	struct ax8817x_info *ax_info = dev->priv;
+	int res;
+
+	read_mii_word(ax_info, phy_id, loc, (u16 *) & res);
+	return res & 0xffff;
+}
+
+static void mdio_write(struct net_device *dev, int phy_id, int loc,
+		       int val)
+{
+	struct ax8817x_info *ax_info = dev->priv;
+
+	write_mii_word(ax_info, phy_id, loc, val);
+}
+
+static int ax8817x_ethtool_ioctl(struct net_device *net, void __user *uaddr)
+{
+	struct ax8817x_info *ax_info;
+	int cmd;
+
+	ax_info = net->priv;
+	if (get_user(cmd, (int *) uaddr))
+		return -EFAULT;
+
+	switch (cmd) {
+	case ETHTOOL_GDRVINFO:{
+			struct ethtool_drvinfo info = { ETHTOOL_GDRVINFO };
+
+			strlcpy(info.driver, DRIVER_NAME,
+				ETHTOOL_BUSINFO_LEN);
+			strlcpy(info.version, DRIVER_VERSION,
+				ETHTOOL_BUSINFO_LEN);
+			usb_make_path(ax_info->usb, info.bus_info,sizeof info.bus_info);
+			if (copy_to_user(uaddr, &info, sizeof(info)))
+				return -EFAULT;
+			return 0;
+		}
+	case ETHTOOL_GSET:{
+			struct ethtool_cmd ecmd;
+
+			mii_ethtool_gset(&ax_info->mii, &ecmd);
+			if (copy_to_user(uaddr, &ecmd, sizeof(ecmd)))
+				return -EFAULT;
+			return 0;
+		}
+	case ETHTOOL_SSET:{
+			int r;
+			struct ethtool_cmd ecmd;
+
+			if (copy_from_user(&ecmd, uaddr, sizeof(ecmd)))
+				return -EFAULT;
+			r = mii_ethtool_sset(&ax_info->mii, &ecmd);
+			return r;
+		}
+	case ETHTOOL_NWAY_RST:{
+			return mii_nway_restart(&ax_info->mii);
+		}
+	case ETHTOOL_GLINK:{
+			struct ethtool_value edata = { ETHTOOL_GLINK };
+
+			edata.data =
+			    ax_info->phy_state == AX_PHY_STATE_LINK;
+			if (copy_to_user(uaddr, &edata, sizeof(edata)))
+				return -EFAULT;
+			return 0;
+		}
+	case ETHTOOL_GMSGLVL:{
+			struct ethtool_value edata = { ETHTOOL_GMSGLVL };
+			/* edata.data = ax_info->msg_enable; FIXME */
+			if (copy_to_user(uaddr, &edata, sizeof(edata)))
+				return -EFAULT;
+			return 0;
+		}
+	case ETHTOOL_SMSGLVL:{
+			struct ethtool_value edata;
+
+			if (copy_from_user(&edata, uaddr, sizeof(edata)))
+				return -EFAULT;
+			/* sp->msg_enable = edata.data;  FIXME */
+			return 0;
+		}
+	}
+	return -EOPNOTSUPP;
+}
+
+static int ax8817x_mii_ioctl(struct net_device *net, struct ifreq *ifr,
+			     int cmd)
+{
+	struct ax8817x_info *ax_info;
+	struct mii_ioctl_data *data_ptr =
+	    (struct mii_ioctl_data *) &(ifr->ifr_data);
+
+	ax_info = net->priv;
+
+	switch (cmd) {
+	case SIOCGMIIPHY:
+		data_ptr->phy_id = ax_info->phy_id;
+		break;
+	case SIOCGMIIREG:
+		if (!capable(CAP_NET_ADMIN))
+			return -EPERM;
+
+		ax_read_cmd(ax_info, AX_CMD_READ_MII_REG, 0,
+			    data_ptr->reg_num & 0x1f, 2,
+			    &(data_ptr->val_out));
+		break;
+	default:
+		return -EOPNOTSUPP;
+	}
+	return 0;
+}
+
+static int ax8817x_ioctl(struct net_device *net, struct ifreq *ifr,
+			 int cmd)
+{
+	struct ax8817x_info *ax_info;
+	int res;
+
+	ax_info = net->priv;
+	res = 0;
+
+	switch (cmd) {
+	case SIOCETHTOOL:
+		res = ax8817x_ethtool_ioctl(net, (void __user *)ifr->ifr_data);
+		break;
+	case SIOCGMIIPHY:	/* Get address of PHY in use */
+	case SIOCGMIIREG:	/* Read from MII PHY register */
+	case SIOCSMIIREG:	/* Write to MII PHY register */
+		return ax8817x_mii_ioctl(net, ifr, cmd);
+	default:
+		res = -EOPNOTSUPP;
+	}
+
+	return res;
+}
+
+static int ax8817x_net_init(struct net_device *net)
+{
+	struct ax8817x_info *ax_info = (struct ax8817x_info *) net->priv;
+	u8 buf[6];
+	u16 *buf16 = (u16 *) buf;
+	int ret;
+
+	ret = ax_write_cmd(ax_info, AX_CMD_WRITE_RX_CTL, 0x80, 0, 0, buf);
+	if (ret < 0) {
+		return ret;
+	}
+
+	memset(buf, 0, 6);
+
+	/* Get the MAC address */
+	ret = ax_read_cmd(ax_info, AX_CMD_READ_NODE_ID, 0, 0, 6, buf);
+	if (ret < 0) {
+		return ret;
+	}
+
+	memcpy(net->dev_addr, buf, 6);
+
+	/* Get the PHY id */
+	ret = ax_read_cmd(ax_info, AX_CMD_READ_PHY_ID, 0, 0, 2, buf);
+	if (ret < 0) {
+		return ret;
+	} else if (ret < 2) {
+		/* this should always return 2 bytes */
+		return -EIO;
+	}
+
+	/* Reset the PHY, and drop it into auto-negotiation mode */
+	ax_info->phy_id = buf[1];
+	ax_info->phy_state = AX_PHY_STATE_INITIALIZING;
+
+	ret = ax_write_cmd(ax_info, AX_CMD_SET_SW_MII, 0, 0, 0, &buf);
+	if (ret < 0) {
+		return ret;
+	}
+
+	*buf16 = cpu_to_le16(BMCR_RESET);
+	ret = ax_write_cmd(ax_info, AX_CMD_WRITE_MII_REG,
+			   ax_info->phy_id, MII_BMCR, 2, buf16);
+	if (ret < 0) {
+		return ret;
+	}
+
+	/* Advertise that we can do full-duplex pause */
+	*buf16 = cpu_to_le16(ADVERTISE_ALL | ADVERTISE_CSMA | 0x0400);
+	ret = ax_write_cmd(ax_info, AX_CMD_WRITE_MII_REG,
+			   ax_info->phy_id, MII_ADVERTISE, 2, buf16);
+	if (ret < 0) {
+		return ret;
+	}
+
+	*buf16 = cpu_to_le16(BMCR_ANENABLE | BMCR_ANRESTART);
+	ret = ax_write_cmd(ax_info, AX_CMD_WRITE_MII_REG,
+			   ax_info->phy_id, MII_BMCR, 2, buf16);
+	if (ret < 0) {
+		return ret;
+	}
+
+	ret = ax_write_cmd(ax_info, AX_CMD_SET_HW_MII, 0, 0, 0, &buf);
+	if (ret < 0) {
+		return ret;
+	}
+
+	net->open = ax8817x_open;
+	net->stop = ax8817x_stop;
+	net->hard_start_xmit = ax8817x_start_xmit;
+	net->tx_timeout = ax8817x_tx_timeout;
+	net->watchdog_timeo = AX_TIMEOUT_TX;
+	net->get_stats = ax8817x_stats;
+	net->do_ioctl = ax8817x_ioctl;
+	net->set_multicast_list = ax8817x_set_multicast;
+
+	return 0;
+}
+
+static int ax8817x_bind(struct usb_interface *intf,
+			const struct usb_device_id *id)
+{
+	struct usb_device *usb = interface_to_usbdev(intf);
+	struct ax8817x_info *ax_info;
+	struct net_device *net;
+	int i, ret;
+	unsigned long gpio_bits = id->driver_info;
+	u8 buf[2];
+
+	/* Allocate the URB lists along with the device info struct */
+	ax_info = kmalloc(sizeof(struct ax8817x_info) +
+			  n_rx_urbs * sizeof(struct urb *), GFP_KERNEL);
+	if (ax_info == NULL) {
+		err("%s: Failed ax alloc\n", __FUNCTION__);
+		goto exit_err;
+	}
+
+	memset(ax_info, 0, sizeof(struct ax8817x_info) +
+	       n_rx_urbs * sizeof(struct urb *));
+
+	ax_info->drv_state = AX_DRV_STATE_INITIALIZING;
+	ax_info->rx_urbs = (struct urb **) (ax_info + 1);
+	ax_info->usb = usb;
+
+	/* Set up the control URB queue */
+
+	INIT_LIST_HEAD(&ax_info->ctl_queue);
+	spin_lock_init(&ax_info->ctl_lock);
+	ax_info->ctl_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (ax_info->ctl_urb == NULL) {
+		goto exit_err_free_ax;
+	}
+
+	/* Toggle the GPIOs in a manufacturer/model specific way */
+
+	for (i = 2; i >= 0; i--) {
+		ret = ax_write_cmd(ax_info, AX_CMD_WRITE_GPIOS,
+				   (gpio_bits >> (i * 8)) & 0xff, 0, 0,
+				   buf);
+		if (ret < 0) {
+			goto exit_err_free_ax;
+		}
+		wait_ms(5);
+	}
+
+	/* Set up the net device */
+
+	net = alloc_etherdev(0);
+	if (net == NULL) {
+		err("%s: Failed net alloc\n", __FUNCTION__);
+		goto exit_err_free_ax;
+	}
+
+	ax_info->net = net;
+
+	SET_MODULE_OWNER(net);
+	net->init = ax8817x_net_init;
+	net->priv = ax_info;
+
+	ret = register_netdev(net);
+	if (ret < 0) {
+		err("%s: Failed net init (%d)\n", __FUNCTION__, ret);
+		goto exit_err_free_net;
+	}
+
+	/* Setup mii structure */
+	ax_info->mii.dev = net;
+	ax_info->mii.mdio_read = mdio_read;
+	ax_info->mii.mdio_write = mdio_write;
+	ax_info->mii.phy_id_mask = 0x1f;
+	ax_info->mii.reg_num_mask = 0x1f;
+
+	/* Set up the interrupt URB, and start PHY state monitoring */
+
+	ax_info->int_urb = usb_alloc_urb(0, GFP_KERNEL);
+	if (ax_info->int_urb == NULL) {
+		goto exit_err_unregister_net;
+	}
+	ax_info->int_buf = kmalloc(8, GFP_KERNEL);
+	if (ax_info->int_buf == NULL) {
+		goto exit_err_free_int_urb;
+	}
+	ax_info->phy_req.data = kmalloc(2, GFP_KERNEL);
+	if (ax_info->phy_req.data == NULL) {
+		goto exit_err_free_int_buf;
+	}
+
+	usb_fill_int_urb(ax_info->int_urb, usb, usb_rcvintpipe(usb, 1),
+			 ax_info->int_buf, 8, ax_int_callback, ax_info,
+			 100);
+
+	ret = usb_submit_urb(ax_info->int_urb, GFP_ATOMIC);
+	if (ret < 0) {
+		err("%s: Failed int URB submit (%d)\n", __FUNCTION__, ret);
+		goto exit_err_free_phy_buf;
+	}
+
+	ax_info->drv_state = AX_DRV_STATE_RUNNING;
+	usb_set_intfdata(intf, ax_info);
+
+	return 0;
+
+      exit_err_free_phy_buf:
+	kfree(ax_info->phy_req.data);
+
+      exit_err_free_int_buf:
+	kfree(ax_info->int_buf);
+
+      exit_err_free_int_urb:
+	usb_free_urb(ax_info->int_urb);
+
+      exit_err_unregister_net:
+	ax_info->drv_state = AX_DRV_STATE_EXITING;
+	unregister_netdev(net);
+
+      exit_err_free_net:
+	kfree(net);
+
+      exit_err_free_ax:
+	if (ax_info->ctl_urb != NULL) {
+		/* no need to unlink, since there should not be any ctl URBs
+		   pending at this point */
+		usb_free_urb(ax_info->ctl_urb);
+	}
+
+	kfree(ax_info);
+
+exit_err:
+	err("%s: Failed to initialize\n", __FUNCTION__);
+	return -EIO;
+}
+
+static void ax8817x_disconnect(struct usb_interface *intf)
+{
+	struct ax8817x_info *ax_info = usb_get_intfdata(intf);
+
+	usb_set_intfdata(intf, NULL);
+	if (ax_info) {
+		ax_info->drv_state = AX_DRV_STATE_EXITING;
+
+		if (ax_info->int_urb != NULL) {
+			usb_unlink_urb(ax_info->int_urb);
+			usb_free_urb(ax_info->int_urb);
+			kfree(ax_info->int_buf);
+		}
+
+		unregister_netdev(ax_info->net);
+
+		/* XXX: hmmm... need to go through and clear out the ctl queue, too... */
+		if (ax_info->ctl_urb != NULL) {
+			usb_unlink_urb(ax_info->ctl_urb);
+			usb_free_urb(ax_info->ctl_urb);
+		}
+
+		kfree(ax_info);
+	}
+}
+
+static struct usb_driver ax8817x_driver = {
+	.owner = THIS_MODULE,
+	.name = DRIVER_NAME,
+	.probe = ax8817x_bind,
+	.disconnect = ax8817x_disconnect,
+	.id_table = ax8817x_id_table,
+};
+
+static int __init ax8817x_init(void)
+{
+	int ret;
+
+	if (n_rx_urbs < 1)
+		n_rx_urbs = AX_RX_URBS_DEFAULT;
+
+	ret = usb_register(&ax8817x_driver);
+	if (ret < 0) {
+		err("%s: Failed to register\n", __FUNCTION__);
+	} else {
+		info(DRIVER_DESC " " DRIVER_VERSION);
+	}
+
+	return ret;
+}
+
+static void __exit ax8817x_exit(void)
+{
+	usb_deregister(&ax8817x_driver);
+}
+
+module_init(ax8817x_init);
+module_exit(ax8817x_exit);
diff -Nru a/drivers/usb/net/catc.c b/drivers/usb/net/catc.c
--- a/drivers/usb/net/catc.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/net/catc.c	Wed Jun 18 23:42:07 2003
@@ -667,7 +667,7 @@
 /*
  * ioctl's
  */
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
 {
         struct catc *catc = dev->priv;
         u32 cmd;
@@ -726,7 +726,7 @@
 {
         switch(cmd) {
         case SIOCETHTOOL:
-                return netdev_ethtool_ioctl(dev, (void *) rq->ifr_data);
+                return netdev_ethtool_ioctl(dev, (void __user *)rq->ifr_data);
         default:
                 return -EOPNOTSUPP;
         }
diff -Nru a/drivers/usb/net/kaweth.c b/drivers/usb/net/kaweth.c
--- a/drivers/usb/net/kaweth.c	Wed Jun 18 23:42:08 2003
+++ b/drivers/usb/net/kaweth.c	Wed Jun 18 23:42:08 2003
@@ -225,13 +225,17 @@
 	struct urb *rx_urb;
 	struct urb *tx_urb;
 	struct urb *irq_urb;
+
+	dma_addr_t intbufferhandle;
+	__u8 *intbuffer;
+	dma_addr_t rxbufferhandle;
+	__u8 *rx_buf;
+
 	
 	struct sk_buff *tx_skb;
 
 	__u8 *firmware_buf;
 	__u8 scratch[KAWETH_SCRATCH_SIZE];
-	__u8 rx_buf[KAWETH_BUF_SIZE];
-	__u8 intbuffer[INTBUFFERSIZE];
 	__u16 packet_filter_bitmap;
 
 	struct kaweth_ethernet_configuration configuration;
@@ -524,6 +528,8 @@
 		      KAWETH_BUF_SIZE,
 		      kaweth_usb_receive,
 		      kaweth);
+	kaweth->rx_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
+	kaweth->rx_urb->transfer_dma = kaweth->rxbufferhandle;
 
 	if((result = usb_submit_urb(kaweth->rx_urb, mem_flags))) {
 		if (result == -ENOMEM)
@@ -532,7 +538,7 @@
 	} else {
 		kaweth->suspend_lowmem = 0;
 	}
-	
+
 	return result;
 }
 
@@ -630,6 +636,8 @@
 		int_callback,
 		kaweth,
 		HZ/4);
+	kaweth->irq_urb->transfer_dma = kaweth->intbufferhandle;
+	kaweth->irq_urb->transfer_flags |= URB_NO_TRANSFER_DMA_MAP;
 
 	res = usb_submit_urb(kaweth->irq_urb, GFP_KERNEL);
 	if (res) {
@@ -662,13 +670,13 @@
 	return 0;
 }
 
-static int netdev_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int netdev_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
 {
 	u32 ethcmd;
-	
+
 	if (copy_from_user(&ethcmd, useraddr, sizeof(ethcmd)))
 		return -EFAULT;
-	
+
 	switch (ethcmd) {
 	case ETHTOOL_GDRVINFO: {
 		struct ethtool_drvinfo info = {ETHTOOL_GDRVINFO};
@@ -678,7 +686,7 @@
 		return 0;
 	}
 	}
-	
+
 	return -EOPNOTSUPP;
 }
 
@@ -689,7 +697,7 @@
 {
 	switch (cmd) {
 	case SIOCETHTOOL:
-		return netdev_ethtool_ioctl(net, (void *) rq->ifr_data);
+		return netdev_ethtool_ioctl(net, (void __user *)rq->ifr_data);
 	}
 	return -EOPNOTSUPP;
 }
@@ -1033,6 +1041,19 @@
 	if (!kaweth->irq_urb)
 		goto err_tx_and_rx;
 
+	kaweth->intbuffer = usb_buffer_alloc(	kaweth->dev,
+						INTBUFFERSIZE,
+						GFP_KERNEL,
+						&kaweth->intbufferhandle);
+	if (!kaweth->intbuffer)
+		goto err_tx_and_rx_and_irq;
+	kaweth->rx_buf = usb_buffer_alloc(	kaweth->dev,
+						KAWETH_BUF_SIZE,
+						GFP_KERNEL,
+						&kaweth->rxbufferhandle);
+	if (!kaweth->rx_buf)
+		goto err_all_but_rxbuf;
+
 	kaweth->net = netdev;
 	memcpy(kaweth->net->broadcast, &bcast_addr, sizeof(bcast_addr));
 	memcpy(kaweth->net->dev_addr,
@@ -1053,7 +1074,7 @@
 	kaweth->net->mtu = le16_to_cpu(kaweth->configuration.segment_size);
 
 	memset(&kaweth->stats, 0, sizeof(kaweth->stats));
-	
+
 	SET_MODULE_OWNER(netdev);
 
 	usb_set_intfdata(intf, kaweth);
@@ -1071,6 +1092,12 @@
 
 err_intfdata:
 	usb_set_intfdata(intf, NULL);
+err_all:
+	usb_buffer_free(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
+err_all_but_rxbuf:
+	usb_buffer_free(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
+err_tx_and_rx_and_irq:
+	usb_free_urb(kaweth->irq_urb);
 err_tx_and_rx:
 	usb_free_urb(kaweth->rx_urb);
 err_only_tx:
@@ -1123,6 +1150,11 @@
 
 	usb_free_urb(kaweth->rx_urb);
 	usb_free_urb(kaweth->tx_urb);
+	usb_free_urb(kaweth->irq_urb);
+
+
+	usb_buffer_free(kaweth->dev, KAWETH_BUF_SIZE, (void *)kaweth->rx_buf, kaweth->rxbufferhandle);
+	usb_buffer_free(kaweth->dev, INTBUFFERSIZE, (void *)kaweth->intbuffer, kaweth->intbufferhandle);
 
 	kfree(kaweth);
 }
diff -Nru a/drivers/usb/net/pegasus.c b/drivers/usb/net/pegasus.c
--- a/drivers/usb/net/pegasus.c	Wed Jun 18 23:42:09 2003
+++ b/drivers/usb/net/pegasus.c	Wed Jun 18 23:42:09 2003
@@ -945,7 +945,7 @@
 	return 0;
 }
 #ifdef	CONFIG_MII
-static int pegasus_ethtool_ioctl(struct net_device *dev, void *useraddr)
+static int pegasus_ethtool_ioctl(struct net_device *dev, void __user *useraddr)
 {
 
 	u32 ethcmd;
@@ -1024,7 +1024,7 @@
 
 }
 #else
-static int pegasus_ethtool_ioctl(struct net_device *net, void *uaddr)
+static int pegasus_ethtool_ioctl(struct net_device *net, void __user *uaddr)
 {
 	pegasus_t *pegasus;
 	int cmd;
@@ -1113,7 +1113,7 @@
 
 	switch (cmd) {
 	case SIOCETHTOOL:
-		res = pegasus_ethtool_ioctl(net, rq->ifr_data);
+		res = pegasus_ethtool_ioctl(net, (void __user *)rq->ifr_data);
 		break;
 	case SIOCDEVPRIVATE:
 		data[0] = pegasus->phy;
diff -Nru a/drivers/usb/net/rtl8150.c b/drivers/usb/net/rtl8150.c
--- a/drivers/usb/net/rtl8150.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/net/rtl8150.c	Wed Jun 18 23:42:07 2003
@@ -673,7 +673,7 @@
 	return res;
 }
 
-static int rtl8150_ethtool_ioctl(struct net_device *netdev, void *uaddr)
+static int rtl8150_ethtool_ioctl(struct net_device *netdev, void __user *uaddr)
 {
 	rtl8150_t *dev;
 	int cmd;
@@ -758,7 +758,7 @@
 
 	switch (cmd) {
 	case SIOCETHTOOL:
-		res = rtl8150_ethtool_ioctl(netdev, rq->ifr_data);
+		res = rtl8150_ethtool_ioctl(netdev, (void __user *)rq->ifr_data);
 		break;
 	case SIOCDEVPRIVATE:
 		data[0] = dev->phy;
diff -Nru a/drivers/usb/net/usbnet.c b/drivers/usb/net/usbnet.c
--- a/drivers/usb/net/usbnet.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/net/usbnet.c	Wed Jun 18 23:42:07 2003
@@ -1622,6 +1622,11 @@
 	.check_connect = always_connected,
 };
 
+static const struct driver_info	blob_info = {
+	.description =	"Boot Loader OBject",
+	.check_connect = always_connected,
+};
+
 #endif	/* CONFIG_USB_ARMLINUX */
 
 
@@ -2097,7 +2102,7 @@
 /*-------------------------------------------------------------------------*/
 
 static inline int
-usbnet_ethtool_ioctl (struct net_device *net, void *useraddr)
+usbnet_ethtool_ioctl (struct net_device *net, void __user *useraddr)
 {
 	struct usbnet	*dev = (struct usbnet *) net->priv;
 	u32		cmd;
@@ -2161,7 +2166,7 @@
 {
 	switch (cmd) {
 	case SIOCETHTOOL:
-		return usbnet_ethtool_ioctl (net, (void *)rq->ifr_data);
+		return usbnet_ethtool_ioctl (net, (void __user *)rq->ifr_data);
 	default:
 		return -EOPNOTSUPP;
 	}
@@ -2707,6 +2712,9 @@
 }, {
 	USB_DEVICE (0x0E7E, 0x1001),	// G.Mate "Yopy"
 	.driver_info =	(unsigned long) &yopy_info,
+}, {
+	USB_DEVICE (0x8086, 0x07d3),	// "blob" bootloader
+	.driver_info =	(unsigned long) &blob_info,
 }, 
 #endif
 
diff -Nru a/drivers/usb/storage/isd200.c b/drivers/usb/storage/isd200.c
--- a/drivers/usb/storage/isd200.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/storage/isd200.c	Wed Jun 18 23:42:07 2003
@@ -548,10 +548,9 @@
 	/* if the command gets aborted by the higher layers, we need to
 	 * short-circuit all other processing
 	 */
-	if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
-		US_DEBUGP("-- transport indicates command was aborted\n");
-		srb->result = DID_ABORT << 16;
-		return;
+	if (us->sm_state == US_STATE_ABORTING) {
+		US_DEBUGP("-- command was aborted\n");
+		goto Handle_Abort;
 	}
 
 	switch (transferStatus) {
@@ -561,6 +560,11 @@
 		srb->result = SAM_STAT_GOOD;
 		break;
 
+	case USB_STOR_TRANSPORT_NO_SENSE:
+		US_DEBUGP("-- transport indicates protocol failure\n");
+		srb->result = SAM_STAT_CHECK_CONDITION;
+		return;
+
 	case USB_STOR_TRANSPORT_FAILED:
 		US_DEBUGP("-- transport indicates command failure\n");
 		need_auto_sense = 1;
@@ -591,10 +595,9 @@
 
 	if (need_auto_sense) {
 		result = isd200_read_regs(us);
-		if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
+		if (us->sm_state == US_STATE_ABORTING) {
 			US_DEBUGP("-- auto-sense aborted\n");
-			srb->result = DID_ABORT << 16;
-			return;
+			goto Handle_Abort;
 		}
 		if (result == ISD200_GOOD) {
 			isd200_build_sense(us, srb);
@@ -603,8 +606,10 @@
 			/* If things are really okay, then let's show that */
 			if ((srb->sense_buffer[2] & 0xf) == 0x0)
 				srb->result = SAM_STAT_GOOD;
-		} else
+		} else {
 			srb->result = DID_ERROR << 16;
+			/* Need reset here */
+		}
 	}
 
 	/* Regardless of auto-sense, if we _know_ we have an error
@@ -612,6 +617,16 @@
 	 */
 	if (transferStatus == USB_STOR_TRANSPORT_FAILED)
 		srb->result = SAM_STAT_CHECK_CONDITION;
+	return;
+
+	/* abort processing: the bulk-only transport requires a reset
+	 * following an abort */
+	Handle_Abort:
+	srb->result = DID_ABORT << 16;
+
+	/* permit the reset transfer to take place */
+	clear_bit(US_FLIDX_ABORTING, &us->flags);
+	/* Need reset here */
 }
 
 #ifdef CONFIG_USB_STORAGE_DEBUG
diff -Nru a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
--- a/drivers/usb/storage/protocol.c	Wed Jun 18 23:42:05 2003
+++ b/drivers/usb/storage/protocol.c	Wed Jun 18 23:42:05 2003
@@ -82,6 +82,10 @@
 	if (srb->cmnd[0] != INQUIRY)
 		return;
 
+	/* oddly short buffer -- bail out */
+	if (srb->request_bufflen < 3)
+		return;
+
 	data_ptr = find_data_location(srb);
 
 	if ((data_ptr[2] & 7) == 2)
diff -Nru a/drivers/usb/storage/protocol.h b/drivers/usb/storage/protocol.h
--- a/drivers/usb/storage/protocol.h	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/storage/protocol.h	Wed Jun 18 23:42:07 2003
@@ -57,6 +57,8 @@
 #define US_SC_MIN	US_SC_RBC
 #define US_SC_MAX	US_SC_ISD200
 
+#define US_SC_DEVICE	0xff		/* Use device's value */
+
 extern void usb_stor_ATAPI_command(Scsi_Cmnd*, struct us_data*);
 extern void usb_stor_qic157_command(Scsi_Cmnd*, struct us_data*);
 extern void usb_stor_ufi_command(Scsi_Cmnd*, struct us_data*);
diff -Nru a/drivers/usb/storage/scsiglue.c b/drivers/usb/storage/scsiglue.c
--- a/drivers/usb/storage/scsiglue.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/storage/scsiglue.c	Wed Jun 18 23:42:07 2003
@@ -57,100 +57,36 @@
  * Host functions 
  ***********************************************************************/
 
-static const char* usb_storage_info(struct Scsi_Host *host)
+static const char* host_info(struct Scsi_Host *host)
 {
 	return "SCSI emulation for USB Mass Storage devices";
 }
 
-#if 0
-/* detect a virtual adapter (always works)
- * Synchronization: 2.4: with the io_request_lock
- * 			2.5: no locks.
- * fortunately we don't care.
- * */
-static int usb_storage_detect(struct SHT *sht)
+static int slave_configure (struct scsi_device *sdev)
 {
-	struct us_data *us;
-	char local_name[32];
-
-	/* This is not nice at all, but how else are we to get the
-	 * data here? */
-	us = (struct us_data *)sht->proc_dir;
-
-	/* set up the name of our subdirectory under /proc/scsi/ */
-	sprintf(local_name, "usb-storage-%d", us->host_number);
-	sht->proc_name = kmalloc (strlen(local_name) + 1, GFP_ATOMIC);
-	if (!sht->proc_name)
-		return 0;
-	strcpy(sht->proc_name, local_name);
-
-	/* we start with no /proc directory entry */
-	sht->proc_dir = NULL;
-
-	/* register the host */
-	us->host = scsi_register(sht, sizeof(us));
-	if (us->host) {
-		struct usb_interface *iface;
-		us->host->hostdata[0] = (unsigned long)us;
-		us->host_no = us->host->host_no;
-		iface = usb_ifnum_to_if(us->pusb_dev, us->ifnum);
-		if (iface)
-			scsi_set_device(us->host, &iface->dev);
-		return 1;
-	}
+	/* set device to use 10-byte commands where possible */
+	sdev->use_10_for_ms = 1;
+	sdev->use_10_for_rw = 1;
 
-	/* odd... didn't register properly.  Abort and free pointers */
-	kfree(sht->proc_name);
-	sht->proc_name = NULL;
+	/* this is to satisify the compiler, tho I don't think the 
+	 * return code is ever checked anywhere. */
 	return 0;
 }
 
-/* Release all resources used by the virtual host
- *
- * NOTE: There is no contention here, because we're already deregistered
- * the driver and we're doing each virtual host in turn, not in parallel
- * Synchronization: BKL, no spinlock.
- */
-static int usb_storage_release(struct Scsi_Host *psh)
-{
-	struct us_data *us = (struct us_data *)psh->hostdata[0];
-
-	US_DEBUGP("release() called for host %s\n", us->htmplt.name);
-
-	/* Kill the control threads
-	 *
-	 * Enqueue the command, wake up the thread, and wait for 
-	 * notification that it has exited.
-	 */
-	US_DEBUGP("-- sending exit command to thread\n");
-	BUG_ON(atomic_read(&us->sm_state) != US_STATE_IDLE);
-	us->srb = NULL;
-	up(&(us->sema));
-	wait_for_completion(&(us->notify));
-
-	/* remove the pointer to the data structure we were using */
-	(struct us_data*)psh->hostdata[0] = NULL;
-
-	/* we always have a successful release */
-	return 0;
-}
-#endif
-
 /* queue a command */
 /* This is always called with scsi_lock(srb->host) held */
-static int usb_storage_queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *))
+static int queuecommand( Scsi_Cmnd *srb , void (*done)(Scsi_Cmnd *))
 {
 	struct us_data *us = (struct us_data *)srb->device->host->hostdata[0];
-	int state = atomic_read(&us->sm_state);
 
-	US_DEBUGP("queuecommand() called\n");
+	US_DEBUGP("%s called\n", __FUNCTION__);
 	srb->host_scribble = (unsigned char *)us;
 
 	/* enqueue the command */
-	if (state != US_STATE_IDLE || us->srb != NULL) {
+	if (us->sm_state != US_STATE_IDLE || us->srb != NULL) {
 		printk(KERN_ERR USB_STORAGE "Error in %s: " 
 			"state = %d, us->srb = %p\n",
-			__FUNCTION__, state, us->srb);
+			__FUNCTION__, us->sm_state, us->srb);
 		return SCSI_MLQUEUE_HOST_BUSY;
 	}
 
@@ -169,11 +105,10 @@
 
 /* Command abort */
 /* This is always called with scsi_lock(srb->host) held */
-static int usb_storage_command_abort( Scsi_Cmnd *srb )
+static int command_abort( Scsi_Cmnd *srb )
 {
 	struct Scsi_Host *host = srb->device->host;
 	struct us_data *us = (struct us_data *) host->hostdata[0];
-	int state = atomic_read(&us->sm_state);
 
 	US_DEBUGP("%s called\n", __FUNCTION__);
 
@@ -186,20 +121,20 @@
 	/* Normally the current state is RUNNING.  If the control thread
 	 * hasn't even started processing this command, the state will be
 	 * IDLE.  Anything else is a bug. */
-	if (state != US_STATE_RUNNING && state != US_STATE_IDLE) {
+	if (us->sm_state != US_STATE_RUNNING
+				&& us->sm_state != US_STATE_IDLE) {
 		printk(KERN_ERR USB_STORAGE "Error in %s: "
-			"invalid state %d\n", __FUNCTION__, state);
+			"invalid state %d\n", __FUNCTION__, us->sm_state);
 		return FAILED;
 	}
 
 	/* Set state to ABORTING, set the ABORTING bit, and release the lock */
-	atomic_set(&us->sm_state, US_STATE_ABORTING);
+	us->sm_state = US_STATE_ABORTING;
 	set_bit(US_FLIDX_ABORTING, &us->flags);
 	scsi_unlock(host);
 
-	/* If the state was RUNNING, stop an ongoing USB transfer */
-	if (state == US_STATE_RUNNING)
-		usb_stor_stop_transport(us);
+	/* Stop an ongoing USB transfer */
+	usb_stor_stop_transport(us);
 
 	/* Wait for the aborted command to finish */
 	wait_for_completion(&us->notify);
@@ -213,35 +148,30 @@
 /* This invokes the transport reset mechanism to reset the state of the
  * device */
 /* This is always called with scsi_lock(srb->host) held */
-static int usb_storage_device_reset( Scsi_Cmnd *srb )
+static int device_reset( Scsi_Cmnd *srb )
 {
 	struct us_data *us = (struct us_data *)srb->device->host->hostdata[0];
-	int state = atomic_read(&us->sm_state);
 	int result;
 
 	US_DEBUGP("%s called\n", __FUNCTION__);
-	if (state != US_STATE_IDLE) {
+	if (us->sm_state != US_STATE_IDLE) {
 		printk(KERN_ERR USB_STORAGE "Error in %s: "
-			"invalid state %d\n", __FUNCTION__, state);
+			"invalid state %d\n", __FUNCTION__, us->sm_state);
 		return FAILED;
 	}
 
 	/* set the state and release the lock */
-	atomic_set(&us->sm_state, US_STATE_RESETTING);
+	us->sm_state = US_STATE_RESETTING;
 	scsi_unlock(srb->device->host);
 
-	/* lock the device pointers */
+	/* lock the device pointers and do the reset */
 	down(&(us->dev_semaphore));
-
-	/* do the reset */
 	result = us->transport_reset(us);
-
-	/* unlock */
 	up(&(us->dev_semaphore));
 
 	/* lock access to the state and clear it */
 	scsi_lock(srb->device->host);
-	atomic_set(&us->sm_state, US_STATE_IDLE);
+	us->sm_state = US_STATE_IDLE;
 	return result;
 }
 
@@ -249,45 +179,42 @@
 /* It refuses to work if there's more than one interface in
  * the device, so that other users are not affected. */
 /* This is always called with scsi_lock(srb->host) held */
-static int usb_storage_bus_reset( Scsi_Cmnd *srb )
+static int bus_reset( Scsi_Cmnd *srb )
 {
 	struct us_data *us = (struct us_data *)srb->device->host->hostdata[0];
-	int state = atomic_read(&us->sm_state);
 	int result;
 
 	US_DEBUGP("%s called\n", __FUNCTION__);
-	if (state != US_STATE_IDLE) {
+	if (us->sm_state != US_STATE_IDLE) {
 		printk(KERN_ERR USB_STORAGE "Error in %s: "
-			"invalid state %d\n", __FUNCTION__, state);
+			"invalid state %d\n", __FUNCTION__, us->sm_state);
 		return FAILED;
 	}
 
 	/* set the state and release the lock */
-	atomic_set(&us->sm_state, US_STATE_RESETTING);
+	us->sm_state = US_STATE_RESETTING;
 	scsi_unlock(srb->device->host);
 
 	/* The USB subsystem doesn't handle synchronisation between
-	   a device's several drivers. Therefore we reset only devices
-	   with just one interface, which we of course own.
-	*/
-
-	//FIXME: needs locking against config changes
-
-	if (us->pusb_dev->actconfig->desc.bNumInterfaces == 1) {
+	 * a device's several drivers. Therefore we reset only devices
+	 * with just one interface, which we of course own. */
 
-		/* lock the device and attempt to reset the port */
-		down(&(us->dev_semaphore));
-		result = usb_reset_device(us->pusb_dev);
-		up(&(us->dev_semaphore));
-		US_DEBUGP("usb_reset_device returns %d\n", result);
-	} else {
+	down(&(us->dev_semaphore));
+	if (test_bit(US_FLIDX_DISCONNECTING, &us->flags)) {
+		result = -EIO;
+		US_DEBUGP("Attempt to reset during disconnect\n");
+	} else if (us->pusb_dev->actconfig->desc.bNumInterfaces != 1) {
 		result = -EBUSY;
 		US_DEBUGP("Refusing to reset a multi-interface device\n");
+	} else {
+		result = usb_reset_device(us->pusb_dev);
+		US_DEBUGP("usb_reset_device returns %d\n", result);
 	}
+	up(&(us->dev_semaphore));
 
 	/* lock access to the state and clear it */
 	scsi_lock(srb->device->host);
-	atomic_set(&us->sm_state, US_STATE_IDLE);
+	us->sm_state = US_STATE_IDLE;
 	return result < 0 ? FAILED : SUCCESS;
 }
 
@@ -300,7 +227,7 @@
 #define SPRINTF(args...) \
 	do { if (pos < buffer+length) pos += sprintf(pos, ## args); } while (0)
 
-static int usb_storage_proc_info (struct Scsi_Host *hostptr, char *buffer, char **start, off_t offset,
+static int proc_info (struct Scsi_Host *hostptr, char *buffer, char **start, off_t offset,
 		int length, int inout)
 {
 	struct us_data *us;
@@ -333,8 +260,6 @@
 #define DO_FLAG(a)  	if (f & US_FL_##a)  pos += sprintf(pos, " " #a)
 		DO_FLAG(SINGLE_LUN);
 		DO_FLAG(MODE_XLATE);
-		DO_FLAG(START_STOP);
-		DO_FLAG(IGNORE_SER);
 		DO_FLAG(SCM_MULT_TARG);
 		DO_FLAG(FIX_INQUIRY);
 		DO_FLAG(FIX_CAPACITY);
@@ -360,29 +285,20 @@
  * this defines our host template, with which we'll allocate hosts
  */
 
-struct SHT usb_stor_host_template = {
+struct scsi_host_template usb_stor_host_template = {
 	/* basic userland interface stuff */
 	.name =				"usb-storage",
 	.proc_name =			"usb-storage",
-	.proc_info =			usb_storage_proc_info,
-	.proc_dir =			NULL,
-	.info =				usb_storage_info,
-	.ioctl =			NULL,
-
-	/* old-style detect and release */
-	.detect =			NULL,
-	.release =			NULL,
+	.proc_info =			proc_info,
+	.info =				host_info,
 
 	/* command interface -- queued only */
-	.command =			NULL,
-	.queuecommand =			usb_storage_queuecommand,
+	.queuecommand =			queuecommand,
 
 	/* error and abort handlers */
-	.eh_abort_handler =		usb_storage_command_abort,
-	.eh_device_reset_handler =	usb_storage_device_reset,
-	.eh_bus_reset_handler =		usb_storage_bus_reset,
-	.eh_host_reset_handler =	NULL,
-	.eh_strategy_handler =		NULL,
+	.eh_abort_handler =		command_abort,
+	.eh_device_reset_handler =	device_reset,
+	.eh_bus_reset_handler =		bus_reset,
 
 	/* queue commands only, only one command per LUN */
 	.can_queue =			1,
@@ -391,21 +307,11 @@
 	/* unknown initiator id */
 	.this_id =			-1,
 
-	/* no limit on commands */
-	.max_sectors =			0,
-	
-	/* pre- and post- device scan functions */
-	.slave_alloc =			NULL,
-	.slave_configure =		NULL,
-	.slave_destroy =		NULL,
+	.slave_configure =		slave_configure,
 
 	/* lots of sg segments can be handled */
 	.sg_tablesize =			SG_ALL,
 
-	/* use 32-bit address space for DMA */
-	.unchecked_isa_dma =		FALSE,
-	.highmem_io =			FALSE,
-
 	/* merge commands... this seems to help performance, but
 	 * periodically someone should test to see which setting is more
 	 * optimal.
@@ -414,9 +320,6 @@
 
 	/* emulated HBA */
 	.emulated =			TRUE,
-
-	/* sorry, no BIOS to help us */
-	.bios_param =			NULL,
 
 	/* module management */
 	.module =			THIS_MODULE
diff -Nru a/drivers/usb/storage/scsiglue.h b/drivers/usb/storage/scsiglue.h
--- a/drivers/usb/storage/scsiglue.h	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/storage/scsiglue.h	Wed Jun 18 23:42:07 2003
@@ -47,7 +47,7 @@
 
 extern unsigned char usb_stor_sense_notready[18];
 extern unsigned char usb_stor_sense_invalidCDB[18];
-extern struct SHT usb_stor_host_template;
+extern struct scsi_host_template usb_stor_host_template;
 extern int usb_stor_scsiSense10to6(Scsi_Cmnd*);
 extern int usb_stor_scsiSense6to10(Scsi_Cmnd*);
 
diff -Nru a/drivers/usb/storage/transport.c b/drivers/usb/storage/transport.c
--- a/drivers/usb/storage/transport.c	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/storage/transport.c	Wed Jun 18 23:42:07 2003
@@ -136,9 +136,9 @@
 	struct timer_list to_timer;
 	int status;
 
-	/* don't submit URBS during abort/disconnect processing */
+	/* don't submit URBs during abort/disconnect processing */
 	if (us->flags & DONT_SUBMIT)
-		return -ECONNRESET;
+		return -EIO;
 
 	/* set up data structures for the wakeup system */
 	init_completion(&urb_done);
@@ -299,17 +299,17 @@
 			return USB_STOR_XFER_ERROR;
 		return USB_STOR_XFER_STALLED;
 
-	/* NAK - that means we've retried this a few times already */
+	/* timeout or excessively long NAK */
 	case -ETIMEDOUT:
-		US_DEBUGP("-- device NAKed\n");
+		US_DEBUGP("-- timeout or NAK\n");
 		return USB_STOR_XFER_ERROR;
 
 	/* babble - the device tried to send more than we wanted to read */
 	case -EOVERFLOW:
-		US_DEBUGP("-- Babble\n");
+		US_DEBUGP("-- babble\n");
 		return USB_STOR_XFER_LONG;
 
-	/* the transfer was cancelled, presumably by an abort */
+	/* the transfer was cancelled by abort, disconnect, or timeout */
 	case -ECONNRESET:
 		US_DEBUGP("-- transfer cancelled\n");
 		return USB_STOR_XFER_ERROR;
@@ -319,6 +319,11 @@
 		US_DEBUGP("-- short read transfer\n");
 		return USB_STOR_XFER_SHORT;
 
+	/* abort or disconnect in progress */
+	case -EIO:
+		US_DEBUGP("-- abort or disconnect in progress\n");
+		return USB_STOR_XFER_ERROR;
+
 	/* the catch-all error case */
 	default:
 		US_DEBUGP("-- unknown error\n");
@@ -430,7 +435,7 @@
 	/* initialize the scatter-gather request block */
 	US_DEBUGP("%s: xfer %u bytes, %d entries\n", __FUNCTION__,
 			length, num_sg);
-	result = usb_sg_init(us->current_sg, us->pusb_dev, pipe, 0,
+	result = usb_sg_init(&us->current_sg, us->pusb_dev, pipe, 0,
 			sg, num_sg, length, SLAB_NOIO);
 	if (result) {
 		US_DEBUGP("usb_sg_init returned %d\n", result);
@@ -447,19 +452,19 @@
 		/* cancel the request, if it hasn't been cancelled already */
 		if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) {
 			US_DEBUGP("-- cancelling sg request\n");
-			usb_sg_cancel(us->current_sg);
+			usb_sg_cancel(&us->current_sg);
 		}
 	}
 
 	/* wait for the completion of the transfer */
-	usb_sg_wait(us->current_sg);
+	usb_sg_wait(&us->current_sg);
 	clear_bit(US_FLIDX_SG_ACTIVE, &us->flags);
 
-	result = us->current_sg->status;
+	result = us->current_sg.status;
 	if (act_len)
-		*act_len = us->current_sg->bytes;
+		*act_len = us->current_sg.bytes;
 	return interpret_urb_result(us, pipe, length, result,
-			us->current_sg->bytes);
+			us->current_sg.bytes);
 }
 
 /*
@@ -518,7 +523,7 @@
 	/* if the command gets aborted by the higher layers, we need to
 	 * short-circuit all other processing
 	 */
-	if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
+	if (us->sm_state == US_STATE_ABORTING) {
 		US_DEBUGP("-- command was aborted\n");
 		goto Handle_Abort;
 	}
@@ -650,7 +655,7 @@
 		srb->cmd_len = old_cmd_len;
 		memcpy(srb->cmnd, old_cmnd, MAX_COMMAND_SIZE);
 
-		if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
+		if (us->sm_state == US_STATE_ABORTING) {
 			US_DEBUGP("-- auto-sense aborted\n");
 			goto Handle_Abort;
 		}
@@ -734,7 +739,7 @@
 	/* If we are waiting for a scatter-gather operation, cancel it. */
 	if (test_and_clear_bit(US_FLIDX_SG_ACTIVE, &us->flags)) {
 		US_DEBUGP("-- cancelling sg request\n");
-		usb_sg_cancel(us->current_sg);
+		usb_sg_cancel(&us->current_sg);
 	}
 }
 
diff -Nru a/drivers/usb/storage/transport.h b/drivers/usb/storage/transport.h
--- a/drivers/usb/storage/transport.h	Wed Jun 18 23:42:07 2003
+++ b/drivers/usb/storage/transport.h	Wed Jun 18 23:42:07 2003
@@ -63,16 +63,18 @@
 #define US_PR_DPCM_USB  0xf0		/* Combination CB/SDDR09 */
 
 #ifdef CONFIG_USB_STORAGE_FREECOM
-#define US_PR_FREECOM   0xf1	    /* Freecom */
+#define US_PR_FREECOM   0xf1		/* Freecom */
 #endif
 
 #ifdef CONFIG_USB_STORAGE_DATAFAB
-#define US_PR_DATAFAB   0xf2	    /* Datafab chipsets */
+#define US_PR_DATAFAB   0xf2		/* Datafab chipsets */
 #endif
 
 #ifdef CONFIG_USB_STORAGE_JUMPSHOT
-#define US_PR_JUMPSHOT  0xf3	    /* Lexar Jumpshot */
+#define US_PR_JUMPSHOT  0xf3		/* Lexar Jumpshot */
 #endif
+
+#define US_PR_DEVICE	0xff		/* Use device's value */
 
 /*
  * Bulk only data structures
diff -Nru a/drivers/usb/storage/unusual_devs.h b/drivers/usb/storage/unusual_devs.h
--- a/drivers/usb/storage/unusual_devs.h	Wed Jun 18 23:42:08 2003
+++ b/drivers/usb/storage/unusual_devs.h	Wed Jun 18 23:42:08 2003
@@ -75,28 +75,26 @@
 
 /* Deduced by Jonathan Woithe <jwoithe@physics.adelaide.edu.au>
  * Entry needed for flags: US_FL_FIX_INQUIRY because initial inquiry message
- * always fails and confuses drive; without US_FL_START_STOP, drive accesses
- * (read or write) all fail.
+ * always fails and confuses drive.
  */
 UNUSUAL_DEV(  0x0411, 0x001c, 0x0113, 0x0113,
 		"Buffalo",
 		"DUB-P40G HDD",
-		US_SC_SCSI, US_PR_BULK, NULL,
-		US_FL_FIX_INQUIRY | US_FL_START_STOP),
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_FIX_INQUIRY ),
 
 #ifdef CONFIG_USB_STORAGE_DPCM
 UNUSUAL_DEV(  0x0436, 0x0005, 0x0100, 0x0100,
 		"Microtech",
 		"CameraMate (DPCM_USB)",
- 		US_SC_SCSI, US_PR_DPCM_USB, NULL,
-		US_FL_START_STOP ),
+ 		US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
 #endif
 
 /* Made with the help of Edd Dumbill <edd@usefulinc.com> */
 UNUSUAL_DEV(  0x0451, 0x5409, 0x0001, 0x0001,
 		"Frontier Labs",
 		"Nex II Digital",
-		US_SC_SCSI, US_PR_BULK, NULL, US_FL_START_STOP),
+		US_SC_SCSI, US_PR_BULK, NULL, 0),
 
 /* Patch submitted by Philipp Friedrich <philipp@void.at> */
 UNUSUAL_DEV(  0x0482, 0x0100, 0x0100, 0x0100,
@@ -124,15 +122,6 @@
 		"785EPX Storage",
 		US_SC_SCSI, US_PR_BULK, NULL, US_FL_SINGLE_LUN),
 
-/* Reported by Jan Willamowius <jan@willamowius.de>
- * The device needs the flags only.
- */
-UNUSUAL_DEV(  0x04c8, 0x0723, 0x0000, 0x9999,
-		"Konica",
-		"KD-200Z",
-		US_SC_SCSI, US_PR_BULK, NULL,
-		US_FL_START_STOP),
-
 UNUSUAL_DEV(  0x04cb, 0x0100, 0x0000, 0x2210,
 		"Fujifilm",
 		"FinePix 1400Zoom",
@@ -144,7 +133,7 @@
 UNUSUAL_DEV(  0x04ce, 0x0002, 0x0074, 0x0074,
 		"ScanLogic",
 		"SL11R-IDE",
-		US_SC_SCSI, US_PR_BULK, NULL,
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY),
 
 /* Reported by Kriston Fincher <kriston@airmail.net>
@@ -183,14 +172,14 @@
 		"Sandisk",
 		"ImageMate SDDR09",
 		US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
-		US_FL_SINGLE_LUN | US_FL_START_STOP ),
+		US_FL_SINGLE_LUN ),
 
 /* This entry is from Andries.Brouwer@cwi.nl */
 UNUSUAL_DEV(  0x04e6, 0x0005, 0x0100, 0x0208,
 		"SCM Microsystems",
 		"eUSB SmartMedia / CompactFlash Adapter",
 		US_SC_SCSI, US_PR_DPCM_USB, sddr09_init, 
-		US_FL_START_STOP), 
+		0), 
 #endif
 
 UNUSUAL_DEV(  0x04e6, 0x0006, 0x0100, 0x0205, 
@@ -247,40 +236,40 @@
 		"Iomega",
 		"USB Clik! 40",
 		US_SC_8070, US_PR_BULK, NULL,
-		US_FL_FIX_INQUIRY | US_FL_START_STOP ),
+		US_FL_FIX_INQUIRY ),
 
 /* This entry is needed because the device reports Sub=ff */
 UNUSUAL_DEV(  0x054c, 0x0010, 0x0106, 0x0450, 
 		"Sony",
 		"DSC-S30/S70/S75/505V/F505/F707/F717/P8", 
 		US_SC_SCSI, US_PR_CB, NULL,
-		US_FL_SINGLE_LUN | US_FL_START_STOP | US_FL_MODE_XLATE ),
+		US_FL_SINGLE_LUN | US_FL_MODE_XLATE ),
 
 /* Reported by wim@geeks.nl */
 UNUSUAL_DEV(  0x054c, 0x0025, 0x0100, 0x0100, 
 		"Sony",
 		"Memorystick NW-MS7",
 		US_SC_UFI, US_PR_CB, NULL,
-		US_FL_SINGLE_LUN | US_FL_START_STOP ),
+		US_FL_SINGLE_LUN ),
 
 UNUSUAL_DEV(  0x054c, 0x002d, 0x0100, 0x0100, 
 		"Sony",
 		"Memorystick MSAC-US1",
 		US_SC_UFI, US_PR_CB, NULL,
-		US_FL_SINGLE_LUN | US_FL_START_STOP ),
+		US_FL_SINGLE_LUN ),
 
 /* Submitted by Klaus Mueller <k.mueller@intershop.de> */
 UNUSUAL_DEV(  0x054c, 0x002e, 0x0106, 0x0310, 
 		"Sony",
 		"Handycam",
 		US_SC_SCSI, US_PR_CB, NULL,
-		US_FL_SINGLE_LUN | US_FL_START_STOP | US_FL_MODE_XLATE),
+		US_FL_SINGLE_LUN | US_FL_MODE_XLATE),
 
 UNUSUAL_DEV(  0x054c, 0x0032, 0x0000, 0x9999,
 		"Sony",
 		"Memorystick MSC-U01N",
 		US_SC_UFI, US_PR_CB, NULL,
-		US_FL_SINGLE_LUN | US_FL_START_STOP ),
+		US_FL_SINGLE_LUN ),
 		
 /* Submitted by Nathan Babb <nathan@lexi.com> */
 UNUSUAL_DEV(  0x054c, 0x006d, 0x0000, 0x9999,
@@ -316,7 +305,7 @@
 UNUSUAL_DEV( 0x0a17, 0x0004, 0x1000, 0x1000,
                 "Pentax",
                 "Optio 2/3/400",
-                US_SC_8070, US_PR_CBI, NULL,
+                US_SC_DEVICE, US_PR_DEVICE, NULL,
                 US_FL_FIX_INQUIRY ),
 
 /* Submitted by Per Winkvist <per.winkvist@uk.com> */
@@ -380,7 +369,7 @@
 UNUSUAL_DEV(  0x05e3, 0x0700, 0x0000, 0xffff,
 		"SIIG",
 		"CompactFlash Card Reader",
-		US_SC_SCSI, US_PR_BULK, NULL,
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY ),
 
 /* Reported by Peter Marks <peter.marks@turner.com>
@@ -393,7 +382,7 @@
 UNUSUAL_DEV(  0x05e3, 0x0702, 0x0000, 0x0001,
 		"EagleTec",
 		"External Hard Disk",
-		US_SC_SCSI, US_PR_BULK, NULL,
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY ),
 
 UNUSUAL_DEV(  0x05e3, 0x0700, 0x0000, 0x9999,
@@ -402,6 +391,14 @@
 		US_SC_SCSI, US_PR_BULK, NULL,
 		US_FL_FIX_INQUIRY | US_FL_MODE_XLATE),
 
+/* Reported by Hanno Boeck <hanno@gmx.de>
+ * Taken from the Lycoris Kernel */
+UNUSUAL_DEV(  0x0636, 0x0003, 0x0000, 0x9999,
+		"Vivitar",
+		"Vivicam 35Xx",
+		US_SC_SCSI, US_PR_BULK, NULL,
+		US_FL_FIX_INQUIRY | US_FL_MODE_XLATE),
+
 UNUSUAL_DEV(  0x0644, 0x0000, 0x0100, 0x0100, 
 		"TEAC",
 		"Floppy Drive",
@@ -412,25 +409,9 @@
 		"Olympus",
 		"Camedia MAUSB-2",
 		US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
-		US_FL_SINGLE_LUN | US_FL_START_STOP ),
+		US_FL_SINGLE_LUN ),
 #endif
 
-/* Submitted by kedar@centillium
- * Needed for START_STOP flag, but that is unconfirmed */
-UNUSUAL_DEV( 0x0686, 0x4006, 0x0001, 0x0001,
-		"Minolta",
-		"Dimage S304",
-		US_SC_SCSI, US_PR_BULK, NULL,
-		US_FL_START_STOP ),
-
-/* Submitted by f.brugmans@hccnet.nl
- * Needed for START_STOP flag */
-UNUSUAL_DEV( 0x0686, 0x4007, 0x0001, 0x0001,
-		"Minolta",
-		"Dimage S304",
-		US_SC_SCSI, US_PR_BULK, NULL,
-		US_FL_START_STOP ),
-
 UNUSUAL_DEV(  0x0693, 0x0002, 0x0100, 0x0100, 
 		"Hagiwara",
 		"FlashGate SmartMedia",
@@ -445,13 +426,12 @@
 		"Sandisk",
 		"ImageMate SDDR-05a",
 		US_SC_SCSI, US_PR_CB, NULL,
-		US_FL_SINGLE_LUN | US_FL_START_STOP),
+		US_FL_SINGLE_LUN ),
 
 UNUSUAL_DEV(  0x0781, 0x0002, 0x0009, 0x0009, 
 		"Sandisk",
 		"ImageMate SDDR-31",
-		US_SC_SCSI, US_PR_BULK, NULL,
-		US_FL_IGNORE_SER),
+		US_SC_SCSI, US_PR_BULK, NULL, 0 ),
 
 UNUSUAL_DEV(  0x0781, 0x0100, 0x0100, 0x0100,
 		"Sandisk",
@@ -464,7 +444,7 @@
 		"Sandisk",
 		"ImageMate SDDR-09",
 		US_SC_SCSI, US_PR_EUSB_SDDR09, NULL,
-		US_FL_SINGLE_LUN | US_FL_START_STOP ),
+		US_FL_SINGLE_LUN ),
 #endif
 
 #ifdef CONFIG_USB_STORAGE_FREECOM
@@ -490,8 +470,7 @@
 UNUSUAL_DEV(  0x07af, 0x0006, 0x0100, 0x0100,
 		"Microtech",
 		"CameraMate (DPCM_USB)",
- 		US_SC_SCSI, US_PR_DPCM_USB, NULL,
-		US_FL_START_STOP ),
+ 		US_SC_SCSI, US_PR_DPCM_USB, NULL, 0 ),
 #endif
 
 #ifdef CONFIG_USB_STORAGE_DATAFAB
@@ -568,7 +547,7 @@
 UNUSUAL_DEV(  0x07c4, 0xa400, 0x0000, 0xffff,
 		"Datafab",
 		"KECF-USB",
-		US_SC_SCSI, US_PR_BULK, NULL,
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
 		US_FL_FIX_INQUIRY ),
 
 /* Casio QV 2x00/3x00/4000/8000 digital still cameras are not conformant
@@ -629,20 +608,7 @@
 		"Global Channel Solutions",
 		"EasyDisk EDxxxx",
 		US_SC_SCSI, US_PR_BULK, NULL,
-		US_FL_MODE_XLATE | US_FL_START_STOP | US_FL_FIX_INQUIRY ),
-
-/* Submitted by Brian Hall <brihall@pcisys.net>
- * Needed for START_STOP flag */
-UNUSUAL_DEV(  0x0c76, 0x0003, 0x0100, 0x0100,
-		"JMTek",
-		"USBDrive",
-		US_SC_SCSI, US_PR_BULK, NULL,
-		US_FL_START_STOP ),
-UNUSUAL_DEV(  0x0c76, 0x0005, 0x0100, 0x0100,
-		"JMTek",
-		"USBDrive",
-		US_SC_SCSI, US_PR_BULK, NULL,
-		US_FL_START_STOP ),
+		US_FL_MODE_XLATE | US_FL_FIX_INQUIRY ),
 
 /* Reported by Dan Pilone <pilone@slac.com>
  * The device needs the flags only.
@@ -652,8 +618,8 @@
 UNUSUAL_DEV(  0x1065, 0x2136, 0x0000, 0x9999,
 		"CCYU TECHNOLOGY",
 		"EasyDisk Portable Device",
-		US_SC_SCSI, US_PR_BULK, NULL,
-		US_FL_MODE_XLATE | US_FL_START_STOP),
+		US_SC_DEVICE, US_PR_DEVICE, NULL,
+		US_FL_MODE_XLATE ),
 
 #ifdef CONFIG_USB_STORAGE_SDDR55
 UNUSUAL_DEV(  0x55aa, 0xa103, 0x0000, 0x9999, 
@@ -670,5 +636,5 @@
 	"AIPTEK",
 	"PocketCAM 3Mega",
 	US_SC_SCSI, US_PR_BULK, NULL,
-	US_FL_MODE_XLATE | US_FL_START_STOP),
+	US_FL_MODE_XLATE ),
 
diff -Nru a/drivers/usb/storage/usb.c b/drivers/usb/storage/usb.c
--- a/drivers/usb/storage/usb.c	Wed Jun 18 23:42:06 2003
+++ b/drivers/usb/storage/usb.c	Wed Jun 18 23:42:06 2003
@@ -102,8 +102,6 @@
 /* The entries in this table, except for final ones here
  * (USB_MASS_STORAGE_CLASS and the empty entry), correspond,
  * line for line with the entries of us_unsuaul_dev_list[].
- * For now, we duplicate idVendor and idProduct in us_unsual_dev_list,
- * just to avoid alignment bugs.
  */
 
 #define UNUSUAL_DEV(id_vendor, id_product, bcdDeviceMin, bcdDeviceMax, \
@@ -328,13 +326,13 @@
 		scsi_lock(host);
 
 		/* has the command been aborted *already* ? */
-		if (atomic_read(&us->sm_state) == US_STATE_ABORTING) {
+		if (us->sm_state == US_STATE_ABORTING) {
 			us->srb->result = DID_ABORT << 16;
 			goto SkipForAbort;
 		}
 
 		/* set the state and release the lock */
-		atomic_set(&us->sm_state, US_STATE_RUNNING);
+		us->sm_state = US_STATE_RUNNING;
 		scsi_unlock(host);
 
 		/* lock the device pointers */
@@ -353,7 +351,7 @@
 		 */
 		else if (us->srb->device->id && 
 				!(us->flags & US_FL_SCM_MULT_TARG)) {
-			US_DEBUGP("Bad target number (%d/%d)\n",
+			US_DEBUGP("Bad target number (%d:%d)\n",
 				  us->srb->device->id, us->srb->device->lun);
 			us->srb->result = DID_BAD_TARGET << 16;
 		}
@@ -404,12 +402,12 @@
 		 * sm_state == US_STATE_ABORTING, not srb->result == DID_ABORT,
 		 * because an abort request might be received after all the
 		 * USB processing was complete. */
-		if (atomic_read(&us->sm_state) == US_STATE_ABORTING)
+		if (us->sm_state == US_STATE_ABORTING)
 			complete(&(us->notify));
 
 		/* empty the queue, reset the state, and release the lock */
 		us->srb = NULL;
-		atomic_set(&us->sm_state, US_STATE_IDLE);
+		us->sm_state = US_STATE_IDLE;
 		scsi_unlock(host);
 	} /* for (;;) */
 
@@ -424,10 +422,13 @@
  ***********************************************************************/
 
 /* Get the unusual_devs entries and the string descriptors */
-static void get_device_info(struct us_data *us,
-			struct us_unusual_dev *unusual_dev)
+static void get_device_info(struct us_data *us, int id_index)
 {
 	struct usb_device *dev = us->pusb_dev;
+	struct usb_host_interface *altsetting =
+		&us->pusb_intf->altsetting[us->pusb_intf->act_altsetting];
+	struct us_unusual_dev *unusual_dev = &us_unusual_dev_list[id_index];
+	struct usb_device_id *id = &storage_usb_ids[id_index];
 
 	if (unusual_dev->vendorName)
 		US_DEBUGP("Vendor: %s\n", unusual_dev->vendorName);
@@ -436,10 +437,40 @@
 
 	/* Store the entries */
 	us->unusual_dev = unusual_dev;
-	us->subclass = unusual_dev->useProtocol;
-	us->protocol = unusual_dev->useTransport;
+	us->subclass = (unusual_dev->useProtocol == US_SC_DEVICE) ?
+			altsetting->desc.bInterfaceSubClass :
+			unusual_dev->useProtocol;
+	us->protocol = (unusual_dev->useTransport == US_PR_DEVICE) ?
+			altsetting->desc.bInterfaceProtocol :
+			unusual_dev->useTransport;
 	us->flags = unusual_dev->flags;
 
+	/* Log a message if a non-generic unusual_dev entry contains an
+	 * unnecessary subclass or protocol override.  This may stimulate
+	 * reports from users that will help us remove unneeded entries
+	 * from the unusual_devs.h table.
+	 */
+	if (id->idVendor || id->idProduct) {
+		static char *msgs[3] = {
+			"an unneeded SubClass entry",
+			"an unneeded Protocol entry",
+			"unneeded SubClass and Protocol entries"};
+		int msg = -1;
+
+		if (unusual_dev->useProtocol != US_SC_DEVICE &&
+			us->subclass == altsetting->desc.bInterfaceSubClass)
+			msg += 1;
+		if (unusual_dev->useTransport != US_PR_DEVICE &&
+			us->protocol == altsetting->desc.bInterfaceProtocol)
+			msg += 2;
+		if (msg >= 0)
+			printk(KERN_NOTICE USB_STORAGE "This device "
+				"(%04x,%04x) has %s in unusual_devs.h\n"
+				"   Please send a copy of this message to "
+				"<linux-usb-devel@lists.sourceforge.net>\n",
+				id->idVendor, id->idProduct, msgs[msg]);
+	}
+
 	/* Read the device's string descriptors */
 	if (dev->descriptor.iManufacturer)
 		usb_string(dev, dev->descriptor.iManufacturer, 
@@ -447,7 +478,7 @@
 	if (dev->descriptor.iProduct)
 		usb_string(dev, dev->descriptor.iProduct, 
 			   us->product, sizeof(us->product));
-	if (dev->descriptor.iSerialNumber && !(us->flags & US_FL_IGNORE_SER))
+	if (dev->descriptor.iSerialNumber)
 		usb_string(dev, dev->descriptor.iSerialNumber, 
 			   us->serial, sizeof(us->serial));
 
@@ -698,13 +729,6 @@
 		return -ENOMEM;
 	}
 
-	US_DEBUGP("Allocating scatter-gather request block\n");
-	us->current_sg = kmalloc(sizeof(*us->current_sg), GFP_KERNEL);
-	if (!us->current_sg) {
-		US_DEBUGP("allocation failed\n");
-		return -ENOMEM;
-	}
-
 	/* Lock the device while we carry out the next two operations */
 	down(&us->dev_semaphore);
 
@@ -720,7 +744,7 @@
 	up(&us->dev_semaphore);
 
 	/* Start up our control thread */
-	atomic_set(&us->sm_state, US_STATE_IDLE);
+	us->sm_state = US_STATE_IDLE;
 	p = kernel_thread(usb_stor_control_thread, us, CLONE_VM);
 	if (p < 0) {
 		printk(KERN_WARNING USB_STORAGE 
@@ -736,7 +760,7 @@
 	 * Since this is a new device, we need to register a SCSI
 	 * host definition with the higher SCSI layers.
 	 */
-	us->host = scsi_register(&usb_stor_host_template, sizeof(us));
+	us->host = scsi_host_alloc(&usb_stor_host_template, sizeof(us));
 	if (!us->host) {
 		printk(KERN_WARNING USB_STORAGE
 			"Unable to register the scsi host\n");
@@ -772,7 +796,7 @@
 	/* Finish the SCSI host removal sequence */
 	if (us->host) {
 		(struct us_data *) us->host->hostdata[0] = NULL;
-		scsi_unregister(us->host);
+		scsi_host_put(us->host);
 	}
 
 	/* Kill the control thread
@@ -782,7 +806,7 @@
 	 */
 	if (us->pid) {
 		US_DEBUGP("-- sending exit command to thread\n");
-		BUG_ON(atomic_read(&us->sm_state) != US_STATE_IDLE);
+		BUG_ON(us->sm_state != US_STATE_IDLE);
 		us->srb = NULL;
 		up(&(us->sema));
 		wait_for_completion(&(us->notify));
@@ -800,8 +824,6 @@
 	}
 
 	/* Free the USB control blocks */
-	if (us->current_sg)
-		kfree(us->current_sg);
 	if (us->current_urb)
 		usb_free_urb(us->current_urb);
 	if (us->dr)
@@ -852,7 +874,7 @@
 	 * of the match from the usb_device_id table, so we can find the
 	 * corresponding entry in the private table.
 	 */
-	get_device_info(us, &us_unusual_dev_list[id_index]);
+	get_device_info(us, id_index);
 
 #ifdef CONFIG_USB_STORAGE_SDDR09
 	if (us->protocol == US_PR_EUSB_SDDR09 ||
diff -Nru a/drivers/usb/storage/usb.h b/drivers/usb/storage/usb.h
--- a/drivers/usb/storage/usb.h	Wed Jun 18 23:42:08 2003
+++ b/drivers/usb/storage/usb.h	Wed Jun 18 23:42:08 2003
@@ -71,8 +71,6 @@
 #define US_FL_SINGLE_LUN      0x00000001 /* allow access to only LUN 0	    */
 #define US_FL_MODE_XLATE      0x00000002 /* translate _6 to _10 commands for
 						    Win/MacOS compatibility */
-#define US_FL_START_STOP      0x00000004 /* ignore START_STOP commands	    */
-#define US_FL_IGNORE_SER      0x00000010 /* Ignore the serial number given  */
 #define US_FL_SCM_MULT_TARG   0x00000020 /* supports multiple targets	    */
 #define US_FL_FIX_INQUIRY     0x00000040 /* INQUIRY response needs fixing   */
 #define US_FL_FIX_CAPACITY    0x00000080 /* READ CAPACITY response too big  */
@@ -139,7 +137,7 @@
 
 	/* thread information */
 	int			pid;		 /* control thread	 */
-	atomic_t		sm_state;	 /* what we are doing	 */
+	int			sm_state;	 /* what we are doing	 */
 
 	/* interrupt communications data */
 	unsigned char		irqdata[2];	 /* data from USB IRQ	 */
@@ -147,7 +145,7 @@
 	/* control and bulk communications data */
 	struct urb		*current_urb;	 /* non-int USB requests */
 	struct usb_ctrlrequest	*dr;		 /* control requests	 */
-	struct usb_sg_request	*current_sg;	 /* scatter-gather USB   */
+	struct usb_sg_request	current_sg;	 /* scatter-gather USB   */
 
 	/* the semaphore for sleeping the control thread */
 	struct semaphore	sema;		 /* to sleep thread on   */
diff -Nru a/fs/Kconfig.binfmt b/fs/Kconfig.binfmt
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/fs/Kconfig.binfmt	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,116 @@
+config BINFMT_ELF
+	tristate "Kernel support for ELF binaries"
+	depends on MMU
+	default y
+	---help---
+	  ELF (Executable and Linkable Format) is a format for libraries and
+	  executables used across different architectures and operating
+	  systems. Saying Y here will enable your kernel to run ELF binaries
+	  and enlarge it by about 13 KB. ELF support under Linux has now all
+	  but replaced the traditional Linux a.out formats (QMAGIC and ZMAGIC)
+	  because it is portable (this does *not* mean that you will be able
+	  to run executables from different architectures or operating systems
+	  however) and makes building run-time libraries very easy. Many new
+	  executables are distributed solely in ELF format. You definitely
+	  want to say Y here.
+
+	  Information about ELF is contained in the ELF HOWTO available from
+	  <http://www.tldp.org/docs.html#howto>.
+
+	  If you find that after upgrading from Linux kernel 1.2 and saying Y
+	  here, you still can't run any ELF binaries (they just crash), then
+	  you'll have to install the newest ELF runtime libraries, including
+	  ld.so (check the file <file:Documentation/Changes> for location and
+	  latest version).
+
+	  If you want to compile this as a module ( = code which can be
+	  inserted in and removed from the running kernel whenever you want),
+	  say M here and read <file:Documentation/modules.txt>.  The module
+	  will be called binfmt_elf. Saying M or N here is dangerous because
+	  some crucial programs on your system might be in ELF format.
+
+config BINFMT_FLAT
+	tristate "Kernel support for flat binaries"
+	depends on !MMU || SUPERH
+	help
+	  Support uClinux FLAT format binaries.
+
+config BINFMT_ZFLAT
+	bool "Enable ZFLAT support"
+	depends on BINFMT_FLAT
+	help
+	  Support FLAT format compressed binaries
+
+config BINFMT_AOUT
+	tristate "Kernel support for a.out and ECOFF binaries"
+	depends on X86 || ALPHA || ARM || M68K || MIPS || SPARC
+	---help---
+	  A.out (Assembler.OUTput) is a set of formats for libraries and
+	  executables used in the earliest versions of UNIX.  Linux used
+	  the a.out formats QMAGIC and ZMAGIC until they were replaced
+	  with the ELF format.
+
+	  The conversion to ELF started in 1995.  This option is primarily
+	  provided for historical interest and for the benefit of those
+	  who need to run binaries from that era.
+
+	  Most people should answer N here.  If you think you may have
+	  occasional use for this format, enable module support above
+	  and answer M here to compile this support as a module called
+	  binfmt_aout.
+
+	  If any crucial components of your system (such as /sbin/init
+	  or /lib/ld.so) are still in a.out format, you will have to
+	  say Y here.
+
+config OSF4_COMPAT
+	bool "OSF/1 v4 readv/writev compatibility"
+	depends on ALPHA && BINFMT_AOUT
+	help
+	  Say Y if you are using OSF/1 binaries (like Netscape and Acrobat)
+	  with v4 shared libraries freely available from Compaq. If you're
+	  going to use shared libraries from Tru64 version 5.0 or later, say N.
+
+config BINFMT_EM86
+	tristate "Kernel support for Linux/Intel ELF binaries"
+	depends on ALPHA
+	---help---
+	  Say Y here if you want to be able to execute Linux/Intel ELF
+	  binaries just like native Alpha binaries on your Alpha machine. For
+	  this to work, you need to have the emulator /usr/bin/em86 in place.
+
+	  You can get the same functionality by saying N here and saying Y to
+	  "Kernel support for MISC binaries".
+
+	  You may answer M to compile the emulation support as a module and
+	  later load the module when you want to use a Linux/Intel binary. The
+	  module will be called binfmt_em86. If unsure, say Y.
+
+config BINFMT_SOM
+	tristate "Kernel support for SOM binaries"
+	depends on PARISC && HPUX
+	help
+	  SOM is a binary executable format inherited from HP/UX.  Say
+	  Y here to be able to load and execute SOM binaries directly.
+
+config BINFMT_MISC
+	tristate "Kernel support for MISC binaries"
+	---help---
+	  If you say Y here, it will be possible to plug wrapper-driven binary
+	  formats into the kernel. You will like this especially when you use
+	  programs that need an interpreter to run like Java, Python or
+	  Emacs-Lisp. It's also useful if you often run DOS executables under
+	  the Linux DOS emulator DOSEMU (read the DOSEMU-HOWTO, available from
+	  <http://www.tldp.org/docs.html#howto>). Once you have
+	  registered such a binary class with the kernel, you can start one of
+	  those programs simply by typing in its name at a shell prompt; Linux
+	  will automatically feed it to the correct interpreter.
+
+	  You can do other nice things, too. Read the file
+	  <file:Documentation/binfmt_misc.txt> to learn how to use this
+	  feature, and <file:Documentation/java.txt> for information about how
+	  to include Java support.
+
+	  You may say M here for module support and later load the module when
+	  you have use for it; the module is called binfmt_misc. If you
+	  don't know what to answer at this point, say Y.
diff -Nru a/fs/ext3/acl.c b/fs/ext3/acl.c
--- a/fs/ext3/acl.c	Wed Jun 18 23:42:06 2003
+++ b/fs/ext3/acl.c	Wed Jun 18 23:42:06 2003
@@ -416,12 +416,14 @@
 
 		handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
 		if (IS_ERR(handle)) {
+			error = PTR_ERR(handle);
 			ext3_std_error(inode->i_sb, error);
-			return PTR_ERR(handle);
+			goto out;
 		}
 		error = ext3_set_acl(handle, inode, ACL_TYPE_ACCESS, clone);
 		ext3_journal_stop(handle);
 	}
+out:
 	posix_acl_release(clone);
 	return error;
 }
diff -Nru a/fs/ext3/balloc.c b/fs/ext3/balloc.c
--- a/fs/ext3/balloc.c	Wed Jun 18 23:42:05 2003
+++ b/fs/ext3/balloc.c	Wed Jun 18 23:42:05 2003
@@ -110,6 +110,7 @@
 	struct super_block * sb;
 	struct ext3_group_desc * gdp;
 	struct ext3_super_block * es;
+	struct ext3_sb_info *sbi;
 	int err = 0, ret;
 	int dquot_freed_blocks = 0;
 
@@ -118,7 +119,7 @@
 		printk ("ext3_free_blocks: nonexistent device");
 		return;
 	}
-	lock_super (sb);
+	sbi = EXT3_SB(sb);
 	es = EXT3_SB(sb)->s_es;
 	if (block < le32_to_cpu(es->s_first_data_block) ||
 	    block + count < block ||
@@ -170,7 +171,7 @@
 	 */
 	/* @@@ check errors */
 	BUFFER_TRACE(bitmap_bh, "getting undo access");
-	err = ext3_journal_get_undo_access(handle, bitmap_bh);
+	err = ext3_journal_get_undo_access(handle, bitmap_bh, NULL);
 	if (err)
 		goto error_return;
 	
@@ -184,16 +185,14 @@
 	if (err)
 		goto error_return;
 
-	BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get_write_access");
-	err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
-	if (err)
-		goto error_return;
-
+	jbd_lock_bh_state(bitmap_bh);
+	
 	for (i = 0; i < count; i++) {
 		/*
 		 * An HJ special.  This is expensive...
 		 */
 #ifdef CONFIG_JBD_DEBUG
+		jbd_unlock_bh_state(bitmap_bh);
 		{
 			struct buffer_head *debug_bh;
 			debug_bh = sb_find_get_block(sb, block + i);
@@ -206,20 +205,8 @@
 				__brelse(debug_bh);
 			}
 		}
+		jbd_lock_bh_state(bitmap_bh);
 #endif
-		BUFFER_TRACE(bitmap_bh, "clear bit");
-		if (!ext3_clear_bit (bit + i, bitmap_bh->b_data)) {
-			ext3_error (sb, __FUNCTION__,
-				      "bit already cleared for block %lu", 
-				      block + i);
-			BUFFER_TRACE(bitmap_bh, "bit already cleared");
-		} else {
-			dquot_freed_blocks++;
-			gdp->bg_free_blocks_count =
-			  cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count)+1);
-			es->s_free_blocks_count =
-			  cpu_to_le32(le32_to_cpu(es->s_free_blocks_count)+1);
-		}
 		/* @@@ This prevents newly-allocated data from being
 		 * freed and then reallocated within the same
 		 * transaction. 
@@ -238,11 +225,36 @@
 		 * activity on the buffer any more and so it is safe to
 		 * reallocate it.  
 		 */
-		BUFFER_TRACE(bitmap_bh, "clear in b_committed_data");
+		BUFFER_TRACE(bitmap_bh, "set in b_committed_data");
 		J_ASSERT_BH(bitmap_bh,
 				bh2jh(bitmap_bh)->b_committed_data != NULL);
-		ext3_set_bit(bit + i, bh2jh(bitmap_bh)->b_committed_data);
+		ext3_set_bit_atomic(sb_bgl_lock(sbi, block_group), bit + i,
+				bh2jh(bitmap_bh)->b_committed_data);
+
+		/*
+		 * We clear the bit in the bitmap after setting the committed
+		 * data bit, because this is the reverse order to that which
+		 * the allocator uses.
+		 */
+		BUFFER_TRACE(bitmap_bh, "clear bit");
+		if (!ext3_clear_bit_atomic(sb_bgl_lock(sbi, block_group),
+						bit + i, bitmap_bh->b_data)) {
+			ext3_error (sb, __FUNCTION__,
+				      "bit already cleared for block %lu", 
+				      block + i);
+			BUFFER_TRACE(bitmap_bh, "bit already cleared");
+		} else {
+			dquot_freed_blocks++;
+		}
 	}
+	jbd_unlock_bh_state(bitmap_bh);
+
+	spin_lock(sb_bgl_lock(sbi, block_group));
+	gdp->bg_free_blocks_count =
+		cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) +
+			dquot_freed_blocks);
+	spin_unlock(sb_bgl_lock(sbi, block_group));
+	percpu_counter_mod(&sbi->s_freeblocks_counter, count);
 
 	/* We dirtied the bitmap block */
 	BUFFER_TRACE(bitmap_bh, "dirtied bitmap block");
@@ -253,11 +265,6 @@
 	ret = ext3_journal_dirty_metadata(handle, gd_bh);
 	if (!err) err = ret;
 
-	/* And the superblock */
-	BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "dirtied superblock");
-	ret = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
-	if (!err) err = ret;
-
 	if (overflow && !err) {
 		block += count;
 		count = overflow;
@@ -267,7 +274,6 @@
 error_return:
 	brelse(bitmap_bh);
 	ext3_std_error(sb, err);
-	unlock_super(sb);
 	if (dquot_freed_blocks)
 		DQUOT_FREE_BLOCK(inode, dquot_freed_blocks);
 	return;
@@ -288,11 +294,12 @@
  * data-writes at some point, and disable it for metadata allocations or
  * sync-data inodes.
  */
-static int ext3_test_allocatable(int nr, struct buffer_head *bh)
+static inline int ext3_test_allocatable(int nr, struct buffer_head *bh,
+					int have_access)
 {
 	if (ext3_test_bit(nr, bh->b_data))
 		return 0;
-	if (!buffer_jbd(bh) || !bh2jh(bh)->b_committed_data)
+	if (!have_access || !buffer_jbd(bh) || !bh2jh(bh)->b_committed_data)
 		return 1;
 	return !ext3_test_bit(nr, bh2jh(bh)->b_committed_data);
 }
@@ -304,8 +311,8 @@
  * the initial goal; then for a free byte somewhere in the bitmap; then
  * for any free bit in the bitmap.
  */
-static int find_next_usable_block(int start,
-			struct buffer_head *bh, int maxblocks)
+static int find_next_usable_block(int start, struct buffer_head *bh,
+				int maxblocks, int have_access)
 {
 	int here, next;
 	char *p, *r;
@@ -321,7 +328,8 @@
 		 */
 		int end_goal = (start + 63) & ~63;
 		here = ext3_find_next_zero_bit(bh->b_data, end_goal, start);
-		if (here < end_goal && ext3_test_allocatable(here, bh))
+		if (here < end_goal &&
+			ext3_test_allocatable(here, bh, have_access))
 			return here;
 		
 		ext3_debug ("Bit not found near goal\n");
@@ -344,7 +352,7 @@
 	r = memscan(p, 0, (maxblocks - here + 7) >> 3);
 	next = (r - ((char *) bh->b_data)) << 3;
 	
-	if (next < maxblocks && ext3_test_allocatable(next, bh))
+	if (next < maxblocks && ext3_test_allocatable(next, bh, have_access))
 		return next;
 	
 	/* The bitmap search --- search forward alternately
@@ -356,17 +364,115 @@
 						 maxblocks, here);
 		if (next >= maxblocks)
 			return -1;
-		if (ext3_test_allocatable(next, bh))
+		if (ext3_test_allocatable(next, bh, have_access))
 			return next;
 
-		J_ASSERT_BH(bh, bh2jh(bh)->b_committed_data);
-		here = ext3_find_next_zero_bit
-			((unsigned long *) bh2jh(bh)->b_committed_data, 
-			 maxblocks, next);
+		if (have_access)
+			here = ext3_find_next_zero_bit
+				((unsigned long *) bh2jh(bh)->b_committed_data, 
+			 	maxblocks, next);
+	}
+	return -1;
+}
+
+/*
+ * We think we can allocate this block in this bitmap.  Try to set the bit.
+ * If that succeeds then check that nobody has allocated and then freed the
+ * block since we saw that is was not marked in b_committed_data.  If it _was_
+ * allocated and freed then clear the bit in the bitmap again and return
+ * zero (failure).
+ */
+static inline int
+claim_block(spinlock_t *lock, int block, struct buffer_head *bh)
+{
+	if (ext3_set_bit_atomic(lock, block, bh->b_data))
+		return 0;
+	if (buffer_jbd(bh) && bh2jh(bh)->b_committed_data &&
+			ext3_test_bit(block, bh2jh(bh)->b_committed_data)) {
+		ext3_clear_bit_atomic(lock, block, bh->b_data);
+		return 0;
+	}
+	return 1;
+}
+
+/*
+ * If we failed to allocate the desired block then we may end up crossing to a
+ * new bitmap.  In that case we must release write access to the old one via
+ * ext3_journal_release_buffer(), else we'll run out of credits.
+ */
+static int
+ext3_try_to_allocate(struct super_block *sb, handle_t *handle, int group,
+		struct buffer_head *bitmap_bh, int goal, int *errp)
+{
+	int i, fatal = 0;
+	int have_access = 0;
+	int credits = 0;
+
+	*errp = 0;
+
+	if (goal >= 0 && ext3_test_allocatable(goal, bitmap_bh, 0))
+		goto got;
+
+repeat:
+	goal = find_next_usable_block(goal, bitmap_bh,
+				EXT3_BLOCKS_PER_GROUP(sb), have_access);
+	if (goal < 0)
+		goto fail;
+
+	for (i = 0;
+		i < 7 && goal > 0 && 
+			ext3_test_allocatable(goal - 1, bitmap_bh, have_access);
+		i++, goal--);
+
+got:
+	if (!have_access) {
+		/*
+		 * Make sure we use undo access for the bitmap, because it is
+	 	 * critical that we do the frozen_data COW on bitmap buffers in
+	 	 * all cases even if the buffer is in BJ_Forget state in the
+	 	 * committing transaction.
+		 */
+		BUFFER_TRACE(bitmap_bh, "get undo access for new block");
+		fatal = ext3_journal_get_undo_access(handle, bitmap_bh,
+							&credits);
+		if (fatal) {
+			*errp = fatal;
+			goto fail;
+		}
+		jbd_lock_bh_state(bitmap_bh);
+		have_access = 1;
+	}
+
+	if (!claim_block(sb_bgl_lock(EXT3_SB(sb), group), goal, bitmap_bh)) {
+		/*
+		 * The block was allocated by another thread, or it was
+		 * allocated and then freed by another thread
+		 */
+		goal++;
+		if (goal >= EXT3_BLOCKS_PER_GROUP(sb))
+			goto fail;
+		goto repeat;
+	}
+
+	BUFFER_TRACE(bitmap_bh, "journal_dirty_metadata for bitmap block");
+	jbd_unlock_bh_state(bitmap_bh);
+	fatal = ext3_journal_dirty_metadata(handle, bitmap_bh);
+	if (fatal) {
+		*errp = fatal;
+		goto fail;
+	}
+
+	return goal;
+fail:
+	if (have_access) {
+		BUFFER_TRACE(bitmap_bh, "journal_release_buffer");
+		jbd_unlock_bh_state(bitmap_bh);
+		ext3_journal_release_buffer(handle, bitmap_bh, credits);
 	}
 	return -1;
 }
 
+
 /*
  * ext3_new_block uses a goal block to assist allocation.  If the goal is
  * free, or there is a free block within 32 blocks of the goal, that block
@@ -383,13 +489,15 @@
 	struct buffer_head *gdp_bh;		/* bh2 */
 	int group_no;				/* i */
 	int ret_block;				/* j */
-	int bit;				/* k */
+	int bgi;				/* blockgroup iteration index */
 	int target_block;			/* tmp */
 	int fatal = 0, err;
 	int performed_allocation = 0;
+	int free_blocks, root_blocks;
 	struct super_block *sb;
 	struct ext3_group_desc *gdp;
 	struct ext3_super_block *es;
+	struct ext3_sb_info *sbi;
 #ifdef EXT3FS_DEBUG
 	static int goal_hits = 0, goal_attempts = 0;
 #endif
@@ -408,18 +516,19 @@
 		return 0;
 	}
 
-	lock_super(sb);
+	sbi = EXT3_SB(sb);
 	es = EXT3_SB(sb)->s_es;
-	if (le32_to_cpu(es->s_free_blocks_count) <=
-			le32_to_cpu(es->s_r_blocks_count) &&
-	    ((EXT3_SB(sb)->s_resuid != current->fsuid) &&
-	     (EXT3_SB(sb)->s_resgid == 0 ||
-	      !in_group_p(EXT3_SB(sb)->s_resgid)) && 
-	     !capable(CAP_SYS_RESOURCE)))
-		goto out;
-
 	ext3_debug("goal=%lu.\n", goal);
 
+	free_blocks = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
+	root_blocks = le32_to_cpu(es->s_r_blocks_count);
+	if (free_blocks < root_blocks + 1 && !capable(CAP_SYS_RESOURCE) &&
+		sbi->s_resuid != current->fsuid &&
+		(sbi->s_resgid == 0 || !in_group_p (sbi->s_resgid))) {
+		*errp = -ENOSPC;
+		return 0;
+	}
+
 	/*
 	 * First, test whether the goal block is free.
 	 */
@@ -432,40 +541,26 @@
 	if (!gdp)
 		goto io_error;
 
-	if (le16_to_cpu(gdp->bg_free_blocks_count) > 0) {
+	free_blocks = le16_to_cpu(gdp->bg_free_blocks_count);
+	if (free_blocks > 0) {
 		ret_block = ((goal - le32_to_cpu(es->s_first_data_block)) %
 				EXT3_BLOCKS_PER_GROUP(sb));
-#ifdef EXT3FS_DEBUG
-		if (ret_block)
-			goal_attempts++;
-#endif
 		bitmap_bh = read_block_bitmap(sb, group_no);
 		if (!bitmap_bh)
-			goto io_error;
-
-		ext3_debug("goal is at %d:%d.\n", group_no, ret_block);
-
-		if (ext3_test_allocatable(ret_block, bitmap_bh)) {
-#ifdef EXT3FS_DEBUG
-			goal_hits++;
-			ext3_debug("goal bit allocated.\n");
-#endif
-			goto got_block;
-		}
-
-		ret_block = find_next_usable_block(ret_block, bitmap_bh,
-				EXT3_BLOCKS_PER_GROUP(sb));
+			goto io_error;	
+		ret_block = ext3_try_to_allocate(sb, handle, group_no,
+					bitmap_bh, ret_block, &fatal);
+		if (fatal)
+			goto out;
 		if (ret_block >= 0)
-			goto search_back;
+			goto allocated;
 	}
-
-	ext3_debug("Bit not found in block group %d.\n", group_no);
-
+	
 	/*
 	 * Now search the rest of the groups.  We assume that 
 	 * i and gdp correctly point to the last group visited.
 	 */
-	for (bit = 0; bit < EXT3_SB(sb)->s_groups_count; bit++) {
+	for (bgi = 0; bgi < EXT3_SB(sb)->s_groups_count; bgi++) {
 		group_no++;
 		if (group_no >= EXT3_SB(sb)->s_groups_count)
 			group_no = 0;
@@ -474,57 +569,36 @@
 			*errp = -EIO;
 			goto out;
 		}
-		if (le16_to_cpu(gdp->bg_free_blocks_count) > 0) {
-			brelse(bitmap_bh);
-			bitmap_bh = read_block_bitmap(sb, group_no);
-			if (!bitmap_bh)
-				goto io_error;
-			ret_block = find_next_usable_block(-1, bitmap_bh, 
-						   EXT3_BLOCKS_PER_GROUP(sb));
-			if (ret_block >= 0) 
-				goto search_back;
-		}
+		free_blocks = le16_to_cpu(gdp->bg_free_blocks_count);
+		if (free_blocks <= 0)
+			continue;
+
+		brelse(bitmap_bh);
+		bitmap_bh = read_block_bitmap(sb, group_no);
+		if (!bitmap_bh)
+			goto io_error;
+		ret_block = ext3_try_to_allocate(sb, handle, group_no,
+						bitmap_bh, -1, &fatal);
+		if (fatal)
+			goto out;
+		if (ret_block >= 0) 
+			goto allocated;
 	}
 
 	/* No space left on the device */
+	*errp = -ENOSPC;
 	goto out;
 
-search_back:
-	/* 
-	 * We have succeeded in finding a free byte in the block
-	 * bitmap.  Now search backwards up to 7 bits to find the
-	 * start of this group of free blocks.
-	 */
-	for (	bit = 0;
-		bit < 7 && ret_block > 0 &&
-			ext3_test_allocatable(ret_block - 1, bitmap_bh);
-		bit++, ret_block--)
-		;
-	
-got_block:
+allocated:
 
 	ext3_debug("using block group %d(%d)\n",
 			group_no, gdp->bg_free_blocks_count);
 
-	/* Make sure we use undo access for the bitmap, because it is
-           critical that we do the frozen_data COW on bitmap buffers in
-           all cases even if the buffer is in BJ_Forget state in the
-           committing transaction.  */
-	BUFFER_TRACE(bitmap_bh, "get undo access for marking new block");
-	fatal = ext3_journal_get_undo_access(handle, bitmap_bh);
-	if (fatal)
-		goto out;
-	
 	BUFFER_TRACE(gdp_bh, "get_write_access");
 	fatal = ext3_journal_get_write_access(handle, gdp_bh);
 	if (fatal)
 		goto out;
 
-	BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get_write_access");
-	fatal = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
-	if (fatal)
-		goto out;
-
 	target_block = ret_block + group_no * EXT3_BLOCKS_PER_GROUP(sb)
 				+ le32_to_cpu(es->s_first_data_block);
 
@@ -536,11 +610,6 @@
 			    "Allocating block in system zone - "
 			    "block = %u", target_block);
 
-	/* The superblock lock should guard against anybody else beating
-	 * us to this point! */
-	J_ASSERT_BH(bitmap_bh, !ext3_test_bit(ret_block, bitmap_bh->b_data));
-	BUFFER_TRACE(bitmap_bh, "setting bitmap bit");
-	ext3_set_bit(ret_block, bitmap_bh->b_data);
 	performed_allocation = 1;
 
 #ifdef CONFIG_JBD_DEBUG
@@ -555,21 +624,23 @@
 			brelse(debug_bh);
 		}
 	}
-#endif
-	if (buffer_jbd(bitmap_bh) && bh2jh(bitmap_bh)->b_committed_data)
-		J_ASSERT_BH(bitmap_bh,
-			!ext3_test_bit(ret_block,
-					bh2jh(bitmap_bh)->b_committed_data));
+	jbd_lock_bh_state(bitmap_bh);
+	spin_lock(sb_bgl_lock(sbi, group_no));
+	if (buffer_jbd(bitmap_bh) && bh2jh(bitmap_bh)->b_committed_data) {
+		if (ext3_test_bit(ret_block,
+				bh2jh(bitmap_bh)->b_committed_data)) {
+			printk("%s: block was unexpectedly set in "
+				"b_committed_data\n", __FUNCTION__);
+		}
+	}
 	ext3_debug("found bit %d\n", ret_block);
+	spin_unlock(sb_bgl_lock(sbi, group_no));
+	jbd_unlock_bh_state(bitmap_bh);
+#endif
 
 	/* ret_block was blockgroup-relative.  Now it becomes fs-relative */
 	ret_block = target_block;
 
-	BUFFER_TRACE(bitmap_bh, "journal_dirty_metadata for bitmap block");
-	err = ext3_journal_dirty_metadata(handle, bitmap_bh);
-	if (!fatal)
-		fatal = err;
-	
 	if (ret_block >= le32_to_cpu(es->s_blocks_count)) {
 		ext3_error(sb, "ext3_new_block",
 			    "block(%d) >= blocks count(%d) - "
@@ -586,27 +657,21 @@
 	ext3_debug("allocating block %d. Goal hits %d of %d.\n",
 			ret_block, goal_hits, goal_attempts);
 
+	spin_lock(sb_bgl_lock(sbi, group_no));
 	gdp->bg_free_blocks_count =
 			cpu_to_le16(le16_to_cpu(gdp->bg_free_blocks_count) - 1);
-	es->s_free_blocks_count =
-			cpu_to_le32(le32_to_cpu(es->s_free_blocks_count) - 1);
+	spin_unlock(sb_bgl_lock(sbi, group_no));
+	percpu_counter_mod(&sbi->s_freeblocks_counter, -1);
 
 	BUFFER_TRACE(gdp_bh, "journal_dirty_metadata for group descriptor");
 	err = ext3_journal_dirty_metadata(handle, gdp_bh);
 	if (!fatal)
 		fatal = err;
 
-	BUFFER_TRACE(EXT3_SB(sb)->s_sbh,
-			"journal_dirty_metadata for superblock");
-	err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
-	if (!fatal)
-		fatal = err;
-
 	sb->s_dirt = 1;
 	if (fatal)
 		goto out;
 
-	unlock_super(sb);
 	*errp = 0;
 	brelse(bitmap_bh);
 	return ret_block;
@@ -618,7 +683,6 @@
 		*errp = fatal;
 		ext3_std_error(sb, fatal);
 	}
-	unlock_super(sb);
 	/*
 	 * Undo the block allocation
 	 */
@@ -631,12 +695,13 @@
 
 unsigned long ext3_count_free_blocks(struct super_block *sb)
 {
+	unsigned long desc_count;
+	struct ext3_group_desc *gdp;
+	int i;
 #ifdef EXT3FS_DEBUG
 	struct ext3_super_block *es;
-	unsigned long desc_count, bitmap_count, x;
+	unsigned long bitmap_count, x;
 	struct buffer_head *bitmap_bh = NULL;
-	struct ext3_group_desc *gdp;
-	int i;
 	
 	lock_super(sb);
 	es = EXT3_SB(sb)->s_es;
@@ -664,7 +729,15 @@
 	unlock_super(sb);
 	return bitmap_count;
 #else
-	return le32_to_cpu(EXT3_SB(sb)->s_es->s_free_blocks_count);
+	desc_count = 0;
+	for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
+		gdp = ext3_get_group_desc(sb, i, NULL);
+		if (!gdp)
+			continue;
+		desc_count += le16_to_cpu(gdp->bg_free_blocks_count);
+	}
+
+	return desc_count;
 #endif
 }
 
diff -Nru a/fs/ext3/ialloc.c b/fs/ext3/ialloc.c
--- a/fs/ext3/ialloc.c	Wed Jun 18 23:42:07 2003
+++ b/fs/ext3/ialloc.c	Wed Jun 18 23:42:07 2003
@@ -97,6 +97,7 @@
 	unsigned long bit;
 	struct ext3_group_desc * gdp;
 	struct ext3_super_block * es;
+	struct ext3_sb_info *sbi = EXT3_SB(sb);
 	int fatal = 0, err;
 
 	if (atomic_read(&inode->i_count) > 1) {
@@ -131,7 +132,6 @@
 	/* Do this BEFORE marking the inode not in use or returning an error */
 	clear_inode (inode);
 
-	lock_super (sb);
 	es = EXT3_SB(sb)->s_es;
 	if (ino < EXT3_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
 		ext3_error (sb, "ext3_free_inode",
@@ -150,7 +150,8 @@
 		goto error_return;
 
 	/* Ok, now we can actually update the inode bitmaps.. */
-	if (!ext3_clear_bit(bit, bitmap_bh->b_data))
+	if (!ext3_clear_bit_atomic(sb_bgl_lock(sbi, block_group),
+					bit, bitmap_bh->b_data))
 		ext3_error (sb, "ext3_free_inode",
 			      "bit already cleared for inode %lu", ino);
 	else {
@@ -160,28 +161,22 @@
 		fatal = ext3_journal_get_write_access(handle, bh2);
 		if (fatal) goto error_return;
 
-		BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get write access");
-		fatal = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
-		if (fatal) goto error_return;
-
 		if (gdp) {
+			spin_lock(sb_bgl_lock(sbi, block_group));
 			gdp->bg_free_inodes_count = cpu_to_le16(
 				le16_to_cpu(gdp->bg_free_inodes_count) + 1);
-			if (is_directory) {
+			if (is_directory)
 				gdp->bg_used_dirs_count = cpu_to_le16(
 				  le16_to_cpu(gdp->bg_used_dirs_count) - 1);
-				EXT3_SB(sb)->s_dir_count--;
-			}
+			spin_unlock(sb_bgl_lock(sbi, block_group));
+			percpu_counter_inc(&sbi->s_freeinodes_counter);
+			if (is_directory)
+				percpu_counter_dec(&sbi->s_dirs_counter);
+
 		}
 		BUFFER_TRACE(bh2, "call ext3_journal_dirty_metadata");
 		err = ext3_journal_dirty_metadata(handle, bh2);
 		if (!fatal) fatal = err;
-		es->s_free_inodes_count =
-			cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) + 1);
-		BUFFER_TRACE(EXT3_SB(sb)->s_sbh,
-					"call ext3_journal_dirty_metadata");
-		err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
-		if (!fatal) fatal = err;
 	}
 	BUFFER_TRACE(bitmap_bh, "call ext3_journal_dirty_metadata");
 	err = ext3_journal_dirty_metadata(handle, bitmap_bh);
@@ -191,7 +186,6 @@
 error_return:
 	brelse(bitmap_bh);
 	ext3_std_error(sb, fatal);
-	unlock_super(sb);
 }
 
 /*
@@ -206,13 +200,15 @@
  */
 static int find_group_dir(struct super_block *sb, struct inode *parent)
 {
-	struct ext3_super_block * es = EXT3_SB(sb)->s_es;
 	int ngroups = EXT3_SB(sb)->s_groups_count;
-	int avefreei = le32_to_cpu(es->s_free_inodes_count) / ngroups;
+	int freei, avefreei;
 	struct ext3_group_desc *desc, *best_desc = NULL;
 	struct buffer_head *bh;
 	int group, best_group = -1;
 
+	freei = percpu_counter_read_positive(&EXT3_SB(sb)->s_freeinodes_counter);
+	avefreei = freei / ngroups;
+
 	for (group = 0; group < ngroups; group++) {
 		desc = ext3_get_group_desc (sb, group, &bh);
 		if (!desc || !desc->bg_free_inodes_count)
@@ -264,15 +260,20 @@
 	struct ext3_super_block *es = sbi->s_es;
 	int ngroups = sbi->s_groups_count;
 	int inodes_per_group = EXT3_INODES_PER_GROUP(sb);
-	int avefreei = le32_to_cpu(es->s_free_inodes_count) / ngroups;
-	int avefreeb = le32_to_cpu(es->s_free_blocks_count) / ngroups;
-	int blocks_per_dir;
-	int ndirs = sbi->s_dir_count;
+	int freei, avefreei;
+	int freeb, avefreeb;
+	int blocks_per_dir, ndirs;
 	int max_debt, max_dirs, min_blocks, min_inodes;
 	int group = -1, i;
 	struct ext3_group_desc *desc;
 	struct buffer_head *bh;
 
+	freei = percpu_counter_read_positive(&sbi->s_freeinodes_counter);
+	avefreei = freei / ngroups;
+	freeb = percpu_counter_read_positive(&sbi->s_freeblocks_counter);
+	avefreeb = freeb / ngroups;
+	ndirs = percpu_counter_read_positive(&sbi->s_dirs_counter);
+
 	if ((parent == sb->s_root->d_inode) ||
 	    (parent->i_flags & EXT3_TOPDIR_FL)) {
 		int best_ndir = inodes_per_group;
@@ -299,8 +300,7 @@
 		goto fallback;
 	}
 
-	blocks_per_dir = (le32_to_cpu(es->s_blocks_count) -
-			  le32_to_cpu(es->s_free_blocks_count)) / ndirs;
+	blocks_per_dir = (le32_to_cpu(es->s_blocks_count) - freeb) / ndirs;
 
 	max_dirs = ndirs / ngroups + inodes_per_group / 16;
 	min_inodes = avefreei - inodes_per_group / 4;
@@ -340,6 +340,15 @@
 			return group;
 	}
 
+	if (avefreei) {
+		/*
+		 * The free-inodes counter is approximate, and for really small
+		 * filesystems the above test can fail to find any blockgroups
+		 */
+		avefreei = 0;
+		goto fallback;
+	}
+
 	return -1;
 }
 
@@ -417,13 +426,15 @@
 	struct buffer_head *bitmap_bh = NULL;
 	struct buffer_head *bh2;
 	int group;
-	unsigned long ino;
+	unsigned long ino = 0;
 	struct inode * inode;
-	struct ext3_group_desc * gdp;
+	struct ext3_group_desc * gdp = NULL;
 	struct ext3_super_block * es;
 	struct ext3_inode_info *ei;
+	struct ext3_sb_info *sbi;
 	int err = 0;
 	struct inode *ret;
+	int i;
 
 	/* Cannot create files in a deleted directory */
 	if (!dir || !dir->i_nlink)
@@ -435,9 +446,8 @@
 		return ERR_PTR(-ENOMEM);
 	ei = EXT3_I(inode);
 
-	lock_super (sb);
 	es = EXT3_SB(sb)->s_es;
-repeat:
+	sbi = EXT3_SB(sb);
 	if (S_ISDIR(mode)) {
 		if (test_opt (sb, OLDALLOC))
 			group = find_group_dir(sb, dir);
@@ -450,48 +460,55 @@
 	if (group == -1)
 		goto out;
 
-	err = -EIO;
-	brelse(bitmap_bh);
-	bitmap_bh = read_inode_bitmap(sb, group);
-	if (!bitmap_bh)
-		goto fail;
-	gdp = ext3_get_group_desc (sb, group, &bh2);
-
-	if ((ino = ext3_find_first_zero_bit((unsigned long *)bitmap_bh->b_data,
-				      EXT3_INODES_PER_GROUP(sb))) <
-	    EXT3_INODES_PER_GROUP(sb)) {
-		BUFFER_TRACE(bitmap_bh, "get_write_access");
-		err = ext3_journal_get_write_access(handle, bitmap_bh);
-		if (err) goto fail;
-
-		if (ext3_set_bit(ino, bitmap_bh->b_data)) {
-			ext3_error (sb, "ext3_new_inode",
-				      "bit already set for inode %lu", ino);
-			goto repeat;
-		}
-		BUFFER_TRACE(bitmap_bh, "call ext3_journal_dirty_metadata");
-		err = ext3_journal_dirty_metadata(handle, bitmap_bh);
-		if (err) goto fail;
-	} else {
-		if (le16_to_cpu(gdp->bg_free_inodes_count) != 0) {
-			ext3_error (sb, "ext3_new_inode",
-				    "Free inodes count corrupted in group %d",
-				    group);
-			/* Is it really ENOSPC? */
-			err = -ENOSPC;
-			if (sb->s_flags & MS_RDONLY)
+	for (i = 0; i < sbi->s_groups_count; i++) {
+		gdp = ext3_get_group_desc(sb, group, &bh2);
+		
+		err = -EIO;
+		brelse(bitmap_bh);
+		bitmap_bh = read_inode_bitmap(sb, group);
+		if (!bitmap_bh)
+			goto fail;
+		
+		ino = ext3_find_first_zero_bit((unsigned long *)
+				bitmap_bh->b_data, EXT3_INODES_PER_GROUP(sb));
+		if (ino < EXT3_INODES_PER_GROUP(sb)) {
+			int credits = 0;
+
+			BUFFER_TRACE(bitmap_bh, "get_write_access");
+			err = ext3_journal_get_write_access_credits(handle,
+							bitmap_bh, &credits);
+			if (err)
 				goto fail;
 
-			BUFFER_TRACE(bh2, "get_write_access");
-			err = ext3_journal_get_write_access(handle, bh2);
-			if (err) goto fail;
-			gdp->bg_free_inodes_count = 0;
-			BUFFER_TRACE(bh2, "call ext3_journal_dirty_metadata");
-			err = ext3_journal_dirty_metadata(handle, bh2);
-			if (err) goto fail;
+			if (!ext3_set_bit_atomic(sb_bgl_lock(sbi, group),
+						ino, bitmap_bh->b_data)) {
+				/* we won it */
+				BUFFER_TRACE(bitmap_bh,
+					"call ext3_journal_dirty_metadata");
+				err = ext3_journal_dirty_metadata(handle,
+								bitmap_bh);
+				if (err)
+					goto fail;
+				goto got;
+			}
+			/* we lost it */
+			journal_release_buffer(handle, bitmap_bh, credits);
 		}
-		goto repeat;
+
+		/*
+		 * This case is possible in concurrent environment.  It is very
+		 * rare.  We cannot repeat the find_group_xxx() call because
+		 * that will simply return the same blockgroup, because the
+		 * group descriptor metadata has not yet been updated.
+		 * So we just go onto the next blockgroup.
+		 */
+		if (++group == sbi->s_groups_count)
+			group = 0;
 	}
+	err = -ENOSPC;
+	goto out;
+
+got:
 	ino += group * EXT3_INODES_PER_GROUP(sb) + 1;
 	if (ino < EXT3_FIRST_INO(sb) || ino > le32_to_cpu(es->s_inodes_count)) {
 		ext3_error (sb, "ext3_new_inode",
@@ -504,26 +521,22 @@
 	BUFFER_TRACE(bh2, "get_write_access");
 	err = ext3_journal_get_write_access(handle, bh2);
 	if (err) goto fail;
+	spin_lock(sb_bgl_lock(sbi, group));
 	gdp->bg_free_inodes_count =
 		cpu_to_le16(le16_to_cpu(gdp->bg_free_inodes_count) - 1);
 	if (S_ISDIR(mode)) {
 		gdp->bg_used_dirs_count =
 			cpu_to_le16(le16_to_cpu(gdp->bg_used_dirs_count) + 1);
-		EXT3_SB(sb)->s_dir_count++;
 	}
+	spin_unlock(sb_bgl_lock(sbi, group));
 	BUFFER_TRACE(bh2, "call ext3_journal_dirty_metadata");
 	err = ext3_journal_dirty_metadata(handle, bh2);
 	if (err) goto fail;
 	
-	BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "get_write_access");
-	err = ext3_journal_get_write_access(handle, EXT3_SB(sb)->s_sbh);
-	if (err) goto fail;
-	es->s_free_inodes_count =
-		cpu_to_le32(le32_to_cpu(es->s_free_inodes_count) - 1);
-	BUFFER_TRACE(EXT3_SB(sb)->s_sbh, "call ext3_journal_dirty_metadata");
-	err = ext3_journal_dirty_metadata(handle, EXT3_SB(sb)->s_sbh);
+	percpu_counter_dec(&sbi->s_freeinodes_counter);
+	if (S_ISDIR(mode))
+		percpu_counter_inc(&sbi->s_dirs_counter);
 	sb->s_dirt = 1;
-	if (err) goto fail;
 
 	inode->i_uid = current->fsuid;
 	if (test_opt (sb, GRPID))
@@ -576,7 +589,6 @@
 
 	ei->i_state = EXT3_STATE_NEW;
 
-	unlock_super(sb);
 	ret = inode;
 	if(DQUOT_ALLOC_INODE(inode)) {
 		DQUOT_DROP(inode);
@@ -600,7 +612,6 @@
 fail:
 	ext3_std_error(sb, err);
 out:
-	unlock_super(sb);
 	iput(inode);
 	ret = ERR_PTR(err);
 really_out:
@@ -673,12 +684,13 @@
 
 unsigned long ext3_count_free_inodes (struct super_block * sb)
 {
+	unsigned long desc_count;
+	struct ext3_group_desc *gdp;
+	int i;
 #ifdef EXT3FS_DEBUG
 	struct ext3_super_block *es;
-	unsigned long desc_count, bitmap_count, x;
-	struct ext3_group_desc *gdp;
+	unsigned long bitmap_count, x;
 	struct buffer_head *bitmap_bh = NULL;
-	int i;
 
 	lock_super (sb);
 	es = EXT3_SB(sb)->s_es;
@@ -706,7 +718,14 @@
 	unlock_super(sb);
 	return desc_count;
 #else
-	return le32_to_cpu(EXT3_SB(sb)->s_es->s_free_inodes_count);
+	desc_count = 0;
+	for (i = 0; i < EXT3_SB(sb)->s_groups_count; i++) {
+		gdp = ext3_get_group_desc (sb, i, NULL);
+		if (!gdp)
+			continue;
+		desc_count += le16_to_cpu(gdp->bg_free_inodes_count);
+	}
+	return desc_count;
 #endif
 }
 
diff -Nru a/fs/ext3/inode.c b/fs/ext3/inode.c
--- a/fs/ext3/inode.c	Wed Jun 18 23:42:08 2003
+++ b/fs/ext3/inode.c	Wed Jun 18 23:42:08 2003
@@ -199,7 +199,6 @@
 	if (is_bad_inode(inode))
 		goto no_delete;
 
-	lock_kernel();
 	handle = start_transaction(inode);
 	if (IS_ERR(handle)) {
 		/* If we're going to skip the normal cleanup, we still
@@ -208,7 +207,6 @@
 		ext3_orphan_del(NULL, inode);
 
 		ext3_std_error(inode->i_sb, PTR_ERR(handle));
-		unlock_kernel();
 		goto no_delete;
 	}
 	
@@ -241,7 +239,6 @@
 	else
 		ext3_free_inode(handle, inode);
 	ext3_journal_stop(handle);
-	unlock_kernel();
 	return;
 no_delete:
 	clear_inode(inode);	/* We must guarantee clearing of inode... */
@@ -251,7 +248,6 @@
 {
 #ifdef EXT3_PREALLOCATE
 	struct ext3_inode_info *ei = EXT3_I(inode);
-	lock_kernel();
 	/* Writer: ->i_prealloc* */
 	if (ei->i_prealloc_count) {
 		unsigned short total = ei->i_prealloc_count;
@@ -261,7 +257,6 @@
 		/* Writer: end */
 		ext3_free_blocks (inode, block, total);
 	}
-	unlock_kernel();
 #endif
 }
 
@@ -781,7 +776,6 @@
 	if (depth == 0)
 		goto out;
 
-	lock_kernel();
 reread:
 	partial = ext3_get_branch(inode, depth, offsets, chain, &err);
 
@@ -806,7 +800,6 @@
 			partial--;
 		}
 		BUFFER_TRACE(bh_result, "returned");
-		unlock_kernel();
 out:
 		return err;
 	}
@@ -894,7 +887,6 @@
 	handle_t *handle = journal_current_handle();
 	int ret = 0;
 
-	lock_kernel();
 	if (handle && handle->h_buffer_credits <= EXT3_RESERVE_TRANS_BLOCKS) {
 		/*
 		 * Getting low on buffer credits...
@@ -911,7 +903,6 @@
 					bh_result, create, 0);
 	if (ret == 0)
 		bh_result->b_size = (1 << inode->i_blkbits);
-	unlock_kernel();
 	return ret;
 }
 
@@ -944,7 +935,6 @@
 			   For now, regular file writes use
 			   ext3_get_block instead, so it's not a
 			   problem. */
-			lock_kernel();
 			lock_buffer(bh);
 			BUFFER_TRACE(bh, "call get_create_access");
 			fatal = ext3_journal_get_create_access(handle, bh);
@@ -957,7 +947,6 @@
 			BUFFER_TRACE(bh, "call ext3_journal_dirty_metadata");
 			err = ext3_journal_dirty_metadata(handle, bh);
 			if (!fatal) fatal = err;
-			unlock_kernel();
 		} else {
 			BUFFER_TRACE(bh, "not a new buffer");
 		}
@@ -1037,11 +1026,13 @@
 	unsigned block_start, block_end;
 	unsigned blocksize = head->b_size;
 	int err, ret = 0;
+	struct buffer_head *next;
 
 	for (	bh = head, block_start = 0;
 		ret == 0 && (bh != head || !block_start);
-	    	block_start = block_end, bh = bh->b_this_page)
+	    	block_start = block_end, bh = next)
 	{
+		next = bh->b_this_page;
 		block_end = block_start + blocksize;
 		if (block_end <= from || block_start >= to) {
 			if (partial && !buffer_uptodate(bh))
@@ -1084,6 +1075,8 @@
 static int do_journal_get_write_access(handle_t *handle, 
 				       struct buffer_head *bh)
 {
+	if (!buffer_mapped(bh) || buffer_freed(bh))
+		return 0;
 	return ext3_journal_get_write_access(handle, bh);
 }
 
@@ -1094,15 +1087,12 @@
 	int ret, needed_blocks = ext3_writepage_trans_blocks(inode);
 	handle_t *handle;
 
-	lock_kernel();
 	handle = ext3_journal_start(inode, needed_blocks);
 	if (IS_ERR(handle)) {
 		ret = PTR_ERR(handle);
 		goto out;
 	}
-	unlock_kernel();
 	ret = block_prepare_write(page, from, to, ext3_get_block);
-	lock_kernel();
 	if (ret != 0)
 		goto prepare_write_failed;
 
@@ -1114,7 +1104,6 @@
 	if (ret)
 		ext3_journal_stop(handle);
 out:
-	unlock_kernel();
 	return ret;
 }
 
@@ -1131,6 +1120,8 @@
 /* For commit_write() in data=journal mode */
 static int commit_write_fn(handle_t *handle, struct buffer_head *bh)
 {
+	if (!buffer_mapped(bh) || buffer_freed(bh))
+		return 0;
 	set_buffer_uptodate(bh);
 	return ext3_journal_dirty_metadata(handle, bh);
 }
@@ -1143,56 +1134,81 @@
  * buffers are managed internally.
  */
 
-static int ext3_commit_write(struct file *file, struct page *page,
+static int ext3_ordered_commit_write(struct file *file, struct page *page,
 			     unsigned from, unsigned to)
 {
 	handle_t *handle = ext3_journal_current_handle();
 	struct inode *inode = page->mapping->host;
 	int ret = 0, ret2;
 
-	lock_kernel();
-	if (ext3_should_journal_data(inode)) {
+	ret = walk_page_buffers(handle, page_buffers(page),
+		from, to, NULL, ext3_journal_dirty_data);
+
+	if (ret == 0) {
 		/*
-		 * Here we duplicate the generic_commit_write() functionality
+		 * generic_commit_write() will run mark_inode_dirty() if i_size
+		 * changes.  So let's piggyback the i_disksize mark_inode_dirty
+		 * into that.
 		 */
-		int partial = 0;
-		loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+		loff_t new_i_size;
 
-		ret = walk_page_buffers(handle, page_buffers(page),
-			from, to, &partial, commit_write_fn);
-		if (!partial)
-			SetPageUptodate(page);
-		if (pos > inode->i_size)
-			inode->i_size = pos;
-		EXT3_I(inode)->i_state |= EXT3_STATE_JDATA;
-		if (inode->i_size > EXT3_I(inode)->i_disksize) {
-			EXT3_I(inode)->i_disksize = inode->i_size;
-			ret2 = ext3_mark_inode_dirty(handle, inode);
-			if (!ret) 
-				ret = ret2;
-		}
-	} else {
-		if (ext3_should_order_data(inode)) {
-			ret = walk_page_buffers(handle, page_buffers(page),
-				from, to, NULL, ext3_journal_dirty_data);
-		}
-		/* Be careful here if generic_commit_write becomes a
-		 * required invocation after block_prepare_write. */
-		if (ret == 0) {
-			/*
-			 * generic_commit_write() will run mark_inode_dirty()
-			 * if i_size changes.  So let's piggyback the
-			 * i_disksize mark_inode_dirty into that.
-			 */
-			loff_t new_i_size =
-				((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
-			if (new_i_size > EXT3_I(inode)->i_disksize)
-				EXT3_I(inode)->i_disksize = new_i_size;
-			ret = generic_commit_write(file, page, from, to);
-		}
+		new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+		if (new_i_size > EXT3_I(inode)->i_disksize)
+			EXT3_I(inode)->i_disksize = new_i_size;
+		ret = generic_commit_write(file, page, from, to);
+	}
+	ret2 = ext3_journal_stop(handle);
+	if (!ret)
+		ret = ret2;
+	return ret;
+}
+
+static int ext3_writeback_commit_write(struct file *file, struct page *page,
+			     unsigned from, unsigned to)
+{
+	handle_t *handle = ext3_journal_current_handle();
+	struct inode *inode = page->mapping->host;
+	int ret = 0, ret2;
+	loff_t new_i_size;
+
+	new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+	if (new_i_size > EXT3_I(inode)->i_disksize)
+		EXT3_I(inode)->i_disksize = new_i_size;
+	ret = generic_commit_write(file, page, from, to);
+	ret2 = ext3_journal_stop(handle);
+	if (!ret)
+		ret = ret2;
+	return ret;
+}
+
+static int ext3_journalled_commit_write(struct file *file,
+			struct page *page, unsigned from, unsigned to)
+{
+	handle_t *handle = ext3_journal_current_handle();
+	struct inode *inode = page->mapping->host;
+	int ret = 0, ret2;
+	int partial = 0;
+	loff_t pos;
+
+	/*
+	 * Here we duplicate the generic_commit_write() functionality
+	 */
+	pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
+
+	ret = walk_page_buffers(handle, page_buffers(page), from,
+				to, &partial, commit_write_fn);
+	if (!partial)
+		SetPageUptodate(page);
+	if (pos > inode->i_size)
+		inode->i_size = pos;
+	EXT3_I(inode)->i_state |= EXT3_STATE_JDATA;
+	if (inode->i_size > EXT3_I(inode)->i_disksize) {
+		EXT3_I(inode)->i_disksize = inode->i_size;
+		ret2 = ext3_mark_inode_dirty(handle, inode);
+		if (!ret) 
+			ret = ret2;
 	}
 	ret2 = ext3_journal_stop(handle);
-	unlock_kernel();
 	if (!ret)
 		ret = ret2;
 	return ret;
@@ -1317,55 +1333,44 @@
  * We don't honour synchronous mounts for writepage().  That would be
  * disastrous.  Any write() or metadata operation will sync the fs for
  * us.
+ *
+ * AKPM2: if all the page's buffers are mapped to disk and !data=journal,
+ * we don't need to open a transaction here.
  */
-static int ext3_writepage(struct page *page, struct writeback_control *wbc)
+static int ext3_ordered_writepage(struct page *page,
+			struct writeback_control *wbc)
 {
 	struct inode *inode = page->mapping->host;
 	struct buffer_head *page_bufs;
 	handle_t *handle = NULL;
-	int ret = 0, err;
-	int needed;
-	int order_data;
+	int ret = 0;
+	int err;
 
 	J_ASSERT(PageLocked(page));
 	
 	/*
-	 * We give up here if we're reentered, because it might be
-	 * for a different filesystem.  One *could* look for a
-	 * nested transaction opportunity.
+	 * We give up here if we're reentered, because it might be for a
+	 * different filesystem.
 	 */
-	lock_kernel();
 	if (ext3_journal_current_handle())
 		goto out_fail;
 
-	needed = ext3_writepage_trans_blocks(inode);
-	handle = ext3_journal_start(inode, needed);
+	handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode));
 				
 	if (IS_ERR(handle)) {
 		ret = PTR_ERR(handle);
 		goto out_fail;
 	}
 
-	order_data = ext3_should_order_data(inode) ||
-			ext3_should_journal_data(inode);
-
-	unlock_kernel();
-
-	page_bufs = NULL;	/* Purely to prevent compiler warning */
-
-	/* bget() all the buffers */
-	if (order_data) {
-		if (!page_has_buffers(page)) {
-			if (!PageUptodate(page))
-				buffer_error();
-			create_empty_buffers(page,
-				inode->i_sb->s_blocksize,
+	if (!page_has_buffers(page)) {
+		if (!PageUptodate(page))
+			buffer_error();
+		create_empty_buffers(page, inode->i_sb->s_blocksize,
 				(1 << BH_Dirty)|(1 << BH_Uptodate));
-		}
-		page_bufs = page_buffers(page);
-		walk_page_buffers(handle, page_bufs, 0,
-				PAGE_CACHE_SIZE, NULL, bget_one);
 	}
+	page_bufs = page_buffers(page);
+	walk_page_buffers(handle, page_bufs, 0,
+			PAGE_CACHE_SIZE, NULL, bget_one);
 
 	ret = block_write_full_page(page, ext3_get_block, wbc);
 
@@ -1376,46 +1381,116 @@
 	 * safe due to elevated refcount.
 	 */
 
-	handle = ext3_journal_current_handle();
-	lock_kernel();
-
 	/*
 	 * And attach them to the current transaction.  But only if 
 	 * block_write_full_page() succeeded.  Otherwise they are unmapped,
 	 * and generally junk.
 	 */
-	if (order_data) {
-		if (ret == 0) {
-			err = walk_page_buffers(handle, page_bufs,
-				0, PAGE_CACHE_SIZE, NULL,
-				journal_dirty_data_fn);
-			if (!ret)
-				ret = err;
-		}
-		walk_page_buffers(handle, page_bufs, 0,
-				PAGE_CACHE_SIZE, NULL, bput_one);
+	if (ret == 0) {
+		err = walk_page_buffers(handle, page_bufs, 0, PAGE_CACHE_SIZE,
+					NULL, journal_dirty_data_fn);
+		if (!ret)
+			ret = err;
 	}
-
+	walk_page_buffers(handle, page_bufs, 0,
+			PAGE_CACHE_SIZE, NULL, bput_one);
 	err = ext3_journal_stop(handle);
 	if (!ret)
 		ret = err;
-	unlock_kernel();
 	return ret;
 
 out_fail:
-	
-	unlock_kernel();
+	__set_page_dirty_nobuffers(page);
+	unlock_page(page);
+	return ret;
+}
 
-	/*
-	 * We have to fail this writepage to avoid cross-fs transactions.
-	 * Put the page back on mapping->dirty_pages.  The page's buffers'
-	 * dirty state will be left as-is.
-	 */
+static int ext3_writeback_writepage(struct page *page,
+				struct writeback_control *wbc)
+{
+	struct inode *inode = page->mapping->host;
+	handle_t *handle = NULL;
+	int ret = 0;
+	int err;
+
+	if (ext3_journal_current_handle())
+		goto out_fail;
+
+	handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode));
+	if (IS_ERR(handle)) {
+		ret = PTR_ERR(handle);
+		goto out_fail;
+	}
+
+	ret = block_write_full_page(page, ext3_get_block, wbc);
+	err = ext3_journal_stop(handle);
+	if (!ret)
+		ret = err;
+	return ret;
+
+out_fail:
 	__set_page_dirty_nobuffers(page);
 	unlock_page(page);
 	return ret;
 }
 
+static int ext3_journalled_writepage(struct page *page,
+				struct writeback_control *wbc)
+{
+	struct inode *inode = page->mapping->host;
+	handle_t *handle = NULL;
+	int ret = 0;
+	int err;
+
+	if (ext3_journal_current_handle())
+		goto no_write;
+
+	handle = ext3_journal_start(inode, ext3_writepage_trans_blocks(inode));
+	if (IS_ERR(handle)) {
+		ret = PTR_ERR(handle);
+		goto no_write;
+	}
+
+	if (!page_has_buffers(page) || PageChecked(page)) {
+		/*
+		 * It's mmapped pagecache.  Add buffers and journal it.  There
+		 * doesn't seem much point in redirtying the page here.
+		 */
+		ClearPageChecked(page);
+		ret = block_prepare_write(page, 0, PAGE_CACHE_SIZE,
+					ext3_get_block);
+		if (ret != 0)
+			goto out_unlock;
+		ret = walk_page_buffers(handle, page_buffers(page), 0,
+			PAGE_CACHE_SIZE, NULL, do_journal_get_write_access);
+
+		err = walk_page_buffers(handle, page_buffers(page), 0,
+				PAGE_CACHE_SIZE, NULL, commit_write_fn);
+		if (ret == 0)
+			ret = err;
+		EXT3_I(inode)->i_state |= EXT3_STATE_JDATA;
+		unlock_page(page);
+	} else {
+		/*
+		 * It may be a page full of checkpoint-mode buffers.  We don't
+		 * really know unless we go poke around in the buffer_heads.
+		 * But block_write_full_page will do the right thing.
+		 */
+		ret = block_write_full_page(page, ext3_get_block, wbc);
+	}
+	err = ext3_journal_stop(handle);
+	if (!ret)
+		ret = err;
+out:
+	return ret;
+
+no_write:
+	__set_page_dirty_nobuffers(page);
+out_unlock:
+	unlock_page(page);
+	goto out;
+}
+
 static int ext3_readpage(struct file *file, struct page *page)
 {
 	return mpage_readpage(page, ext3_get_block);
@@ -1431,12 +1506,21 @@
 static int ext3_invalidatepage(struct page *page, unsigned long offset)
 {
 	journal_t *journal = EXT3_JOURNAL(page->mapping->host);
+
+	/*
+	 * If it's a full truncate we just forget about the pending dirtying
+	 */
+	if (offset == 0)
+		ClearPageChecked(page);
+
 	return journal_invalidatepage(journal, page, offset);
 }
 
 static int ext3_releasepage(struct page *page, int wait)
 {
 	journal_t *journal = EXT3_JOURNAL(page->mapping->host);
+
+	WARN_ON(PageChecked(page));
 	return journal_try_to_free_buffers(journal, page, wait);
 }
 
@@ -1463,17 +1547,13 @@
 	if (rw == WRITE) {
 		loff_t final_size = offset + count;
 
-		lock_kernel();
 		handle = ext3_journal_start(inode, DIO_CREDITS);
-		unlock_kernel();
 		if (IS_ERR(handle)) {
 			ret = PTR_ERR(handle);
 			goto out;
 		}
 		if (final_size > inode->i_size) {
-			lock_kernel();
 			ret = ext3_orphan_add(handle, inode);
-			unlock_kernel();
 			if (ret)
 				goto out_stop;
 			orphan = 1;
@@ -1488,7 +1568,6 @@
 	if (handle) {
 		int err;
 
-		lock_kernel();
 		if (orphan) 
 			ext3_orphan_del(handle, inode);
 		if (orphan && ret > 0) {
@@ -1504,47 +1583,79 @@
 		err = ext3_journal_stop(handle);
 		if (ret == 0)
 			ret = err;
-		unlock_kernel();
 	}
 out:
 	return ret;
 }
 
-struct address_space_operations ext3_aops = {
-	.readpage	= ext3_readpage,	/* BKL not held.  Don't need */
-	.readpages	= ext3_readpages,	/* BKL not held.  Don't need */
-	.writepage	= ext3_writepage,	/* BKL not held.  We take it */
+/*
+ * Pages can be marked dirty completely asynchronously from ext3's journalling
+ * activity.  By filemap_sync_pte(), try_to_unmap_one(), etc.  We cannot do
+ * much here because ->set_page_dirty is called under VFS locks.  The page is
+ * not necessarily locked.
+ *
+ * We cannot just dirty the page and leave attached buffers clean, because the
+ * buffers' dirty state is "definitive".  We cannot just set the buffers dirty
+ * or jbddirty because all the journalling code will explode.
+ *
+ * So what we do is to mark the page "pending dirty" and next time writepage
+ * is called, propagate that into the buffers appropriately.
+ */
+static int ext3_journalled_set_page_dirty(struct page *page)
+{
+	SetPageChecked(page);
+	return __set_page_dirty_nobuffers(page);
+}
+
+static struct address_space_operations ext3_ordered_aops = {
+	.readpage	= ext3_readpage,
+	.readpages	= ext3_readpages,
+	.writepage	= ext3_ordered_writepage,
 	.sync_page	= block_sync_page,
-	.prepare_write	= ext3_prepare_write,	/* BKL not held.  We take it */
-	.commit_write	= ext3_commit_write,	/* BKL not held.  We take it */
-	.bmap		= ext3_bmap,		/* BKL held */
-	.invalidatepage	= ext3_invalidatepage,	/* BKL not held.  Don't need */
-	.releasepage	= ext3_releasepage,	/* BKL not held.  Don't need */
-	.direct_IO	= ext3_direct_IO,	/* BKL not held.  Don't need */
+	.prepare_write	= ext3_prepare_write,
+	.commit_write	= ext3_ordered_commit_write,
+	.bmap		= ext3_bmap,
+	.invalidatepage	= ext3_invalidatepage,
+	.releasepage	= ext3_releasepage,
+	.direct_IO	= ext3_direct_IO,
 };
 
-/* For writeback mode, we can use mpage_writepages() */
-#if 0	/* Doesn't work for shared mappings */
-static int
-ext3_writepages(struct address_space *mapping, struct writeback_control *wbc)
-{
-	return mpage_writepages(mapping, wbc, ext3_get_block);
-}
-#endif
+static struct address_space_operations ext3_writeback_aops = {
+	.readpage	= ext3_readpage,
+	.readpages	= ext3_readpages,
+	.writepage	= ext3_writeback_writepage,
+	.sync_page	= block_sync_page,
+	.prepare_write	= ext3_prepare_write,
+	.commit_write	= ext3_writeback_commit_write,
+	.bmap		= ext3_bmap,
+	.invalidatepage	= ext3_invalidatepage,
+	.releasepage	= ext3_releasepage,
+	.direct_IO	= ext3_direct_IO,
+};
 
-struct address_space_operations ext3_writeback_aops = {
-	.readpage	= ext3_readpage,	/* BKL not held.  Don't need */
-	.readpages	= ext3_readpages,	/* BKL not held.  Don't need */
-	.writepage	= ext3_writepage,	/* BKL not held.  We take it */
+static struct address_space_operations ext3_journalled_aops = {
+	.readpage	= ext3_readpage,
+	.readpages	= ext3_readpages,
+	.writepage	= ext3_journalled_writepage,
 	.sync_page	= block_sync_page,
-	.prepare_write	= ext3_prepare_write,	/* BKL not held.  We take it */
-	.commit_write	= ext3_commit_write,	/* BKL not held.  We take it */
-	.bmap		= ext3_bmap,		/* BKL held */
-	.invalidatepage	= ext3_invalidatepage,	/* BKL not held.  Don't need */
-	.releasepage	= ext3_releasepage,	/* BKL not held.  Don't need */
-	.direct_IO	= ext3_direct_IO,	/* BKL not held.  Don't need */
+	.prepare_write	= ext3_prepare_write,
+	.commit_write	= ext3_journalled_commit_write,
+	.set_page_dirty	= ext3_journalled_set_page_dirty,
+	.bmap		= ext3_bmap,
+	.invalidatepage	= ext3_invalidatepage,
+	.releasepage	= ext3_releasepage,
 };
 
+void ext3_set_aops(struct inode *inode)
+{
+	if (ext3_should_order_data(inode))
+		inode->i_mapping->a_ops = &ext3_ordered_aops;
+	else if (ext3_should_writeback_data(inode))
+		inode->i_mapping->a_ops = &ext3_writeback_aops;
+	else
+		inode->i_mapping->a_ops = &ext3_journalled_aops;
+}
+
 /*
  * ext3_block_truncate_page() zeroes out a mapping from file offset `from'
  * up to the end of the block which corresponds to `from'.
@@ -1591,11 +1702,19 @@
 	}
 
 	err = 0;
+	if (buffer_freed(bh)) {
+		BUFFER_TRACE(bh, "freed: skip");
+		goto unlock;
+	}
+
 	if (!buffer_mapped(bh)) {
+		BUFFER_TRACE(bh, "unmapped");
 		ext3_get_block(inode, iblock, bh, 0);
 		/* unmapped? It's a hole - nothing to do */
-		if (!buffer_mapped(bh))
+		if (!buffer_mapped(bh)) {
+			BUFFER_TRACE(bh, "still unmapped");
 			goto unlock;
+		}
 	}
 
 	/* Ok, it's mapped. Make sure it's up-to-date */
@@ -2034,12 +2153,10 @@
 	if (IS_APPEND(inode) || IS_IMMUTABLE(inode))
 		return;
 
-	lock_kernel();
 	ext3_discard_prealloc(inode);
 
 	handle = start_transaction(inode);
 	if (IS_ERR(handle)) {
-		unlock_kernel();
 		return;		/* AKPM: return what? */
 	}
 
@@ -2163,7 +2280,6 @@
 		ext3_orphan_del(handle, inode);
 
 	ext3_journal_stop(handle);
-	unlock_kernel();
 }
 
 /* 
@@ -2338,10 +2454,7 @@
 	if (S_ISREG(inode->i_mode)) {
 		inode->i_op = &ext3_file_inode_operations;
 		inode->i_fop = &ext3_file_operations;
-		if (ext3_should_writeback_data(inode))
-			inode->i_mapping->a_ops = &ext3_writeback_aops;
-		else
-			inode->i_mapping->a_ops = &ext3_aops;
+		ext3_set_aops(inode);
 	} else if (S_ISDIR(inode->i_mode)) {
 		inode->i_op = &ext3_dir_inode_operations;
 		inode->i_fop = &ext3_dir_operations;
@@ -2350,10 +2463,7 @@
 			inode->i_op = &ext3_fast_symlink_inode_operations;
 		else {
 			inode->i_op = &ext3_symlink_inode_operations;
-			if (ext3_should_writeback_data(inode))
-				inode->i_mapping->a_ops = &ext3_writeback_aops;
-			else
-				inode->i_mapping->a_ops = &ext3_aops;
+			ext3_set_aops(inode);
 		}
 	} else {
 		inode->i_op = &ext3_special_inode_operations;
@@ -2517,6 +2627,7 @@
 
 	if (ext3_journal_current_handle()) {
 		jbd_debug(0, "called recursively, non-PF_MEMALLOC!\n");
+		dump_stack();
 		return;
 	}
 
@@ -2560,8 +2671,6 @@
 			return error;
 	}
 
-	lock_kernel();
-
 	if (S_ISREG(inode->i_mode) &&
 	    attr->ia_valid & ATTR_SIZE && attr->ia_size < inode->i_size) {
 		handle_t *handle;
@@ -2593,7 +2702,6 @@
 
 err_out:
 	ext3_std_error(inode->i_sb, error);
-	unlock_kernel();
 	if (!error)
 		error = rc;
 	return error;
@@ -2739,7 +2847,6 @@
 	handle_t *current_handle = ext3_journal_current_handle();
 	handle_t *handle;
 
-	lock_kernel();
 	handle = ext3_journal_start(inode, 2);
 	if (IS_ERR(handle))
 		goto out;
@@ -2755,7 +2862,7 @@
 	}
 	ext3_journal_stop(handle);
 out:
-	unlock_kernel();
+	return;
 }
 
 #ifdef AKPM
@@ -2839,61 +2946,3 @@
 	
 	return err;
 }
-
-
-/*
- * ext3_aops_journal_start().
- *
- * <This function died, but the comment lives on>
- *
- * We need to take the inode semaphore *outside* the
- * journal_start/journal_stop.  Otherwise, a different task could do a
- * wait_for_commit() while holding ->i_sem, which deadlocks.  The rule
- * is: transaction open/closes are considered to be a locking operation
- * and they nest *inside* ->i_sem.
- * ----------------------------------------------------------------------------
- * Possible problem:
- *	ext3_file_write()
- *	-> generic_file_write()
- *	   -> __alloc_pages()
- *	      -> page_launder()
- *		 -> ext3_writepage()
- *
- * And the writepage can be on a different fs while we have a
- * transaction open against this one!  Bad.
- *
- * I tried making the task PF_MEMALLOC here, but that simply results in
- * 0-order allocation failures passed back to generic_file_write().
- * Instead, we rely on the reentrancy protection in ext3_writepage().
- * ----------------------------------------------------------------------------
- * When we do the journal_start() here we don't really need to reserve
- * any blocks - we won't need any until we hit ext3_prepare_write(),
- * which does all the needed journal extending.  However!  There is a
- * problem with quotas:
- *
- * Thread 1:
- * sys_sync
- * ->sync_dquots
- *   ->commit_dquot
- *     ->lock_dquot
- *     ->write_dquot
- *       ->ext3_file_write
- *         ->journal_start
- *         ->ext3_prepare_write
- *           ->journal_extend
- *           ->journal_start
- * Thread 2:
- * ext3_create		(for example)
- * ->ext3_new_inode
- *   ->dquot_initialize
- *     ->lock_dquot
- *
- * Deadlock.  Thread 1's journal_start blocks because thread 2 has a
- * transaction open.  Thread 2's transaction will never close because
- * thread 2 is stuck waiting for the dquot lock.
- *
- * So.  We must ensure that thread 1 *never* needs to extend the journal
- * for quota writes.  We do that by reserving enough journal blocks
- * here, in ext3_aops_journal_start() to ensure that the forthcoming "see if we
- * need to extend" test in ext3_prepare_write() succeeds.  
- */
diff -Nru a/fs/ext3/ioctl.c b/fs/ext3/ioctl.c
--- a/fs/ext3/ioctl.c	Wed Jun 18 23:42:07 2003
+++ b/fs/ext3/ioctl.c	Wed Jun 18 23:42:07 2003
@@ -119,13 +119,11 @@
 		if (IS_ERR(handle))
 			return PTR_ERR(handle);
 		err = ext3_reserve_inode_write(handle, inode, &iloc);
-		if (err)
-			return err;
-
-		inode->i_ctime = CURRENT_TIME;
-		inode->i_generation = generation;
-
-		err = ext3_mark_iloc_dirty(handle, inode, &iloc);
+		if (err == 0) {
+			inode->i_ctime = CURRENT_TIME;
+			inode->i_generation = generation;
+			err = ext3_mark_iloc_dirty(handle, inode, &iloc);
+		}
 		ext3_journal_stop(handle);
 		return err;
 	}
diff -Nru a/fs/ext3/namei.c b/fs/ext3/namei.c
--- a/fs/ext3/namei.c	Wed Jun 18 23:42:07 2003
+++ b/fs/ext3/namei.c	Wed Jun 18 23:42:07 2003
@@ -981,7 +981,6 @@
 	if (dentry->d_name.len > EXT3_NAME_LEN)
 		return ERR_PTR(-ENAMETOOLONG);
 
-	lock_kernel();
 	bh = ext3_find_entry(dentry, &de);
 	inode = NULL;
 	if (bh) {
@@ -989,12 +988,9 @@
 		brelse (bh);
 		inode = iget(dir->i_sb, ino);
 
-		if (!inode) {
-			unlock_kernel();
+		if (!inode)
 			return ERR_PTR(-EACCES);
-		}
 	}
-	unlock_kernel();
 	if (inode)
 		return d_splice_alias(inode, dentry);
 	d_add(dentry, inode);
@@ -1015,17 +1011,13 @@
 	dotdot.d_name.len = 2;
 	dotdot.d_parent = child; /* confusing, isn't it! */
 
-	lock_kernel();
 	bh = ext3_find_entry(&dotdot, &de);
 	inode = NULL;
-	if (!bh) {
-		unlock_kernel();
+	if (!bh)
 		return ERR_PTR(-ENOENT);
-	}
 	ino = le32_to_cpu(de->inode);
 	brelse(bh);
 	inode = iget(child->d_inode->i_sb, ino);
-	unlock_kernel();
 
 	if (!inode)
 		return ERR_PTR(-EACCES);
@@ -1639,13 +1631,10 @@
 	struct inode * inode;
 	int err;
 
-	lock_kernel();
 	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
 					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-	if (IS_ERR(handle)) {
-		unlock_kernel();
+	if (IS_ERR(handle))
 		return PTR_ERR(handle);
-	}
 
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
@@ -1655,14 +1644,10 @@
 	if (!IS_ERR(inode)) {
 		inode->i_op = &ext3_file_inode_operations;
 		inode->i_fop = &ext3_file_operations;
-		if (ext3_should_writeback_data(inode))
-			inode->i_mapping->a_ops = &ext3_writeback_aops;
-		else
-			inode->i_mapping->a_ops = &ext3_aops;
+		ext3_set_aops(inode);
 		err = ext3_add_nondir(handle, dentry, inode);
 	}
 	ext3_journal_stop(handle);
-	unlock_kernel();
 	return err;
 }
 
@@ -1673,13 +1658,10 @@
 	struct inode *inode;
 	int err;
 
-	lock_kernel();
 	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
 			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-	if (IS_ERR(handle)) {
-		unlock_kernel();
+	if (IS_ERR(handle))
 		return PTR_ERR(handle);
-	}
 
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
@@ -1694,7 +1676,6 @@
 		err = ext3_add_nondir(handle, dentry, inode);
 	}
 	ext3_journal_stop(handle);
-	unlock_kernel();
 	return err;
 }
 
@@ -1709,13 +1690,10 @@
 	if (dir->i_nlink >= EXT3_LINK_MAX)
 		return -EMLINK;
 
-	lock_kernel();
 	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
 					EXT3_INDEX_EXTRA_TRANS_BLOCKS + 3);
-	if (IS_ERR(handle)) {
-		unlock_kernel();
+	if (IS_ERR(handle))
 		return PTR_ERR(handle);
-	}
 
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
@@ -1768,7 +1746,6 @@
 	d_instantiate(dentry, inode);
 out_stop:
 	ext3_journal_stop(handle);
-	unlock_kernel();
 	return err;
 }
 
@@ -1993,12 +1970,9 @@
 	struct ext3_dir_entry_2 * de;
 	handle_t *handle;
 
-	lock_kernel();
 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
-	if (IS_ERR(handle)) {
-		unlock_kernel();
+	if (IS_ERR(handle))
 		return PTR_ERR(handle);
-	}
 
 	retval = -ENOENT;
 	bh = ext3_find_entry (dentry, &de);
@@ -2042,7 +2016,6 @@
 end_rmdir:
 	ext3_journal_stop(handle);
 	brelse (bh);
-	unlock_kernel();
 	return retval;
 }
 
@@ -2054,12 +2027,9 @@
 	struct ext3_dir_entry_2 * de;
 	handle_t *handle;
 
-	lock_kernel();
 	handle = ext3_journal_start(dir, EXT3_DELETE_TRANS_BLOCKS);
-	if (IS_ERR(handle)) {
-		unlock_kernel();
+	if (IS_ERR(handle))
 		return PTR_ERR(handle);
-	}
 
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
@@ -2097,7 +2067,6 @@
 
 end_unlink:
 	ext3_journal_stop(handle);
-	unlock_kernel();
 	brelse (bh);
 	return retval;
 }
@@ -2113,13 +2082,10 @@
 	if (l > dir->i_sb->s_blocksize)
 		return -ENAMETOOLONG;
 
-	lock_kernel();
 	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
 			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 5);
-	if (IS_ERR(handle)) {
-		unlock_kernel();
+	if (IS_ERR(handle))
 		return PTR_ERR(handle);
-	}
 
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
@@ -2131,10 +2097,7 @@
 
 	if (l > sizeof (EXT3_I(inode)->i_data)) {
 		inode->i_op = &ext3_symlink_inode_operations;
-		if (ext3_should_writeback_data(inode))
-			inode->i_mapping->a_ops = &ext3_writeback_aops;
-		else
-			inode->i_mapping->a_ops = &ext3_aops;
+		ext3_set_aops(inode);
 		/*
 		 * page_symlink() calls into ext3_prepare/commit_write.
 		 * We have a transaction open.  All is sweetness.  It also sets
@@ -2156,7 +2119,6 @@
 	err = ext3_add_nondir(handle, dentry, inode);
 out_stop:
 	ext3_journal_stop(handle);
-	unlock_kernel();
 	return err;
 }
 
@@ -2167,18 +2129,13 @@
 	struct inode *inode = old_dentry->d_inode;
 	int err;
 
-	lock_kernel();
-	if (inode->i_nlink >= EXT3_LINK_MAX) {
-		unlock_kernel();
+	if (inode->i_nlink >= EXT3_LINK_MAX)
 		return -EMLINK;
-	}
 
 	handle = ext3_journal_start(dir, EXT3_DATA_TRANS_BLOCKS +
 					EXT3_INDEX_EXTRA_TRANS_BLOCKS);
-	if (IS_ERR(handle)) {
-		unlock_kernel();
+	if (IS_ERR(handle))
 		return PTR_ERR(handle);
-	}
 
 	if (IS_DIRSYNC(dir))
 		handle->h_sync = 1;
@@ -2189,7 +2146,6 @@
 
 	err = ext3_add_nondir(handle, dentry, inode);
 	ext3_journal_stop(handle);
-	unlock_kernel();
 	return err;
 }
 
@@ -2212,13 +2168,10 @@
 
 	old_bh = new_bh = dir_bh = NULL;
 
-	lock_kernel();
 	handle = ext3_journal_start(old_dir, 2 * EXT3_DATA_TRANS_BLOCKS +
 			 		EXT3_INDEX_EXTRA_TRANS_BLOCKS + 2);
-	if (IS_ERR(handle)) {
-		unlock_kernel();
+	if (IS_ERR(handle))
 		return PTR_ERR(handle);
-	}
 
 	if (IS_DIRSYNC(old_dir) || IS_DIRSYNC(new_dir))
 		handle->h_sync = 1;
@@ -2346,7 +2299,6 @@
 	brelse (old_bh);
 	brelse (new_bh);
 	ext3_journal_stop(handle);
-	unlock_kernel();
 	return retval;
 }
 
@@ -2378,6 +2330,4 @@
 	.listxattr	= ext3_listxattr,
 	.removexattr	= ext3_removexattr,
 	.permission	= ext3_permission,
-};
-
- 
+}; 
diff -Nru a/fs/ext3/super.c b/fs/ext3/super.c
--- a/fs/ext3/super.c	Wed Jun 18 23:42:09 2003
+++ b/fs/ext3/super.c	Wed Jun 18 23:42:09 2003
@@ -947,6 +947,9 @@
 		block += EXT3_BLOCKS_PER_GROUP(sb);
 		gdp++;
 	}
+
+	sbi->s_es->s_free_blocks_count=cpu_to_le32(ext3_count_free_blocks(sb));
+	sbi->s_es->s_free_inodes_count=cpu_to_le32(ext3_count_free_inodes(sb));
 	return 1;
 }
 
@@ -1307,13 +1310,19 @@
 		printk (KERN_ERR "EXT3-fs: not enough memory\n");
 		goto failed_mount;
 	}
-	sbi->s_debts = kmalloc(sbi->s_groups_count * sizeof(*sbi->s_debts),
+	sbi->s_debts = kmalloc(sbi->s_groups_count * sizeof(u8),
 			GFP_KERNEL);
 	if (!sbi->s_debts) {
-		printk ("EXT3-fs: not enough memory\n");
+		printk("EXT3-fs: not enough memory to allocate s_bgi\n");
 		goto failed_mount2;
 	}
-	memset(sbi->s_debts, 0, sbi->s_groups_count * sizeof(*sbi->s_debts));
+	memset(sbi->s_debts, 0,  sbi->s_groups_count * sizeof(u8));
+
+	percpu_counter_init(&sbi->s_freeblocks_counter);
+	percpu_counter_init(&sbi->s_freeinodes_counter);
+	percpu_counter_init(&sbi->s_dirs_counter);
+	bgl_lock_init(&sbi->s_blockgroup_lock);
+
 	for (i = 0; i < db_count; i++) {
 		block = descriptor_loc(sb, logic_sb_block, i);
 		sbi->s_group_desc[i] = sb_bread(sb, block);
@@ -1329,7 +1338,6 @@
 		goto failed_mount2;
 	}
 	sbi->s_gdb_count = db_count;
-	sbi->s_dir_count = ext3_count_dirs(sb);
 	/*
 	 * set up enough so that it can read an inode
 	 */
@@ -1427,13 +1435,19 @@
 		test_opt(sb,DATA_FLAGS) == EXT3_MOUNT_ORDERED_DATA ? "ordered":
 		"writeback");
 
+	percpu_counter_mod(&sbi->s_freeblocks_counter,
+		ext3_count_free_blocks(sb));
+	percpu_counter_mod(&sbi->s_freeinodes_counter,
+		ext3_count_free_inodes(sb));
+	percpu_counter_mod(&sbi->s_dirs_counter,
+		ext3_count_dirs(sb));
+
 	return 0;
 
 failed_mount3:
 	journal_destroy(sbi->s_journal);
 failed_mount2:
-	if (sbi->s_debts)
-		kfree(sbi->s_debts);
+	kfree(sbi->s_debts);
 	for (i = 0; i < db_count; i++)
 		brelse(sbi->s_group_desc[i]);
 	kfree(sbi->s_group_desc);
@@ -1702,6 +1716,8 @@
 	if (!sbh)
 		return;
 	es->s_wtime = cpu_to_le32(get_seconds());
+	es->s_free_blocks_count = cpu_to_le32(ext3_count_free_blocks(sb));
+	es->s_free_inodes_count = cpu_to_le32(ext3_count_free_inodes(sb));
 	BUFFER_TRACE(sbh, "marking dirty");
 	mark_buffer_dirty(sbh);
 	if (sync)
@@ -1777,9 +1793,7 @@
 
 	journal = EXT3_SB(sb)->s_journal;
 	sb->s_dirt = 0;
-	lock_kernel();	/* important: lock down j_running_transaction */
 	ret = ext3_journal_force_commit(journal);
-	unlock_kernel();
 	return ret;
 }
 
@@ -1794,24 +1808,21 @@
 
 void ext3_write_super (struct super_block * sb)
 {
-	lock_kernel();	
 	if (down_trylock(&sb->s_lock) == 0)
 		BUG();
 	sb->s_dirt = 0;
-	log_start_commit(EXT3_SB(sb)->s_journal, NULL);
-	unlock_kernel();
+	journal_start_commit(EXT3_SB(sb)->s_journal, NULL);
 }
 
 static int ext3_sync_fs(struct super_block *sb, int wait)
 {
 	tid_t target;
 
-	lock_kernel();	
 	sb->s_dirt = 0;
-	target = log_start_commit(EXT3_SB(sb)->s_journal, NULL);
-	if (wait)
-		log_wait_commit(EXT3_SB(sb)->s_journal, target);
-	unlock_kernel();
+	if (journal_start_commit(EXT3_SB(sb)->s_journal, &target)) {
+		if (wait)
+			log_wait_commit(EXT3_SB(sb)->s_journal, target);
+	}
 	return 0;
 }
 
@@ -1823,7 +1834,6 @@
 {
 	sb->s_dirt = 0;
 
-	lock_kernel();		/* 2.4.5 forgot to do this for us */
 	if (!(sb->s_flags & MS_RDONLY)) {
 		journal_t *journal = EXT3_SB(sb)->s_journal;
 
@@ -1835,7 +1845,6 @@
 		EXT3_CLEAR_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
 		ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1);
 	}
-	unlock_kernel();
 }
 
 /*
@@ -1845,14 +1854,12 @@
 void ext3_unlockfs(struct super_block *sb)
 {
 	if (!(sb->s_flags & MS_RDONLY)) {
-		lock_kernel();
 		lock_super(sb);
 		/* Reser the needs_recovery flag before the fs is unlocked. */
 		EXT3_SET_INCOMPAT_FEATURE(sb, EXT3_FEATURE_INCOMPAT_RECOVER);
 		ext3_commit_super(sb, EXT3_SB(sb)->s_es, 1);
 		unlock_super(sb);
 		journal_unlock_updates(EXT3_SB(sb)->s_journal);
-		unlock_kernel();
 	}
 }
 
@@ -1997,7 +2004,9 @@
 
 static int ext3_sync_dquot(struct dquot *dquot)
 {
-	int nblocks, ret;
+	int nblocks;
+	int ret;
+	int err;
 	handle_t *handle;
 	struct quota_info *dqops = sb_dqopt(dquot->dq_sb);
 	struct inode *qinode;
@@ -2012,18 +2021,17 @@
 		default:
 			nblocks = EXT3_MAX_TRANS_DATA;
 	}
-	lock_kernel();
 	qinode = dqops->files[dquot->dq_type]->f_dentry->d_inode;
 	handle = ext3_journal_start(qinode, nblocks);
 	if (IS_ERR(handle)) {
-		unlock_kernel();
-		return PTR_ERR(handle);
+		ret = PTR_ERR(handle);
+		goto out;
 	}
-	unlock_kernel();
 	ret = old_sync_dquot(dquot);
-	lock_kernel();
-	ret = ext3_journal_stop(handle);
-	unlock_kernel();
+	err = ext3_journal_stop(handle);
+	if (ret == 0)
+		ret = err;
+out:
 	return ret;
 }
 #endif
diff -Nru a/fs/ext3/xattr.c b/fs/ext3/xattr.c
--- a/fs/ext3/xattr.c	Wed Jun 18 23:42:07 2003
+++ b/fs/ext3/xattr.c	Wed Jun 18 23:42:07 2003
@@ -849,7 +849,6 @@
 	handle_t *handle;
 	int error, error2;
 
-	lock_kernel();
 	handle = ext3_journal_start(inode, EXT3_XATTR_TRANS_BLOCKS);
 	if (IS_ERR(handle))
 		error = PTR_ERR(handle);
@@ -857,7 +856,6 @@
 		error = ext3_xattr_set_handle(handle, inode, name_index, name,
 					      value, value_len, flags);
 	error2 = ext3_journal_stop(handle);
-	unlock_kernel();
 
 	return error ? error : error2;
 }
diff -Nru a/fs/jbd/checkpoint.c b/fs/jbd/checkpoint.c
--- a/fs/jbd/checkpoint.c	Wed Jun 18 23:42:06 2003
+++ b/fs/jbd/checkpoint.c	Wed Jun 18 23:42:06 2003
@@ -23,12 +23,10 @@
 #include <linux/errno.h>
 #include <linux/slab.h>
 
-extern spinlock_t journal_datalist_lock;
-
 /*
  * Unlink a buffer from a transaction. 
  *
- * Called with journal_datalist_lock held.
+ * Called with j_list_lock held.
  */
 
 static inline void __buffer_unlink(struct journal_head *jh)
@@ -49,7 +47,8 @@
 /*
  * Try to release a checkpointed buffer from its transaction.
  * Returns 1 if we released it.
- * Requires journal_datalist_lock
+ * Requires j_list_lock
+ * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it
  */
 static int __try_to_free_cp_buf(struct journal_head *jh)
 {
@@ -59,40 +58,63 @@
 	if (jh->b_jlist == BJ_None && !buffer_locked(bh) && !buffer_dirty(bh)) {
 		JBUFFER_TRACE(jh, "remove from checkpoint list");
 		__journal_remove_checkpoint(jh);
-		__journal_remove_journal_head(bh);
+		jbd_unlock_bh_state(bh);
+		journal_remove_journal_head(bh);
 		BUFFER_TRACE(bh, "release");
 		__brelse(bh);
 		ret = 1;
+	} else {
+		jbd_unlock_bh_state(bh);
 	}
 	return ret;
 }
 
 /*
- * log_wait_for_space: wait until there is space in the journal.
+ * __log_wait_for_space: wait until there is space in the journal.
  *
- * Called with the journal already locked, but it will be unlocked if we have
- * to wait for a checkpoint to free up some space in the log.
+ * Called under j-state_lock *only*.  It will be unlocked if we have to wait
+ * for a checkpoint to free up some space in the log.
  */
 
-void log_wait_for_space(journal_t *journal, int nblocks)
+void __log_wait_for_space(journal_t *journal, int nblocks)
 {
-	while (log_space_left(journal) < nblocks) {
+	assert_spin_locked(&journal->j_state_lock);
+
+	while (__log_space_left(journal) < nblocks) {
 		if (journal->j_flags & JFS_ABORT)
 			return;
-		unlock_journal(journal);
+		spin_unlock(&journal->j_state_lock);
 		down(&journal->j_checkpoint_sem);
-		lock_journal(journal);
 		
-		/* Test again, another process may have checkpointed
-		 * while we were waiting for the checkpoint lock */
-		if (log_space_left(journal) < nblocks) {
+		/*
+		 * Test again, another process may have checkpointed while we
+		 * were waiting for the checkpoint lock
+		 */
+		spin_lock(&journal->j_state_lock);
+		if (__log_space_left(journal) < nblocks) {
+			spin_unlock(&journal->j_state_lock);
 			log_do_checkpoint(journal, nblocks);
+			spin_lock(&journal->j_state_lock);
 		}
 		up(&journal->j_checkpoint_sem);
 	}
 }
 
 /*
+ * We were unable to perform jbd_trylock_bh_state() inside j_list_lock.
+ * The caller must restart a list walk.  Wait for someone else to run
+ * jbd_unlock_bh_state().
+ */
+static void jbd_sync_bh(journal_t *journal, struct buffer_head *bh)
+{
+	get_bh(bh);
+	spin_unlock(&journal->j_list_lock);
+	jbd_lock_bh_state(bh);
+	jbd_unlock_bh_state(bh);
+	put_bh(bh);
+}
+
+/*
  * Clean up a transaction's checkpoint list.  
  *
  * We wait for any pending IO to complete and make sure any clean
@@ -102,8 +124,7 @@
  * checkpoint.  (journal_remove_checkpoint() deletes the transaction when
  * the last checkpoint buffer is cleansed)
  *
- * Called with the journal locked.
- * Called with journal_datalist_lock held.
+ * Called with j_list_lock held.
  */
 static int __cleanup_transaction(journal_t *journal, transaction_t *transaction)
 {
@@ -111,7 +132,7 @@
 	struct buffer_head *bh;
 	int ret = 0;
 
-	assert_spin_locked(&journal_datalist_lock);
+	assert_spin_locked(&journal->j_list_lock);
 	jh = transaction->t_checkpoint_list;
 	if (!jh)
 		return 0;
@@ -123,67 +144,70 @@
 		bh = jh2bh(jh);
 		if (buffer_locked(bh)) {
 			atomic_inc(&bh->b_count);
-			spin_unlock(&journal_datalist_lock);
-			unlock_journal(journal);
+			spin_unlock(&journal->j_list_lock);
 			wait_on_buffer(bh);
 			/* the journal_head may have gone by now */
 			BUFFER_TRACE(bh, "brelse");
 			__brelse(bh);
 			goto out_return_1;
 		}
-		
+
+		/*
+		 * This is foul
+		 */
+		if (!jbd_trylock_bh_state(bh)) {
+			jbd_sync_bh(journal, bh);
+			goto out_return_1;
+		}
+
 		if (jh->b_transaction != NULL) {
-			transaction_t *transaction = jh->b_transaction;
-			tid_t tid = transaction->t_tid;
+			transaction_t *t = jh->b_transaction;
+			tid_t tid = t->t_tid;
 
-			spin_unlock(&journal_datalist_lock);
-			log_start_commit(journal, transaction);
-			unlock_journal(journal);
+			spin_unlock(&journal->j_list_lock);
+			jbd_unlock_bh_state(bh);
+			log_start_commit(journal, tid);
 			log_wait_commit(journal, tid);
 			goto out_return_1;
 		}
 
 		/*
-		 * We used to test for (jh->b_list != BUF_CLEAN) here.
-		 * But unmap_underlying_metadata() can place buffer onto
-		 * BUF_CLEAN.
-		 */
-		/*
-		 * AKPM: I think the buffer_jdirty test is redundant - it
+		 * AKPM: I think the buffer_jbddirty test is redundant - it
 		 * shouldn't have NULL b_transaction?
 		 */
 		next_jh = jh->b_cpnext;
-		if (!buffer_dirty(bh) && !buffer_jdirty(bh)) {
+		if (!buffer_dirty(bh) && !buffer_jbddirty(bh)) {
 			BUFFER_TRACE(bh, "remove from checkpoint");
 			__journal_remove_checkpoint(jh);
-			__journal_remove_journal_head(bh);
+			jbd_unlock_bh_state(bh);
+			journal_remove_journal_head(bh);
 			__brelse(bh);
 			ret = 1;
+		} else {
+			jbd_unlock_bh_state(bh);
 		}
-		
 		jh = next_jh;
 	} while (jh != last_jh);
 
 	return ret;
 out_return_1:
-	lock_journal(journal);
-	spin_lock(&journal_datalist_lock);
+	spin_lock(&journal->j_list_lock);
 	return 1;
 }
 
 #define NR_BATCH	64
 
-static void __flush_batch(struct buffer_head **bhs, int *batch_count)
+static void
+__flush_batch(journal_t *journal, struct buffer_head **bhs, int *batch_count)
 {
 	int i;
 
-	spin_unlock(&journal_datalist_lock);
+	spin_unlock(&journal->j_list_lock);
 	ll_rw_block(WRITE, *batch_count, bhs);
-	blk_run_queues();
-	spin_lock(&journal_datalist_lock);
+	spin_lock(&journal->j_list_lock);
 	for (i = 0; i < *batch_count; i++) {
 		struct buffer_head *bh = bhs[i];
-		clear_bit(BH_JWrite, &bh->b_state);
+		clear_buffer_jwrite(bh);
 		BUFFER_TRACE(bh, "brelse");
 		__brelse(bh);
 	}
@@ -196,7 +220,8 @@
  * Return 1 if something happened which requires us to abort the current
  * scan of the checkpoint list.  
  *
- * Called with journal_datalist_lock held.
+ * Called with j_list_lock held.
+ * Called under jbd_lock_bh_state(jh2bh(jh)), and drops it
  */
 static int __flush_buffer(journal_t *journal, struct journal_head *jh,
 			struct buffer_head **bhs, int *batch_count,
@@ -216,13 +241,14 @@
 		 * disk, as that would break recoverability.  
 		 */
 		BUFFER_TRACE(bh, "queue");
-		atomic_inc(&bh->b_count);
-		J_ASSERT_BH(bh, !test_bit(BH_JWrite, &bh->b_state));
-		set_bit(BH_JWrite, &bh->b_state);
+		get_bh(bh);
+		J_ASSERT_BH(bh, !buffer_jwrite(bh));
+		set_buffer_jwrite(bh);
 		bhs[*batch_count] = bh;
+		jbd_unlock_bh_state(bh);
 		(*batch_count)++;
 		if (*batch_count == NR_BATCH) {
-			__flush_batch(bhs, batch_count);
+			__flush_batch(journal, bhs, batch_count);
 			ret = 1;
 		}
 	} else {
@@ -246,7 +272,7 @@
  * Perform an actual checkpoint.  We don't write out only enough to
  * satisfy the current blocked requests: rather we submit a reasonably
  * sized chunk of the outstanding data to disk at once for
- * efficiency.  log_wait_for_space() will retry if we didn't free enough.
+ * efficiency.  __log_wait_for_space() will retry if we didn't free enough.
  * 
  * However, we _do_ take into account the amount requested so that once
  * the IO has been queued, we can return as soon as enough of it has
@@ -256,9 +282,8 @@
  */
 
 /* @@@ `nblocks' is unused.  Should it be used? */
-int log_do_checkpoint (journal_t *journal, int nblocks)
+int log_do_checkpoint(journal_t *journal, int nblocks)
 {
-	transaction_t *transaction, *last_transaction, *next_transaction;
 	int result;
 	int batch_count = 0;
 	struct buffer_head *bhs[NR_BATCH];
@@ -283,36 +308,59 @@
 	 * AKPM: check this code.  I had a feeling a while back that it
 	 * degenerates into a busy loop at unmount time.
 	 */
-	spin_lock(&journal_datalist_lock);
-repeat:
-	transaction = journal->j_checkpoint_transactions;
-	if (transaction == NULL)
-		goto done;
-	last_transaction = transaction->t_cpprev;
-	next_transaction = transaction;
-
-	do {
+	spin_lock(&journal->j_list_lock);
+	while (journal->j_checkpoint_transactions) {
+		transaction_t *transaction;
 		struct journal_head *jh, *last_jh, *next_jh;
 		int drop_count = 0;
 		int cleanup_ret, retry = 0;
+		tid_t this_tid;
 
-		transaction = next_transaction;
-		next_transaction = transaction->t_cpnext;
+		transaction = journal->j_checkpoint_transactions->t_cpnext;
+		this_tid = transaction->t_tid;
 		jh = transaction->t_checkpoint_list;
 		last_jh = jh->b_cpprev;
 		next_jh = jh;
 		do {
+			struct buffer_head *bh;
+
 			jh = next_jh;
 			next_jh = jh->b_cpnext;
+			bh = jh2bh(jh);
+			if (!jbd_trylock_bh_state(bh)) {
+				jbd_sync_bh(journal, bh);
+				spin_lock(&journal->j_list_lock);
+				retry = 1;
+				break;
+			}
 			retry = __flush_buffer(journal, jh, bhs, &batch_count,
 						&drop_count);
 		} while (jh != last_jh && !retry);
 		if (batch_count) {
-			__flush_batch(bhs, &batch_count);
-			goto repeat;
+			__flush_batch(journal, bhs, &batch_count);
+			continue;
 		}
 		if (retry)
-			goto repeat;
+			continue;
+
+		/*
+		 * If someone emptied the checkpoint list while we slept, we're
+		 * done.
+		 */
+		if (!journal->j_checkpoint_transactions)
+			break;
+		/*
+		 * If someone cleaned up this transaction while we slept, we're
+		 * done
+		 */
+		if (journal->j_checkpoint_transactions->t_cpnext != transaction)
+			continue;
+		/*
+		 * Maybe it's a new transaction, but it fell at the same
+		 * address
+		 */
+		if (transaction->t_tid != this_tid)
+			continue;
 		/*
 		 * We have walked the whole transaction list without
 		 * finding anything to write to disk.  We had better be
@@ -320,11 +368,8 @@
 		 */
 		cleanup_ret = __cleanup_transaction(journal, transaction);
 		J_ASSERT(drop_count != 0 || cleanup_ret != 0);
-		goto repeat;	/* __cleanup may have dropped lock */
-	} while (transaction != last_transaction);
-
-done:
-	spin_unlock(&journal_datalist_lock);
+	}
+	spin_unlock(&journal->j_list_lock);
 	result = cleanup_journal_tail(journal);
 	if (result < 0)
 		return result;
@@ -362,8 +407,8 @@
 	 * next transaction ID we will write, and where it will
 	 * start. */
 
-	/* j_checkpoint_transactions needs locking */
-	spin_lock(&journal_datalist_lock);
+	spin_lock(&journal->j_state_lock);
+	spin_lock(&journal->j_list_lock);
 	transaction = journal->j_checkpoint_transactions;
 	if (transaction) {
 		first_tid = transaction->t_tid;
@@ -378,13 +423,15 @@
 		first_tid = journal->j_transaction_sequence;
 		blocknr = journal->j_head;
 	}
-	spin_unlock(&journal_datalist_lock);
-	J_ASSERT (blocknr != 0);
+	spin_unlock(&journal->j_list_lock);
+	J_ASSERT(blocknr != 0);
 
 	/* If the oldest pinned transaction is at the tail of the log
            already then there's not much we can do right now. */
-	if (journal->j_tail_sequence == first_tid)
+	if (journal->j_tail_sequence == first_tid) {
+		spin_unlock(&journal->j_state_lock);
 		return 1;
+	}
 
 	/* OK, update the superblock to recover the freed space.
 	 * Physical blocks come first: have we wrapped beyond the end of
@@ -401,6 +448,7 @@
 	journal->j_free += freed;
 	journal->j_tail_sequence = first_tid;
 	journal->j_tail = blocknr;
+	spin_unlock(&journal->j_state_lock);
 	if (!(journal->j_flags & JFS_ABORT))
 		journal_update_superblock(journal, 1);
 	return 0;
@@ -415,7 +463,7 @@
  * Find all the written-back checkpoint buffers in the journal and release them.
  *
  * Called with the journal locked.
- * Called with journal_datalist_lock held.
+ * Called with j_list_lock held.
  * Returns number of bufers reaped (for debug)
  */
 
@@ -439,10 +487,13 @@
 		if (jh) {
 			struct journal_head *last_jh = jh->b_cpprev;
 			struct journal_head *next_jh = jh;
+
 			do {
 				jh = next_jh;
 				next_jh = jh->b_cpnext;
-				ret += __try_to_free_cp_buf(jh);
+				/* Use trylock because of the ranknig */
+				if (jbd_trylock_bh_state(jh2bh(jh)))
+					ret += __try_to_free_cp_buf(jh);
 			} while (jh != last_jh);
 		}
 	} while (transaction != last_transaction);
@@ -464,7 +515,7 @@
  * checkpoint list.  
  *
  * This function is called with the journal locked.
- * This function is called with journal_datalist_lock held.
+ * This function is called with j_list_lock held.
  */
 
 void __journal_remove_checkpoint(struct journal_head *jh)
@@ -478,7 +529,6 @@
 		JBUFFER_TRACE(jh, "not on transaction");
 		goto out;
 	}
-
 	journal = transaction->t_journal;
 
 	__buffer_unlink(jh);
@@ -487,11 +537,15 @@
 		goto out;
 	JBUFFER_TRACE(jh, "transaction has no more buffers");
 
-	/* There is one special case to worry about: if we have just
-           pulled the buffer off a committing transaction's forget list,
-           then even if the checkpoint list is empty, the transaction
-           obviously cannot be dropped! */
-
+	/*
+	 * There is one special case to worry about: if we have just pulled the
+	 * buffer off a committing transaction's forget list, then even if the
+	 * checkpoint list is empty, the transaction obviously cannot be
+	 * dropped!
+	 *
+	 * The locking here around j_committing_transaction is a bit sleazy.
+	 * See the comment at the end of journal_commit_transaction().
+	 */
 	if (transaction == journal->j_committing_transaction) {
 		JBUFFER_TRACE(jh, "belongs to committing transaction");
 		goto out;
@@ -509,29 +563,21 @@
 	JBUFFER_TRACE(jh, "exit");
 }
 
-void journal_remove_checkpoint(struct journal_head *jh)
-{
-	spin_lock(&journal_datalist_lock);
-	__journal_remove_checkpoint(jh);
-	spin_unlock(&journal_datalist_lock);
-}
-
 /*
  * journal_insert_checkpoint: put a committed buffer onto a checkpoint
  * list so that we know when it is safe to clean the transaction out of
  * the log.
  *
  * Called with the journal locked.
- * Called with journal_datalist_lock held.
+ * Called with j_list_lock held.
  */
 void __journal_insert_checkpoint(struct journal_head *jh, 
 			       transaction_t *transaction)
 {
 	JBUFFER_TRACE(jh, "entry");
-	J_ASSERT_JH(jh, buffer_dirty(jh2bh(jh)) || buffer_jdirty(jh2bh(jh)));
+	J_ASSERT_JH(jh, buffer_dirty(jh2bh(jh)) || buffer_jbddirty(jh2bh(jh)));
 	J_ASSERT_JH(jh, jh->b_cp_transaction == NULL);
 
-	assert_spin_locked(&journal_datalist_lock);
 	jh->b_cp_transaction = transaction;
 
 	if (!transaction->t_checkpoint_list) {
@@ -545,14 +591,6 @@
 	transaction->t_checkpoint_list = jh;
 }
 
-void journal_insert_checkpoint(struct journal_head *jh, 
-			       transaction_t *transaction)
-{
-	spin_lock(&journal_datalist_lock);
-	__journal_insert_checkpoint(jh, transaction);
-	spin_unlock(&journal_datalist_lock);
-}
-
 /*
  * We've finished with this transaction structure: adios...
  * 
@@ -560,12 +598,12 @@
  * point.
  *
  * Called with the journal locked.
- * Called with journal_datalist_lock held.
+ * Called with j_list_lock held.
  */
 
 void __journal_drop_transaction(journal_t *journal, transaction_t *transaction)
 {
-	assert_spin_locked(&journal_datalist_lock);
+	assert_spin_locked(&journal->j_list_lock);
 	if (transaction->t_cpnext) {
 		transaction->t_cpnext->t_cpprev = transaction->t_cpprev;
 		transaction->t_cpprev->t_cpnext = transaction->t_cpnext;
@@ -576,22 +614,19 @@
 			journal->j_checkpoint_transactions = NULL;
 	}
 
-	J_ASSERT (transaction->t_ilist == NULL);
-	J_ASSERT (transaction->t_buffers == NULL);
-	J_ASSERT (transaction->t_sync_datalist == NULL);
-	J_ASSERT (transaction->t_forget == NULL);
-	J_ASSERT (transaction->t_iobuf_list == NULL);
-	J_ASSERT (transaction->t_shadow_list == NULL);
-	J_ASSERT (transaction->t_log_list == NULL);
-	J_ASSERT (transaction->t_checkpoint_list == NULL);
-	J_ASSERT (transaction->t_updates == 0);
-	J_ASSERT (list_empty(&transaction->t_jcb));
+	J_ASSERT(transaction->t_state == T_FINISHED);
+	J_ASSERT(transaction->t_buffers == NULL);
+	J_ASSERT(transaction->t_sync_datalist == NULL);
+	J_ASSERT(transaction->t_forget == NULL);
+	J_ASSERT(transaction->t_iobuf_list == NULL);
+	J_ASSERT(transaction->t_shadow_list == NULL);
+	J_ASSERT(transaction->t_log_list == NULL);
+	J_ASSERT(transaction->t_checkpoint_list == NULL);
+	J_ASSERT(transaction->t_updates == 0);
+	J_ASSERT(list_empty(&transaction->t_jcb));
+	J_ASSERT(journal->j_committing_transaction != transaction);
+	J_ASSERT(journal->j_running_transaction != transaction);
 
-	J_ASSERT (transaction->t_journal->j_committing_transaction !=
-					transaction);
-	
-	jbd_debug (1, "Dropping transaction %d, all done\n", 
-		   transaction->t_tid);
-	kfree (transaction);
+	jbd_debug(1, "Dropping transaction %d, all done\n", transaction->t_tid);
+	kfree(transaction);
 }
-
diff -Nru a/fs/jbd/commit.c b/fs/jbd/commit.c
--- a/fs/jbd/commit.c	Wed Jun 18 23:42:09 2003
+++ b/fs/jbd/commit.c	Wed Jun 18 23:42:09 2003
@@ -18,10 +18,10 @@
 #include <linux/jbd.h>
 #include <linux/errno.h>
 #include <linux/slab.h>
+#include <linux/mm.h>
+#include <linux/pagemap.h>
 #include <linux/smp_lock.h>
 
-extern spinlock_t journal_datalist_lock;
-
 /*
  * Default IO end handler for temporary BJ_IO buffer_heads.
  */
@@ -36,6 +36,49 @@
 }
 
 /*
+ * When an ext3-ordered file is truncated, it is possible that many pages are
+ * not sucessfully freed, because they are attached to a committing transaction.
+ * After the transaction commits, these pages are left on the LRU, with no
+ * ->mapping, and with attached buffers.  These pages are trivially reclaimable
+ * by the VM, but their apparent absence upsets the VM accounting, and it makes
+ * the numbers in /proc/meminfo look odd.
+ *
+ * So here, we have a buffer which has just come off the forget list.  Look to
+ * see if we can strip all buffers from the backing page.
+ *
+ * Called under lock_journal(), and possibly under journal_datalist_lock.  The
+ * caller provided us with a ref against the buffer, and we drop that here.
+ */
+static void release_buffer_page(struct buffer_head *bh)
+{
+	struct page *page;
+
+	if (buffer_dirty(bh))
+		goto nope;
+	if (atomic_read(&bh->b_count) != 1)
+		goto nope;
+	page = bh->b_page;
+	if (!page)
+		goto nope;
+	if (page->mapping)
+		goto nope;
+
+	/* OK, it's a truncated page */
+	if (TestSetPageLocked(page))
+		goto nope;
+
+	page_cache_get(page);
+	__brelse(bh);
+	try_to_free_buffers(page);
+	unlock_page(page);
+	page_cache_release(page);
+	return;
+
+nope:
+	__brelse(bh);
+}
+
+/*
  * journal_commit_transaction
  *
  * The primary function for committing a transaction to the log.  This
@@ -64,43 +107,52 @@
 	 * all outstanding updates to complete.
 	 */
 
-	lock_journal(journal); /* Protect journal->j_running_transaction */
-
 #ifdef COMMIT_STATS
-	spin_lock(&journal_datalist_lock);
+	spin_lock(&journal->j_list_lock);
 	summarise_journal_usage(journal);
-	spin_unlock(&journal_datalist_lock);
+	spin_unlock(&journal->j_list_lock);
 #endif
 
-	lock_kernel();
+	/* Do we need to erase the effects of a prior journal_flush? */
+	if (journal->j_flags & JFS_FLUSHED) {
+		jbd_debug(3, "super block updated\n");
+		journal_update_superblock(journal, 1);
+	} else {
+		jbd_debug(3, "superblock not updated\n");
+	}
 
-	J_ASSERT (journal->j_running_transaction != NULL);
-	J_ASSERT (journal->j_committing_transaction == NULL);
+	J_ASSERT(journal->j_running_transaction != NULL);
+	J_ASSERT(journal->j_committing_transaction == NULL);
 
 	commit_transaction = journal->j_running_transaction;
-	J_ASSERT (commit_transaction->t_state == T_RUNNING);
+	J_ASSERT(commit_transaction->t_state == T_RUNNING);
 
-	jbd_debug (1, "JBD: starting commit of transaction %d\n",
-		   commit_transaction->t_tid);
+	jbd_debug(1, "JBD: starting commit of transaction %d\n",
+			commit_transaction->t_tid);
 
+	spin_lock(&journal->j_state_lock);
 	commit_transaction->t_state = T_LOCKED;
-	while (commit_transaction->t_updates != 0) {
-		unlock_journal(journal);
-		sleep_on(&journal->j_wait_updates);
-		lock_journal(journal);
+
+	spin_lock(&commit_transaction->t_handle_lock);
+	while (commit_transaction->t_updates) {
+		DEFINE_WAIT(wait);
+
+		prepare_to_wait(&journal->j_wait_updates, &wait,
+					TASK_UNINTERRUPTIBLE);
+		if (commit_transaction->t_updates) {
+			spin_unlock(&commit_transaction->t_handle_lock);
+			spin_unlock(&journal->j_state_lock);
+			schedule();
+			spin_lock(&journal->j_state_lock);
+			spin_lock(&commit_transaction->t_handle_lock);
+		}
+		finish_wait(&journal->j_wait_updates, &wait);
 	}
+	spin_unlock(&commit_transaction->t_handle_lock);
 
 	J_ASSERT (commit_transaction->t_outstanding_credits <=
 			journal->j_max_transaction_buffers);
 
-	/* Do we need to erase the effects of a prior journal_flush? */
-	if (journal->j_flags & JFS_FLUSHED) {
-		jbd_debug(3, "super block updated\n");
-		journal_update_superblock(journal, 1);
-	} else {
-		jbd_debug(3, "superblock not updated\n");
-	}
-
 	/*
 	 * First thing we are allowed to do is to discard any remaining
 	 * BJ_Reserved buffers.  Note, it is _not_ permissible to assume
@@ -117,11 +169,10 @@
 	 * that multiple journal_get_write_access() calls to the same
 	 * buffer are perfectly permissable.
 	 */
-
 	while (commit_transaction->t_reserved_list) {
 		jh = commit_transaction->t_reserved_list;
 		JBUFFER_TRACE(jh, "reserved, unused: refile");
-		journal_refile_buffer(jh);
+		journal_refile_buffer(journal, jh);
 	}
 
 	/*
@@ -129,42 +180,23 @@
 	 * checkpoint lists.  We do this *before* commit because it potentially
 	 * frees some memory
 	 */
-	spin_lock(&journal_datalist_lock);
+	spin_lock(&journal->j_list_lock);
 	__journal_clean_checkpoint_list(journal);
-	spin_unlock(&journal_datalist_lock);
-
-	/* First part of the commit: force the revoke list out to disk.
-	 * The revoke code generates its own metadata blocks on disk for this.
-	 *
-	 * It is important that we do this while the transaction is
-	 * still locked.  Generating the revoke records should not
-	 * generate any IO stalls, so this should be quick; and doing
-	 * the work while we have the transaction locked means that we
-	 * only ever have to maintain the revoke list for one
-	 * transaction at a time.
-	 */
+	spin_unlock(&journal->j_list_lock);
 
 	jbd_debug (3, "JBD: commit phase 1\n");
 
-	journal_write_revoke_records(journal, commit_transaction);
-
 	/*
-	 * Now that we have built the revoke records, we can start
-	 * reusing the revoke list for a new running transaction.  We
-	 * can now safely start committing the old transaction: time to
-	 * get a new running transaction for incoming filesystem updates
+	 * Switch to a new revoke table.
 	 */
+	journal_switch_revoke_table(journal);
 
 	commit_transaction->t_state = T_FLUSH;
-
-	wake_up(&journal->j_wait_transaction_locked);
-
 	journal->j_committing_transaction = commit_transaction;
 	journal->j_running_transaction = NULL;
-
 	commit_transaction->t_log_start = journal->j_head;
-
-	unlock_kernel();
+	wake_up(&journal->j_wait_transaction_locked);
+	spin_unlock(&journal->j_state_lock);
 	
 	jbd_debug (3, "JBD: commit phase 2\n");
 
@@ -185,10 +217,10 @@
 	 * Cleanup any flushed data buffers from the data list.  Even in
 	 * abort mode, we want to flush this out as soon as possible.
 	 *
-	 * We take journal_datalist_lock to protect the lists from
+	 * We take j_list_lock to protect the lists from
 	 * journal_try_to_free_buffers().
 	 */
-	spin_lock(&journal_datalist_lock);
+	spin_lock(&journal->j_list_lock);
 
 write_out_data_locked:
 	bufs = 0;
@@ -210,9 +242,19 @@
 				wbuf[bufs++] = bh;
 			} else {
 				BUFFER_TRACE(bh, "writeout complete: unfile");
+				/*
+				 * We have a lock ranking problem..
+				 */
+				if (!jbd_trylock_bh_state(bh)) {
+					spin_unlock(&journal->j_list_lock);
+					schedule();
+					spin_lock(&journal->j_list_lock);
+					break;
+				}
 				__journal_unfile_buffer(jh);
 				jh->b_transaction = NULL;
-				__journal_remove_journal_head(bh);
+				jbd_unlock_bh_state(bh);
+				journal_remove_journal_head(bh);
 				__brelse(bh);
 			}
 		}
@@ -228,14 +270,12 @@
 
 	if (bufs || need_resched()) {
 		jbd_debug(2, "submit %d writes\n", bufs);
-		spin_unlock(&journal_datalist_lock);
-		unlock_journal(journal);
+		spin_unlock(&journal->j_list_lock);
 		if (bufs)
 			ll_rw_block(WRITE, bufs, wbuf);
 		cond_resched();
 		journal_brelse_array(wbuf, bufs);
-		lock_journal(journal);
-		spin_lock(&journal_datalist_lock);
+		spin_lock(&journal->j_list_lock);
 		if (bufs)
 			goto write_out_data_locked;
 	}
@@ -253,14 +293,12 @@
 		bh = jh2bh(jh);
 		if (buffer_locked(bh)) {
 			get_bh(bh);
-			spin_unlock(&journal_datalist_lock);
-			unlock_journal(journal);
+			spin_unlock(&journal->j_list_lock);
 			wait_on_buffer(bh);
 			if (unlikely(!buffer_uptodate(bh)))
 				err = -EIO;
 			put_bh(bh);
 			/* the journal_head may have been removed now */
-			lock_journal(journal);
 			goto write_out_data;
 		} else if (buffer_dirty(bh)) {
 			goto write_out_data_locked;
@@ -269,7 +307,11 @@
 	goto write_out_data_locked;
 
 sync_datalist_empty:
-	spin_unlock(&journal_datalist_lock);
+	spin_unlock(&journal->j_list_lock);
+
+	journal_write_revoke_records(journal, commit_transaction);
+
+	jbd_debug(3, "JBD: commit phase 2\n");
 
 	/*
 	 * If we found any dirty or locked buffers, then we should have
@@ -301,7 +343,7 @@
 
 		if (is_journal_aborted(journal)) {
 			JBUFFER_TRACE(jh, "journal is aborting: refile");
-			journal_refile_buffer(jh);
+			journal_refile_buffer(journal, jh);
 			/* If that was the last one, we need to clean up
 			 * any descriptor buffers which may have been
 			 * already allocated, even if we are now
@@ -345,7 +387,7 @@
                            completion later */
 			BUFFER_TRACE(bh, "ph3: file as descriptor");
 			journal_file_buffer(descriptor, commit_transaction,
-						BJ_LogCtl);
+					BJ_LogCtl);
 		}
 
 		/* Where is the buffer to be written? */
@@ -419,8 +461,7 @@
 			tag->t_flags |= htonl(JFS_FLAG_LAST_TAG);
 
 start_journal_io:
-			unlock_journal(journal);
-			for (i=0; i<bufs; i++) {
+			for (i = 0; i < bufs; i++) {
 				struct buffer_head *bh = wbuf[i];
 				set_buffer_locked(bh);
 				clear_buffer_dirty(bh);
@@ -429,7 +470,6 @@
 				submit_bh(WRITE, bh);
 			}
 			cond_resched();
-			lock_journal(journal);
 
 			/* Force a new descriptor to be generated next
                            time round the loop. */
@@ -452,27 +492,26 @@
 	jbd_debug(3, "JBD: commit phase 4\n");
 
 	/*
-	 * akpm: these are BJ_IO, and journal_datalist_lock is not needed.
+	 * akpm: these are BJ_IO, and j_list_lock is not needed.
 	 * See __journal_try_to_free_buffer.
 	 */
- wait_for_iobuf:
+wait_for_iobuf:
 	while (commit_transaction->t_iobuf_list != NULL) {
 		struct buffer_head *bh;
+
 		jh = commit_transaction->t_iobuf_list->b_tprev;
 		bh = jh2bh(jh);
 		if (buffer_locked(bh)) {
-			unlock_journal(journal);
 			wait_on_buffer(bh);
 			if (unlikely(!buffer_uptodate(bh)))
 				err = -EIO;
-			lock_journal(journal);
 			goto wait_for_iobuf;
 		}
 
-		clear_bit(BH_JWrite, &jh2bh(jh)->b_state);
+		clear_buffer_jwrite(bh);
 
 		JBUFFER_TRACE(jh, "ph4: unfile after journal write");
-		journal_unfile_buffer(jh);
+		journal_unfile_buffer(journal, jh);
 
 		/*
 		 * akpm: don't put back a buffer_head with stale pointers
@@ -485,9 +524,8 @@
 		 * ->t_iobuf_list should contain only dummy buffer_heads
 		 * which were created by journal_write_metadata_buffer().
 		 */
-		bh = jh2bh(jh);
 		BUFFER_TRACE(bh, "dumping temporary bh");
-		journal_unlock_journal_head(jh);
+		journal_put_journal_head(jh);
 		__brelse(bh);
 		J_ASSERT_BH(bh, atomic_read(&bh->b_count) == 0);
 		free_buffer_head(bh);
@@ -497,7 +535,7 @@
 		jh = commit_transaction->t_shadow_list->b_tprev;
 		bh = jh2bh(jh);
 		clear_bit(BH_JWrite, &bh->b_state);
-		J_ASSERT_BH(bh, buffer_jdirty(bh));
+		J_ASSERT_BH(bh, buffer_jbddirty(bh));
 
 		/* The metadata is now released for reuse, but we need
                    to remember it against this transaction so that when
@@ -524,29 +562,25 @@
 		jh = commit_transaction->t_log_list->b_tprev;
 		bh = jh2bh(jh);
 		if (buffer_locked(bh)) {
-			unlock_journal(journal);
 			wait_on_buffer(bh);
 			if (unlikely(!buffer_uptodate(bh)))
 				err = -EIO;
-			lock_journal(journal);
 			goto wait_for_ctlbuf;
 		}
 
 		BUFFER_TRACE(bh, "ph5: control buffer writeout done: unfile");
-		clear_bit(BH_JWrite, &bh->b_state);
-		journal_unfile_buffer(jh);
+		clear_buffer_jwrite(bh);
+		journal_unfile_buffer(journal, jh);
 		jh->b_transaction = NULL;
-		journal_unlock_journal_head(jh);
+		journal_put_journal_head(jh);
 		__brelse(bh);		/* One for getblk */
 		/* AKPM: bforget here */
 	}
 
 	jbd_debug(3, "JBD: commit phase 6\n");
 
-	if (is_journal_aborted(journal)) {
-		unlock_journal(journal);
+	if (is_journal_aborted(journal))
 		goto skip_commit;
-	}
 
 	/* Done it all: now write the commit record.  We should have
 	 * cleaned up our previous buffers by now, so if we are in abort
@@ -556,7 +590,6 @@
 	descriptor = journal_get_descriptor_buffer(journal);
 	if (!descriptor) {
 		__journal_abort_hard(journal);
-		unlock_journal(journal);
 		goto skip_commit;
 	}
 
@@ -569,7 +602,6 @@
 		tmp->h_sequence = htonl(commit_transaction->t_tid);
 	}
 
-	unlock_journal(journal);
 	JBUFFER_TRACE(descriptor, "write commit block");
 	{
 		struct buffer_head *bh = jh2bh(descriptor);
@@ -578,7 +610,7 @@
 		if (unlikely(!buffer_uptodate(bh)))
 			err = -EIO;
 		put_bh(bh);		/* One for getblk() */
-		journal_unlock_journal_head(descriptor);
+		journal_put_journal_head(descriptor);
 	}
 
 	/* End of a transaction!  Finally, we can do checkpoint
@@ -588,16 +620,17 @@
 
 skip_commit: /* The journal should be unlocked by now. */
 
-	if (err) {
-		lock_journal(journal);
+	if (err)
 		__journal_abort_hard(journal);
-		unlock_journal(journal);
-	}
 	
-	/* Call any callbacks that had been registered for handles in this
+	/*
+	 * Call any callbacks that had been registered for handles in this
 	 * transaction.  It is up to the callback to free any allocated
 	 * memory.
+	 *
+	 * The spinlocking (t_jcb_lock) here is surely unnecessary...
 	 */
+	spin_lock(&commit_transaction->t_jcb_lock);
 	if (!list_empty(&commit_transaction->t_jcb)) {
 		struct list_head *p, *n;
 		int error = is_journal_aborted(journal);
@@ -607,11 +640,12 @@
 
 			jcb = list_entry(p, struct journal_callback, jcb_list);
 			list_del(p);
+			spin_unlock(&commit_transaction->t_jcb_lock);
 			jcb->jcb_func(jcb, error);
+			spin_lock(&commit_transaction->t_jcb_lock);
 		}
 	}
-
-	lock_journal(journal);
+	spin_unlock(&commit_transaction->t_jcb_lock);
 
 	jbd_debug(3, "JBD: commit phase 7\n");
 
@@ -627,6 +661,8 @@
 		struct buffer_head *bh;
 
 		jh = commit_transaction->t_forget;
+		bh = jh2bh(jh);
+		jbd_lock_bh_state(bh);
 		J_ASSERT_JH(jh,	jh->b_transaction == commit_transaction ||
 			jh->b_transaction == journal->j_running_transaction);
 
@@ -652,7 +688,7 @@
 			jh->b_frozen_data = NULL;
 		}
 
-		spin_lock(&journal_datalist_lock);
+		spin_lock(&journal->j_list_lock);
 		cp_transaction = jh->b_cp_transaction;
 		if (cp_transaction) {
 			JBUFFER_TRACE(jh, "remove from old cp transaction");
@@ -665,7 +701,6 @@
 		 * by journal_forget, it may no longer be dirty and
 		 * there's no point in keeping a checkpoint record for
 		 * it. */
-		bh = jh2bh(jh);
 
 		/* A buffer which has been freed while still being
 		 * journaled by a previous transaction may end up still
@@ -680,34 +715,45 @@
 			clear_buffer_jbddirty(bh);
 		}
 			
-		if (buffer_jdirty(bh)) {
+		if (buffer_jbddirty(bh)) {
 			JBUFFER_TRACE(jh, "add to new checkpointing trans");
 			__journal_insert_checkpoint(jh, commit_transaction);
 			JBUFFER_TRACE(jh, "refile for checkpoint writeback");
 			__journal_refile_buffer(jh);
+			jbd_unlock_bh_state(bh);
 		} else {
 			J_ASSERT_BH(bh, !buffer_dirty(bh));
 			J_ASSERT_JH(jh, jh->b_next_transaction == NULL);
 			__journal_unfile_buffer(jh);
 			jh->b_transaction = 0;
-			__journal_remove_journal_head(bh);
-			__brelse(bh);
+			jbd_unlock_bh_state(bh);
+			journal_remove_journal_head(bh);
+			if (buffer_freed(bh))
+				release_buffer_page(bh);
 		}
-		spin_unlock(&journal_datalist_lock);
+		spin_unlock(&journal->j_list_lock);
 	}
 
 	/* Done with this transaction! */
 
 	jbd_debug(3, "JBD: commit phase 8\n");
 
-	J_ASSERT (commit_transaction->t_state == T_COMMIT);
-	commit_transaction->t_state = T_FINISHED;
+	J_ASSERT(commit_transaction->t_state == T_COMMIT);
 
-	J_ASSERT (commit_transaction == journal->j_committing_transaction);
+	/*
+	 * This is a bit sleazy.  We borrow j_list_lock to protect
+	 * journal->j_committing_transaction in __journal_remove_checkpoint.
+	 * Really, __jornal_remove_checkpoint should be using j_state_lock but
+	 * it's a bit hassle to hold that across __journal_remove_checkpoint
+	 */
+	spin_lock(&journal->j_state_lock);
+	spin_lock(&journal->j_list_lock);
+	commit_transaction->t_state = T_FINISHED;
+	J_ASSERT(commit_transaction == journal->j_committing_transaction);
 	journal->j_commit_sequence = commit_transaction->t_tid;
 	journal->j_committing_transaction = NULL;
+	spin_unlock(&journal->j_state_lock);
 
-	spin_lock(&journal_datalist_lock);
 	if (commit_transaction->t_checkpoint_list == NULL) {
 		__journal_drop_transaction(journal, commit_transaction);
 	} else {
@@ -726,11 +772,10 @@
 				commit_transaction;
 		}
 	}
-	spin_unlock(&journal_datalist_lock);
+	spin_unlock(&journal->j_list_lock);
 
 	jbd_debug(1, "JBD: commit %d complete, head %d\n",
 		  journal->j_commit_sequence, journal->j_tail_sequence);
 
-	unlock_journal(journal);
 	wake_up(&journal->j_wait_done_commit);
 }
diff -Nru a/fs/jbd/journal.c b/fs/jbd/journal.c
--- a/fs/jbd/journal.c	Wed Jun 18 23:42:06 2003
+++ b/fs/jbd/journal.c	Wed Jun 18 23:42:06 2003
@@ -48,9 +48,7 @@
 EXPORT_SYMBOL(journal_get_undo_access);
 EXPORT_SYMBOL(journal_dirty_data);
 EXPORT_SYMBOL(journal_dirty_metadata);
-#if 0
 EXPORT_SYMBOL(journal_release_buffer);
-#endif
 EXPORT_SYMBOL(journal_forget);
 #if 0
 EXPORT_SYMBOL(journal_sync_buffer);
@@ -75,7 +73,7 @@
 EXPORT_SYMBOL(journal_ack_err);
 EXPORT_SYMBOL(journal_clear_err);
 EXPORT_SYMBOL(log_wait_commit);
-EXPORT_SYMBOL(log_start_commit);
+EXPORT_SYMBOL(journal_start_commit);
 EXPORT_SYMBOL(journal_wipe);
 EXPORT_SYMBOL(journal_blocks_per_page);
 EXPORT_SYMBOL(journal_invalidatepage);
@@ -86,76 +84,6 @@
 static int journal_convert_superblock_v1(journal_t *, journal_superblock_t *);
 
 /*
- * journal_datalist_lock is used to protect data buffers:
- *
- *	bh->b_transaction
- *	bh->b_tprev
- *	bh->b_tnext
- *
- * journal_free_buffer() is called from journal_try_to_free_buffer(), and is
- * async wrt everything else.
- *
- * It is also used for checkpoint data, also to protect against
- * journal_try_to_free_buffer():
- *
- *	bh->b_cp_transaction
- *	bh->b_cpnext
- *	bh->b_cpprev
- *	transaction->t_checkpoint_list
- *	transaction->t_cpnext
- *	transaction->t_cpprev
- *	journal->j_checkpoint_transactions
- *
- * It is global at this time rather than per-journal because it's
- * impossible for __journal_free_buffer to go from a buffer_head
- * back to a journal_t unracily (well, not true.  Fix later)
- *
- *
- * The `datalist' and `checkpoint list' functions are quite
- * separate and we could use two spinlocks here.
- *
- * lru_list_lock nests inside journal_datalist_lock.
- */
-spinlock_t journal_datalist_lock = SPIN_LOCK_UNLOCKED;
-
-/*
- * jh_splice_lock needs explantion.
- *
- * In a number of places we want to do things like:
- *
- *	if (buffer_jbd(bh) && bh2jh(bh)->foo)
- *
- * This is racy on SMP, because another CPU could remove the journal_head
- * in the middle of this expression.  We need locking.
- *
- * But we can greatly optimise the locking cost by testing BH_JBD
- * outside the lock.  So, effectively:
- *
- *	ret = 0;
- *	if (buffer_jbd(bh)) {
- *		spin_lock(&jh_splice_lock);
- *		if (buffer_jbd(bh)) {	 (* Still there? *)
- *			ret = bh2jh(bh)->foo;
- *		}
- *		spin_unlock(&jh_splice_lock);
- *	}
- *	return ret;
- *
- * Now, that protects us from races where another CPU can remove the
- * journal_head.  But it doesn't defend us from the situation where another
- * CPU can *add* a journal_head.  This is a correctness issue.  But it's not
- * a problem because a) the calling code was *already* racy and b) it often
- * can't happen at the call site and c) the places where we add journal_heads
- * tend to be under external locking.
- */
-spinlock_t jh_splice_lock = SPIN_LOCK_UNLOCKED;
-
-/*
- * List of all journals in the system.  Protected by the BKL.
- */
-static LIST_HEAD(all_journals);
-
-/*
  * Helper function used to manage commit timeouts
  */
 
@@ -204,8 +132,6 @@
 
 	daemonize("kjournald");
 
-	lock_kernel();
-
 	/* Set up an interval timer which can be used to trigger a
            commit wakeup after the commit interval expires */
 	init_timer(&timer);
@@ -219,68 +145,87 @@
 
 	printk(KERN_INFO "kjournald starting.  Commit interval %ld seconds\n",
 			journal->j_commit_interval / HZ);
-	list_add(&journal->j_all_journals, &all_journals);
 
-	/* And now, wait forever for commit wakeup events. */
-	while (1) {
-		if (journal->j_flags & JFS_UNMOUNT)
-			break;
-
-		jbd_debug(1, "commit_sequence=%d, commit_request=%d\n",
-			journal->j_commit_sequence, journal->j_commit_request);
-
-		if (journal->j_commit_sequence != journal->j_commit_request) {
-			jbd_debug(1, "OK, requests differ\n");
-			if (journal->j_commit_timer_active) {
-				journal->j_commit_timer_active = 0;
-				del_timer(journal->j_commit_timer);
-			}
+	/*
+	 * And now, wait forever for commit wakeup events.
+	 */
+	spin_lock(&journal->j_state_lock);
 
-			journal_commit_transaction(journal);
-			continue;
-		}
+loop:
+	jbd_debug(1, "commit_sequence=%d, commit_request=%d\n",
+		journal->j_commit_sequence, journal->j_commit_request);
+
+	if (journal->j_commit_sequence != journal->j_commit_request) {
+		jbd_debug(1, "OK, requests differ\n");
+		spin_unlock(&journal->j_state_lock);
+		del_timer_sync(journal->j_commit_timer);
+		journal_commit_transaction(journal);
+		spin_lock(&journal->j_state_lock);
+		goto loop;
+	}
 
-		wake_up(&journal->j_wait_done_commit);
-		if (current->flags & PF_FREEZE) { /* The simpler the better. Flushing journal isn't a
-						     good idea, because that depends on threads that
-						     may be already stopped. */
-			jbd_debug(1, "Now suspending kjournald\n");
-			refrigerator(PF_IOTHREAD);
-			jbd_debug(1, "Resuming kjournald\n");						
-		} else		/* we assume on resume that commits are already there,
-				   so we don't sleep */
-			interruptible_sleep_on(&journal->j_wait_commit);
-
-		jbd_debug(1, "kjournald wakes\n");
-
-		/* Were we woken up by a commit wakeup event? */
-		if ((transaction = journal->j_running_transaction) != NULL &&
-		    time_after_eq(jiffies, transaction->t_expires)) {
-			journal->j_commit_request = transaction->t_tid;
-			jbd_debug(1, "woke because of timeout\n");
+	wake_up(&journal->j_wait_done_commit);
+	if (current->flags & PF_FREEZE) {
+		/*
+		 * The simpler the better. Flushing journal isn't a
+		 * good idea, because that depends on threads that may
+		 * be already stopped.
+		 */
+		jbd_debug(1, "Now suspending kjournald\n");
+		spin_unlock(&journal->j_state_lock);
+		refrigerator(PF_IOTHREAD);
+		spin_lock(&journal->j_state_lock);
+		jbd_debug(1, "Resuming kjournald\n");						
+	} else {
+		/*
+		 * We assume on resume that commits are already there,
+		 * so we don't sleep
+		 */
+		DEFINE_WAIT(wait);
+		int should_sleep = 1;
+
+		prepare_to_wait(&journal->j_wait_commit, &wait,
+				TASK_INTERRUPTIBLE);		
+		if (journal->j_commit_sequence != journal->j_commit_request)
+			should_sleep = 0;
+		transaction = journal->j_running_transaction;
+		if (transaction && time_after_eq(jiffies,
+						transaction->t_expires))
+			should_sleep = 0;
+		if (should_sleep) {
+			spin_unlock(&journal->j_state_lock);
+			schedule();
+			spin_lock(&journal->j_state_lock);
 		}
+		finish_wait(&journal->j_wait_commit, &wait);
 	}
 
-	if (journal->j_commit_timer_active) {
-		journal->j_commit_timer_active = 0;
-		del_timer_sync(journal->j_commit_timer);
+	jbd_debug(1, "kjournald wakes\n");
+
+	/*
+	 * Were we woken up by a commit wakeup event?
+	 */
+	transaction = journal->j_running_transaction;
+	if (transaction && time_after_eq(jiffies, transaction->t_expires)) {
+		journal->j_commit_request = transaction->t_tid;
+		jbd_debug(1, "woke because of timeout\n");
 	}
 
-	list_del(&journal->j_all_journals);
+	if (!(journal->j_flags & JFS_UNMOUNT))
+		goto loop;
 
+	spin_unlock(&journal->j_state_lock);
+	del_timer_sync(journal->j_commit_timer);
 	journal->j_task = NULL;
 	wake_up(&journal->j_wait_done_commit);
 	jbd_debug(1, "Journal thread exiting.\n");
-	unlock_kernel();
 	return 0;
 }
 
 static void journal_start_thread(journal_t *journal)
 {
-	kernel_thread(kjournald, (void *) journal,
-		      CLONE_VM | CLONE_FS | CLONE_FILES);
-	while (!journal->j_task)
-		sleep_on(&journal->j_wait_done_commit);
+	kernel_thread(kjournald, journal, CLONE_VM|CLONE_FS|CLONE_FILES);
+	wait_event(journal->j_wait_done_commit, journal->j_task != 0);
 }
 
 static void journal_kill_thread(journal_t *journal)
@@ -289,60 +234,10 @@
 
 	while (journal->j_task) {
 		wake_up(&journal->j_wait_commit);
-		sleep_on(&journal->j_wait_done_commit);
+		wait_event(journal->j_wait_done_commit, journal->j_task == 0);
 	}
 }
 
-#if 0
-
-This is no longer needed - we do it in commit quite efficiently.
-Note that if this function is resurrected, the loop needs to
-be reorganised into the next_jh/last_jh algorithm.
-
-/*
- * journal_clean_data_list: cleanup after data IO.
- *
- * Once the IO system has finished writing the buffers on the transaction's
- * data list, we can remove those buffers from the list.  This function
- * scans the list for such buffers and removes them cleanly.
- *
- * We assume that the journal is already locked.
- * We are called with journal_datalist_lock held.
- *
- * AKPM: This function looks inefficient.  Approximately O(n^2)
- * for potentially thousands of buffers.  It no longer shows on profiles
- * because these buffers are mainly dropped in journal_commit_transaction().
- */
-
-void __journal_clean_data_list(transaction_t *transaction)
-{
-	struct journal_head *jh, *next;
-
-	assert_spin_locked(&journal_datalist_lock);
-
-restart:
-	jh = transaction->t_sync_datalist;
-	if (!jh)
-		goto out;
-	do {
-		next = jh->b_tnext;
-		if (!buffer_locked(jh2bh(jh)) && !buffer_dirty(jh2bh(jh))) {
-			struct buffer_head *bh = jh2bh(jh);
-			BUFFER_TRACE(bh, "data writeout complete: unfile");
-			__journal_unfile_buffer(jh);
-			jh->b_transaction = NULL;
-			__journal_remove_journal_head(bh);
-			__brelse(bh);
-			goto restart;
-		}
-		jh = next;
-	} while (transaction->t_sync_datalist &&
-			jh != transaction->t_sync_datalist);
-out:
-	return;
-}
-#endif
-
 /*
  * journal_write_metadata_buffer: write a metadata buffer to the journal.
  *
@@ -393,9 +288,10 @@
 	int do_escape = 0;
 	char *mapped_data;
 	struct buffer_head *new_bh;
-	struct journal_head * new_jh;
+	struct journal_head *new_jh;
 	struct page *new_page;
 	unsigned int new_offset;
+	struct buffer_head *bh_in = jh2bh(jh_in);
 
 	/*
 	 * The buffer really shouldn't be locked: only the current committing
@@ -406,13 +302,16 @@
 	 * also part of a shared mapping, and another thread has
 	 * decided to launch a writepage() against this buffer.
 	 */
-	J_ASSERT_JH(jh_in, buffer_jdirty(jh2bh(jh_in)));
+	J_ASSERT_BH(bh_in, buffer_jbddirty(bh_in));
+
+	new_bh = alloc_buffer_head(GFP_NOFS|__GFP_NOFAIL);
 
 	/*
 	 * If a new transaction has already done a buffer copy-out, then
 	 * we use that version of the data for the commit.
 	 */
-
+	jbd_lock_bh_state(bh_in);
+repeat:
 	if (jh_in->b_frozen_data) {
 		done_copy_out = 1;
 		new_page = virt_to_page(jh_in->b_frozen_data);
@@ -422,12 +321,13 @@
 		new_offset = virt_to_offset(jh2bh(jh_in)->b_data);
 	}
 
-	mapped_data = ((char *) kmap(new_page)) + new_offset;
+	mapped_data = kmap_atomic(new_page, KM_USER0);
 
 	/*
 	 * Check for escaping
 	 */
-	if (* ((unsigned int *) mapped_data) == htonl(JFS_MAGIC_NUMBER)) {
+	if (*((unsigned int *)(mapped_data + new_offset)) ==
+				htonl(JFS_MAGIC_NUMBER)) {
 		need_copy_out = 1;
 		do_escape = 1;
 	}
@@ -435,38 +335,47 @@
 	/*
 	 * Do we need to do a data copy?
 	 */
-
 	if (need_copy_out && !done_copy_out) {
 		char *tmp;
-		tmp = jbd_rep_kmalloc(jh2bh(jh_in)->b_size, GFP_NOFS);
+
+		kunmap_atomic(mapped_data, KM_USER0);
+		jbd_unlock_bh_state(bh_in);
+		tmp = jbd_rep_kmalloc(bh_in->b_size, GFP_NOFS);
+		jbd_lock_bh_state(bh_in);
+		if (jh_in->b_frozen_data) {
+			kfree(new_page);
+			goto repeat;
+		}
 
 		jh_in->b_frozen_data = tmp;
-		memcpy (tmp, mapped_data, jh2bh(jh_in)->b_size);
-		
+		mapped_data = kmap_atomic(new_page, KM_USER0);
+		memcpy(tmp, mapped_data + new_offset, jh2bh(jh_in)->b_size);
+
 		/* If we get to this path, we'll always need the new
 		   address kmapped so that we can clear the escaped
 		   magic number below. */
-		kunmap(new_page);
 		new_page = virt_to_page(tmp);
 		new_offset = virt_to_offset(tmp);
-		mapped_data = ((char *) kmap(new_page)) + new_offset;
-		
 		done_copy_out = 1;
 	}
 
 	/*
-	 * Right, time to make up the new buffer_head.
+	 * Did we need to do an escaping?  Now we've done all the
+	 * copying, we can finally do so.
 	 */
-	new_bh = alloc_buffer_head(GFP_NOFS|__GFP_NOFAIL);
+	if (do_escape)
+		*((unsigned int *)(mapped_data + new_offset)) = 0;
+	kunmap_atomic(mapped_data, KM_USER0);
 
 	/* keep subsequent assertions sane */
 	new_bh->b_state = 0;
 	init_buffer(new_bh, NULL, NULL);
 	atomic_set(&new_bh->b_count, 1);
-	new_jh = journal_add_journal_head(new_bh);
+	jbd_unlock_bh_state(bh_in);
 
-	set_bh_page(new_bh, new_page, new_offset);
+	new_jh = journal_add_journal_head(new_bh);	/* This sleeps */
 
+	set_bh_page(new_bh, new_page, new_offset);
 	new_jh->b_transaction = NULL;
 	new_bh->b_size = jh2bh(jh_in)->b_size;
 	new_bh->b_bdev = transaction->t_journal->j_dev;
@@ -477,15 +386,6 @@
 	*jh_out = new_jh;
 
 	/*
-	 * Did we need to do an escaping?  Now we've done all the
-	 * copying, we can finally do so.
-	 */
-
-	if (do_escape)
-		* ((unsigned int *) mapped_data) = 0;
-	kunmap(new_page);
-	
-	/*
 	 * The to-be-written buffer needs to get moved to the io queue,
 	 * and the original buffer whose contents we are shadowing or
 	 * copying is moved to the transaction's shadow queue.
@@ -504,17 +404,23 @@
  */
 
 /*
- * log_space_left: Return the number of free blocks left in the journal.
+ * __log_space_left: Return the number of free blocks left in the journal.
  *
  * Called with the journal already locked.
+ *
+ * Called under j_state_lock
  */
 
-int log_space_left (journal_t *journal)
+int __log_space_left(journal_t *journal)
 {
 	int left = journal->j_free;
 
-	/* Be pessimistic here about the number of those free blocks
-	 * which might be required for log descriptor control blocks. */
+	assert_spin_locked(&journal->j_state_lock);
+
+	/*
+	 * Be pessimistic here about the number of those free blocks which
+	 * might be required for log descriptor control blocks.
+	 */
 
 #define MIN_LOG_RESERVED_BLOCKS 32 /* Allow for rounding errors */
 
@@ -527,80 +433,92 @@
 }
 
 /*
- * This function must be non-allocating for PF_MEMALLOC tasks
+ * Called under j_state_lock.  Returns true if a transaction was started.
  */
-tid_t log_start_commit (journal_t *journal, transaction_t *transaction)
+int __log_start_commit(journal_t *journal, tid_t target)
 {
-	tid_t target = journal->j_commit_request;
-
-	lock_kernel(); /* Protect journal->j_running_transaction */
-	
-	/*
-	 * A NULL transaction asks us to commit the currently running
-	 * transaction, if there is one.  
-	 */
-	if (transaction)
-		target = transaction->t_tid;
-	else {
-		transaction = journal->j_running_transaction;
-		if (!transaction)
-			goto out;
-		target = transaction->t_tid;
-	}
-		
 	/*
 	 * Are we already doing a recent enough commit?
 	 */
-	if (tid_geq(journal->j_commit_request, target))
-		goto out;
+	if (!tid_geq(journal->j_commit_request, target)) {
+		/*
+		 * We want a new commit: OK, mark the request and wakup the
+		 * commit thread.  We do _not_ do the commit ourselves.
+		 */
 
-	/*
-	 * We want a new commit: OK, mark the request and wakup the
-	 * commit thread.  We do _not_ do the commit ourselves.
-	 */
+		journal->j_commit_request = target;
+		jbd_debug(1, "JBD: requesting commit %d/%d\n",
+			  journal->j_commit_request,
+			  journal->j_commit_sequence);
+		wake_up(&journal->j_wait_commit);
+		return 1;
+	}
+	return 0;
+}
 
-	journal->j_commit_request = target;
-	jbd_debug(1, "JBD: requesting commit %d/%d\n",
-		  journal->j_commit_request,
-		  journal->j_commit_sequence);
-	wake_up(&journal->j_wait_commit);
+int log_start_commit(journal_t *journal, tid_t tid)
+{
+	int ret;
 
-out:
-	unlock_kernel();
-	return target;
+	spin_lock(&journal->j_state_lock);
+	ret = __log_start_commit(journal, tid);
+	spin_unlock(&journal->j_state_lock);
+	return ret;
+}
+
+/*
+ * Start a commit of the current running transaction (if any).  Returns true
+ * if a transaction was started, and fills its tid in at *ptid
+ */
+int journal_start_commit(journal_t *journal, tid_t *ptid)
+{
+	int ret = 0;
+
+	spin_lock(&journal->j_state_lock);
+	if (journal->j_running_transaction) {
+		tid_t tid = journal->j_running_transaction->t_tid;
+
+		ret = __log_start_commit(journal, tid);
+		if (ret && ptid)
+			*ptid = tid;
+	}
+	spin_unlock(&journal->j_state_lock);
+	return ret;
 }
 
 /*
  * Wait for a specified commit to complete.
  * The caller may not hold the journal lock.
  */
-int log_wait_commit (journal_t *journal, tid_t tid)
+int log_wait_commit(journal_t *journal, tid_t tid)
 {
 	int err = 0;
 
-	lock_kernel();
 #ifdef CONFIG_JBD_DEBUG
-	lock_journal(journal);
+	spin_lock(&journal->j_state_lock);
 	if (!tid_geq(journal->j_commit_request, tid)) {
 		printk(KERN_EMERG
 		       "%s: error: j_commit_request=%d, tid=%d\n",
 		       __FUNCTION__, journal->j_commit_request, tid);
 	}
-	unlock_journal(journal);
+	spin_unlock(&journal->j_state_lock);
 #endif
+	spin_lock(&journal->j_state_lock);
 	while (tid_gt(tid, journal->j_commit_sequence)) {
 		jbd_debug(1, "JBD: want %d, j_commit_sequence=%d\n",
 				  tid, journal->j_commit_sequence);
 		wake_up(&journal->j_wait_commit);
-		sleep_on(&journal->j_wait_done_commit);
+		spin_unlock(&journal->j_state_lock);
+		wait_event(journal->j_wait_done_commit,
+				!tid_gt(tid, journal->j_commit_sequence));
+		spin_lock(&journal->j_state_lock);
 	}
+	spin_unlock(&journal->j_state_lock);
 
 	if (unlikely(is_journal_aborted(journal))) {
 		printk(KERN_EMERG "journal commit I/O error\n");
 		err = -EIO;
 	}
-
-	unlock_kernel();
 	return err;
 }
 
@@ -612,6 +530,7 @@
 {
 	unsigned long blocknr;
 
+	spin_lock(&journal->j_state_lock);
 	J_ASSERT(journal->j_free > 1);
 
 	blocknr = journal->j_head;
@@ -619,6 +538,7 @@
 	journal->j_free--;
 	if (journal->j_head == journal->j_last)
 		journal->j_head = journal->j_first;
+	spin_unlock(&journal->j_state_lock);
 	return journal_bmap(journal, blocknr, retp);
 }
 
@@ -706,7 +626,9 @@
 	init_waitqueue_head(&journal->j_wait_updates);
 	init_MUTEX(&journal->j_barrier);
 	init_MUTEX(&journal->j_checkpoint_sem);
-	init_MUTEX(&journal->j_sem);
+	spin_lock_init(&journal->j_revoke_lock);
+	spin_lock_init(&journal->j_list_lock);
+	spin_lock_init(&journal->j_state_lock);
 
 	journal->j_commit_interval = (HZ * 5);
 
@@ -835,7 +757,7 @@
  * subsequent use.
  */
 
-static int journal_reset (journal_t *journal)
+static int journal_reset(journal_t *journal)
 {
 	journal_superblock_t *sb = journal->j_superblock;
 	unsigned int first, last;
@@ -858,11 +780,7 @@
 
 	/* Add the dynamic fields and write it to disk. */
 	journal_update_superblock(journal, 1);
-
-	lock_journal(journal);
 	journal_start_thread(journal);
-	unlock_journal(journal);
-
 	return 0;
 }
 
@@ -950,12 +868,14 @@
 	journal_superblock_t *sb = journal->j_superblock;
 	struct buffer_head *bh = journal->j_sb_buffer;
 
+	spin_lock(&journal->j_state_lock);
 	jbd_debug(1,"JBD: updating superblock (start %ld, seq %d, errno %d)\n",
 		  journal->j_tail, journal->j_tail_sequence, journal->j_errno);
 
 	sb->s_sequence = htonl(journal->j_tail_sequence);
 	sb->s_start    = htonl(journal->j_tail);
 	sb->s_errno    = htonl(journal->j_errno);
+	spin_unlock(&journal->j_state_lock);
 
 	BUFFER_TRACE(bh, "marking dirty");
 	mark_buffer_dirty(bh);
@@ -968,13 +888,14 @@
 	 * any future commit will have to be careful to update the
 	 * superblock again to re-record the true start of the log. */
 
+	spin_lock(&journal->j_state_lock);
 	if (sb->s_start)
 		journal->j_flags &= ~JFS_FLUSHED;
 	else
 		journal->j_flags |= JFS_FLUSHED;
+	spin_unlock(&journal->j_state_lock);
 }
 
-
 /*
  * Read the superblock for a given journal, performing initial
  * validation of the format.
@@ -1116,11 +1037,11 @@
 /**
  * void journal_destroy() - Release a journal_t structure.
  * @journal: Journal to act on.
-* 
+ *
  * Release a journal_t structure once it is no longer in use by the
  * journaled object.
  */
-void journal_destroy (journal_t *journal)
+void journal_destroy(journal_t *journal)
 {
 	/* Wait for the commit thread to wake up and die. */
 	journal_kill_thread(journal);
@@ -1130,13 +1051,19 @@
 		journal_commit_transaction(journal);
 
 	/* Force any old transactions to disk */
-	lock_journal(journal);
-	while (journal->j_checkpoint_transactions != NULL)
+
+	/* Totally anal locking here... */
+	spin_lock(&journal->j_list_lock);
+	while (journal->j_checkpoint_transactions != NULL) {
+		spin_unlock(&journal->j_list_lock);
 		log_do_checkpoint(journal, 1);
+		spin_lock(&journal->j_list_lock);
+	}
 
 	J_ASSERT(journal->j_running_transaction == NULL);
 	J_ASSERT(journal->j_committing_transaction == NULL);
 	J_ASSERT(journal->j_checkpoint_transactions == NULL);
+	spin_unlock(&journal->j_list_lock);
 
 	/* We can now mark the journal as empty. */
 	journal->j_tail = 0;
@@ -1150,8 +1077,6 @@
 		iput(journal->j_inode);
 	if (journal->j_revoke)
 		journal_destroy_revoke(journal);
-
-	unlock_journal(journal);
 	kfree(journal);
 }
 
@@ -1310,29 +1235,39 @@
  * recovery does not need to happen on remount.
  */
 
-int journal_flush (journal_t *journal)
+int journal_flush(journal_t *journal)
 {
 	int err = 0;
 	transaction_t *transaction = NULL;
 	unsigned long old_tail;
 
-	lock_kernel();
+	spin_lock(&journal->j_state_lock);
 	
 	/* Force everything buffered to the log... */
 	if (journal->j_running_transaction) {
 		transaction = journal->j_running_transaction;
-		log_start_commit(journal, transaction);
+		__log_start_commit(journal, transaction->t_tid);
 	} else if (journal->j_committing_transaction)
 		transaction = journal->j_committing_transaction;
 
 	/* Wait for the log commit to complete... */
-	if (transaction)
-		log_wait_commit(journal, transaction->t_tid);
+	if (transaction) {
+		tid_t tid = transaction->t_tid;
+
+		spin_unlock(&journal->j_state_lock);
+		log_wait_commit(journal, tid);
+	} else {
+		spin_unlock(&journal->j_state_lock);
+	}
 
 	/* ...and flush everything in the log out to disk. */
-	lock_journal(journal);
-	while (!err && journal->j_checkpoint_transactions != NULL)
+	spin_lock(&journal->j_list_lock);
+	while (!err && journal->j_checkpoint_transactions != NULL) {
+		spin_unlock(&journal->j_list_lock);
 		err = log_do_checkpoint(journal, journal->j_maxlen);
+		spin_lock(&journal->j_list_lock);
+	}
+	spin_unlock(&journal->j_list_lock);
 	cleanup_journal_tail(journal);
 
 	/* Finally, mark the journal as really needing no recovery.
@@ -1340,21 +1275,20 @@
 	 * the magic code for a fully-recovered superblock.  Any future
 	 * commits of data to the journal will restore the current
 	 * s_start value. */
+	spin_lock(&journal->j_state_lock);
 	old_tail = journal->j_tail;
 	journal->j_tail = 0;
+	spin_unlock(&journal->j_state_lock);
 	journal_update_superblock(journal, 1);
+	spin_lock(&journal->j_state_lock);
 	journal->j_tail = old_tail;
 
-	unlock_journal(journal);
-
 	J_ASSERT(!journal->j_running_transaction);
 	J_ASSERT(!journal->j_committing_transaction);
 	J_ASSERT(!journal->j_checkpoint_transactions);
 	J_ASSERT(journal->j_head == journal->j_tail);
 	J_ASSERT(journal->j_tail_sequence == journal->j_transaction_sequence);
-
-	unlock_kernel();
-	
+	spin_unlock(&journal->j_state_lock);
 	return err;
 }
 
@@ -1371,7 +1305,7 @@
  * we merely suppress recovery.
  */
 
-int journal_wipe (journal_t *journal, int write)
+int journal_wipe(journal_t *journal, int write)
 {
 	journal_superblock_t *sb;
 	int err = 0;
@@ -1423,10 +1357,12 @@
  * itself are here.
  */
 
-/* Quick version for internal journal use (doesn't lock the journal).
+/*
+ * Quick version for internal journal use (doesn't lock the journal).
  * Aborts hard --- we mark the abort as occurred, but do _nothing_ else,
- * and don't attempt to make any other journal updates. */
-void __journal_abort_hard (journal_t *journal)
+ * and don't attempt to make any other journal updates.
+ */
+void __journal_abort_hard(journal_t *journal)
 {
 	transaction_t *transaction;
 	char b[BDEVNAME_SIZE];
@@ -1434,13 +1370,15 @@
 	if (journal->j_flags & JFS_ABORT)
 		return;
 
-	printk (KERN_ERR "Aborting journal on device %s.\n",
+	printk(KERN_ERR "Aborting journal on device %s.\n",
 		journal_dev_name(journal, b));
 
+	spin_lock(&journal->j_state_lock);
 	journal->j_flags |= JFS_ABORT;
 	transaction = journal->j_running_transaction;
 	if (transaction)
-		log_start_commit(journal, transaction);
+		__log_start_commit(journal, transaction->t_tid);
+	spin_unlock(&journal->j_state_lock);
 }
 
 /* Soft abort: record the abort error status in the journal superblock,
@@ -1505,11 +1443,9 @@
  * 
  */
 
-void journal_abort (journal_t *journal, int errno)
+void journal_abort(journal_t *journal, int errno)
 {
-	lock_journal(journal);
 	__journal_abort_soft(journal, errno);
-	unlock_journal(journal);
 }
 
 /** 
@@ -1523,53 +1459,50 @@
  * If the journal has been aborted on this mount time -EROFS will
  * be returned.
  */
-int journal_errno (journal_t *journal)
+int journal_errno(journal_t *journal)
 {
 	int err;
 
-	lock_journal(journal);
+	spin_lock(&journal->j_state_lock);
 	if (journal->j_flags & JFS_ABORT)
 		err = -EROFS;
 	else
 		err = journal->j_errno;
-	unlock_journal(journal);
+	spin_unlock(&journal->j_state_lock);
 	return err;
 }
 
-
-
 /** 
  * int journal_clear_err () - clears the journal's error state
  *
  * An error must be cleared or Acked to take a FS out of readonly
  * mode.
  */
-int journal_clear_err (journal_t *journal)
+int journal_clear_err(journal_t *journal)
 {
 	int err = 0;
 
-	lock_journal(journal);
+	spin_lock(&journal->j_state_lock);
 	if (journal->j_flags & JFS_ABORT)
 		err = -EROFS;
 	else
 		journal->j_errno = 0;
-	unlock_journal(journal);
+	spin_unlock(&journal->j_state_lock);
 	return err;
 }
 
-
 /** 
  * void journal_ack_err() - Ack journal err.
  *
  * An error must be cleared or Acked to take a FS out of readonly
  * mode.
  */
-void journal_ack_err (journal_t *journal)
+void journal_ack_err(journal_t *journal)
 {
-	lock_journal(journal);
+	spin_lock(&journal->j_state_lock);
 	if (journal->j_errno)
 		journal->j_flags |= JFS_ACK_ERR;
-	unlock_journal(journal);
+	spin_unlock(&journal->j_state_lock);
 }
 
 int journal_blocks_per_page(struct inode *inode)
@@ -1578,26 +1511,6 @@
 }
 
 /*
- * shrink_journal_memory().
- * Called when we're under memory pressure.  Free up all the written-back
- * checkpointed metadata buffers.
- */
-void shrink_journal_memory(void)
-{
-	struct list_head *list;
-
-	lock_kernel();
-	list_for_each(list, &all_journals) {
-		journal_t *journal =
-			list_entry(list, journal_t, j_all_journals);
-		spin_lock(&journal_datalist_lock);
-		__journal_clean_checkpoint_list(journal);
-		spin_unlock(&journal_datalist_lock);
-	}
-	unlock_kernel();
-}
-
-/*
  * Simple support for retying memory allocations.  Introduced to help to
  * debug different VM deadlock avoidance strategies. 
  */
@@ -1703,7 +1616,7 @@
  * _before_ attaching the journal_head to a transaction.  To protect the
  * journal_head in this situation, journal_add_journal_head elevates the
  * journal_head's b_jcount refcount by one.  The caller must call
- * journal_unlock_journal_head() to undo this.
+ * journal_put_journal_head() to undo this.
  *
  * So the typical usage would be:
  *
@@ -1711,7 +1624,7 @@
  *	struct journal_head *jh = journal_add_journal_head(bh);
  *	...
  *	jh->b_transaction = xxx;
- *	journal_unlock_journal_head(jh);
+ *	journal_put_journal_head(jh);
  *
  * Now, the journal_head's b_jcount is zero, but it is safe from being released
  * because it has a non-zero b_transaction.
@@ -1722,70 +1635,70 @@
  *
  * Doesn't need the journal lock.
  * May sleep.
- * Cannot be called with journal_datalist_lock held.
  */
 struct journal_head *journal_add_journal_head(struct buffer_head *bh)
 {
 	struct journal_head *jh;
+	struct journal_head *new_jh = NULL;
+
+repeat:
+	if (!buffer_jbd(bh)) {
+		new_jh = journal_alloc_journal_head();
+		memset(new_jh, 0, sizeof(*new_jh));
+	}
 
-	spin_lock(&journal_datalist_lock);
+	jbd_lock_bh_journal_head(bh);
 	if (buffer_jbd(bh)) {
 		jh = bh2jh(bh);
 	} else {
 		J_ASSERT_BH(bh,
 			(atomic_read(&bh->b_count) > 0) ||
 			(bh->b_page && bh->b_page->mapping));
-		spin_unlock(&journal_datalist_lock);
-		jh = journal_alloc_journal_head();
-		memset(jh, 0, sizeof(*jh));
-		spin_lock(&journal_datalist_lock);
-
-		if (buffer_jbd(bh)) {
-			/* Someone did it for us! */
-			J_ASSERT_BH(bh, bh->b_private != NULL);
-			journal_free_journal_head(jh);
-			jh = bh->b_private;
-		} else {
-			/*
-			 * We actually don't need jh_splice_lock when
-			 * adding a journal_head - only on removal.
-			 */
-			spin_lock(&jh_splice_lock);
-			set_bit(BH_JBD, &bh->b_state);
-			bh->b_private = jh;
-			jh->b_bh = bh;
-			atomic_inc(&bh->b_count);
-			spin_unlock(&jh_splice_lock);
-			BUFFER_TRACE(bh, "added journal_head");
+
+		if (!new_jh) {
+			jbd_unlock_bh_journal_head(bh);
+			goto repeat;
 		}
+
+		jh = new_jh;
+		new_jh = NULL;		/* We consumed it */
+		set_buffer_jbd(bh);
+		bh->b_private = jh;
+		jh->b_bh = bh;
+		get_bh(bh);
+		BUFFER_TRACE(bh, "added journal_head");
 	}
 	jh->b_jcount++;
-	spin_unlock(&journal_datalist_lock);
+	jbd_unlock_bh_journal_head(bh);
+	if (new_jh)
+		journal_free_journal_head(new_jh);
 	return bh->b_private;
 }
 
 /*
- * journal_remove_journal_head(): if the buffer isn't attached to a transaction
- * and has a zero b_jcount then remove and release its journal_head.   If we did
- * see that the buffer is not used by any transaction we also "logically"
- * decrement ->b_count.
- *
- * We in fact take an additional increment on ->b_count as a convenience,
- * because the caller usually wants to do additional things with the bh
- * after calling here.
- * The caller of journal_remove_journal_head() *must* run __brelse(bh) at some
- * time.  Once the caller has run __brelse(), the buffer is eligible for
- * reaping by try_to_free_buffers().
- *
- * Requires journal_datalist_lock.
+ * Grab a ref against this buffer_head's journal_head.  If it ended up not
+ * having a journal_head, return NULL
  */
-void __journal_remove_journal_head(struct buffer_head *bh)
+struct journal_head *journal_grab_journal_head(struct buffer_head *bh)
+{
+	struct journal_head *jh = NULL;
+
+	jbd_lock_bh_journal_head(bh);
+	if (buffer_jbd(bh)) {
+		jh = bh2jh(bh);
+		jh->b_jcount++;
+	}
+	jbd_unlock_bh_journal_head(bh);
+	return jh;
+}
+
+static void __journal_remove_journal_head(struct buffer_head *bh)
 {
 	struct journal_head *jh = bh2jh(bh);
 
-	assert_spin_locked(&journal_datalist_lock);
 	J_ASSERT_JH(jh, jh->b_jcount >= 0);
-	atomic_inc(&bh->b_count);
+
+	get_bh(bh);
 	if (jh->b_jcount == 0) {
 		if (jh->b_transaction == NULL &&
 				jh->b_next_transaction == NULL &&
@@ -1793,12 +1706,10 @@
 			J_ASSERT_BH(bh, buffer_jbd(bh));
 			J_ASSERT_BH(bh, jh2bh(jh) == bh);
 			BUFFER_TRACE(bh, "remove journal_head");
-			spin_lock(&jh_splice_lock);
 			bh->b_private = NULL;
 			jh->b_bh = NULL;	/* debug, really */
-			clear_bit(BH_JBD, &bh->b_state);
+			clear_buffer_jbd(bh);
 			__brelse(bh);
-			spin_unlock(&jh_splice_lock);
 			journal_free_journal_head(jh);
 		} else {
 			BUFFER_TRACE(bh, "journal_head was locked");
@@ -1806,26 +1717,42 @@
 	}
 }
 
-void journal_unlock_journal_head(struct journal_head *jh)
+/*
+ * journal_remove_journal_head(): if the buffer isn't attached to a transaction
+ * and has a zero b_jcount then remove and release its journal_head.   If we did
+ * see that the buffer is not used by any transaction we also "logically"
+ * decrement ->b_count.
+ *
+ * We in fact take an additional increment on ->b_count as a convenience,
+ * because the caller usually wants to do additional things with the bh
+ * after calling here.
+ * The caller of journal_remove_journal_head() *must* run __brelse(bh) at some
+ * time.  Once the caller has run __brelse(), the buffer is eligible for
+ * reaping by try_to_free_buffers().
+ */
+void journal_remove_journal_head(struct buffer_head *bh)
+{
+	jbd_lock_bh_journal_head(bh);
+	__journal_remove_journal_head(bh);
+	jbd_unlock_bh_journal_head(bh);
+}
+
+/*
+ * Drop a reference on the passed journal_head.  If it fell to zero then try to
+ * release the journal_head from the buffer_head.
+ */
+void journal_put_journal_head(struct journal_head *jh)
 {
-	spin_lock(&journal_datalist_lock);
+	struct buffer_head *bh = jh2bh(jh);
+
+	jbd_lock_bh_journal_head(bh);
 	J_ASSERT_JH(jh, jh->b_jcount > 0);
 	--jh->b_jcount;
 	if (!jh->b_jcount && !jh->b_transaction) {
-		struct buffer_head *bh;
-		bh = jh2bh(jh);
 		__journal_remove_journal_head(bh);
 		__brelse(bh);
 	}
-	
-	spin_unlock(&journal_datalist_lock);
-}
-
-void journal_remove_journal_head(struct buffer_head *bh)
-{
-	spin_lock(&journal_datalist_lock);
-	__journal_remove_journal_head(bh);
-	spin_unlock(&journal_datalist_lock);
+	jbd_unlock_bh_journal_head(bh);
 }
 
 /*
diff -Nru a/fs/jbd/revoke.c b/fs/jbd/revoke.c
--- a/fs/jbd/revoke.c	Wed Jun 18 23:42:06 2003
+++ b/fs/jbd/revoke.c	Wed Jun 18 23:42:06 2003
@@ -129,7 +129,9 @@
 	record->sequence = seq;
 	record->blocknr = blocknr;
 	hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
+	spin_lock(&journal->j_revoke_lock);
 	list_add(&record->hash, hash_list);
+	spin_unlock(&journal->j_revoke_lock);
 	return 0;
 
 oom:
@@ -150,12 +152,16 @@
 	
 	hash_list = &journal->j_revoke->hash_table[hash(journal, blocknr)];
 
+	spin_lock(&journal->j_revoke_lock);
 	record = (struct jbd_revoke_record_s *) hash_list->next;
 	while (&(record->hash) != hash_list) {
-		if (record->blocknr == blocknr)
+		if (record->blocknr == blocknr) {
+			spin_unlock(&journal->j_revoke_lock);
 			return record;
+		}
 		record = (struct jbd_revoke_record_s *) record->hash.next;
 	}
+	spin_unlock(&journal->j_revoke_lock);	
 	return NULL;
 }
 
@@ -192,27 +198,29 @@
 {
 	int shift, tmp;
 	
-	J_ASSERT (journal->j_revoke == NULL);
+	J_ASSERT (journal->j_revoke_table[0] == NULL);
 	
-	journal->j_revoke = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
-	if (!journal->j_revoke)
+	shift = 0;
+	tmp = hash_size;
+	while((tmp >>= 1UL) != 0UL)
+		shift++;
+
+	journal->j_revoke_table[0] = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
+	if (!journal->j_revoke_table[0])
 		return -ENOMEM;
+	journal->j_revoke = journal->j_revoke_table[0];
 	
 	/* Check that the hash_size is a power of two */
 	J_ASSERT ((hash_size & (hash_size-1)) == 0);
 
 	journal->j_revoke->hash_size = hash_size;
 
-	shift = 0;
-	tmp = hash_size;
-	while((tmp >>= 1UL) != 0UL)
-		shift++;
 	journal->j_revoke->hash_shift = shift;
 
 	journal->j_revoke->hash_table =
 		kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL);
 	if (!journal->j_revoke->hash_table) {
-		kmem_cache_free(revoke_table_cache, journal->j_revoke);
+		kmem_cache_free(revoke_table_cache, journal->j_revoke_table[0]);
 		journal->j_revoke = NULL;
 		return -ENOMEM;
 	}
@@ -220,6 +228,37 @@
 	for (tmp = 0; tmp < hash_size; tmp++)
 		INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
 	
+	journal->j_revoke_table[1] = kmem_cache_alloc(revoke_table_cache, GFP_KERNEL);
+	if (!journal->j_revoke_table[1]) {
+		kfree(journal->j_revoke_table[0]->hash_table);
+		kmem_cache_free(revoke_table_cache, journal->j_revoke_table[0]);
+		return -ENOMEM;
+	}
+	
+	journal->j_revoke = journal->j_revoke_table[1];
+	
+	/* Check that the hash_size is a power of two */
+	J_ASSERT ((hash_size & (hash_size-1)) == 0);
+
+	journal->j_revoke->hash_size = hash_size;
+
+	journal->j_revoke->hash_shift = shift;
+
+	journal->j_revoke->hash_table =
+		kmalloc(hash_size * sizeof(struct list_head), GFP_KERNEL);
+	if (!journal->j_revoke->hash_table) {
+		kfree(journal->j_revoke_table[0]->hash_table);
+		kmem_cache_free(revoke_table_cache, journal->j_revoke_table[0]);
+		kmem_cache_free(revoke_table_cache, journal->j_revoke_table[1]);
+		journal->j_revoke = NULL;
+		return -ENOMEM;
+	}
+	
+	for (tmp = 0; tmp < hash_size; tmp++)
+		INIT_LIST_HEAD(&journal->j_revoke->hash_table[tmp]);
+
+	spin_lock_init(&journal->j_revoke_lock);
+
 	return 0;
 }
 
@@ -231,7 +270,20 @@
 	struct list_head *hash_list;
 	int i;
 	
-	table = journal->j_revoke;
+	table = journal->j_revoke_table[0];
+	if (!table)
+		return;
+	
+	for (i=0; i<table->hash_size; i++) {
+		hash_list = &table->hash_table[i];
+		J_ASSERT (list_empty(hash_list));
+	}
+	
+	kfree(table->hash_table);
+	kmem_cache_free(revoke_table_cache, table);
+	journal->j_revoke = NULL;
+
+	table = journal->j_revoke_table[1];
 	if (!table)
 		return;
 	
@@ -337,11 +389,9 @@
 		}
 	}
 
-	lock_journal(journal);
 	jbd_debug(2, "insert revoke for block %lu, bh_in=%p\n", blocknr, bh_in);
 	err = insert_revoke_hash(journal, blocknr,
 				handle->h_transaction->t_tid);
-	unlock_journal(journal);
 	BUFFER_TRACE(bh_in, "exit");
 	return err;
 }
@@ -389,7 +439,9 @@
 		if (record) {
 			jbd_debug(4, "cancelled existing revoke on "
 				  "blocknr %llu\n", (u64)bh->b_blocknr);
+			spin_lock(&journal->j_revoke_lock);
 			list_del(&record->hash);
+			spin_unlock(&journal->j_revoke_lock);
 			kmem_cache_free(revoke_record_cache, record);
 			did_revoke = 1;
 		}
@@ -418,6 +470,22 @@
 	return did_revoke;
 }
 
+/* journal_switch_revoke table select j_revoke for next transaction
+ * we do not want to suspend any processing until all revokes are
+ * written -bzzz
+ */
+void journal_switch_revoke_table(journal_t *journal)
+{
+	int i;
+
+	if (journal->j_revoke == journal->j_revoke_table[0])
+		journal->j_revoke = journal->j_revoke_table[1];
+	else
+		journal->j_revoke = journal->j_revoke_table[0];
+		
+	for (i = 0; i < journal->j_revoke->hash_size; i++) 
+		INIT_LIST_HEAD(&journal->j_revoke->hash_table[i]);
+}
 
 /*
  * Write revoke records to the journal for all entries in the current
@@ -438,7 +506,10 @@
 	descriptor = NULL; 
 	offset = 0;
 	count = 0;
-	revoke = journal->j_revoke;
+	
+	/* select revoke table for committing transaction */
+	revoke = journal->j_revoke == journal->j_revoke_table[0] ?
+		journal->j_revoke_table[1] : journal->j_revoke_table[0];
 	
 	for (i = 0; i < revoke->hash_size; i++) {
 		hash_list = &revoke->hash_table[i];
diff -Nru a/fs/jbd/transaction.c b/fs/jbd/transaction.c
--- a/fs/jbd/transaction.c	Wed Jun 18 23:42:06 2003
+++ b/fs/jbd/transaction.c	Wed Jun 18 23:42:06 2003
@@ -27,8 +27,6 @@
 #include <linux/mm.h>
 #include <linux/highmem.h>
 
-extern spinlock_t journal_datalist_lock;
-
 /*
  * get_transaction: obtain a new transaction_t object.
  *
@@ -41,31 +39,26 @@
  *	The journal MUST be locked.  We don't perform atomic mallocs on the
  *	new transaction	and we can't block without protecting against other
  *	processes trying to touch the journal while it is in transition.
+ *
+ * Called under j_state_lock
  */
 
-static transaction_t * get_transaction (journal_t * journal, int is_try)
+static transaction_t *
+get_transaction(journal_t *journal, transaction_t *transaction)
 {
-	transaction_t * transaction;
-
-	transaction = jbd_kmalloc (sizeof (transaction_t), GFP_NOFS);
-	if (!transaction)
-		return NULL;
-	
-	memset (transaction, 0, sizeof (transaction_t));
-	
 	transaction->t_journal = journal;
 	transaction->t_state = T_RUNNING;
 	transaction->t_tid = journal->j_transaction_sequence++;
 	transaction->t_expires = jiffies + journal->j_commit_interval;
 	INIT_LIST_HEAD(&transaction->t_jcb);
+	spin_lock_init(&transaction->t_handle_lock);
+	spin_lock_init(&transaction->t_jcb_lock);
 
 	/* Set up the commit timer for the new transaction. */
-	J_ASSERT (!journal->j_commit_timer_active);
-	journal->j_commit_timer_active = 1;
 	journal->j_commit_timer->expires = transaction->t_expires;
 	add_timer(journal->j_commit_timer);
 	
-	J_ASSERT (journal->j_running_transaction == NULL);
+	J_ASSERT(journal->j_running_transaction == NULL);
 	journal->j_running_transaction = transaction;
 
 	return transaction;
@@ -91,69 +84,101 @@
 	transaction_t *transaction;
 	int needed;
 	int nblocks = handle->h_buffer_credits;
+	transaction_t *new_transaction = NULL;
+	int ret;
 
 	if (nblocks > journal->j_max_transaction_buffers) {
 		printk(KERN_ERR "JBD: %s wants too many credits (%d > %d)\n",
 		       current->comm, nblocks,
 		       journal->j_max_transaction_buffers);
-		return -ENOSPC;
+		ret = -ENOSPC;
+		goto out;
+	}
+
+alloc_transaction:
+	if (!journal->j_running_transaction) {
+		new_transaction = jbd_kmalloc(sizeof(*new_transaction),
+						GFP_NOFS);
+		if (!new_transaction) {
+			ret = -ENOMEM;
+			goto out;
+		}
+		memset(new_transaction, 0, sizeof(*new_transaction));
 	}
 
 	jbd_debug(3, "New handle %p going live.\n", handle);
 
 repeat:
 
-	lock_journal(journal);
-
+	/*
+	 * We need to hold j_state_lock until t_updates has been incremented,
+	 * for proper journal barrier handling
+	 */
+	spin_lock(&journal->j_state_lock);
+repeat_locked:
 	if (is_journal_aborted(journal) ||
 	    (journal->j_errno != 0 && !(journal->j_flags & JFS_ACK_ERR))) {
-		unlock_journal(journal);
-		return -EROFS; 
+		spin_unlock(&journal->j_state_lock);
+		ret = -EROFS; 
+		goto out;
 	}
 
 	/* Wait on the journal's transaction barrier if necessary */
 	if (journal->j_barrier_count) {
-		unlock_journal(journal);
-		sleep_on(&journal->j_wait_transaction_locked);
+		spin_unlock(&journal->j_state_lock);
+		wait_event(journal->j_wait_transaction_locked,
+				journal->j_barrier_count == 0);
 		goto repeat;
 	}
 	
-repeat_locked:
-	if (!journal->j_running_transaction)
-		get_transaction(journal, 0);
-	/* @@@ Error? */
-	J_ASSERT(journal->j_running_transaction);
-	
-	transaction = journal->j_running_transaction;
+	if (!journal->j_running_transaction) {
+		if (!new_transaction) {
+			spin_unlock(&journal->j_state_lock);
+			goto alloc_transaction;
+		}
+		get_transaction(journal, new_transaction);
+		new_transaction = NULL;
+	}
 
-	/* If the current transaction is locked down for commit, wait
-	 * for the lock to be released. */
+	transaction = journal->j_running_transaction;
 
+	/*
+	 * If the current transaction is locked down for commit, wait for the
+	 * lock to be released.
+	 */
 	if (transaction->t_state == T_LOCKED) {
-		unlock_journal(journal);
+		spin_unlock(&journal->j_state_lock);
 		jbd_debug(3, "Handle %p stalling...\n", handle);
-		sleep_on(&journal->j_wait_transaction_locked);
+		wait_event(journal->j_wait_transaction_locked,
+				transaction->t_state != T_LOCKED);
 		goto repeat;
 	}
 	
-	/* If there is not enough space left in the log to write all
-	 * potential buffers requested by this operation, we need to
-	 * stall pending a log checkpoint to free some more log
-	 * space. */
-
+	/*
+	 * If there is not enough space left in the log to write all potential
+	 * buffers requested by this operation, we need to stall pending a log
+	 * checkpoint to free some more log space.
+	 */
+	spin_lock(&transaction->t_handle_lock);
 	needed = transaction->t_outstanding_credits + nblocks;
 
 	if (needed > journal->j_max_transaction_buffers) {
-		/* If the current transaction is already too large, then
-		 * start to commit it: we can then go back and attach
-		 * this handle to a new transaction. */
-		
+		/*
+		 * If the current transaction is already too large, then start
+		 * to commit it: we can then go back and attach this handle to
+		 * a new transaction.
+		 */
+		DEFINE_WAIT(wait);
+
 		jbd_debug(2, "Handle %p starting new commit...\n", handle);
-		log_start_commit(journal, transaction);
-		unlock_journal(journal);
-		sleep_on(&journal->j_wait_transaction_locked);
-		lock_journal(journal);
-		goto repeat_locked;
+		spin_unlock(&transaction->t_handle_lock);
+		prepare_to_wait(&journal->j_wait_transaction_locked, &wait,
+				TASK_UNINTERRUPTIBLE);
+		__log_start_commit(journal, transaction->t_tid);
+		spin_unlock(&journal->j_state_lock);
+		schedule();
+		finish_wait(&journal->j_wait_transaction_locked, &wait);
+		goto repeat;
 	}
 
 	/* 
@@ -186,9 +211,10 @@
 		needed += journal->j_committing_transaction->
 					t_outstanding_credits;
 	
-	if (log_space_left(journal) < needed) {
+	if (__log_space_left(journal) < needed) {
 		jbd_debug(2, "Handle %p waiting for checkpoint...\n", handle);
-		log_wait_for_space(journal, needed);
+		spin_unlock(&transaction->t_handle_lock);
+		__log_wait_for_space(journal, needed);
 		goto repeat_locked;
 	}
 
@@ -201,10 +227,12 @@
 	transaction->t_handle_count++;
 	jbd_debug(4, "Handle %p given %d credits (total %d, free %d)\n",
 		  handle, nblocks, transaction->t_outstanding_credits,
-		  log_space_left(journal));
-
-	unlock_journal(journal);
-	
+		  __log_space_left(journal));
+	spin_unlock(&transaction->t_handle_lock);
+	spin_unlock(&journal->j_state_lock);
+out:
+	if (new_transaction)
+		kfree(new_transaction);
 	return 0;
 }
 
@@ -260,9 +288,8 @@
 	if (err < 0) {
 		jbd_free_handle(handle);
 		current->journal_info = NULL;
-		return ERR_PTR(err);
+		handle = ERR_PTR(err);
 	}
-
 	return handle;
 }
 
@@ -286,40 +313,41 @@
  * return code < 0 implies an error
  * return code > 0 implies normal transaction-full status.
  */
-int journal_extend (handle_t *handle, int nblocks)
+int journal_extend(handle_t *handle, int nblocks)
 {
 	transaction_t *transaction = handle->h_transaction;
 	journal_t *journal = transaction->t_journal;
 	int result;
 	int wanted;
 
-	lock_journal (journal);
-
 	result = -EIO;
 	if (is_handle_aborted(handle))
 		goto error_out;
 
 	result = 1;
-	       
+
+	spin_lock(&journal->j_state_lock);
+
 	/* Don't extend a locked-down transaction! */
 	if (handle->h_transaction->t_state != T_RUNNING) {
 		jbd_debug(3, "denied handle %p %d blocks: "
 			  "transaction not running\n", handle, nblocks);
 		goto error_out;
 	}
-	
+
+	spin_lock(&transaction->t_handle_lock);
 	wanted = transaction->t_outstanding_credits + nblocks;
 	
 	if (wanted > journal->j_max_transaction_buffers) {
 		jbd_debug(3, "denied handle %p %d blocks: "
 			  "transaction too large\n", handle, nblocks);
-		goto error_out;
+		goto unlock;
 	}
 
-	if (wanted > log_space_left(journal)) {
+	if (wanted > __log_space_left(journal)) {
 		jbd_debug(3, "denied handle %p %d blocks: "
 			  "insufficient log space\n", handle, nblocks);
-		goto error_out;
+		goto unlock;
 	}
 	
 	handle->h_buffer_credits += nblocks;
@@ -327,9 +355,10 @@
 	result = 0;
 
 	jbd_debug(3, "extended handle %p by %d\n", handle, nblocks);
-	
+unlock:
+	spin_unlock(&transaction->t_handle_lock);
 error_out:
-	unlock_journal (journal);
+	spin_unlock(&journal->j_state_lock);
 	return result;
 }
 
@@ -360,20 +389,25 @@
 	if (is_handle_aborted(handle))
 		return 0;
 	
-	/* First unlink the handle from its current transaction, and
-	 * start the commit on that. */
-	
-	J_ASSERT (transaction->t_updates > 0);
-	J_ASSERT (journal_current_handle() == handle);
+	/*
+	 * First unlink the handle from its current transaction, and start the
+	 * commit on that.
+	 */
+	J_ASSERT(transaction->t_updates > 0);
+	J_ASSERT(journal_current_handle() == handle);
 
+	spin_lock(&journal->j_state_lock);
+	spin_lock(&transaction->t_handle_lock);
 	transaction->t_outstanding_credits -= handle->h_buffer_credits;
 	transaction->t_updates--;
 
 	if (!transaction->t_updates)
 		wake_up(&journal->j_wait_updates);
+	spin_unlock(&transaction->t_handle_lock);
 
 	jbd_debug(2, "restarting handle %p\n", handle);
-	log_start_commit(journal, transaction);
+	__log_start_commit(journal, transaction->t_tid);
+	spin_unlock(&journal->j_state_lock);
 
 	handle->h_buffer_credits = nblocks;
 	ret = start_this_handle(journal, handle);
@@ -391,30 +425,41 @@
  *
  * The journal lock should not be held on entry.
  */
-void journal_lock_updates (journal_t *journal)
+void journal_lock_updates(journal_t *journal)
 {
-	lock_journal(journal);
+	DEFINE_WAIT(wait);
+
+	spin_lock(&journal->j_state_lock);
 	++journal->j_barrier_count;
 
 	/* Wait until there are no running updates */
 	while (1) {
 		transaction_t *transaction = journal->j_running_transaction;
+
 		if (!transaction)
 			break;
-		if (!transaction->t_updates)
+
+		spin_lock(&transaction->t_handle_lock);
+		if (!transaction->t_updates) {
+			spin_unlock(&transaction->t_handle_lock);
 			break;
-		
-		unlock_journal(journal);
-		sleep_on(&journal->j_wait_updates);
-		lock_journal(journal);
+		}
+		prepare_to_wait(&journal->j_wait_updates, &wait,
+				TASK_UNINTERRUPTIBLE);
+		spin_unlock(&transaction->t_handle_lock);
+		spin_unlock(&journal->j_state_lock);
+		schedule();
+		finish_wait(&journal->j_wait_updates, &wait);
+		spin_lock(&journal->j_state_lock);
 	}
+	spin_unlock(&journal->j_state_lock);
 
-	unlock_journal(journal);
-
-	/* We have now established a barrier against other normal
-	 * updates, but we also need to barrier against other
-	 * journal_lock_updates() calls to make sure that we serialise
-	 * special journal-locked operations too. */
+	/*
+	 * We have now established a barrier against other normal updates, but
+	 * we also need to barrier against other journal_lock_updates() calls
+	 * to make sure that we serialise special journal-locked operations
+	 * too.
+	 */
 	down(&journal->j_barrier);
 }
 
@@ -428,14 +473,13 @@
  */
 void journal_unlock_updates (journal_t *journal)
 {
-	lock_journal(journal);
+	J_ASSERT(journal->j_barrier_count != 0);
 
-	J_ASSERT (journal->j_barrier_count != 0);
-	
 	up(&journal->j_barrier);
+	spin_lock(&journal->j_state_lock);
 	--journal->j_barrier_count;
+	spin_unlock(&journal->j_state_lock);
 	wake_up(&journal->j_wait_transaction_locked);
-	unlock_journal(journal);
 }
 
 /*
@@ -445,7 +489,7 @@
  * continuing as gracefully as possible.  #
  *
  * The caller should already hold the journal lock and
- * journal_datalist_lock spinlock: most callers will need those anyway
+ * j_list_lock spinlock: most callers will need those anyway
  * in order to probe the buffer's journaling state safely.
  */
 static void jbd_unexpected_dirty_buffer(struct journal_head *jh)
@@ -482,7 +526,8 @@
  */
 
 static int
-do_get_write_access(handle_t *handle, struct journal_head *jh, int force_copy) 
+do_get_write_access(handle_t *handle, struct journal_head *jh,
+			int force_copy, int *credits) 
 {
 	struct buffer_head *bh;
 	transaction_t *transaction = handle->h_transaction;
@@ -490,7 +535,6 @@
 	int error;
 	char *frozen_buffer = NULL;
 	int need_copy = 0;
-	int locked;
 
 	jbd_debug(5, "buffer_head %p, force_copy %d\n", jh, force_copy);
 
@@ -500,16 +544,9 @@
 
 	/* @@@ Need to check for errors here at some point. */
 
-	locked = test_set_buffer_locked(bh);
-	if (locked) {
-		/* We can't reliably test the buffer state if we found
-		 * it already locked, so just wait for the lock and
-		 * retry. */
-		unlock_journal(journal);
-		wait_on_buffer(bh);
-		lock_journal(journal);
-		goto repeat;
-	}
+	lock_buffer(bh);
+	jbd_lock_bh_state(bh);
+	spin_lock(&journal->j_list_lock);
 
 	/* We now hold the buffer lock so it is safe to query the buffer
 	 * state.  Is the buffer dirty? 
@@ -525,7 +562,6 @@
 	 * the buffer dirtied, ugh.)  */
 
 	if (buffer_dirty(bh)) {
-		spin_lock(&journal_datalist_lock);
 		/* First question: is this buffer already part of the
 		 * current transaction or the existing committing
 		 * transaction? */
@@ -540,18 +576,18 @@
 			JBUFFER_TRACE(jh, "Unexpected dirty buffer");
 			jbd_unexpected_dirty_buffer(jh);
  		}
- 		spin_unlock(&journal_datalist_lock);
  	}
 
 	unlock_buffer(bh);
 
 	error = -EROFS;
-	if (is_handle_aborted(handle)) 
+	if (is_handle_aborted(handle)) {
+		spin_unlock(&journal->j_list_lock);
+		jbd_unlock_bh_state(bh);
 		goto out_unlocked;
+	}
 	error = 0;
 
-	spin_lock(&journal_datalist_lock);
-
 	/* The buffer is already part of this transaction if
 	 * b_transaction or b_next_transaction points to it. */
 
@@ -569,6 +605,8 @@
 
 		J_ASSERT_JH(jh, handle->h_buffer_credits > 0);
 		handle->h_buffer_credits--;
+		if (credits)
+			(*credits)++;
 		goto done_locked;
 	}
 	
@@ -593,12 +631,11 @@
 			wait_queue_head_t *wqh;
 
 			JBUFFER_TRACE(jh, "on shadow: sleep");
-			spin_unlock(&journal_datalist_lock);
-			unlock_journal(journal);
+			spin_unlock(&journal->j_list_lock);
+			jbd_unlock_bh_state(bh);
 			/* commit wakes up all shadow buffers after IO */
 			wqh = bh_waitq_head(jh2bh(jh));
 			wait_event(*wqh, (jh->b_jlist != BJ_Shadow));
-			lock_journal(journal);
 			goto repeat;
 		}
 			
@@ -620,18 +657,18 @@
 			JBUFFER_TRACE(jh, "generate frozen data");
 			if (!frozen_buffer) {
 				JBUFFER_TRACE(jh, "allocate memory for buffer");
-				spin_unlock(&journal_datalist_lock);
-				unlock_journal(journal);
+				spin_unlock(&journal->j_list_lock);
+				jbd_unlock_bh_state(bh);
 				frozen_buffer = jbd_kmalloc(jh2bh(jh)->b_size,
 							    GFP_NOFS);
-				lock_journal(journal);
 				if (!frozen_buffer) {
 					printk(KERN_EMERG
 					       "%s: OOM for frozen_buffer\n",
 					       __FUNCTION__);
 					JBUFFER_TRACE(jh, "oom!");
 					error = -ENOMEM;
-					spin_lock(&journal_datalist_lock);
+					jbd_lock_bh_state(bh);
+					spin_lock(&journal->j_list_lock);
 					goto done_locked;
 				}
 				goto repeat;
@@ -646,6 +683,8 @@
 
 	J_ASSERT(handle->h_buffer_credits > 0);
 	handle->h_buffer_credits--;
+	if (credits)
+		(*credits)++;
 
 	/* Finally, if the buffer is not journaled right now, we need to
 	 * make sure it doesn't get written to disk before the caller
@@ -660,7 +699,7 @@
 	}
 	
 done_locked:
-	spin_unlock(&journal_datalist_lock);
+	spin_unlock(&journal->j_list_lock);
 	if (need_copy) {
 		struct page *page;
 		int offset;
@@ -670,11 +709,11 @@
 			    "Possible IO failure.\n");
 		page = jh2bh(jh)->b_page;
 		offset = ((unsigned long) jh2bh(jh)->b_data) & ~PAGE_MASK;
-		source = kmap(page);
+		source = kmap_atomic(page, KM_USER0);
 		memcpy(jh->b_frozen_data, source+offset, jh2bh(jh)->b_size);
-		kunmap(page);
+		kunmap_atomic(source, KM_USER0);
 	}
-	
+	jbd_unlock_bh_state(bh);
 
 	/* If we are about to journal a buffer, then any revoke pending
            on it is no longer valid. */
@@ -699,20 +738,17 @@
  * because we're write()ing a buffer which is also part of a shared mapping.
  */
 
-int journal_get_write_access (handle_t *handle, struct buffer_head *bh) 
+int journal_get_write_access(handle_t *handle,
+			struct buffer_head *bh, int *credits)
 {
-	transaction_t *transaction = handle->h_transaction;
-	journal_t *journal = transaction->t_journal;
 	struct journal_head *jh = journal_add_journal_head(bh);
 	int rc;
 
 	/* We do not want to get caught playing with fields which the
 	 * log thread also manipulates.  Make sure that the buffer
 	 * completes any outstanding IO before proceeding. */
-	lock_journal(journal);
-	rc = do_get_write_access(handle, jh, 0);
-	journal_unlock_journal_head(jh);
-	unlock_journal(journal);
+	rc = do_get_write_access(handle, jh, 0, NULL);
+	journal_put_journal_head(jh);
 	return rc;
 }
 
@@ -736,7 +772,7 @@
  *
  * Call this if you create a new bh.
  */
-int journal_get_create_access (handle_t *handle, struct buffer_head *bh) 
+int journal_get_create_access(handle_t *handle, struct buffer_head *bh) 
 {
 	transaction_t *transaction = handle->h_transaction;
 	journal_t *journal = transaction->t_journal;
@@ -744,21 +780,24 @@
 	int err;
 	
 	jbd_debug(5, "journal_head %p\n", jh);
-	lock_journal(journal);
 	err = -EROFS;
 	if (is_handle_aborted(handle))
 		goto out;
 	err = 0;
 	
 	JBUFFER_TRACE(jh, "entry");
-	/* The buffer may already belong to this transaction due to
-	 * pre-zeroing in the filesystem's new_block code.  It may also
-	 * be on the previous, committing transaction's lists, but it
-	 * HAS to be in Forget state in that case: the transaction must
-	 * have deleted the buffer for it to be reused here. */
+	/*
+	 * The buffer may already belong to this transaction due to pre-zeroing
+	 * in the filesystem's new_block code.  It may also be on the previous,
+	 * committing transaction's lists, but it HAS to be in Forget state in
+	 * that case: the transaction must have deleted the buffer for it to be
+	 * reused here.
+	 */
+	jbd_lock_bh_state(bh);
+	spin_lock(&journal->j_list_lock);
 	J_ASSERT_JH(jh, (jh->b_transaction == transaction ||
-			 jh->b_transaction == NULL ||
-			 (jh->b_transaction == journal->j_committing_transaction &&
+		jh->b_transaction == NULL ||
+		(jh->b_transaction == journal->j_committing_transaction &&
 			  jh->b_jlist == BJ_Forget)));
 
 	J_ASSERT_JH(jh, jh->b_next_transaction == NULL);
@@ -767,7 +806,6 @@
 	J_ASSERT_JH(jh, handle->h_buffer_credits > 0);
 	handle->h_buffer_credits--;
 
-	spin_lock(&journal_datalist_lock);
 	if (jh->b_transaction == NULL) {
 		jh->b_transaction = transaction;
 		JBUFFER_TRACE(jh, "file as BJ_Reserved");
@@ -776,7 +814,8 @@
 		JBUFFER_TRACE(jh, "set next transaction");
 		jh->b_next_transaction = transaction;
 	}
-	spin_unlock(&journal_datalist_lock);
+	spin_unlock(&journal->j_list_lock);
+	jbd_unlock_bh_state(bh);
 
 	/*
 	 * akpm: I added this.  ext3_alloc_branch can pick up new indirect
@@ -787,19 +826,18 @@
 	 */
 	JBUFFER_TRACE(jh, "cancelling revoke");
 	journal_cancel_revoke(handle, jh);
-	journal_unlock_journal_head(jh);
+	journal_put_journal_head(jh);
 out:
-	unlock_journal(journal);
 	return err;
 }
 
-
-
 /**
- * int journal_get_undo_access() -  Notify intent to modify metadata with non-rewindable consequences
+ * int journal_get_undo_access() -  Notify intent to modify metadata with
+ *     non-rewindable consequences
  * @handle: transaction
  * @bh: buffer to undo
- * 
+ * @credits: store the number of taken credits here (if not NULL)
+ *
  * Sometimes there is a need to distinguish between metadata which has
  * been committed to disk and that which has not.  The ext3fs code uses
  * this for freeing and allocating space, we have to make sure that we
@@ -818,47 +856,56 @@
  * will be committed to a new transaction in due course, at which point
  * we can discard the old committed data pointer.
  *
- * Returns error number or 0 on success.  
+ * Returns error number or 0 on success.
  */
-int journal_get_undo_access (handle_t *handle, struct buffer_head *bh)
+int journal_get_undo_access(handle_t *handle, struct buffer_head *bh,
+				int *credits)
 {
-	journal_t *journal = handle->h_transaction->t_journal;
 	int err;
 	struct journal_head *jh = journal_add_journal_head(bh);
+	char *committed_data = NULL;
 
 	JBUFFER_TRACE(jh, "entry");
-	lock_journal(journal);
 
-	/* Do this first --- it can drop the journal lock, so we want to
+	/*
+	 * Do this first --- it can drop the journal lock, so we want to
 	 * make sure that obtaining the committed_data is done
-	 * atomically wrt. completion of any outstanding commits. */
-	err = do_get_write_access (handle, jh, 1);
+	 * atomically wrt. completion of any outstanding commits.
+	 */
+	err = do_get_write_access(handle, jh, 1, credits);
 	if (err)
 		goto out;
-	
+
+repeat:
 	if (!jh->b_committed_data) {
-		/* Copy out the current buffer contents into the
-		 * preserved, committed copy. */
-		JBUFFER_TRACE(jh, "generate b_committed data");
-		jh->b_committed_data = jbd_kmalloc(jh2bh(jh)->b_size, 
-						   GFP_NOFS);
-		if (!jh->b_committed_data) {
-			printk(KERN_EMERG
-			       "%s: No memory for committed data!\n",
-			       __FUNCTION__);
+		committed_data = jbd_kmalloc(jh2bh(jh)->b_size, GFP_NOFS);
+		if (!committed_data) {
+			printk(KERN_EMERG "%s: No memory for committed data\n",
+				__FUNCTION__);
 			err = -ENOMEM;
 			goto out;
 		}
-		
-		memcpy (jh->b_committed_data, jh2bh(jh)->b_data,
-				jh2bh(jh)->b_size);
 	}
 
+	jbd_lock_bh_state(bh);
+	if (!jh->b_committed_data) {
+		/* Copy out the current buffer contents into the
+		 * preserved, committed copy. */
+		JBUFFER_TRACE(jh, "generate b_committed data");
+		if (!committed_data) {
+			jbd_unlock_bh_state(bh);
+			goto repeat;
+		}
+
+		jh->b_committed_data = committed_data;
+		committed_data = NULL;
+		memcpy(jh->b_committed_data, bh->b_data, bh->b_size);
+	}
+	jbd_unlock_bh_state(bh);
 out:
-	if (!err)
-		J_ASSERT_JH(jh, jh->b_committed_data);
-	journal_unlock_journal_head(jh);
-	unlock_journal(journal);
+	journal_put_journal_head(jh);
+	if (committed_data)
+		kfree(committed_data);
 	return err;
 }
 
@@ -875,10 +922,9 @@
  * Returns error number or 0 on success.
  *
  * journal_dirty_data() can be called via page_launder->ext3_writepage
- * by kswapd.  So it cannot block.  Happily, there's nothing here
- * which needs lock_journal if `async' is set.
+ * by kswapd.
  */
-int journal_dirty_data (handle_t *handle, struct buffer_head *bh)
+int journal_dirty_data(handle_t *handle, struct buffer_head *bh)
 {
 	journal_t *journal = handle->h_transaction->t_journal;
 	int need_brelse = 0;
@@ -917,7 +963,8 @@
 	 * never, ever allow this to happen: there's nothing we can do
 	 * about it in this layer.
 	 */
-	spin_lock(&journal_datalist_lock);
+	jbd_lock_bh_state(bh);
+	spin_lock(&journal->j_list_lock);
 	if (jh->b_transaction) {
 		JBUFFER_TRACE(jh, "has transaction");
 		if (jh->b_transaction != handle->h_transaction) {
@@ -971,11 +1018,13 @@
 			 * commit to never terminate.
 			 */
 			if (buffer_dirty(bh)) {
-				atomic_inc(&bh->b_count);
-				spin_unlock(&journal_datalist_lock);
+				get_bh(bh);
+				spin_unlock(&journal->j_list_lock);
+				jbd_unlock_bh_state(bh);
 				need_brelse = 1;
 				sync_dirty_buffer(bh);
-				spin_lock(&journal_datalist_lock);
+				jbd_lock_bh_state(bh);
+				spin_lock(&journal->j_list_lock);
 				/* The buffer may become locked again at any
 				   time if it is redirtied */
 			}
@@ -1009,13 +1058,14 @@
 		__journal_file_buffer(jh, handle->h_transaction, BJ_SyncData);
 	}
 no_journal:
-	spin_unlock(&journal_datalist_lock);
+	spin_unlock(&journal->j_list_lock);
+	jbd_unlock_bh_state(bh);
 	if (need_brelse) {
 		BUFFER_TRACE(bh, "brelse");
 		__brelse(bh);
 	}
 	JBUFFER_TRACE(jh, "exit");
-	journal_unlock_journal_head(jh);
+	journal_put_journal_head(jh);
 	return 0;
 }
 
@@ -1038,7 +1088,7 @@
  * buffer: that only gets done when the old transaction finally
  * completes its commit.
  */
-int journal_dirty_metadata (handle_t *handle, struct buffer_head *bh)
+int journal_dirty_metadata(handle_t *handle, struct buffer_head *bh)
 {
 	transaction_t *transaction = handle->h_transaction;
 	journal_t *journal = transaction->t_journal;
@@ -1046,12 +1096,38 @@
 
 	jbd_debug(5, "journal_head %p\n", jh);
 	JBUFFER_TRACE(jh, "entry");
-	lock_journal(journal);
 	if (is_handle_aborted(handle))
-		goto out_unlock;
+		goto out;
 	
-	spin_lock(&journal_datalist_lock);
-	set_bit(BH_JBDDirty, &bh->b_state);
+	jbd_lock_bh_state(bh);
+
+	/*
+	 * fastpath, to avoid expensive locking.  If this buffer is already
+	 * on the running transaction's metadata list there is nothing to do.
+	 * Nobody can take it off again because there is a handle open.
+	 * I _think_ we're OK here with SMP barriers - a mistaken decision will
+	 * result in this test being false, so we go in and take the locks.
+	 */
+	if (jh->b_transaction == handle->h_transaction &&
+					jh->b_jlist == BJ_Metadata) {
+		JBUFFER_TRACE(jh, "fastpath");
+		console_verbose();
+		if (jh->b_transaction != journal->j_running_transaction) {
+			printk("jh->b_transaction=%p\n", jh->b_transaction);
+			printk("journal->j_running_transaction=%p\n",
+				journal->j_running_transaction);
+			printk("handle->h_transaction=%p\n",
+				handle->h_transaction);
+			printk("journal->j_committing_transaction=%p\n",
+				journal->j_committing_transaction);
+		}
+		J_ASSERT_JH(jh, jh->b_transaction ==
+					journal->j_running_transaction);
+		goto out_unlock_bh;
+	}
+
+	spin_lock(&journal->j_list_lock);
+	set_buffer_jbddirty(bh);
 
 	J_ASSERT_JH(jh, jh->b_transaction != NULL);
 	
@@ -1070,8 +1146,7 @@
 		/* And this case is illegal: we can't reuse another
 		 * transaction's data buffer, ever. */
 		/* FIXME: writepage() should be journalled */
-		J_ASSERT_JH(jh, jh->b_jlist != BJ_SyncData);
-		goto done_locked;
+		goto out_unlock_list;
 	}
 
 	/* That test should have eliminated the following case: */
@@ -1080,49 +1155,51 @@
 	JBUFFER_TRACE(jh, "file as BJ_Metadata");
 	__journal_file_buffer(jh, handle->h_transaction, BJ_Metadata);
 
-done_locked:
-	spin_unlock(&journal_datalist_lock);
+out_unlock_list:
+	spin_unlock(&journal->j_list_lock);
+out_unlock_bh:
+	jbd_unlock_bh_state(bh);
+out:
 	JBUFFER_TRACE(jh, "exit");
-out_unlock:
-	unlock_journal(journal);
 	return 0;
 }
 
-#if 0
 /* 
  * journal_release_buffer: undo a get_write_access without any buffer
  * updates, if the update decided in the end that it didn't need access.
  *
  * journal_get_write_access() can block, so it is quite possible for a
  * journaling component to decide after the write access is returned
- * that global state has changed and the update is no longer required.  */
-
-void journal_release_buffer (handle_t *handle, struct buffer_head *bh)
+ * that global state has changed and the update is no longer required.
+ *
+ * The caller passes in the number of credits which should be put back for
+ * this buffer (zero or one).
+ */
+void
+journal_release_buffer(handle_t *handle, struct buffer_head *bh, int credits)
 {
 	transaction_t *transaction = handle->h_transaction;
 	journal_t *journal = transaction->t_journal;
 	struct journal_head *jh = bh2jh(bh);
 
-	lock_journal(journal);
 	JBUFFER_TRACE(jh, "entry");
 
 	/* If the buffer is reserved but not modified by this
 	 * transaction, then it is safe to release it.  In all other
 	 * cases, just leave the buffer as it is. */
 
-	spin_lock(&journal_datalist_lock);
+	jbd_lock_bh_state(bh);
+	spin_lock(&journal->j_list_lock);
 	if (jh->b_jlist == BJ_Reserved && jh->b_transaction == transaction &&
-	    !buffer_jdirty(jh2bh(jh))) {
+	    !buffer_jbddirty(jh2bh(jh))) {
 		JBUFFER_TRACE(jh, "unused: refiling it");
-		handle->h_buffer_credits++;
 		__journal_refile_buffer(jh);
 	}
-	spin_unlock(&journal_datalist_lock);
-
+	spin_unlock(&journal->j_list_lock);
+	jbd_unlock_bh_state(bh);
+	handle->h_buffer_credits += credits;
 	JBUFFER_TRACE(jh, "exit");
-	unlock_journal(journal);
 }
-#endif
 
 /** 
  * void journal_forget() - bforget() for potentially-journaled buffers.
@@ -1141,7 +1218,7 @@
  * Allow this call even if the handle has aborted --- it may be part of
  * the caller's cleanup after an abort.
  */
-void journal_forget (handle_t *handle, struct buffer_head *bh)
+void journal_forget(handle_t *handle, struct buffer_head *bh)
 {
 	transaction_t *transaction = handle->h_transaction;
 	journal_t *journal = transaction->t_journal;
@@ -1149,8 +1226,8 @@
 
 	BUFFER_TRACE(bh, "entry");
 
-	lock_journal(journal);
-	spin_lock(&journal_datalist_lock);
+	jbd_lock_bh_state(bh);
+	spin_lock(&journal->j_list_lock);
 
 	if (!buffer_jbd(bh))
 		goto not_jbd;
@@ -1163,7 +1240,7 @@
 		 * of this transaction, then we can just drop it from
 		 * the transaction immediately. */
 		clear_buffer_dirty(bh);
-		clear_bit(BH_JBDDirty, &bh->b_state);
+		clear_buffer_jbddirty(bh);
 
 		JBUFFER_TRACE(jh, "belongs to current transaction: unfile");
 		J_ASSERT_JH(jh, !jh->b_committed_data);
@@ -1186,11 +1263,11 @@
 		if (jh->b_cp_transaction) {
 			__journal_file_buffer(jh, transaction, BJ_Forget);
 		} else {
-			__journal_remove_journal_head(bh);
+			journal_remove_journal_head(bh);
 			__brelse(bh);
 			if (!buffer_jbd(bh)) {
-				spin_unlock(&journal_datalist_lock);
-				unlock_journal(journal);
+				spin_unlock(&journal->j_list_lock);
+				jbd_unlock_bh_state(bh);
 				__bforget(bh);
 				return;
 			}
@@ -1212,72 +1289,12 @@
 	}
 
 not_jbd:
-	spin_unlock(&journal_datalist_lock);
-	unlock_journal(journal);
+	spin_unlock(&journal->j_list_lock);
+	jbd_unlock_bh_state(bh);
 	__brelse(bh);
 	return;
 }
 
-#if 0	/* Unused */
-/*
- * journal_sync_buffer: flush a potentially-journaled buffer to disk.
- *
- * Used for O_SYNC filesystem operations.  If the buffer is journaled,
- * we need to complete the O_SYNC by waiting for the transaction to
- * complete.  It is an error to call journal_sync_buffer before
- * journal_stop!
- */
-
-void journal_sync_buffer(struct buffer_head *bh)
-{
-	transaction_t *transaction;
-	journal_t *journal;
-	long sequence;
-	struct journal_head *jh;
-
-	/* If the buffer isn't journaled, this is easy: just sync it to
-	 * disk.  */
-	BUFFER_TRACE(bh, "entry");
-
-	spin_lock(&journal_datalist_lock);
-	if (!buffer_jbd(bh)) {
-		spin_unlock(&journal_datalist_lock);
-		return;
-	}
-	jh = bh2jh(bh);
-	if (jh->b_transaction == NULL) {
-		/* If the buffer has already been journaled, then this
-		 * is a noop. */
-		if (jh->b_cp_transaction == NULL) {
-			spin_unlock(&journal_datalist_lock);
-			return;
-		}
-		atomic_inc(&bh->b_count);
-		spin_unlock(&journal_datalist_lock);
-		sync_dirty_buffer(bh);
-		__brelse(bh);
-		goto out;
-	}
-	
-	/* Otherwise, just wait until the transaction is synced to disk. */
-	transaction = jh->b_transaction;
-	journal = transaction->t_journal;
-	sequence = transaction->t_tid;
-	spin_unlock(&journal_datalist_lock);
-
-	jbd_debug(2, "requesting commit for jh %p\n", jh);
-	log_start_commit (journal, transaction);
-	
-	while (tid_gt(sequence, journal->j_commit_sequence)) {
-		wake_up(&journal->j_wait_done_commit);
-		sleep_on(&journal->j_wait_done_commit);
-	}
-	JBUFFER_TRACE(jh, "exit");
-out:
-	return;
-}
-#endif
-
 /**
  * void journal_callback_set() -  Register a callback function for this handle.
  * @handle: handle to attach the callback to.
@@ -1299,14 +1316,15 @@
  * and has the caller-specific data afterwards.
  */
 void journal_callback_set(handle_t *handle,
-			  void (*func)(struct journal_callback *jcb, int error),
-			  struct journal_callback *jcb)
+			void (*func)(struct journal_callback *jcb, int error),
+			struct journal_callback *jcb)
 {
+	spin_lock(&handle->h_transaction->t_jcb_lock);
 	list_add_tail(&jcb->jcb_list, &handle->h_jcb);
+	spin_unlock(&handle->h_transaction->t_jcb_lock);
 	jcb->jcb_func = func;
 }
 
-
 /**
  * int journal_stop() - complete a transaction
  * @handle: tranaction to complete.
@@ -1332,8 +1350,8 @@
 	if (!handle)
 		return 0;
 
-	J_ASSERT (transaction->t_updates > 0);
-	J_ASSERT (journal_current_handle() == handle);
+	J_ASSERT(transaction->t_updates > 0);
+	J_ASSERT(journal_current_handle() == handle);
 	
 	if (is_handle_aborted(handle))
 		err = -EIO;
@@ -1366,6 +1384,8 @@
 	}
 
 	current->journal_info = NULL;
+	spin_lock(&journal->j_state_lock);
+	spin_lock(&transaction->t_handle_lock);
 	transaction->t_outstanding_credits -= handle->h_buffer_credits;
 	transaction->t_updates--;
 	if (!transaction->t_updates) {
@@ -1375,7 +1395,9 @@
 	}
 
 	/* Move callbacks from the handle to the transaction. */
+	spin_lock(&transaction->t_jcb_lock);
 	list_splice(&handle->h_jcb, &transaction->t_jcb);
+	spin_unlock(&transaction->t_jcb_lock);
 
 	/*
 	 * If the handle is marked SYNC, we need to set another commit
@@ -1392,18 +1414,24 @@
 		 * anything to disk. */
 		tid_t tid = transaction->t_tid;
 		
+		spin_unlock(&transaction->t_handle_lock);
 		jbd_debug(2, "transaction too old, requesting commit for "
 					"handle %p\n", handle);
 		/* This is non-blocking */
-		log_start_commit(journal, transaction);
-		
+		__log_start_commit(journal, transaction->t_tid);
+		spin_unlock(&journal->j_state_lock);
+
 		/*
 		 * Special case: JFS_SYNC synchronous updates require us
 		 * to wait for the commit to complete.  
 		 */
 		if (handle->h_sync && !(current->flags & PF_MEMALLOC))
 			err = log_wait_commit(journal, tid);
+	} else {
+		spin_unlock(&transaction->t_handle_lock);
+		spin_unlock(&journal->j_state_lock);
 	}
+
 	jbd_free_handle(handle);
 	return err;
 }
@@ -1420,16 +1448,13 @@
 	handle_t *handle;
 	int ret;
 
-	lock_kernel();
 	handle = journal_start(journal, 1);
 	if (IS_ERR(handle)) {
 		ret = PTR_ERR(handle);
-		goto out;
+	} else {
+		handle->h_sync = 1;
+		ret = journal_stop(handle);
 	}
-	handle->h_sync = 1;
-	ret = journal_stop(handle);
-out:
-	unlock_kernel();
 	return ret;
 }
 
@@ -1443,7 +1468,10 @@
 /*
  * Append a buffer to a transaction list, given the transaction's list head
  * pointer.
- * journal_datalist_lock is held.
+ *
+ * j_list_lock is held.
+ *
+ * jbd_lock_bh_state(jh2bh(jh)) is held.
  */
 
 static inline void 
@@ -1465,8 +1493,9 @@
  * Remove a buffer from a transaction list, given the transaction's list
  * head pointer.
  *
- * Called with journal_datalist_lock held, and the journal may not
- * be locked.
+ * Called with j_list_lock held, and the journal may not be locked.
+ *
+ * jbd_lock_bh_state(jh2bh(jh)) is held.
  */
 
 static inline void
@@ -1490,23 +1519,20 @@
  * is holding onto a copy of one of thee pointers, it could go bad.
  * Generally the caller needs to re-read the pointer from the transaction_t.
  *
- * If bh->b_jlist is BJ_SyncData then we may have been called
- * via journal_try_to_free_buffer() or journal_clean_data_list().  In that
- * case, journal_datalist_lock will be held, and the journal may not be locked.
+ * Called under j_list_lock.  The journal may not be locked.
  */
 void __journal_unfile_buffer(struct journal_head *jh)
 {
 	struct journal_head **list = 0;
-	transaction_t * transaction;
+	transaction_t *transaction;
+	struct buffer_head *bh = jh2bh(jh);
 
-	assert_spin_locked(&journal_datalist_lock);
+	J_ASSERT_JH(jh, jbd_is_locked_bh_state(bh));
 	transaction = jh->b_transaction;
+	if (transaction)
+		assert_spin_locked(&transaction->t_journal->j_list_lock);
 
-#ifdef __SMP__
-	J_ASSERT (current->lock_depth >= 0);
-#endif
 	J_ASSERT_JH(jh, jh->b_jlist < BJ_Types);
-
 	if (jh->b_jlist != BJ_None)
 		J_ASSERT_JH(jh, transaction != 0);
 
@@ -1540,38 +1566,29 @@
 	
 	__blist_del_buffer(list, jh);
 	jh->b_jlist = BJ_None;
-	if (test_and_clear_bit(BH_JBDDirty, &jh2bh(jh)->b_state))
-		mark_buffer_dirty(jh2bh(jh));	/* Expose it to the VM */
+	if (test_clear_buffer_jbddirty(bh))
+		mark_buffer_dirty(bh);	/* Expose it to the VM */
 }
 
-void journal_unfile_buffer(struct journal_head *jh)
+void journal_unfile_buffer(journal_t *journal, struct journal_head *jh)
 {
-	spin_lock(&journal_datalist_lock);
+	jbd_lock_bh_state(jh2bh(jh));
+	spin_lock(&journal->j_list_lock);
 	__journal_unfile_buffer(jh);
-	spin_unlock(&journal_datalist_lock);
+	spin_unlock(&journal->j_list_lock);
+	jbd_unlock_bh_state(jh2bh(jh));
 }
 
 /*
- * Called from journal_try_to_free_buffers().  The journal is not
- * locked. lru_list_lock is not held.
- *
- * Here we see why journal_datalist_lock is global and not per-journal.
- * We cannot get back to this buffer's journal pointer without locking
- * out journal_clean_data_list() in some manner.
+ * Called from journal_try_to_free_buffers().
  *
- * One could use journal_datalist_lock to get unracy access to a
- * per-journal lock.
- *
- * Called with journal_datalist_lock held.
- *
- * Returns non-zero iff we were able to free the journal_head.
+ * Called under jbd_lock_bh_state(bh)
  */
-static inline int __journal_try_to_free_buffer(struct buffer_head *bh)
+static void
+__journal_try_to_free_buffer(journal_t *journal, struct buffer_head *bh)
 {
 	struct journal_head *jh;
 
-	assert_spin_locked(&journal_datalist_lock);
-
 	jh = bh2jh(bh);
 
 	if (buffer_locked(bh) || buffer_dirty(bh))
@@ -1580,13 +1597,14 @@
 	if (jh->b_next_transaction != 0)
 		goto out;
 
+	spin_lock(&journal->j_list_lock);
 	if (jh->b_transaction != 0 && jh->b_cp_transaction == 0) {
 		if (jh->b_jlist == BJ_SyncData) {
 			/* A written-back ordered data buffer */
 			JBUFFER_TRACE(jh, "release data");
 			__journal_unfile_buffer(jh);
 			jh->b_transaction = 0;
-			__journal_remove_journal_head(bh);
+			journal_remove_journal_head(bh);
 			__brelse(bh);
 		}
 	} else if (jh->b_cp_transaction != 0 && jh->b_transaction == 0) {
@@ -1594,14 +1612,13 @@
 		if (jh->b_jlist == BJ_None) {
 			JBUFFER_TRACE(jh, "remove from checkpoint list");
 			__journal_remove_checkpoint(jh);
-			__journal_remove_journal_head(bh);
+			journal_remove_journal_head(bh);
 			__brelse(bh);
 		}
 	}
-	return !buffer_jbd(bh);
-
+	spin_unlock(&journal->j_list_lock);
 out:
-	return 0;
+	return;
 }
 
 
@@ -1650,14 +1667,25 @@
 
 	head = page_buffers(page);
 	bh = head;
-	spin_lock(&journal_datalist_lock);
 	do {
-		if (buffer_jbd(bh) && !__journal_try_to_free_buffer(bh)) {
-			spin_unlock(&journal_datalist_lock);
+		struct journal_head *jh;
+
+		/*
+		 * We take our own ref against the journal_head here to avoid
+		 * having to add tons of locking around each instance of
+		 * journal_remove_journal_head() and journal_put_journal_head().
+		 */
+		jh = journal_grab_journal_head(bh);
+		if (!jh)
+			continue;
+
+		jbd_lock_bh_state(bh);
+		__journal_try_to_free_buffer(journal, bh);
+		journal_put_journal_head(jh);
+		jbd_unlock_bh_state(bh);
+		if (buffer_jbd(bh))
 			goto busy;
-		}
 	} while ((bh = bh->b_this_page) != head);
-	spin_unlock(&journal_datalist_lock);
 	ret = try_to_free_buffers(page);
 busy:
 	return ret;
@@ -1670,28 +1698,29 @@
  * this transaction commits.  If the buffer isn't on a checkpoint list, we
  * release it.
  * Returns non-zero if JBD no longer has an interest in the buffer.
+ *
+ * Called under j_list_lock.
+ *
+ * Called under jbd_lock_bh_state(bh).
  */
-static int dispose_buffer(struct journal_head *jh,
-		transaction_t *transaction)
+static int __dispose_buffer(struct journal_head *jh, transaction_t *transaction)
 {
 	int may_free = 1;
 	struct buffer_head *bh = jh2bh(jh);
 
-	spin_lock(&journal_datalist_lock);
 	__journal_unfile_buffer(jh);
 	jh->b_transaction = 0;
 
 	if (jh->b_cp_transaction) {
 		JBUFFER_TRACE(jh, "on running+cp transaction");
 		__journal_file_buffer(jh, transaction, BJ_Forget);
-		clear_bit(BH_JBDDirty, &bh->b_state);
+		clear_buffer_jbddirty(bh);
 		may_free = 0;
 	} else {
 		JBUFFER_TRACE(jh, "on running transaction");
-		__journal_remove_journal_head(bh);
+		journal_remove_journal_head(bh);
 		__brelse(bh);
 	}
-	spin_unlock(&journal_datalist_lock);
 	return may_free;
 }
 
@@ -1747,14 +1776,27 @@
 	transaction_t *transaction;
 	struct journal_head *jh;
 	int may_free = 1;
+	int ret;
 
 	BUFFER_TRACE(bh, "entry");
 
-	/* It is safe to proceed here without the
-	 * journal_datalist_spinlock because the buffers cannot be
-	 * stolen by try_to_free_buffers as long as we are holding the
-	 * page lock. --sct */
+	/*
+	 * It is safe to proceed here without the j_list_lock because the
+	 * buffers cannot be stolen by try_to_free_buffers as long as we are
+	 * holding the page lock. --sct
+	 */
+
+	if (!buffer_jbd(bh))
+		goto zap_buffer_unlocked;
+
+	spin_lock(&journal->j_state_lock);
+	jbd_lock_bh_state(bh);
+	spin_lock(&journal->j_list_lock);
 
+	/*
+	 * Now we have the locks, check again to see whether kjournald has
+	 * taken the buffer off the transaction.
+	 */
 	if (!buffer_jbd(bh))
 		goto zap_buffer;
 
@@ -1784,8 +1826,12 @@
 			 * committed, the buffer won't be needed any
 			 * longer. */
 			JBUFFER_TRACE(jh, "checkpointed: add to BJ_Forget");
-			return dispose_buffer(jh,
+			ret = __dispose_buffer(jh,
 					journal->j_running_transaction);
+			spin_unlock(&journal->j_list_lock);
+			jbd_unlock_bh_state(bh);
+			spin_unlock(&journal->j_state_lock);
+			return ret;
 		} else {
 			/* There is no currently-running transaction. So the
 			 * orphan record which we wrote for this file must have
@@ -1793,12 +1839,16 @@
 			 * the committing transaction, if it exists. */
 			if (journal->j_committing_transaction) {
 				JBUFFER_TRACE(jh, "give to committing trans");
-				return dispose_buffer(jh,
+				ret = __dispose_buffer(jh,
 					journal->j_committing_transaction);
+				spin_unlock(&journal->j_list_lock);
+				jbd_unlock_bh_state(bh);
+				spin_unlock(&journal->j_state_lock);
+				return ret;
 			} else {
 				/* The orphan record's transaction has
 				 * committed.  We can cleanse this buffer */
-				clear_bit(BH_JBDDirty, &bh->b_state);
+				clear_buffer_jbddirty(bh);
 				goto zap_buffer;
 			}
 		}
@@ -1814,6 +1864,9 @@
 					journal->j_running_transaction);
 			jh->b_next_transaction = NULL;
 		}
+		spin_unlock(&journal->j_list_lock);
+		jbd_unlock_bh_state(bh);
+		spin_unlock(&journal->j_state_lock);
 		return 0;
 	} else {
 		/* Good, the buffer belongs to the running transaction.
@@ -1823,12 +1876,16 @@
 		 * i_size already for this truncate so recovery will not
 		 * expose the disk blocks we are discarding here.) */
 		J_ASSERT_JH(jh, transaction == journal->j_running_transaction);
-		may_free = dispose_buffer(jh, transaction);
+		may_free = __dispose_buffer(jh, transaction);
 	}
 
-zap_buffer:	
+zap_buffer:
+	spin_unlock(&journal->j_list_lock);
+	jbd_unlock_bh_state(bh);
+	spin_unlock(&journal->j_state_lock);
+zap_buffer_unlocked:
 	clear_buffer_dirty(bh);
-	J_ASSERT_BH(bh, !buffer_jdirty(bh));
+	J_ASSERT_BH(bh, !buffer_jbddirty(bh));
 	clear_buffer_mapped(bh);
 	clear_buffer_req(bh);
 	clear_buffer_new(bh);
@@ -1862,7 +1919,6 @@
 	/* We will potentially be playing with lists other than just the
 	 * data lists (especially for journaled data mode), so be
 	 * cautious in our locking. */
-	lock_journal(journal);
 
 	head = bh = page_buffers(page);
 	do {
@@ -1881,8 +1937,6 @@
 
 	} while (bh != head);
 
-	unlock_journal(journal);
-
 	if (!offset) {
 		if (!may_free || !try_to_free_buffers(page))
 			return 0;
@@ -1901,8 +1955,9 @@
 	int was_dirty = 0;
 	struct buffer_head *bh = jh2bh(jh);
 
-	assert_spin_locked(&journal_datalist_lock);
-	
+	J_ASSERT_JH(jh, jbd_is_locked_bh_state(bh));
+	assert_spin_locked(&transaction->t_journal->j_list_lock);
+
 #ifdef __SMP__
 	J_ASSERT (current->lock_depth >= 0);
 #endif
@@ -1968,9 +2023,11 @@
 void journal_file_buffer(struct journal_head *jh,
 				transaction_t *transaction, int jlist)
 {
-	spin_lock(&journal_datalist_lock);
+	jbd_lock_bh_state(jh2bh(jh));
+	spin_lock(&transaction->t_journal->j_list_lock);
 	__journal_file_buffer(jh, transaction, jlist);
-	spin_unlock(&journal_datalist_lock);
+	spin_unlock(&transaction->t_journal->j_list_lock);
+	jbd_unlock_bh_state(jh2bh(jh));
 }
 
 /* 
@@ -1978,14 +2035,19 @@
  * dropping it from its current transaction entirely.  If the buffer has
  * already started to be used by a subsequent transaction, refile the
  * buffer on that transaction's metadata list.
+ *
+ * Called under journal->j_list_lock
+ *
+ * Called under jbd_lock_bh_state(jh2bh(jh))
  */
-
 void __journal_refile_buffer(struct journal_head *jh)
 {
 	int was_dirty;
+	struct buffer_head *bh = jh2bh(jh);
 
-	assert_spin_locked(&journal_datalist_lock);
-	J_ASSERT_JH(jh, kernel_locked());
+	J_ASSERT_JH(jh, jbd_is_locked_bh_state(bh));
+	if (jh->b_transaction)
+		assert_spin_locked(&jh->b_transaction->t_journal->j_list_lock);
 
 	/* If the buffer is now unused, just drop it. */
 	if (jh->b_next_transaction == NULL) {
@@ -1994,10 +2056,12 @@
 		return;
 	}
 	
-	/* It has been modified by a later transaction: add it to the
-	 * new transaction's metadata list. */
+	/*
+	 * It has been modified by a later transaction: add it to the new
+	 * transaction's metadata list.
+	 */
 
-	was_dirty = test_clear_buffer_jbddirty(jh2bh(jh));
+	was_dirty = test_clear_buffer_jbddirty(bh);
 	__journal_unfile_buffer(jh);
 	jh->b_transaction = jh->b_next_transaction;
 	jh->b_next_transaction = NULL;
@@ -2005,7 +2069,7 @@
 	J_ASSERT_JH(jh, jh->b_transaction->t_state == T_RUNNING);
 
 	if (was_dirty)
-		set_buffer_jbddirty(jh2bh(jh));
+		set_buffer_jbddirty(bh);
 }
 
 /*
@@ -2022,16 +2086,17 @@
  *
  * *** The journal_head may be freed by this call! ***
  */
-void journal_refile_buffer(struct journal_head *jh)
+void journal_refile_buffer(journal_t *journal, struct journal_head *jh)
 {
-	struct buffer_head *bh;
+	struct buffer_head *bh = jh2bh(jh);
 
-	spin_lock(&journal_datalist_lock);
-	bh = jh2bh(jh);
+	jbd_lock_bh_state(bh);
+	spin_lock(&journal->j_list_lock);
 
 	__journal_refile_buffer(jh);
-	__journal_remove_journal_head(bh);
+	jbd_unlock_bh_state(bh);
+	journal_remove_journal_head(bh);
 
-	spin_unlock(&journal_datalist_lock);
+	spin_unlock(&journal->j_list_lock);
 	__brelse(bh);
 }
diff -Nru a/fs/namei.c b/fs/namei.c
--- a/fs/namei.c	Wed Jun 18 23:42:06 2003
+++ b/fs/namei.c	Wed Jun 18 23:42:06 2003
@@ -985,6 +985,8 @@
  *  7. If we were asked to remove a directory and victim isn't one - ENOTDIR.
  *  8. If we were asked to remove a non-directory and victim isn't one - EISDIR.
  *  9. We can't remove a root or mountpoint.
+ * 10. We don't allow removal of NFS sillyrenamed files; it's handled by
+ *     nfs_async_unlink().
  */
 static inline int may_delete(struct inode *dir,struct dentry *victim, int isdir)
 {
@@ -1008,6 +1010,8 @@
 		return -EISDIR;
 	if (IS_DEADDIR(dir))
 		return -ENOENT;
+	if (victim->d_flags & DCACHE_NFSFS_RENAMED)
+		return -EBUSY;
 	return 0;
 }
 
diff -Nru a/fs/nfs/inode.c b/fs/nfs/inode.c
--- a/fs/nfs/inode.c	Wed Jun 18 23:42:08 2003
+++ b/fs/nfs/inode.c	Wed Jun 18 23:42:08 2003
@@ -715,7 +715,6 @@
 		if (fattr->valid & NFS_ATTR_FATTR_V4)
 			nfsi->change_attr = fattr->change_attr;
 		inode->i_size = nfs_size_to_loff_t(fattr->size);
-		inode->i_mode = fattr->mode;
 		inode->i_nlink = fattr->nlink;
 		inode->i_uid = fattr->uid;
 		inode->i_gid = fattr->gid;
diff -Nru a/fs/nfsd/auth.c b/fs/nfsd/auth.c
--- a/fs/nfsd/auth.c	Wed Jun 18 23:42:09 2003
+++ b/fs/nfsd/auth.c	Wed Jun 18 23:42:09 2003
@@ -17,9 +17,6 @@
 	struct svc_cred	*cred = &rqstp->rq_cred;
 	int		i;
 
-	if (rqstp->rq_userset)
-		return;
-
 	if (exp->ex_flags & NFSEXP_ALLSQUASH) {
 		cred->cr_uid = exp->ex_anon_uid;
 		cred->cr_gid = exp->ex_anon_gid;
@@ -57,5 +54,4 @@
 						  current->cap_permitted);
 	}
 
-	rqstp->rq_userset = 1;
 }
diff -Nru a/fs/nfsd/export.c b/fs/nfsd/export.c
--- a/fs/nfsd/export.c	Wed Jun 18 23:42:07 2003
+++ b/fs/nfsd/export.c	Wed Jun 18 23:42:07 2003
@@ -153,9 +153,13 @@
 		goto out;
 	dprintk("Path seems to be <%s>\n", buf);
 	err = 0;
-	if (len == 0)
+	if (len == 0) {
+		struct svc_expkey *ek;
 		set_bit(CACHE_NEGATIVE, &key.h.flags);
-	else {
+		ek = svc_expkey_lookup(&key, 2);
+		if (ek)
+			expkey_put(&ek->h, &svc_expkey_cache);
+	} else {
 		struct nameidata nd;
 		struct svc_expkey *ek;
 		struct svc_export *exp;
diff -Nru a/fs/nfsd/nfs4proc.c b/fs/nfsd/nfs4proc.c
--- a/fs/nfsd/nfs4proc.c	Wed Jun 18 23:42:09 2003
+++ b/fs/nfsd/nfs4proc.c	Wed Jun 18 23:42:09 2003
@@ -147,12 +147,6 @@
 	return 0;
 }
 
-static inline int
-nfsd4_renew(clientid_t *clientid)
-{
-	return nfs_ok;
-}
-
 /*
  * filehandle-manipulating ops.
  */
diff -Nru a/fs/nfsd/nfs4state.c b/fs/nfsd/nfs4state.c
--- a/fs/nfsd/nfs4state.c	Wed Jun 18 23:42:08 2003
+++ b/fs/nfsd/nfs4state.c	Wed Jun 18 23:42:08 2003
@@ -43,6 +43,7 @@
 #include <linux/nfsd/nfsd.h>
 #include <linux/nfsd/cache.h>
 #include <linux/mount.h>
+#include <linux/workqueue.h>
 #include <linux/nfs4.h>
 #include <linux/nfsd/state.h>
 #include <linux/nfsd/xdr4.h>
@@ -54,6 +55,7 @@
 static u32 current_clientid = 1;
 static u32 current_ownerid = 0;
 static u32 current_fileid = 0;
+static u32 nfs4_init = 0;
 
 /* debug counters */
 u32 list_add_perfile = 0; 
@@ -105,11 +107,28 @@
  *
  * unconf_str_hastbl[] and unconf_id_hashtbl[] hold unconfirmed 
  * setclientid info.
+ *
+ * client_lru holds client queue ordered by nfs4_client.cl_time
+ * for lease renewal.
  */
 static struct list_head	conf_id_hashtbl[CLIENT_HASH_SIZE];
 static struct list_head	conf_str_hashtbl[CLIENT_HASH_SIZE];
 static struct list_head	unconf_str_hashtbl[CLIENT_HASH_SIZE];
 static struct list_head	unconf_id_hashtbl[CLIENT_HASH_SIZE];
+static struct list_head client_lru;
+
+static inline void
+renew_client(struct nfs4_client *clp)
+{
+	/*
+	* Move client to the end to the LRU list.
+	*/
+	dprintk("renewing client (clientid %08x/%08x)\n", 
+			clp->cl_clientid.cl_boot, 
+			clp->cl_clientid.cl_id);
+	list_move_tail(&clp->cl_lru, &client_lru);
+	clp->cl_time = get_seconds();
+}
 
 /* SETCLIENTID and SETCLIENTID_CONFIRM Helper functions */
 static int
@@ -160,6 +179,7 @@
 	dprintk("NFSD: expire_client\n");
 	list_del(&clp->cl_idhash);
 	list_del(&clp->cl_strhash);
+	list_del(&clp->cl_lru);
 	while (!list_empty(&clp->cl_perclient)) {
 		sop = list_entry(clp->cl_perclient.next, struct nfs4_stateowner, so_perclient);
 		release_stateowner(sop);
@@ -176,6 +196,7 @@
 	INIT_LIST_HEAD(&clp->cl_idhash);
 	INIT_LIST_HEAD(&clp->cl_strhash);
 	INIT_LIST_HEAD(&clp->cl_perclient);
+	INIT_LIST_HEAD(&clp->cl_lru);
 out:
 	return clp;
 }
@@ -264,6 +285,8 @@
 	list_add(&clp->cl_strhash, &unconf_str_hashtbl[strhashval]);
 	idhashval = clientid_hashval(clp->cl_clientid.cl_id);
 	list_add(&clp->cl_idhash, &unconf_id_hashtbl[idhashval]);
+	list_add_tail(&clp->cl_lru, &client_lru);
+	clp->cl_time = get_seconds();
 }
 
 void
@@ -271,13 +294,13 @@
 {
 	unsigned int strhashval;
 
-	printk("ANDROS: move_to_confirm nfs4_client %p\n", clp);
 	list_del_init(&clp->cl_strhash);
 	list_del_init(&clp->cl_idhash);
 	list_add(&clp->cl_idhash, &conf_id_hashtbl[idhashval]);
 	strhashval = clientstr_hashval(clp->cl_name.data, 
 			clp->cl_name.len);
 	list_add(&clp->cl_strhash, &conf_str_hashtbl[strhashval]);
+	renew_client(clp);
 }
 
 /*
@@ -940,9 +963,7 @@
 	open->op_stateowner = sop;
 	status = nfs_ok;
 renew:
-	/* XXX implement LRU and state recovery thread 
-	 * renew will place nfs4_client at end of LRU 
-	 */
+	renew_client(sop->so_client);
 out:
 	up(&client_sema); /*XXX need finer grained locking */
 	return status;
@@ -1048,13 +1069,98 @@
 	kfree(stp);
 	goto out;
 }
+static struct work_struct laundromat_work;
+static void laundromat_main(void *);
+static DECLARE_WORK(laundromat_work, laundromat_main, NULL);
+
+int 
+nfsd4_renew(clientid_t *clid)
+{
+	struct nfs4_client *clp;
+	struct list_head *pos, *next;
+	unsigned int idhashval;
+	int status;
+
+	down(&client_sema);
+	printk("process_renew(%08x/%08x): starting\n", 
+			clid->cl_boot, clid->cl_id);
+	status = nfserr_stale_clientid;
+	if (STALE_CLIENTID(clid))
+		goto out;
+	status = nfs_ok;
+	idhashval = clientid_hashval(clid->cl_id);
+	list_for_each_safe(pos, next, &conf_id_hashtbl[idhashval]) {
+		clp = list_entry(pos, struct nfs4_client, cl_idhash);
+		if (!cmp_clid(&clp->cl_clientid, clid))
+			continue;
+		renew_client(clp);
+		goto out;
+	}
+	list_for_each_safe(pos, next, &unconf_id_hashtbl[idhashval]) {
+		clp = list_entry(pos, struct nfs4_client, cl_idhash);
+		if (!cmp_clid(&clp->cl_clientid, clid))
+			continue;
+		renew_client(clp);
+	goto out;
+	}
+	/*
+	* Couldn't find an nfs4_client for this clientid.  
+	* Presumably this is because the client took too long to 
+	* RENEW, so return NFS4ERR_EXPIRED.
+	*/
+	printk("nfsd4_renew: clientid not found!\n");
+	status = nfserr_expired;
+out:
+	up(&client_sema);
+	return status;
+}
+
+time_t
+nfs4_laundromat(void)
+{
+	struct nfs4_client *clp;
+	struct list_head *pos, *next;
+	time_t cutoff = get_seconds() - NFSD_LEASE_TIME;
+	time_t t, return_val = NFSD_LEASE_TIME;
+
+	down(&client_sema);
+
+	dprintk("NFSD: laundromat service - starting, examining clients\n");
+	list_for_each_safe(pos, next, &client_lru) {
+		clp = list_entry(pos, struct nfs4_client, cl_lru);
+		if (time_after((unsigned long)clp->cl_time, (unsigned long)cutoff)) {
+			t = clp->cl_time - cutoff;
+			if (return_val > t)
+				return_val = t;
+			break;
+		}
+		dprintk("NFSD: purging unused client (clientid %08x)\n",
+			clp->cl_clientid.cl_id);
+		expire_client(clp);
+	}
+	if (return_val < NFSD_LAUNDROMAT_MINTIMEOUT)
+		return_val = NFSD_LAUNDROMAT_MINTIMEOUT;
+	up(&client_sema); 
+	return return_val;
+}
+
+void
+laundromat_main(void *not_used)
+{
+	time_t t;
+
+	t = nfs4_laundromat();
+	dprintk("NFSD: laundromat_main - sleeping for %ld seconds\n", t);
+	schedule_delayed_work(&laundromat_work, t*HZ);
+}
 
 void 
 nfs4_state_init(void)
 {
-	struct timespec 	tv;
 	int i;
 
+	if (nfs4_init)
+		return;
 	for (i = 0; i < CLIENT_HASH_SIZE; i++) {
 		INIT_LIST_HEAD(&conf_id_hashtbl[i]);
 		INIT_LIST_HEAD(&conf_str_hashtbl[i]);
@@ -1067,9 +1173,13 @@
 	for (i = 0; i < OWNER_HASH_SIZE; i++) {
 		INIT_LIST_HEAD(&ownerstr_hashtbl[i]);
 	}
+	INIT_LIST_HEAD(&client_lru);
 	init_MUTEX(&client_sema);
-	tv = CURRENT_TIME;
-	boot_time = tv.tv_sec;
+	boot_time = get_seconds();
+	INIT_WORK(&laundromat_work,laundromat_main, NULL);
+	schedule_delayed_work(&laundromat_work, NFSD_LEASE_TIME*HZ);
+	nfs4_init = 1;
+
 }
 
 static void
@@ -1089,6 +1199,9 @@
 		}
 	}
 	release_all_files();
+	cancel_delayed_work(&laundromat_work);
+	flush_scheduled_work();
+	nfs4_init = 0;
 	dprintk("NFSD: list_add_perfile %d list_del_perfile %d\n",
 			list_add_perfile, list_del_perfile);
 	dprintk("NFSD: add_perclient %d del_perclient %d\n",
diff -Nru a/fs/nfsd/nfs4xdr.c b/fs/nfsd/nfs4xdr.c
--- a/fs/nfsd/nfs4xdr.c	Wed Jun 18 23:42:08 2003
+++ b/fs/nfsd/nfs4xdr.c	Wed Jun 18 23:42:08 2003
@@ -1039,6 +1039,7 @@
 	*p++ = htonl((u32)(n));					\
 } while (0)
 #define WRITEMEM(ptr,nbytes)     do {				\
+	*(p + XDR_QUADLEN(nbytes) -1) = 0;                      \
 	memcpy(p, ptr, nbytes);					\
 	p += XDR_QUADLEN(nbytes);				\
 } while (0)
@@ -1425,6 +1426,7 @@
 	u32 *p = cd->buffer;
 	u32 *attrlenp;
 	struct dentry *dentry;
+	struct svc_export *exp = cd->rd_fhp->fh_export;
 	u32 bmval0, bmval1;
 	int nfserr = 0;
 
@@ -1454,9 +1456,7 @@
 	if ((bmval0 & ~(FATTR4_WORD0_RDATTR_ERROR | FATTR4_WORD0_FILEID)) || bmval1)  {
 		/*
 		 * "Heavyweight" case: we have no choice except to
-		 * call nfsd4_encode_fattr().  As far as I know,
-		 * only Windows clients will trigger this code
-		 * path.
+		 * call nfsd4_encode_fattr(). 
 		 */
 		dentry = lookup_one_len(name, cd->rd_fhp->fh_dentry, namlen);
 		if (IS_ERR(dentry)) {
@@ -1464,10 +1464,25 @@
 			goto error;
 		}
 
-		nfserr = nfsd4_encode_fattr(NULL, cd->rd_fhp->fh_export,
-					    dentry, p, &buflen, cd->rd_bmval);
-		dput(dentry);
+		if (d_mountpoint(dentry)) {
+			if ((nfserr = nfsd_cross_mnt(cd->rd_rqstp, &dentry, 
+					 &exp))) {	
+			/* 
+			 * -EAGAIN is the only error returned from 
+			 * nfsd_cross_mnt() and it indicates that an 
+			 * up-call has  been initiated to fill in the export 
+			 * options on exp.  When the answer comes back,
+			 * this call will be retried.
+			 */
+				dput(dentry);
+				nfserr = nfserr_dropit;
+				goto error;
+			}
 
+		}
+
+		nfserr = nfsd4_encode_fattr(NULL, exp,
+				dentry, p, &buflen, cd->rd_bmval);
 		if (!nfserr) {
 			p += buflen;
 			goto out;
diff -Nru a/fs/nfsd/nfsctl.c b/fs/nfsd/nfsctl.c
--- a/fs/nfsd/nfsctl.c	Wed Jun 18 23:42:06 2003
+++ b/fs/nfsd/nfsctl.c	Wed Jun 18 23:42:06 2003
@@ -453,7 +453,6 @@
 	nfsd_cache_init();	/* RPC reply cache */
 	nfsd_export_init();	/* Exports table */
 	nfsd_lockd_init();	/* lockd->nfsd callbacks */
-	nfs4_state_init();      /* NFSv4 State */
 	if (proc_mkdir("fs/nfs", 0)) {
 		struct proc_dir_entry *entry;
 		entry = create_proc_entry("fs/nfs/exports", 0, NULL);
diff -Nru a/fs/nfsd/nfsfh.c b/fs/nfsd/nfsfh.c
--- a/fs/nfsd/nfsfh.c	Wed Jun 18 23:42:06 2003
+++ b/fs/nfsd/nfsfh.c	Wed Jun 18 23:42:06 2003
@@ -161,9 +161,6 @@
 			goto out;
 		}
 
-		/* Set user creds if we haven't done so already. */
-		nfsd_setuser(rqstp, exp);
-
 		/*
 		 * Look up the dentry using the NFS file handle.
 		 */
@@ -222,6 +219,10 @@
 	cache_get(&exp->h);
 
 	inode = dentry->d_inode;
+
+
+	/* Set user creds for this exportpoint */
+	nfsd_setuser(rqstp, exp);
 
 	/* Type check. The correct error return for type mismatches
 	 * does not seem to be generally agreed upon. SunOS seems to
diff -Nru a/fs/nfsd/nfsproc.c b/fs/nfsd/nfsproc.c
--- a/fs/nfsd/nfsproc.c	Wed Jun 18 23:42:06 2003
+++ b/fs/nfsd/nfsproc.c	Wed Jun 18 23:42:06 2003
@@ -591,6 +591,7 @@
 		{ nfserr_dquot, -EDQUOT },
 #endif
 		{ nfserr_stale, -ESTALE },
+		{ nfserr_dropit, -EAGAIN },
 		{ nfserr_dropit, -ENOMEM },
 		{ -1, -EIO }
 	};
diff -Nru a/fs/nfsd/nfssvc.c b/fs/nfsd/nfssvc.c
--- a/fs/nfsd/nfssvc.c	Wed Jun 18 23:42:07 2003
+++ b/fs/nfsd/nfssvc.c	Wed Jun 18 23:42:07 2003
@@ -91,6 +91,7 @@
 	
 	/* Readahead param cache - will no-op if it already exists */
 	error =	nfsd_racache_init(2*nrservs);
+	nfs4_state_init();
 	if (error<0)
 		goto out;
 	if (!nfsd_serv) {
diff -Nru a/fs/nfsd/vfs.c b/fs/nfsd/vfs.c
--- a/fs/nfsd/vfs.c	Wed Jun 18 23:42:07 2003
+++ b/fs/nfsd/vfs.c	Wed Jun 18 23:42:07 2003
@@ -74,6 +74,46 @@
 static struct raparms *		raparml;
 static struct raparms *		raparm_cache;
 
+/* 
+ * Called from nfsd_lookup and encode_dirent. Check if we have crossed 
+ * a mount point.
+ * Returns -EAGAIN leaving *dpp and *expp unchanged, 
+ *  or nfs_ok having possibly changed *dpp and *expp
+ */
+int
+nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp, 
+		        struct svc_export **expp)
+{
+	struct svc_export *exp = *expp, *exp2 = NULL;
+	struct dentry *dentry = *dpp;
+	struct vfsmount *mnt = mntget(exp->ex_mnt);
+	struct dentry *mounts = dget(dentry);
+	int err = nfs_ok;
+
+	while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts));
+
+	exp2 = exp_get_by_name(exp->ex_client, mnt, mounts, &rqstp->rq_chandle);
+	if (IS_ERR(exp2)) {
+		err = PTR_ERR(exp2);
+		dput(mounts);
+		mntput(mnt);
+		goto out;
+	}
+	if (exp2 && ((exp->ex_flags & NFSEXP_CROSSMNT) || EX_NOHIDE(exp2))) {
+		/* successfully crossed mount point */
+		exp_put(exp);
+		*expp = exp2;
+		dput(dentry);
+		*dpp = mounts;
+	} else {
+		if (exp2) exp_put(exp2);
+		dput(mounts);
+	}
+	mntput(mnt);
+out:
+	return err;
+}
+
 /*
  * Look up one component of a pathname.
  * N.B. After this call _both_ fhp and resfh need an fh_put
@@ -154,34 +194,10 @@
 		 * check if we have crossed a mount point ...
 		 */
 		if (d_mountpoint(dentry)) {
-			struct svc_export *exp2 = NULL;
-			struct vfsmount *mnt = mntget(exp->ex_mnt);
-			struct dentry *mounts = dget(dentry);
-			while (follow_down(&mnt,&mounts)&&d_mountpoint(mounts))
-				;
-
-			exp2 = exp_get_by_name(exp->ex_client, mnt, 
-					       mounts, &rqstp->rq_chandle);
-			if (IS_ERR(exp2)) {
-				err = PTR_ERR(exp2);
-				dput(mounts);
-				dput(dentry);
-				mntput(mnt);
-				goto out;
-			}
-			if (exp2 &&
-			    ((exp->ex_flags & NFSEXP_CROSSMNT)
-			     || EX_NOHIDE(exp2))) {
-				/* successfully crossed mount point */
-				exp_put(exp);
-				exp = exp2;
+			if ((err = nfsd_cross_mnt(rqstp, &dentry, &exp))) {
 				dput(dentry);
-				dentry = mounts;
-			} else {
-				if (exp2) exp_put(exp2);
-				dput(mounts);
+				goto out_nfserr;
 			}
-			mntput(mnt);
 		}
 	}
 	/*
diff -Nru a/include/asm-arm/hardware/amba.h b/include/asm-arm/hardware/amba.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-arm/hardware/amba.h	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,44 @@
+/*
+ *  linux/include/asm-arm/hardware/amba.h
+ *
+ *  Copyright (C) 2003 Deep Blue Solutions Ltd, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ */
+#ifndef ASMARM_AMBA_H
+#define ASMARM_AMBA_H
+
+struct amba_device {
+	struct device		dev;
+	struct resource		res;
+	unsigned int		irq;
+	unsigned int		periphid;
+};
+
+struct amba_id {
+	unsigned int		id;
+	unsigned int		mask;
+	void			*data;
+};
+
+struct amba_driver {
+	struct device_driver	drv;
+	int			(*probe)(struct amba_device *, void *);
+	int			(*remove)(struct amba_device *);
+	void			(*shutdown)(struct amba_device *);
+	int			(*suspend)(struct amba_device *, u32, u32);
+	int			(*resume)(struct amba_device *, u32);
+	struct amba_id		*id_table;
+};
+
+#define amba_get_drvdata(d)	dev_get_drvdata(&d->dev)
+#define amba_set_drvdata(d,p)	dev_set_drvdata(&d->dev, p)
+
+int amba_driver_register(struct amba_driver *);
+void amba_driver_unregister(struct amba_driver *);
+int amba_device_register(struct amba_device *, struct resource *);
+void amba_device_unregister(struct amba_device *);
+
+#endif
diff -Nru a/include/asm-arm/hardware/icst525.h b/include/asm-arm/hardware/icst525.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-arm/hardware/icst525.h	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,36 @@
+/*
+ *  linux/include/asm-arm/hardware/icst525.h
+ *
+ *  Copyright (C) 2003 Deep Blue Solutions, Ltd, All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ *  Support functions for calculating clocks/divisors for the ICST525
+ *  clock generators.  See http://www.icst.com/ for more information
+ *  on these devices.
+ */
+#ifndef ASMARM_HARDWARE_ICST525_H
+#define ASMARM_HARDWARE_ICST525_H
+
+struct icst525_params {
+	unsigned long	ref;
+	unsigned long	vco_max;	/* inclusive */
+	unsigned short	vd_min;		/* inclusive */
+	unsigned short	vd_max;		/* inclusive */
+	unsigned char	rd_min;		/* inclusive */
+	unsigned char	rd_max;		/* inclusive */
+};
+
+struct icst525_vco {
+	unsigned short	v;
+	unsigned char	r;
+	unsigned char	s;
+};
+
+unsigned long icst525_khz(const struct icst525_params *p, struct icst525_vco vco);
+struct icst525_vco icst525_khz_to_vco(const struct icst525_params *p, unsigned long freq);
+struct icst525_vco icst525_ps_to_vco(const struct icst525_params *p, unsigned long period);
+
+#endif
diff -Nru a/include/asm-arm/memory.h b/include/asm-arm/memory.h
--- a/include/asm-arm/memory.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-arm/memory.h	Wed Jun 18 23:42:09 2003
@@ -27,6 +27,9 @@
 
 /*
  * These are *only* valid on the kernel direct mapped RAM memory.
+ * Note: Drivers should NOT use these.  They are the wrong
+ * translation for translating DMA addresses.  Use the driver
+ * DMA support - see dma-mapping.h.
  */
 static inline unsigned long virt_to_phys(void *x)
 {
@@ -38,6 +41,9 @@
 	return (void *)(__phys_to_virt((unsigned long)(x)));
 }
 
+/*
+ * Drivers should NOT use these either.
+ */
 #define __pa(x)			__virt_to_phys((unsigned long)(x))
 #define __va(x)			((void *)__phys_to_virt((unsigned long)(x)))
 
@@ -72,7 +78,7 @@
 #define pfn_valid(pfn)		((pfn) >= PHYS_PFN_OFFSET && (pfn) < (PHYS_PFN_OFFSET + max_mapnr))
 
 #define virt_to_page(kaddr)	(pfn_to_page(__pa(kaddr) >> PAGE_SHIFT))
-#define virt_addr_valid(kaddr)	((kaddr) >= PAGE_OFFSET && (kaddr) < (unsigned long)high_memory)
+#define virt_addr_valid(kaddr)	((unsigned long)(kaddr) >= PAGE_OFFSET && (unsigned long)(kaddr) < (unsigned long)high_memory)
 
 #define PHYS_TO_NID(addr)	(0)
 
diff -Nru a/include/asm-arm/proc-armv/uaccess.h b/include/asm-arm/proc-armv/uaccess.h
--- a/include/asm-arm/proc-armv/uaccess.h	Wed Jun 18 23:42:05 2003
+++ b/include/asm-arm/proc-armv/uaccess.h	Wed Jun 18 23:42:05 2003
@@ -87,10 +87,18 @@
 	: "r" (x), "r" (__pu_addr), "i" (-EFAULT)		\
 	: "cc")
 
+#ifndef __ARMEB__
+#define	__reg_oper0	"%R2"
+#define	__reg_oper1	"%Q2"
+#else
+#define	__reg_oper0	"%Q2"
+#define	__reg_oper1	"%R2"
+#endif
+
 #define __put_user_asm_dword(x,__pu_addr,err)			\
 	__asm__ __volatile__(					\
-	"1:	strt	%Q2, [%1], #4\n"			\
-	"2:	strt	%R2, [%1], #0\n"			\
+	"1:	strt	" __reg_oper1 ", [%1], #4\n"		\
+	"2:	strt	" __reg_oper0 ", [%1], #0\n"		\
 	"3:\n"							\
 	"	.section .fixup,\"ax\"\n"			\
 	"	.align	2\n"					\
diff -Nru a/include/asm-i386/apic.h b/include/asm-i386/apic.h
--- a/include/asm-i386/apic.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-i386/apic.h	Wed Jun 18 23:42:09 2003
@@ -81,6 +81,8 @@
 extern void setup_apic_nmi_watchdog (void);
 extern void disable_lapic_nmi_watchdog(void);
 extern void enable_lapic_nmi_watchdog(void);
+extern void disable_timer_nmi_watchdog(void);
+extern void enable_timer_nmi_watchdog(void);
 extern inline void nmi_watchdog_tick (struct pt_regs * regs);
 extern int APIC_init_uniprocessor (void);
 extern void disable_APIC_timer(void);
diff -Nru a/include/asm-ia64/a.out.h b/include/asm-ia64/a.out.h
--- a/include/asm-ia64/a.out.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/a.out.h	Wed Jun 18 23:42:08 2003
@@ -30,9 +30,6 @@
 #define N_TXTOFF(x)	0
 
 #ifdef __KERNEL__
-# include <asm/page.h>
-# define STACK_TOP	(0x6000000000000000UL + (1UL << (4*PAGE_SHIFT - 12)) - PAGE_SIZE)
-# define IA64_RBS_BOT	(STACK_TOP - 0x80000000L + PAGE_SIZE)	/* bottom of reg. backing store */
+#include <asm/ustack.h>
 #endif
-
 #endif /* _ASM_IA64_A_OUT_H */
diff -Nru a/include/asm-ia64/asmmacro.h b/include/asm-ia64/asmmacro.h
--- a/include/asm-ia64/asmmacro.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/asmmacro.h	Wed Jun 18 23:42:06 2003
@@ -43,21 +43,25 @@
 	.section "__ex_table", "a"		// declare section & section attributes
 	.previous
 
-#if __GNUC__ >= 3
 # define EX(y,x...)				\
 	.xdata4 "__ex_table", 99f-., y-.;	\
   [99:]	x
 # define EXCLR(y,x...)				\
 	.xdata4 "__ex_table", 99f-., y-.+4;	\
   [99:]	x
-#else
-# define EX(y,x...)				\
-	.xdata4 "__ex_table", 99f-., y-.;	\
-  99:	x
-# define EXCLR(y,x...)				\
-	.xdata4 "__ex_table", 99f-., y-.+4;	\
-  99:	x
-#endif
+
+/*
+ * Mark instructions that need a load of a virtual address patched to be
+ * a load of a physical address.  We use this either in critical performance
+ * path (ivt.S - TLB miss processing) or in places where it might not be
+ * safe to use a "tpa" instruction (mca_asm.S - error recovery).
+ */
+	.section ".data.patch.vtop", "a"	// declare section & section attributes
+	.previous
+
+#define	LOAD_PHYSICAL(pr, reg, obj)		\
+[1:](pr)movl reg = obj;				\
+	.xdata4 ".data.patch.vtop", 1b-.
 
 /*
  * For now, we always put in the McKinley E9 workaround.  On CPUs that don't need it,
@@ -65,11 +69,11 @@
  */
 #define DO_MCKINLEY_E9_WORKAROUND
 #ifdef DO_MCKINLEY_E9_WORKAROUND
-	.section "__mckinley_e9_bundles", "a"
+	.section ".data.patch.mckinley_e9", "a"
 	.previous
 /* workaround for Itanium 2 Errata 9: */
 # define MCKINLEY_E9_WORKAROUND			\
-	.xdata4 "__mckinley_e9_bundles", 1f-.;	\
+	.xdata4 ".data.patch.mckinley_e9", 1f-.;\
 1:{ .mib;					\
 	nop.m 0;				\
 	nop.i 0;				\
diff -Nru a/include/asm-ia64/compat.h b/include/asm-ia64/compat.h
--- a/include/asm-ia64/compat.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-ia64/compat.h	Wed Jun 18 23:42:09 2003
@@ -128,4 +128,11 @@
 	return (void *) (unsigned long) uptr;
 }
 
+static __inline__ void *
+compat_alloc_user_space (long len)
+{
+	struct pt_regs *regs = ia64_task_regs(current);
+	return (void *) ((regs->r12 & -16) - len);
+}
+
 #endif /* _ASM_IA64_COMPAT_H */
diff -Nru a/include/asm-ia64/elf.h b/include/asm-ia64/elf.h
--- a/include/asm-ia64/elf.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/elf.h	Wed Jun 18 23:42:08 2003
@@ -42,6 +42,93 @@
  */
 #define ELF_ET_DYN_BASE		(TASK_UNMAPPED_BASE + 0x800000000)
 
+#define PT_IA_64_UNWIND		0x70000001
+
+/* IA-64 relocations: */
+#define R_IA64_NONE		0x00	/* none */
+#define R_IA64_IMM14		0x21	/* symbol + addend, add imm14 */
+#define R_IA64_IMM22		0x22	/* symbol + addend, add imm22 */
+#define R_IA64_IMM64		0x23	/* symbol + addend, mov imm64 */
+#define R_IA64_DIR32MSB		0x24	/* symbol + addend, data4 MSB */
+#define R_IA64_DIR32LSB		0x25	/* symbol + addend, data4 LSB */
+#define R_IA64_DIR64MSB		0x26	/* symbol + addend, data8 MSB */
+#define R_IA64_DIR64LSB		0x27	/* symbol + addend, data8 LSB */
+#define R_IA64_GPREL22		0x2a	/* @gprel(sym+add), add imm22 */
+#define R_IA64_GPREL64I		0x2b	/* @gprel(sym+add), mov imm64 */
+#define R_IA64_GPREL32MSB	0x2c	/* @gprel(sym+add), data4 MSB */
+#define R_IA64_GPREL32LSB	0x2d	/* @gprel(sym+add), data4 LSB */
+#define R_IA64_GPREL64MSB	0x2e	/* @gprel(sym+add), data8 MSB */
+#define R_IA64_GPREL64LSB	0x2f	/* @gprel(sym+add), data8 LSB */
+#define R_IA64_LTOFF22		0x32	/* @ltoff(sym+add), add imm22 */
+#define R_IA64_LTOFF64I		0x33	/* @ltoff(sym+add), mov imm64 */
+#define R_IA64_PLTOFF22		0x3a	/* @pltoff(sym+add), add imm22 */
+#define R_IA64_PLTOFF64I	0x3b	/* @pltoff(sym+add), mov imm64 */
+#define R_IA64_PLTOFF64MSB	0x3e	/* @pltoff(sym+add), data8 MSB */
+#define R_IA64_PLTOFF64LSB	0x3f	/* @pltoff(sym+add), data8 LSB */
+#define R_IA64_FPTR64I		0x43	/* @fptr(sym+add), mov imm64 */
+#define R_IA64_FPTR32MSB	0x44	/* @fptr(sym+add), data4 MSB */
+#define R_IA64_FPTR32LSB	0x45	/* @fptr(sym+add), data4 LSB */
+#define R_IA64_FPTR64MSB	0x46	/* @fptr(sym+add), data8 MSB */
+#define R_IA64_FPTR64LSB	0x47	/* @fptr(sym+add), data8 LSB */
+#define R_IA64_PCREL60B		0x48	/* @pcrel(sym+add), brl */
+#define R_IA64_PCREL21B		0x49	/* @pcrel(sym+add), ptb, call */
+#define R_IA64_PCREL21M		0x4a	/* @pcrel(sym+add), chk.s */
+#define R_IA64_PCREL21F		0x4b	/* @pcrel(sym+add), fchkf */
+#define R_IA64_PCREL32MSB	0x4c	/* @pcrel(sym+add), data4 MSB */
+#define R_IA64_PCREL32LSB	0x4d	/* @pcrel(sym+add), data4 LSB */
+#define R_IA64_PCREL64MSB	0x4e	/* @pcrel(sym+add), data8 MSB */
+#define R_IA64_PCREL64LSB	0x4f	/* @pcrel(sym+add), data8 LSB */
+#define R_IA64_LTOFF_FPTR22	0x52	/* @ltoff(@fptr(s+a)), imm22 */
+#define R_IA64_LTOFF_FPTR64I	0x53	/* @ltoff(@fptr(s+a)), imm64 */
+#define R_IA64_LTOFF_FPTR32MSB	0x54	/* @ltoff(@fptr(s+a)), 4 MSB */
+#define R_IA64_LTOFF_FPTR32LSB	0x55	/* @ltoff(@fptr(s+a)), 4 LSB */
+#define R_IA64_LTOFF_FPTR64MSB	0x56	/* @ltoff(@fptr(s+a)), 8 MSB */
+#define R_IA64_LTOFF_FPTR64LSB	0x57	/* @ltoff(@fptr(s+a)), 8 LSB */
+#define R_IA64_SEGREL32MSB	0x5c	/* @segrel(sym+add), data4 MSB */
+#define R_IA64_SEGREL32LSB	0x5d	/* @segrel(sym+add), data4 LSB */
+#define R_IA64_SEGREL64MSB	0x5e	/* @segrel(sym+add), data8 MSB */
+#define R_IA64_SEGREL64LSB	0x5f	/* @segrel(sym+add), data8 LSB */
+#define R_IA64_SECREL32MSB	0x64	/* @secrel(sym+add), data4 MSB */
+#define R_IA64_SECREL32LSB	0x65	/* @secrel(sym+add), data4 LSB */
+#define R_IA64_SECREL64MSB	0x66	/* @secrel(sym+add), data8 MSB */
+#define R_IA64_SECREL64LSB	0x67	/* @secrel(sym+add), data8 LSB */
+#define R_IA64_REL32MSB		0x6c	/* data 4 + REL */
+#define R_IA64_REL32LSB		0x6d	/* data 4 + REL */
+#define R_IA64_REL64MSB		0x6e	/* data 8 + REL */
+#define R_IA64_REL64LSB		0x6f	/* data 8 + REL */
+#define R_IA64_LTV32MSB		0x74	/* symbol + addend, data4 MSB */
+#define R_IA64_LTV32LSB		0x75	/* symbol + addend, data4 LSB */
+#define R_IA64_LTV64MSB		0x76	/* symbol + addend, data8 MSB */
+#define R_IA64_LTV64LSB		0x77	/* symbol + addend, data8 LSB */
+#define R_IA64_PCREL21BI	0x79	/* @pcrel(sym+add), ptb, call */
+#define R_IA64_PCREL22		0x7a	/* @pcrel(sym+add), imm22 */
+#define R_IA64_PCREL64I		0x7b	/* @pcrel(sym+add), imm64 */
+#define R_IA64_IPLTMSB		0x80	/* dynamic reloc, imported PLT, MSB */
+#define R_IA64_IPLTLSB		0x81	/* dynamic reloc, imported PLT, LSB */
+#define R_IA64_COPY		0x84	/* dynamic reloc, data copy */
+#define R_IA64_SUB		0x85	/* -symbol + addend, add imm22 */
+#define R_IA64_LTOFF22X		0x86	/* LTOFF22, relaxable.  */
+#define R_IA64_LDXMOV		0x87	/* Use of LTOFF22X.  */
+#define R_IA64_TPREL14		0x91	/* @tprel(sym+add), add imm14 */
+#define R_IA64_TPREL22		0x92	/* @tprel(sym+add), add imm22 */
+#define R_IA64_TPREL64I		0x93	/* @tprel(sym+add), add imm64 */
+#define R_IA64_TPREL64MSB	0x96	/* @tprel(sym+add), data8 MSB */
+#define R_IA64_TPREL64LSB	0x97	/* @tprel(sym+add), data8 LSB */
+#define R_IA64_LTOFF_TPREL22	0x9a	/* @ltoff(@tprel(s+a)), add imm22 */
+#define R_IA64_DTPMOD64MSB	0xa6	/* @dtpmod(sym+add), data8 MSB */
+#define R_IA64_DTPMOD64LSB	0xa7	/* @dtpmod(sym+add), data8 LSB */
+#define R_IA64_LTOFF_DTPMOD22	0xaa	/* @ltoff(@dtpmod(s+a)), imm22 */
+#define R_IA64_DTPREL14		0xb1	/* @dtprel(sym+add), imm14 */
+#define R_IA64_DTPREL22		0xb2	/* @dtprel(sym+add), imm22 */
+#define R_IA64_DTPREL64I	0xb3	/* @dtprel(sym+add), imm64 */
+#define R_IA64_DTPREL32MSB	0xb4	/* @dtprel(sym+add), data4 MSB */
+#define R_IA64_DTPREL32LSB	0xb5	/* @dtprel(sym+add), data4 LSB */
+#define R_IA64_DTPREL64MSB	0xb6	/* @dtprel(sym+add), data8 MSB */
+#define R_IA64_DTPREL64LSB	0xb7	/* @dtprel(sym+add), data8 LSB */
+#define R_IA64_LTOFF_DTPREL22	0xba	/* @ltoff(@dtprel(s+a)), imm22 */
+
+/* IA-64 specific section flags: */
+#define SHF_IA_64_SHORT		0x10000000	/* section near gp */
 
 /*
  * We use (abuse?) this macro to insert the (empty) vm_area that is
@@ -62,7 +149,7 @@
  *	b0-b7
  *	ip cfm psr
  *	ar.rsc ar.bsp ar.bspstore ar.rnat
- *	ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec
+ *	ar.ccv ar.unat ar.fpsr ar.pfs ar.lc ar.ec ar.csd ar.ssd
  */
 #define ELF_NGREG	128	/* we really need just 72 but let's leave some headroom... */
 #define ELF_NFPREG	128	/* f0 and f1 could be omitted, but so what... */
@@ -91,28 +178,72 @@
 #define ELF_PLATFORM	0
 
 /*
- * This should go into linux/elf.h...
+ * Architecture-neutral AT_ values are in the range 0-17.  Leave some room for more of
+ * them, start the architecture-specific ones at 32.
  */
 #define AT_SYSINFO	32
+#define AT_SYSINFO_EHDR	33
 
 #ifdef __KERNEL__
 struct elf64_hdr;
 extern void ia64_set_personality (struct elf64_hdr *elf_ex, int ibcs2_interpreter);
 #define SET_PERSONALITY(ex, ibcs2)	ia64_set_personality(&(ex), ibcs2)
 
+struct task_struct;
+
 extern int dump_task_regs(struct task_struct *, elf_gregset_t *);
 extern int dump_task_fpu (struct task_struct *, elf_fpregset_t *);
 
 #define ELF_CORE_COPY_TASK_REGS(tsk, elf_gregs) dump_task_regs(tsk, elf_gregs)
 #define ELF_CORE_COPY_FPREGS(tsk, elf_fpregs) dump_task_fpu(tsk, elf_fpregs)
 
-#ifdef CONFIG_FSYS
-#define ARCH_DLINFO									\
-do {											\
-	extern char syscall_via_epc[], __start_gate_section[];				\
-	NEW_AUX_ENT(AT_SYSINFO, GATE_ADDR + (syscall_via_epc - __start_gate_section));	\
+#define GATE_EHDR	((const struct elfhdr *) GATE_ADDR)
+
+#define ARCH_DLINFO							\
+do {									\
+	extern char __kernel_syscall_via_epc[];				\
+	NEW_AUX_ENT(AT_SYSINFO, __kernel_syscall_via_epc);		\
+	NEW_AUX_ENT(AT_SYSINFO_EHDR, (unsigned long) GATE_EHDR);	\
+} while (0)
+
+/*
+ * These macros parameterize elf_core_dump in fs/binfmt_elf.c to write out extra segments
+ * containing the gate DSO contents.  Dumping its contents makes post-mortem fully
+ * interpretable later without matching up the same kernel and hardware config to see what
+ * IP values meant.  Dumping its extra ELF program headers includes all the other
+ * information a debugger needs to easily find how the gate DSO was being used.
+ */
+#define ELF_CORE_EXTRA_PHDRS		(GATE_EHDR->e_phnum)
+#define ELF_CORE_WRITE_EXTRA_PHDRS						\
+do {										\
+	const struct elf_phdr *const gate_phdrs =				\
+		(const struct elf_phdr *) (GATE_ADDR + GATE_EHDR->e_phoff);	\
+	int i;									\
+	Elf64_Off ofs = 0;							\
+	for (i = 0; i < GATE_EHDR->e_phnum; ++i) {				\
+		struct elf_phdr phdr = gate_phdrs[i];				\
+		if (phdr.p_type == PT_LOAD) {					\
+			ofs = phdr.p_offset = offset;				\
+			offset += phdr.p_filesz;				\
+		} else								\
+			phdr.p_offset += ofs;					\
+		phdr.p_paddr = 0; /* match other core phdrs */			\
+		DUMP_WRITE(&phdr, sizeof(phdr));				\
+	}									\
+} while (0)
+
+#define ELF_CORE_WRITE_EXTRA_DATA					\
+do {									\
+	const struct elf_phdr *const gate_phdrs =			\
+		(const struct elf_phdr *) (GATE_ADDR			\
+					   + GATE_EHDR->e_phoff);	\
+	int i;								\
+	for (i = 0; i < GATE_EHDR->e_phnum; ++i) {			\
+		if (gate_phdrs[i].p_type == PT_LOAD)			\
+			DUMP_WRITE((void *) gate_phdrs[i].p_vaddr,	\
+				   gate_phdrs[i].p_filesz);		\
+	}								\
 } while (0)
-#endif
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/asm-ia64/ia32.h b/include/asm-ia64/ia32.h
--- a/include/asm-ia64/ia32.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-ia64/ia32.h	Wed Jun 18 23:42:09 2003
@@ -3,478 +3,19 @@
 
 #include <linux/config.h>
 
-#ifdef CONFIG_IA32_SUPPORT
-
-#include <linux/binfmts.h>
-#include <linux/compat.h>
-
-/*
- * 32 bit structures for IA32 support.
- */
-
-#define IA32_PAGE_SHIFT		12	/* 4KB pages */
-#define IA32_PAGE_SIZE		(1UL << IA32_PAGE_SHIFT)
-#define IA32_PAGE_MASK		(~(IA32_PAGE_SIZE - 1))
-#define IA32_PAGE_ALIGN(addr)	(((addr) + IA32_PAGE_SIZE - 1) & IA32_PAGE_MASK)
-#define IA32_CLOCKS_PER_SEC	100	/* Cast in stone for IA32 Linux */
-
-/* sigcontext.h */
-/*
- * As documented in the iBCS2 standard..
- *
- * The first part of "struct _fpstate" is just the
- * normal i387 hardware setup, the extra "status"
- * word is used to save the coprocessor status word
- * before entering the handler.
- */
-struct _fpreg_ia32 {
-       unsigned short significand[4];
-       unsigned short exponent;
-};
-
-struct _fpxreg_ia32 {
-        unsigned short significand[4];
-        unsigned short exponent;
-        unsigned short padding[3];
-};
-
-struct _xmmreg_ia32 {
-        unsigned int element[4];
-};
-
-
-struct _fpstate_ia32 {
-       unsigned int    cw,
-		       sw,
-		       tag,
-		       ipoff,
-		       cssel,
-		       dataoff,
-		       datasel;
-       struct _fpreg_ia32      _st[8];
-       unsigned short  status;
-       unsigned short  magic;          /* 0xffff = regular FPU data only */
-
-       /* FXSR FPU environment */
-       unsigned int         _fxsr_env[6];   /* FXSR FPU env is ignored */
-       unsigned int         mxcsr;
-       unsigned int         reserved;
-       struct _fpxreg_ia32  _fxsr_st[8];    /* FXSR FPU reg data is ignored */
-       struct _xmmreg_ia32  _xmm[8];
-       unsigned int         padding[56];
-};
-
-struct sigcontext_ia32 {
-       unsigned short gs, __gsh;
-       unsigned short fs, __fsh;
-       unsigned short es, __esh;
-       unsigned short ds, __dsh;
-       unsigned int edi;
-       unsigned int esi;
-       unsigned int ebp;
-       unsigned int esp;
-       unsigned int ebx;
-       unsigned int edx;
-       unsigned int ecx;
-       unsigned int eax;
-       unsigned int trapno;
-       unsigned int err;
-       unsigned int eip;
-       unsigned short cs, __csh;
-       unsigned int eflags;
-       unsigned int esp_at_signal;
-       unsigned short ss, __ssh;
-       unsigned int fpstate;		/* really (struct _fpstate_ia32 *) */
-       unsigned int oldmask;
-       unsigned int cr2;
-};
-
-/* user.h */
-/*
- * IA32 (Pentium III/4) FXSR, SSE support
- *
- * Provide support for the GDB 5.0+ PTRACE_{GET|SET}FPXREGS requests for
- * interacting with the FXSR-format floating point environment.  Floating
- * point data can be accessed in the regular format in the usual manner,
- * and both the standard and SIMD floating point data can be accessed via
- * the new ptrace requests.  In either case, changes to the FPU environment
- * will be reflected in the task's state as expected.
- */
-struct ia32_user_i387_struct {
-	int	cwd;
-	int	swd;
-	int	twd;
-	int	fip;
-	int	fcs;
-	int	foo;
-	int	fos;
-	int	st_space[20];	/* 8*10 bytes for each FP-reg = 80 bytes */
-};
-
-struct ia32_user_fxsr_struct {
-	unsigned short	cwd;
-	unsigned short	swd;
-	unsigned short	twd;
-	unsigned short	fop;
-	int	fip;
-	int	fcs;
-	int	foo;
-	int	fos;
-	int	mxcsr;
-	int	reserved;
-	int	st_space[32];	/* 8*16 bytes for each FP-reg = 128 bytes */
-	int	xmm_space[32];	/* 8*16 bytes for each XMM-reg = 128 bytes */
-	int	padding[56];
-};
-
-/* signal.h */
-#define IA32_SET_SA_HANDLER(ka,handler,restorer)				\
-				((ka)->sa.sa_handler = (__sighandler_t)		\
-					(((unsigned long)(restorer) << 32)	\
-					 | ((handler) & 0xffffffff)))
-#define IA32_SA_HANDLER(ka)	((unsigned long) (ka)->sa.sa_handler & 0xffffffff)
-#define IA32_SA_RESTORER(ka)	((unsigned long) (ka)->sa.sa_handler >> 32)
-
-struct sigaction32 {
-       unsigned int sa_handler;		/* Really a pointer, but need to deal with 32 bits */
-       unsigned int sa_flags;
-       unsigned int sa_restorer;	/* Another 32 bit pointer */
-       compat_sigset_t sa_mask;		/* A 32 bit mask */
-};
-
-struct old_sigaction32 {
-       unsigned int  sa_handler;	/* Really a pointer, but need to deal
-					     with 32 bits */
-       compat_old_sigset_t sa_mask;		/* A 32 bit mask */
-       unsigned int sa_flags;
-       unsigned int sa_restorer;	/* Another 32 bit pointer */
-};
-
-typedef struct sigaltstack_ia32 {
-	unsigned int	ss_sp;
-	int		ss_flags;
-	unsigned int	ss_size;
-} stack_ia32_t;
-
-struct ucontext_ia32 {
-	unsigned int	  uc_flags;
-	unsigned int	  uc_link;
-	stack_ia32_t	  uc_stack;
-	struct sigcontext_ia32 uc_mcontext;
-	sigset_t	  uc_sigmask;	/* mask last for extensibility */
-};
-
-struct stat64 {
-	unsigned short	st_dev;
-	unsigned char	__pad0[10];
-	unsigned int	__st_ino;
-	unsigned int	st_mode;
-	unsigned int	st_nlink;
-	unsigned int	st_uid;
-	unsigned int	st_gid;
-	unsigned short	st_rdev;
-	unsigned char	__pad3[10];
-	unsigned int	st_size_lo;
-	unsigned int	st_size_hi;
-	unsigned int	st_blksize;
-	unsigned int	st_blocks;	/* Number 512-byte blocks allocated. */
-	unsigned int	__pad4;		/* future possible st_blocks high bits */
-	unsigned int	st_atime;
-	unsigned int	st_atime_nsec;
-	unsigned int	st_mtime;
-	unsigned int	st_mtime_nsec;
-	unsigned int	st_ctime;
-	unsigned int	st_ctime_nsec;
-	unsigned int	st_ino_lo;
-	unsigned int	st_ino_hi;
-};
-
-typedef union sigval32 {
-	int sival_int;
-	unsigned int sival_ptr;
-} sigval_t32;
-
-typedef struct siginfo32 {
-	int si_signo;
-	int si_errno;
-	int si_code;
-
-	union {
-		int _pad[((128/sizeof(int)) - 3)];
-
-		/* kill() */
-		struct {
-			unsigned int _pid;	/* sender's pid */
-			unsigned int _uid;	/* sender's uid */
-		} _kill;
-
-		/* POSIX.1b timers */
-		struct {
-			timer_t _tid;		/* timer id */
-			int _overrun;		/* overrun count */
-			char _pad[sizeof(unsigned int) - sizeof(int)];
-			sigval_t32 _sigval;	/* same as below */
-			int _sys_private;       /* not to be passed to user */
-		} _timer;
-
-		/* POSIX.1b signals */
-		struct {
-			unsigned int _pid;	/* sender's pid */
-			unsigned int _uid;	/* sender's uid */
-			sigval_t32 _sigval;
-		} _rt;
-
-		/* SIGCHLD */
-		struct {
-			unsigned int _pid;	/* which child */
-			unsigned int _uid;	/* sender's uid */
-			int _status;		/* exit code */
-			compat_clock_t _utime;
-			compat_clock_t _stime;
-		} _sigchld;
-
-		/* SIGILL, SIGFPE, SIGSEGV, SIGBUS */
-		struct {
-			unsigned int _addr;	/* faulting insn/memory ref. */
-		} _sigfault;
-
-		/* SIGPOLL */
-		struct {
-			int _band;	/* POLL_IN, POLL_OUT, POLL_MSG */
-			int _fd;
-		} _sigpoll;
-	} _sifields;
-} siginfo_t32;
-
-struct linux32_dirent {
-	u32	d_ino;
-	u32	d_off;
-	u16	d_reclen;
-	char	d_name[256];
-};
-
-struct old_linux32_dirent {
-	u32	d_ino;
-	u32	d_offset;
-	u16	d_namlen;
-	char	d_name[1];
-};
-
-/*
- * IA-32 ELF specific definitions for IA-64.
- */
-
-#define _ASM_IA64_ELF_H		/* Don't include elf.h */
-
-#include <linux/sched.h>
-#include <asm/processor.h>
-
-/*
- * This is used to ensure we don't load something for the wrong architecture.
- */
-#define elf_check_arch(x) ((x)->e_machine == EM_386)
-
-/*
- * These are used to set parameters in the core dumps.
- */
-#define ELF_CLASS	ELFCLASS32
-#define ELF_DATA	ELFDATA2LSB
-#define ELF_ARCH	EM_386
+#include <asm/ptrace.h>
+#include <asm/signal.h>
 
-#define IA32_PAGE_OFFSET	0xc0000000
-#define IA32_STACK_TOP		IA32_PAGE_OFFSET
-
-/*
- * The system segments (GDT, TSS, LDT) have to be mapped below 4GB so the IA-32 engine can
- * access them.
- */
-#define IA32_GDT_OFFSET		(IA32_PAGE_OFFSET)
-#define IA32_TSS_OFFSET		(IA32_PAGE_OFFSET + PAGE_SIZE)
-#define IA32_LDT_OFFSET		(IA32_PAGE_OFFSET + 2*PAGE_SIZE)
-
-#define USE_ELF_CORE_DUMP
-#define ELF_EXEC_PAGESIZE	IA32_PAGE_SIZE
-
-/*
- * This is the location that an ET_DYN program is loaded if exec'ed.
- * Typical use of this is to invoke "./ld.so someprog" to test out a
- * new version of the loader.  We need to make sure that it is out of
- * the way of the program that it will "exec", and that there is
- * sufficient room for the brk.
- */
-#define ELF_ET_DYN_BASE		(IA32_PAGE_OFFSET/3 + 0x1000000)
-
-void ia64_elf32_init(struct pt_regs *regs);
-#define ELF_PLAT_INIT(_r, load_addr)	ia64_elf32_init(_r)
-
-#define elf_addr_t	u32
-
-/* ELF register definitions.  This is needed for core dump support.  */
-
-#define ELF_NGREG	128			/* XXX fix me */
-#define ELF_NFPREG	128			/* XXX fix me */
-
-typedef unsigned long elf_greg_t;
-typedef elf_greg_t elf_gregset_t[ELF_NGREG];
-
-typedef struct {
-	unsigned long w0;
-	unsigned long w1;
-} elf_fpreg_t;
-typedef elf_fpreg_t elf_fpregset_t[ELF_NFPREG];
-
-/* This macro yields a bitmask that programs can use to figure out
-   what instruction set this CPU supports.  */
-#define ELF_HWCAP	0
-
-/* This macro yields a string that ld.so will use to load
-   implementation specific libraries for optimization.  Not terribly
-   relevant until we have real hardware to play with... */
-#define ELF_PLATFORM	0
-
-#ifdef __KERNEL__
-# define SET_PERSONALITY(EX,IBCS2)				\
-	(current->personality = (IBCS2) ? PER_SVR4 : PER_LINUX)
-#endif
-
-#define IA32_EFLAG	0x200
-
-/*
- * IA-32 ELF specific definitions for IA-64.
- */
-
-#define __USER_CS      0x23
-#define __USER_DS      0x2B
-
-#define FIRST_TSS_ENTRY 6
-#define FIRST_LDT_ENTRY (FIRST_TSS_ENTRY+1)
-#define _TSS(n) ((((unsigned long) n)<<4)+(FIRST_TSS_ENTRY<<3))
-#define _LDT(n) ((((unsigned long) n)<<4)+(FIRST_LDT_ENTRY<<3))
-
-#define IA32_SEGSEL_RPL		(0x3 << 0)
-#define IA32_SEGSEL_TI		(0x1 << 2)
-#define IA32_SEGSEL_INDEX_SHIFT	3
-
-#define IA32_SEG_BASE		16
-#define IA32_SEG_TYPE		40
-#define IA32_SEG_SYS		44
-#define IA32_SEG_DPL		45
-#define IA32_SEG_P		47
-#define IA32_SEG_HIGH_LIMIT	48
-#define IA32_SEG_AVL		52
-#define IA32_SEG_DB		54
-#define IA32_SEG_G		55
-#define IA32_SEG_HIGH_BASE	56
-
-#define IA32_SEG_DESCRIPTOR(base, limit, segtype, nonsysseg, dpl, segpresent, avl, segdb, gran)	\
-	       (((limit) & 0xffff)								\
-		| (((unsigned long) (base) & 0xffffff) << IA32_SEG_BASE)			\
-		| ((unsigned long) (segtype) << IA32_SEG_TYPE)					\
-		| ((unsigned long) (nonsysseg) << IA32_SEG_SYS)					\
-		| ((unsigned long) (dpl) << IA32_SEG_DPL)					\
-		| ((unsigned long) (segpresent) << IA32_SEG_P)					\
-		| ((((unsigned long) (limit) >> 16) & 0xf) << IA32_SEG_HIGH_LIMIT)		\
-		| ((unsigned long) (avl) << IA32_SEG_AVL)					\
-		| ((unsigned long) (segdb) << IA32_SEG_DB)					\
-		| ((unsigned long) (gran) << IA32_SEG_G)					\
-		| ((((unsigned long) (base) >> 24) & 0xff) << IA32_SEG_HIGH_BASE))
-
-#define SEG_LIM		32
-#define SEG_TYPE	52
-#define SEG_SYS		56
-#define SEG_DPL		57
-#define SEG_P		59
-#define SEG_AVL		60
-#define SEG_DB		62
-#define SEG_G		63
-
-/* Unscramble an IA-32 segment descriptor into the IA-64 format.  */
-#define IA32_SEG_UNSCRAMBLE(sd)									 \
-	(   (((sd) >> IA32_SEG_BASE) & 0xffffff) | ((((sd) >> IA32_SEG_HIGH_BASE) & 0xff) << 24) \
-	 | ((((sd) & 0xffff) | ((((sd) >> IA32_SEG_HIGH_LIMIT) & 0xf) << 16)) << SEG_LIM)	 \
-	 | ((((sd) >> IA32_SEG_TYPE) & 0xf) << SEG_TYPE)					 \
-	 | ((((sd) >> IA32_SEG_SYS) & 0x1) << SEG_SYS)						 \
-	 | ((((sd) >> IA32_SEG_DPL) & 0x3) << SEG_DPL)						 \
-	 | ((((sd) >> IA32_SEG_P) & 0x1) << SEG_P)						 \
-	 | ((((sd) >> IA32_SEG_AVL) & 0x1) << SEG_AVL)						 \
-	 | ((((sd) >> IA32_SEG_DB) & 0x1) << SEG_DB)						 \
-	 | ((((sd) >> IA32_SEG_G) & 0x1) << SEG_G))
-
-#define IA32_IOBASE	0x2000000000000000 /* Virtual address for I/O space */
-
-#define IA32_CR0	0x80000001	/* Enable PG and PE bits */
-#define IA32_CR4	0x600		/* MMXEX and FXSR on */
-
-/*
- *  IA32 floating point control registers starting values
- */
-
-#define IA32_FSR_DEFAULT	0x55550000		/* set all tag bits */
-#define IA32_FCR_DEFAULT	0x17800000037fUL	/* extended precision, all masks */
-
-#define IA32_PTRACE_GETREGS	12
-#define IA32_PTRACE_SETREGS	13
-#define IA32_PTRACE_GETFPREGS	14
-#define IA32_PTRACE_SETFPREGS	15
-#define IA32_PTRACE_GETFPXREGS	18
-#define IA32_PTRACE_SETFPXREGS	19
-
-#define ia32_start_thread(regs,new_ip,new_sp) do {				\
-	set_fs(USER_DS);							\
-	ia64_psr(regs)->cpl = 3;	/* set user mode */			\
-	ia64_psr(regs)->ri = 0;		/* clear return slot number */		\
-	ia64_psr(regs)->is = 1;		/* IA-32 instruction set */		\
-	regs->cr_iip = new_ip;							\
-	regs->ar_rsc = 0xc;		/* enforced lazy mode, priv. level 3 */	\
-	regs->ar_rnat = 0;							\
-	regs->loadrs = 0;							\
-	regs->r12 = new_sp;							\
-} while (0)
-
-/*
- * Local Descriptor Table (LDT) related declarations.
- */
-
-#define IA32_LDT_ENTRIES	8192		/* Maximum number of LDT entries supported. */
-#define IA32_LDT_ENTRY_SIZE	8		/* The size of each LDT entry. */
-
-struct ia32_modify_ldt_ldt_s {
-	unsigned int entry_number;
-	unsigned int base_addr;
-	unsigned int limit;
-	unsigned int seg_32bit:1;
-	unsigned int contents:2;
-	unsigned int read_exec_only:1;
-	unsigned int limit_in_pages:1;
-	unsigned int seg_not_present:1;
-	unsigned int useable:1;
-};
-
-struct linux_binprm;
+#ifdef CONFIG_IA32_SUPPORT
 
+extern void ia32_cpu_init (void);
 extern void ia32_gdt_init (void);
-extern void ia32_init_addr_space (struct pt_regs *regs);
-extern int ia32_setup_arg_pages (struct linux_binprm *bprm);
 extern int ia32_exception (struct pt_regs *regs, unsigned long isr);
 extern int ia32_intercept (struct pt_regs *regs, unsigned long isr);
-extern unsigned long ia32_do_mmap (struct file *, unsigned long, unsigned long, int, int, loff_t);
-extern void ia32_load_segment_descriptors (struct task_struct *task);
-
-#define ia32f2ia64f(dst,src) \
-	do { \
-	register double f6 asm ("f6"); \
-	asm volatile ("ldfe f6=[%2];; stf.spill [%1]=f6" : "=f"(f6): "r"(dst), "r"(src) : "memory"); \
-	} while(0)
-
-#define ia64f2ia32f(dst,src) \
-	do { \
-	register double f6 asm ("f6"); \
-	asm volatile ("ldf.fill f6=[%2];; stfe [%1]=f6" : "=f"(f6): "r"(dst),  "r"(src) : "memory"); \
-	} while(0)
 
 #endif /* !CONFIG_IA32_SUPPORT */
 
-/* Declare this uncondiontally, so we don't get warnings for unreachable code.  */
+/* Declare this unconditionally, so we don't get warnings for unreachable code.  */
 extern int ia32_setup_frame1 (int sig, struct k_sigaction *ka, siginfo_t *info,
 			      sigset_t *set, struct pt_regs *regs);
 
diff -Nru a/include/asm-ia64/io.h b/include/asm-ia64/io.h
--- a/include/asm-ia64/io.h	Wed Jun 18 23:42:05 2003
+++ b/include/asm-ia64/io.h	Wed Jun 18 23:42:05 2003
@@ -413,4 +413,17 @@
 
 # endif /* __KERNEL__ */
 
+/*
+ * It makes no sense at all to have this BIO_VMERGE_BOUNDARY macro here.  Should be
+ * replaced by dma_merge_mask() or something of that sort.  Note: the only way
+ * BIO_VMERGE_BOUNDARY is used is to mask off bits.  Effectively, our definition gets
+ * expanded into:
+ *
+ *	addr & ((ia64_max_iommu_merge_mask + 1) - 1) == (addr & ia64_max_iommu_vmerge_mask)
+ *
+ * which is precisely what we want.
+ */
+extern unsigned long ia64_max_iommu_merge_mask;
+#define BIO_VMERGE_BOUNDARY	(ia64_max_iommu_merge_mask + 1)
+
 #endif /* _ASM_IA64_IO_H */
diff -Nru a/include/asm-ia64/ioctl32.h b/include/asm-ia64/ioctl32.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ia64/ioctl32.h	Wed Jun 18 23:42:09 2003
@@ -0,0 +1 @@
+#include <linux/ioctl32.h>
diff -Nru a/include/asm-ia64/kregs.h b/include/asm-ia64/kregs.h
--- a/include/asm-ia64/kregs.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/kregs.h	Wed Jun 18 23:42:06 2003
@@ -72,7 +72,7 @@
 #define IA64_PSR_BITS_TO_CLEAR	(IA64_PSR_MFL | IA64_PSR_MFH | IA64_PSR_DB | IA64_PSR_LP | \
 				 IA64_PSR_TB  | IA64_PSR_ID  | IA64_PSR_DA | IA64_PSR_DD | \
 				 IA64_PSR_SS  | IA64_PSR_ED  | IA64_PSR_IA)
-#define IA64_PSR_BITS_TO_SET	(IA64_PSR_DFH)
+#define IA64_PSR_BITS_TO_SET	(IA64_PSR_DFH | IA64_PSR_SP)
 
 #define IA64_PSR_BE	(__IA64_UL(1) << IA64_PSR_BE_BIT)
 #define IA64_PSR_UP	(__IA64_UL(1) << IA64_PSR_UP_BIT)
diff -Nru a/include/asm-ia64/machvec.h b/include/asm-ia64/machvec.h
--- a/include/asm-ia64/machvec.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/machvec.h	Wed Jun 18 23:42:07 2003
@@ -74,8 +74,6 @@
 #  include <asm/machvec_dig.h>
 # elif defined (CONFIG_IA64_HP_ZX1)
 #  include <asm/machvec_hpzx1.h>
-# elif defined (CONFIG_IA64_SGI_SN1)
-#  include <asm/machvec_sn1.h>
 # elif defined (CONFIG_IA64_SGI_SN2)
 #  include <asm/machvec_sn2.h>
 # elif defined (CONFIG_IA64_GENERIC)
diff -Nru a/include/asm-ia64/mca.h b/include/asm-ia64/mca.h
--- a/include/asm-ia64/mca.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/mca.h	Wed Jun 18 23:42:06 2003
@@ -92,6 +92,8 @@
 	u64		imsto_sal_check_ra;	/* Return address in SAL_CHECK while going
 						 * back to SAL from OS after MCA handling.
 						 */
+	u64		pal_min_state;		/* from PAL in r17 */
+	u64		proc_state_param;	/* from PAL in r18. See SDV 2:268 11.3.2.1 */
 } ia64_mca_sal_to_os_state_t;
 
 enum {
diff -Nru a/include/asm-ia64/mca_asm.h b/include/asm-ia64/mca_asm.h
--- a/include/asm-ia64/mca_asm.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-ia64/mca_asm.h	Wed Jun 18 23:42:09 2003
@@ -35,7 +35,7 @@
  *	1. Lop off bits 61 thru 63 in the virtual address
  */
 #define DATA_VA_TO_PA(addr)							\
-	dep	addr	= 0, addr, 61, 3
+	tpa	addr	= addr
 /*
  * This macro converts a data physical address to a virtual address
  * Right now for simulation purposes the virtual addresses are
diff -Nru a/include/asm-ia64/nodedata.h b/include/asm-ia64/nodedata.h
--- a/include/asm-ia64/nodedata.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/nodedata.h	Wed Jun 18 23:42:08 2003
@@ -22,6 +22,7 @@
 
 struct pglist_data;
 struct ia64_node_data {
+	short			active_cpu_count;
 	short			node;
         struct pglist_data	*pg_data_ptrs[NR_NODES];
 	struct page		*bank_mem_map_base[NR_BANKS];
diff -Nru a/include/asm-ia64/page.h b/include/asm-ia64/page.h
--- a/include/asm-ia64/page.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/page.h	Wed Jun 18 23:42:06 2003
@@ -33,6 +33,8 @@
 #define PERCPU_PAGE_SHIFT	16	/* log2() of max. size of per-CPU area */
 #define PERCPU_PAGE_SIZE	(__IA64_UL_CONST(1) << PERCPU_PAGE_SHIFT)
 
+#define RGN_MAP_LIMIT	((1UL << (4*PAGE_SHIFT - 12)) - PAGE_SIZE)	/* per region addr limit */
+
 #ifdef CONFIG_HUGETLB_PAGE
 
 # if defined(CONFIG_HUGETLB_PAGE_SIZE_4GB)
@@ -60,6 +62,7 @@
 # define HPAGE_SIZE	(__IA64_UL_CONST(1) << HPAGE_SHIFT)
 # define HPAGE_MASK	(~(HPAGE_SIZE - 1))
 # define HAVE_ARCH_HUGETLB_UNMAPPED_AREA
+# define ARCH_HAS_VALID_HUGEPAGE_RANGE
 #endif /* CONFIG_HUGETLB_PAGE */
 
 #ifdef __ASSEMBLY__
@@ -131,9 +134,7 @@
 # define htlbpage_to_page(x)	((REGION_NUMBER(x) << 61)				\
 				 | (REGION_OFFSET(x) >> (HPAGE_SHIFT-PAGE_SHIFT)))
 # define HUGETLB_PAGE_ORDER	(HPAGE_SHIFT - PAGE_SHIFT)
-extern int  is_invalid_hugepage_range(unsigned long addr, unsigned long len);
-#else
-#define is_invalid_hugepage_range(addr, len) 0
+extern int  check_valid_hugepage_range(unsigned long addr, unsigned long len);
 #endif
 
 static __inline__ int
diff -Nru a/include/asm-ia64/patch.h b/include/asm-ia64/patch.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ia64/patch.h	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,25 @@
+#ifndef _ASM_IA64_PATCH_H
+#define _ASM_IA64_PATCH_H
+
+/*
+ * Copyright (C) 2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
+ *
+ * There are a number of reasons for patching instructions.  Rather than duplicating code
+ * all over the place, we put the common stuff here.  Reasons for patching: in-kernel
+ * module-loader, virtual-to-physical patch-list, McKinley Errata 9 workaround, and gate
+ * shared library.  Undoubtedly, some of these reasons will disappear and others will
+ * be added over time.
+ */
+#include <linux/elf.h>
+#include <linux/types.h>
+
+extern void ia64_patch (u64 insn_addr, u64 mask, u64 val);	/* patch any insn slot */
+extern void ia64_patch_imm64 (u64 insn_addr, u64 val);		/* patch "movl" w/abs. value*/
+extern void ia64_patch_imm60 (u64 insn_addr, u64 val);		/* patch "brl" w/ip-rel value */
+
+extern void ia64_patch_mckinley_e9 (unsigned long start, unsigned long end);
+extern void ia64_patch_vtop (unsigned long start, unsigned long end);
+extern void ia64_patch_gate (void);
+
+#endif /* _ASM_IA64_PATCH_H */
diff -Nru a/include/asm-ia64/pci.h b/include/asm-ia64/pci.h
--- a/include/asm-ia64/pci.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-ia64/pci.h	Wed Jun 18 23:42:09 2003
@@ -26,11 +26,19 @@
 struct pci_dev;
 
 /*
- * The PCI address space does equal the physical memory address space.
- * The networking and block device layers use this boolean for bounce
- * buffer decisions.
+ * PCI_DMA_BUS_IS_PHYS should be set to 1 if there is _necessarily_ a direct correspondence
+ * between device bus addresses and CPU physical addresses.  Platforms with a hardware I/O
+ * MMU _must_ turn this off to suppress the bounce buffer handling code in the block and
+ * network device layers.  Platforms with separate bus address spaces _must_ turn this off
+ * and provide a device DMA mapping implementation that takes care of the necessary
+ * address translation.
+ *
+ * For now, the ia64 platforms which may have separate/multiple bus address spaces all
+ * have I/O MMUs which support the merging of physically discontiguous buffers, so we can
+ * use that as the sole factor to determine the setting of PCI_DMA_BUS_IS_PHYS.
  */
-#define PCI_DMA_BUS_IS_PHYS	(1)
+extern unsigned long ia64_max_iommu_merge_mask;
+#define PCI_DMA_BUS_IS_PHYS	(ia64_max_iommu_merge_mask == ~0UL)
 
 static inline void
 pcibios_set_master (struct pci_dev *dev)
diff -Nru a/include/asm-ia64/perfmon.h b/include/asm-ia64/perfmon.h
--- a/include/asm-ia64/perfmon.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/perfmon.h	Wed Jun 18 23:42:07 2003
@@ -14,20 +14,21 @@
 #define PFM_READ_PMDS		0x03
 #define PFM_STOP		0x04
 #define PFM_START		0x05
-#define PFM_ENABLE		0x06
-#define PFM_DISABLE		0x07
+#define PFM_ENABLE		0x06 /* obsolete */
+#define PFM_DISABLE		0x07 /* obsolete */
 #define PFM_CREATE_CONTEXT	0x08
-#define PFM_DESTROY_CONTEXT	0x09
+#define PFM_DESTROY_CONTEXT	0x09 /* obsolete use close() */
 #define PFM_RESTART		0x0a
-#define PFM_PROTECT_CONTEXT	0x0b
+#define PFM_PROTECT_CONTEXT	0x0b /* obsolete */
 #define PFM_GET_FEATURES	0x0c
 #define PFM_DEBUG		0x0d
-#define PFM_UNPROTECT_CONTEXT	0x0e
+#define PFM_UNPROTECT_CONTEXT	0x0e /* obsolete */
 #define PFM_GET_PMC_RESET_VAL	0x0f
-
+#define PFM_LOAD_CONTEXT	0x10
+#define PFM_UNLOAD_CONTEXT	0x11
 
 /*
- * CPU model specific commands (may not be supported on all models)
+ * PMU model specific commands (may not be supported on all PMU models)
  */
 #define PFM_WRITE_IBRS		0x20
 #define PFM_WRITE_DBRS		0x21
@@ -35,19 +36,21 @@
 /*
  * context flags
  */
-#define PFM_FL_INHERIT_NONE	 0x00	/* never inherit a context across fork (default) */
-#define PFM_FL_INHERIT_ONCE	 0x01	/* clone pfm_context only once across fork() */
-#define PFM_FL_INHERIT_ALL	 0x02	/* always clone pfm_context across fork() */
-#define PFM_FL_NOTIFY_BLOCK    	 0x04	/* block task on user level notifications */
-#define PFM_FL_SYSTEM_WIDE	 0x08	/* create a system wide context */
-#define PFM_FL_EXCL_IDLE         0x20   /* exclude idle task from system wide session */
-#define PFM_FL_UNSECURE		 0x40   /* allow unsecure monitoring for non self-monitoring task */
+#define PFM_FL_NOTIFY_BLOCK    	 0x01	/* block task on user level notifications */
+#define PFM_FL_SYSTEM_WIDE	 0x02	/* create a system wide context */
+#define PFM_FL_UNSECURE		 0x04   /* allow unsecure monitoring for non self-monitoring task */
+#define PFM_FL_OVFL_NO_MSG	 0x80   /* do not post overflow/end messages for notification */
+
+/*
+ * event set flags
+ */
+#define PFM_SETFL_EXCL_IDLE      0x01   /* exclude idle task (syswide only) XXX: DO NOT USE YET */
 
 /*
  * PMC flags
  */
 #define PFM_REGFL_OVFL_NOTIFY	0x1	/* send notification on overflow */
-#define PFM_REGFL_RANDOM	0x2	/* randomize sampling periods    */
+#define PFM_REGFL_RANDOM	0x2	/* randomize sampling interval   */
 
 /*
  * PMD/PMC/IBR/DBR return flags (ignored on input)
@@ -55,150 +58,196 @@
  * Those flags are used on output and must be checked in case EAGAIN is returned
  * by any of the calls using a pfarg_reg_t or pfarg_dbreg_t structure.
  */
-#define PFM_REG_RETFL_NOTAVAIL	(1U<<31) /* set if register is implemented but not available */
-#define PFM_REG_RETFL_EINVAL	(1U<<30) /* set if register entry is invalid */
+#define PFM_REG_RETFL_NOTAVAIL	(1UL<<31) /* set if register is implemented but not available */
+#define PFM_REG_RETFL_EINVAL	(1UL<<30) /* set if register entry is invalid */
 #define PFM_REG_RETFL_MASK	(PFM_REG_RETFL_NOTAVAIL|PFM_REG_RETFL_EINVAL)
 
 #define PFM_REG_HAS_ERROR(flag)	(((flag) & PFM_REG_RETFL_MASK) != 0)
 
+typedef unsigned char pfm_uuid_t[16];	/* custom sampling buffer identifier type */
+
 /*
  * Request structure used to define a context
  */
 typedef struct {
-	unsigned long ctx_smpl_entries;	/* how many entries in sampling buffer */
-	unsigned long ctx_smpl_regs[4];	/* which pmds to record on overflow */
-
-	pid_t	      ctx_notify_pid;	/* which process to notify on overflow */
-	int	      ctx_flags;	/* noblock/block, inherit flags */
-	void	      *ctx_smpl_vaddr;	/* returns address of BTB buffer */
-
-	unsigned long ctx_cpu_mask;	/* on which CPU to enable perfmon (systemwide) */
-
-	unsigned long reserved[8];	/* for future use */
+	pfm_uuid_t    ctx_smpl_buf_id;	/* which buffer format to use (if needed) */
+	unsigned long ctx_flags;	/* noblock/block */
+	unsigned int  ctx_nextra_sets;	/* number of extra event sets (you always get 1) */
+	int	      ctx_fd;		/* return arg: unique identification for context */
+	void	      *ctx_smpl_vaddr;	/* return arg: virtual address of sampling buffer, is used */
+	unsigned long ctx_reserved[11];	/* for future use */
 } pfarg_context_t;
 
 /*
  * Request structure used to write/read a PMC or PMD
  */
 typedef struct {
-	unsigned int	reg_num;	/* which register */
-	unsigned int	reg_flags;	/* PMC: notify/don't notify. PMD/PMC: return flags */
-	unsigned long	reg_value;	/* configuration (PMC) or initial value (PMD) */
-
-	unsigned long	reg_long_reset;	/* reset after sampling buffer overflow (large) */
-	unsigned long	reg_short_reset;/* reset after counter overflow (small) */
-
-	unsigned long	reg_reset_pmds[4];   /* which other counters to reset on overflow */
-	unsigned long	reg_random_seed;     /* seed value when randomization is used */
-	unsigned long	reg_random_mask;     /* bitmask used to limit random value */
-	unsigned long	reg_last_reset_value;/* last value used to reset the PMD (PFM_READ_PMDS) */
+	unsigned int	reg_num;	   /* which register                             */
+	unsigned int	reg_set;	   /* event set for this register                */
+
+	unsigned long	reg_value;	   /* initial pmc/pmd value                      */
+	unsigned long	reg_flags;	   /* input: pmc/pmd flags, return: reg error    */
 
-	unsigned long   reserved[13];	/* for future use */
+	unsigned long	reg_long_reset;	   /* reset after buffer overflow notification   */
+	unsigned long	reg_short_reset;   /* reset after counter overflow               */
+
+	unsigned long	reg_reset_pmds[4]; /* which other counters to reset on overflow  */
+	unsigned long	reg_random_seed;   /* seed value when randomization is used      */
+	unsigned long	reg_random_mask;   /* bitmask used to limit random value         */
+	unsigned long   reg_last_reset_val;/* return: PMD last reset value               */
+
+	unsigned long	reg_smpl_pmds[4];  /* which pmds are accessed when PMC overflows */
+	unsigned long	reg_smpl_eventid;  /* opaque sampling event identifier           */
+
+	unsigned long   reserved[3];	   /* for future use                             */
 } pfarg_reg_t;
 
 typedef struct {
-	unsigned int	dbreg_num;	/* which register */
-	unsigned int	dbreg_flags;	/* dbregs return flags */
-	unsigned long	dbreg_value;	/* configuration (PMC) or initial value (PMD) */
-	unsigned long	reserved[6];
+	unsigned int	dbreg_num;		/* which debug register        */
+	unsigned int 	dbreg_set;		/* event set for this register */
+	unsigned long	dbreg_value;		/* value for debug register    */
+	unsigned long	dbreg_flags;		/* return: dbreg error         */
+	unsigned long	dbreg_reserved[1];	/* for future use              */
 } pfarg_dbreg_t;
 
-typedef struct {			
+typedef struct {
 	unsigned int	ft_version;	/* perfmon: major [16-31], minor [0-15] */
-	unsigned int	ft_smpl_version;/* sampling format: major [16-31], minor [0-15] */
-	unsigned long	reserved[4];	/* for future use */
+	unsigned int	ft_reserved;	/* reserved for future use              */
+	unsigned long	reserved[4];	/* for future use                       */
 } pfarg_features_t;
 
-/*
- * This header is at the beginning of the sampling buffer returned to the user.
- * It is exported as Read-Only at this point. It is directly followed by the
- * first record.
- */
 typedef struct {
-	unsigned int	hdr_version;		/* contains perfmon version (smpl format diffs) */
-	unsigned int	reserved;
-	unsigned long	hdr_entry_size;		/* size of one entry in bytes */
-	unsigned long	hdr_count;		/* how many valid entries */
-	unsigned long	hdr_pmds[4];		/* which pmds are recorded */
-} perfmon_smpl_hdr_t;
+	pid_t		load_pid;	  /* process to load the context into */
+	unsigned int	load_set;	  /* first event set to load          */
+	unsigned long	load_reserved[2]; /* for future use                   */
+} pfarg_load_t;
+
+typedef struct {
+	int		msg_type;		/* generic message header */
+	int		msg_ctx_fd;		/* generic message header */
+	unsigned long	msg_tstamp;		/* for perf tuning */
+	unsigned int	msg_active_set;		/* active set at the time of overflow */
+	unsigned long	msg_ovfl_pmds[4];	/* which PMDs overflowed */
+} pfm_ovfl_msg_t;
+
+typedef struct {
+	int		msg_type;		/* generic message header */
+	int		msg_ctx_fd;		/* generic message header */
+	unsigned long	msg_tstamp;		/* for perf tuning */
+} pfm_end_msg_t;
+
+typedef struct {
+	int		msg_type;		/* type of the message */
+	int		msg_ctx_fd;		/* unique identifier for the context */
+	unsigned long	msg_tstamp;		/* for perf tuning */
+} pfm_gen_msg_t;
+
+#define PFM_MSG_OVFL	1	/* an overflow happened */
+#define PFM_MSG_END	2	/* task to which context was attached ended */
+
+typedef union {
+	pfm_ovfl_msg_t	pfm_ovfl_msg;
+	pfm_end_msg_t	pfm_end_msg;
+	pfm_gen_msg_t	pfm_gen_msg;
+} pfm_msg_t;
 
 /*
  * Define the version numbers for both perfmon as a whole and the sampling buffer format.
  */
-#define PFM_VERSION_MAJ		1U
-#define PFM_VERSION_MIN		4U
-#define PFM_VERSION		(((PFM_VERSION_MAJ&0xffff)<<16)|(PFM_VERSION_MIN & 0xffff))
-
-#define PFM_SMPL_VERSION_MAJ	1U
-#define PFM_SMPL_VERSION_MIN	0U
-#define PFM_SMPL_VERSION	(((PFM_SMPL_VERSION_MAJ&0xffff)<<16)|(PFM_SMPL_VERSION_MIN & 0xffff))
+#define PFM_VERSION_MAJ		 2U
+#define PFM_VERSION_MIN		 0U
+#define PFM_SMPL_HDR_VERSION_MAJ 2U
+#define PFM_SMPL_HDR_VERSION_MIN 0U
+#define PFM_VERSION		 (((PFM_VERSION_MAJ&0xffff)<<16)|(PFM_VERSION_MIN & 0xffff))
+#define PFM_VERSION_MAJOR(x)	 (((x)>>16) & 0xffff)
+#define PFM_VERSION_MINOR(x)	 ((x) & 0xffff)
 
 
-#define PFM_VERSION_MAJOR(x)	(((x)>>16) & 0xffff)
-#define PFM_VERSION_MINOR(x)	((x) & 0xffff)
-
 /*
- * Entry header in the sampling buffer.  The header is directly followed
- * with the PMDs saved in increasing index order: PMD4, PMD5, .... How
- * many PMDs are present is determined by the user program during
- * context creation.
- *
- * XXX: in this version of the entry, only up to 64 registers can be
- * recorded. This should be enough for quite some time. Always check
- * sampling format before parsing entries!
- *
- * In the case where multiple counters overflow at the same time, the
- * last_reset_value member indicates the initial value of the PMD with
- * the smallest index.  For instance, if PMD2 and PMD5 have overflowed,
- * the last_reset_value member contains the initial value of PMD2.
- */
-typedef struct {
-	int		pid;			/* identification of process */
-	int		cpu;			/* which cpu was used */
-	unsigned long	last_reset_value;	/* initial value of counter that overflowed */
-	unsigned long	stamp;			/* timestamp */
-	unsigned long	ip;			/* where did the overflow interrupt happened */
-	unsigned long	regs;			/* bitmask of which registers overflowed */
-	unsigned long   reserved;		/* unused */
-} perfmon_smpl_entry_t;
-
-extern long perfmonctl(pid_t pid, int cmd, void *arg, int narg);
+ * miscellaneous architected definitions
+ */
+#define PMU_FIRST_COUNTER	4	/* first counting monitor (PMC/PMD) */
+#define PMU_MAX_PMCS		256	/* maximum architected number of PMC registers */
+#define PMU_MAX_PMDS		256	/* maximum architected number of PMD registers */
 
 #ifdef __KERNEL__
 
-typedef struct {
-	void (*handler)(int irq, void *arg, struct pt_regs *regs);
-} pfm_intr_handler_desc_t;
+extern long perfmonctl(int fd, int cmd, void *arg, int narg);
 
 extern void pfm_save_regs (struct task_struct *);
 extern void pfm_load_regs (struct task_struct *);
 
-extern int  pfm_inherit (struct task_struct *, struct pt_regs *);
-extern void pfm_context_exit (struct task_struct *);
-extern void pfm_flush_regs (struct task_struct *);
-extern void pfm_cleanup_notifiers (struct task_struct *);
-extern void pfm_cleanup_owners (struct task_struct *);
+extern void pfm_exit_thread(struct task_struct *);
 extern int  pfm_use_debug_registers(struct task_struct *);
 extern int  pfm_release_debug_registers(struct task_struct *);
-extern int  pfm_cleanup_smpl_buf(struct task_struct *);
 extern void pfm_syst_wide_update_task(struct task_struct *, unsigned long info, int is_ctxswin);
-extern void pfm_ovfl_block_reset(void);
+extern void pfm_inherit(struct task_struct *task, struct pt_regs *regs);
 extern void pfm_init_percpu(void);
+extern void pfm_handle_work(void);
+
+/*
+ * Reset PMD register flags
+ */
+#define PFM_PMD_NO_RESET	0
+#define PFM_PMD_LONG_RESET	1
+#define PFM_PMD_SHORT_RESET	2
+
+typedef struct {
+	unsigned int notify_user:1;	/* notify user program of overflow                           */
+	unsigned int reset_pmds :2;	/* PFM_PMD_NO_RESET, PFM_PMD_LONG_RESET, PFM_PMD_SHORT_RESET */
+	unsigned int block:1;		/* block monitored task on kernel exit                       */
+	unsigned int stop_monitoring:1; /* will mask monitoring via PMCx.plm                         */
+	unsigned int reserved:26;	/* for future use                                            */
+} pfm_ovfl_ctrl_t;
 
-/* 
- * hooks to allow VTune/Prospect to cooperate with perfmon.
- * (reserved for system wide monitoring modules only)
+typedef struct {
+	unsigned long   ovfl_pmds[4];	/* bitmask of overflowed pmds                            */
+	unsigned long   ovfl_notify[4];	/* bitmask of overflow pmds which asked for notification */
+	unsigned long   pmd_value;	/* current 64-bit value of 1st pmd which overflowed      */
+	unsigned long   pmd_last_reset;	/* last reset value of 1st pmd which overflowed          */
+	unsigned long	pmd_eventid;	/* eventid associated with 1st pmd which overflowed      */
+	unsigned int    active_set;	/* event set active at the time of the overflow          */
+	unsigned int    reserved1;
+	unsigned long	smpl_pmds[4];
+	unsigned long   smpl_pmds_values[PMU_MAX_PMDS];
+	pfm_ovfl_ctrl_t ovfl_ctrl;	/* return: perfmon controls to set by handler            */
+} pfm_ovfl_arg_t;
+
+
+typedef struct _pfm_buffer_fmt_t {
+	char		*fmt_name;
+	pfm_uuid_t	fmt_uuid;
+	size_t		fmt_arg_size;
+	unsigned long	fmt_flags;
+
+	int		(*fmt_validate)(struct task_struct *task, unsigned int flags, int cpu, void *arg);
+	int		(*fmt_getsize)(struct task_struct *task, unsigned int flags, int cpu, void *arg, unsigned long *size);
+	int 		(*fmt_init)(struct task_struct *task, void *buf, unsigned int flags, int cpu, void *arg);
+	int		(*fmt_handler)(struct task_struct *task, void *buf, pfm_ovfl_arg_t *arg, struct pt_regs *regs);
+	int		(*fmt_restart)(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs);
+	int		(*fmt_restart_active)(struct task_struct *task, pfm_ovfl_ctrl_t *ctrl, void *buf, struct pt_regs *regs);
+	int		(*fmt_exit)(struct task_struct *task, void *buf, struct pt_regs *regs);
+
+	struct _pfm_buffer_fmt_t *fmt_next;
+	struct _pfm_buffer_fmt_t *fmt_prev;
+} pfm_buffer_fmt_t;
+
+extern int pfm_register_buffer_fmt(pfm_buffer_fmt_t *fmt);
+extern int pfm_unregister_buffer_fmt(pfm_uuid_t uuid);
+
+/*
+ * perfmon interface exported to modules
  */
-extern int pfm_install_alternate_syswide_subsystem(pfm_intr_handler_desc_t *h);
-extern int pfm_remove_alternate_syswide_subsystem(pfm_intr_handler_desc_t *h);
+extern long pfm_mod_fast_read_pmds(struct task_struct *, unsigned long mask[4], unsigned long *addr, struct pt_regs *regs);
+extern long pfm_mod_read_pmds(struct task_struct *, pfarg_reg_t *req, unsigned int nreq, struct pt_regs *regs);
+extern long pfm_mod_write_pmcs(struct task_struct *, pfarg_reg_t *req, unsigned int nreq, struct pt_regs *regs);
 
 /*
  * describe the content of the local_cpu_date->pfm_syst_info field
  */
-#define PFM_CPUINFO_SYST_WIDE	0x1	/* if set a system wide session exist */
+#define PFM_CPUINFO_SYST_WIDE	0x1	/* if set a system wide session exists */
 #define PFM_CPUINFO_DCR_PP	0x2	/* if set the system wide session has started */
 #define PFM_CPUINFO_EXCL_IDLE	0x4	/* the system wide session excludes the idle task */
-
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/asm-ia64/perfmon_default_smpl.h b/include/asm-ia64/perfmon_default_smpl.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ia64/perfmon_default_smpl.h	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,81 @@
+/*
+ * Copyright (C) 2002-2003 Hewlett-Packard Co
+ *               Stephane Eranian <eranian@hpl.hp.com>
+ *
+ * This file implements the default sampling buffer format
+ * for Linux/ia64 perfmon subsystem.
+ */
+#ifndef __PERFMON_DEFAULT_SMPL_H__
+#define __PERFMON_DEFAULT_SMPL_H__ 1
+
+#define PFM_DEFAULT_SMPL_UUID { \
+		0x4d, 0x72, 0xbe, 0xc0, 0x06, 0x64, 0x41, 0x43, 0x82, 0xb4, 0xd3, 0xfd, 0x27, 0x24, 0x3c, 0x97}
+
+/*
+ * format specific parameters (passed at context creation)
+ */
+typedef struct {
+	unsigned long buf_size;		/* size of the buffer in bytes */
+	unsigned long reserved[3];	/* for future use */
+} pfm_default_smpl_arg_t;
+
+/*
+ * combined context+format specific structure. Can be passed
+ * to PFM_CONTEXT_CREATE
+ */
+typedef struct {
+	pfarg_context_t		ctx_arg;
+	pfm_default_smpl_arg_t	buf_arg;
+} pfm_default_smpl_ctx_arg_t;
+
+/*
+ * This header is at the beginning of the sampling buffer returned to the user.
+ * It is directly followed by the first record.
+ */
+typedef struct {
+	unsigned long	hdr_count;		/* how many valid entries */
+	void		*hdr_cur_pos;		/* current position in the buffer */
+	void		*hdr_last_pos;		/* first byte beyond buffer */
+
+	unsigned long	hdr_overflows;		/* how many times the buffer overflowed */
+	unsigned long   hdr_buf_size;		/* how many bytes in the buffer */
+	unsigned int	hdr_version;		/* contains perfmon version (smpl format diffs) */
+	unsigned int	hdr_reserved1;		/* for future use */
+	unsigned long	hdr_reserved[10];	/* for future use */
+} pfm_default_smpl_hdr_t;
+
+/*
+ * Entry header in the sampling buffer.  The header is directly followed
+ * with the PMDs saved in increasing index order: PMD4, PMD5, .... How
+ * many PMDs are present depends on how the session was programmed.
+ *
+ * XXX: in this version of the entry, only up to 64 registers can be
+ * recorded. This should be enough for quite some time. Always check
+ * sampling format before parsing entries!
+ *
+ * In the case where multiple counters overflow at the same time, the
+ * last_reset_value member indicates the initial value of the
+ * overflowed PMD with the smallest index.  For instance, if PMD2 and
+ * PMD5 have overflowed, the last_reset_value member contains the
+ * initial value of PMD2.
+ */
+typedef struct {
+	int		pid;			/* current process at PMU interrupt point */
+	int		cpu;			/* cpu on which the overfow occured */
+	unsigned long	last_reset_val;		/* initial value of 1st overflowed PMD */
+	unsigned long	ip;			/* where did the overflow interrupt happened */
+	unsigned long	ovfl_pmds;		/* which PMDS registers overflowed (64 max) */
+	unsigned long   tstamp;			/* ar.itc on the CPU that took the overflow */
+	unsigned int	set;			/* event set active when overflow ocurred   */
+	unsigned int	reserved1;		/* for future use */
+} pfm_default_smpl_entry_t;
+
+#define PFM_DEFAULT_MAX_PMDS		64 /* how many pmds supported by data structures (sizeof(unsigned long) */
+#define PFM_DEFAULT_MAX_ENTRY_SIZE	(sizeof(pfm_default_smpl_entry_t)+(sizeof(unsigned long)*PFM_DEFAULT_MAX_PMDS))
+#define PFM_DEFAULT_SMPL_MIN_BUF_SIZE	(sizeof(pfm_default_smpl_hdr_t)+PFM_DEFAULT_MAX_ENTRY_SIZE)
+
+#define PFM_DEFAULT_SMPL_VERSION_MAJ	2U
+#define PFM_DEFAULT_SMPL_VERSION_MIN	0U
+#define PFM_DEFAULT_SMPL_VERSION	(((PFM_DEFAULT_SMPL_VERSION_MAJ&0xffff)<<16)|(PFM_DEFAULT_SMPL_VERSION_MIN & 0xffff))
+
+#endif /* __PERFMON_DEFAULT_SMPL_H__ */
diff -Nru a/include/asm-ia64/pgalloc.h b/include/asm-ia64/pgalloc.h
--- a/include/asm-ia64/pgalloc.h	Wed Jun 18 23:42:05 2003
+++ b/include/asm-ia64/pgalloc.h	Wed Jun 18 23:42:05 2003
@@ -158,29 +158,4 @@
 
 extern void check_pgt_cache (void);
 
-/*
- * IA-64 doesn't have any external MMU info: the page tables contain all the necessary
- * information.  However, we use this macro to take care of any (delayed) i-cache flushing
- * that may be necessary.
- */
-static inline void
-update_mmu_cache (struct vm_area_struct *vma, unsigned long vaddr, pte_t pte)
-{
-	unsigned long addr;
-	struct page *page;
-
-	if (!pte_exec(pte))
-		return;				/* not an executable page... */
-
-	page = pte_page(pte);
-	/* don't use VADDR: it may not be mapped on this CPU (or may have just been flushed): */
-	addr = (unsigned long) page_address(page);
-
-	if (test_bit(PG_arch_1, &page->flags))
-		return;				/* i-cache is already coherent with d-cache */
-
-	flush_icache_range(addr, addr + PAGE_SIZE);
-	set_bit(PG_arch_1, &page->flags);	/* mark page as clean */
-}
-
 #endif /* _ASM_IA64_PGALLOC_H */
diff -Nru a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
--- a/include/asm-ia64/pgtable.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/pgtable.h	Wed Jun 18 23:42:06 2003
@@ -8,7 +8,7 @@
  * This hopefully works with any (fixed) IA-64 page-size, as defined
  * in <asm/page.h> (currently 8192).
  *
- * Copyright (C) 1998-2002 Hewlett-Packard Co
+ * Copyright (C) 1998-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
@@ -75,6 +75,8 @@
 #define _PAGE_SIZE_16M	24
 #define _PAGE_SIZE_64M	26
 #define _PAGE_SIZE_256M	28
+#define _PAGE_SIZE_1G	30
+#define _PAGE_SIZE_4G	32
 
 #define __ACCESS_BITS		_PAGE_ED | _PAGE_A | _PAGE_P | _PAGE_MA_WB
 #define __DIRTY_BITS_NO_ED	_PAGE_A | _PAGE_P | _PAGE_D | _PAGE_MA_WB
@@ -202,16 +204,21 @@
 #define set_pte(ptep, pteval)	(*(ptep) = (pteval))
 
 #define RGN_SIZE	(1UL << 61)
-#define RGN_MAP_LIMIT	((1UL << (4*PAGE_SHIFT - 12)) - PAGE_SIZE)	/* per region addr limit */
 #define RGN_KERNEL	7
 
-#define VMALLOC_START		(0xa000000000000000 + 3*PERCPU_PAGE_SIZE)
+#define VMALLOC_START		0xa000000200000000
 #define VMALLOC_VMADDR(x)	((unsigned long)(x))
-#define VMALLOC_END		(0xa000000000000000 + (1UL << (4*PAGE_SHIFT - 9)))
+#ifdef CONFIG_VIRTUAL_MEM_MAP
+# define VMALLOC_END_INIT	(0xa000000000000000 + (1UL << (4*PAGE_SHIFT - 9)))
+# define VMALLOC_END		vmalloc_end
+  extern unsigned long vmalloc_end;
+#else
+# define VMALLOC_END		(0xa000000000000000 + (1UL << (4*PAGE_SHIFT - 9)))
+#endif
 
 /* fs/proc/kcore.c */
-#define	kc_vaddr_to_offset(v) ((v) - 0xA000000000000000)
-#define	kc_offset_to_vaddr(o) ((o) + 0xA000000000000000)
+#define	kc_vaddr_to_offset(v) ((v) - 0xa000000000000000)
+#define	kc_offset_to_vaddr(o) ((o) + 0xa000000000000000)
 
 /*
  * Conversion functions: convert page frame number (pfn) and a protection value to a page
@@ -255,6 +262,7 @@
 /*
  * The following have defined behavior only work if pte_present() is true.
  */
+#define pte_user(pte)		((pte_val(pte) & _PAGE_PL_MASK) == _PAGE_PL_3)
 #define pte_read(pte)		(((pte_val(pte) & _PAGE_AR_MASK) >> _PAGE_AR_SHIFT) < 6)
 #define pte_write(pte)	((unsigned) (((pte_val(pte) & _PAGE_AR_MASK) >> _PAGE_AR_SHIFT) - 2) <= 4)
 #define pte_exec(pte)		((pte_val(pte) & _PAGE_AR_RX) != 0)
@@ -274,10 +282,9 @@
 #define pte_mkdirty(pte)	(__pte(pte_val(pte) | _PAGE_D))
 
 /*
- * Macro to make mark a page protection value as "uncacheable".  Note
- * that "protection" is really a misnomer here as the protection value
- * contains the memory attribute bits, dirty bits, and various other
- * bits as well.
+ * Macro to a page protection value as "uncacheable".  Note that "protection" is really a
+ * misnomer here as the protection value contains the memory attribute bits, dirty bits,
+ * and various other bits as well.
  */
 #define pgprot_noncached(prot)		__pgprot((pgprot_val(prot) & ~_PAGE_MA_MASK) | _PAGE_MA_UC)
 
@@ -446,13 +453,27 @@
  * for zero-mapped memory areas etc..
  */
 extern unsigned long empty_zero_page[PAGE_SIZE/sizeof(unsigned long)];
-#define ZERO_PAGE(vaddr) (virt_to_page(empty_zero_page))
+extern struct page *zero_page_memmap_ptr;
+#define ZERO_PAGE(vaddr) (zero_page_memmap_ptr)
 
 /* We provide our own get_unmapped_area to cope with VA holes for userland */
 #define HAVE_ARCH_UNMAPPED_AREA
 
 typedef pte_t *pte_addr_t;
 
+/*
+ * IA-64 doesn't have any external MMU info: the page tables contain all the necessary
+ * information.  However, we use this routine to take care of any (delayed) i-cache
+ * flushing that may be necessary.
+ */
+extern void update_mmu_cache (struct vm_area_struct *vma, unsigned long vaddr, pte_t pte);
+
+#  ifdef CONFIG_VIRTUAL_MEM_MAP
+  /* arch mem_map init routine is needed due to holes in a virtual mem_map */
+#   define __HAVE_ARCH_MEMMAP_INIT
+    extern void memmap_init (struct page *start, unsigned long size, int nid, unsigned long zone,
+			     unsigned long start_pfn);
+#  endif /* CONFIG_VIRTUAL_MEM_MAP */
 # endif /* !__ASSEMBLY__ */
 
 /*
@@ -471,11 +492,14 @@
  */
 #define KERNEL_TR_PAGE_SHIFT	_PAGE_SIZE_64M
 #define KERNEL_TR_PAGE_SIZE	(1 << KERNEL_TR_PAGE_SHIFT)
-#define KERNEL_TR_PAGE_NUM	((KERNEL_START - PAGE_OFFSET) / KERNEL_TR_PAGE_SIZE)
 
 /*
  * No page table caches to initialise
  */
 #define pgtable_cache_init()	do { } while (0)
+
+/* These tell get_user_pages() that the first gate page is accessible from user-level.  */
+#define FIXADDR_USER_START	GATE_ADDR
+#define FIXADDR_USER_END	(GATE_ADDR + 2*PAGE_SIZE)
 
 #endif /* _ASM_IA64_PGTABLE_H */
diff -Nru a/include/asm-ia64/processor.h b/include/asm-ia64/processor.h
--- a/include/asm-ia64/processor.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/processor.h	Wed Jun 18 23:42:06 2003
@@ -17,7 +17,7 @@
 
 #include <asm/ptrace.h>
 #include <asm/kregs.h>
-#include <asm/types.h>
+#include <asm/ustack.h>
 
 #define IA64_NUM_DBG_REGS	8
 /*
@@ -87,9 +87,9 @@
 #include <linux/cache.h>
 #include <linux/compiler.h>
 #include <linux/threads.h>
+#include <linux/types.h>
 
 #include <asm/fpu.h>
-#include <asm/offsets.h>
 #include <asm/page.h>
 #include <asm/percpu.h>
 #include <asm/rse.h>
@@ -236,6 +236,7 @@
 	__u64 ksp;			/* kernel stack pointer */
 	__u64 map_base;			/* base address for get_unmapped_area() */
 	__u64 task_size;		/* limit for task size */
+	__u64 rbs_bot;			/* the base address for the RBS */
 	int last_fph_cpu;		/* CPU that may hold the contents of f32-f127 */
 
 #ifdef CONFIG_IA32_SUPPORT
@@ -244,8 +245,6 @@
 	__u64 fcr;			/* IA32 floating pt control reg */
 	__u64 fir;			/* IA32 fp except. instr. reg */
 	__u64 fdr;			/* IA32 fp except. data reg */
-	__u64 csd;			/* IA32 code selector descriptor */
-	__u64 ssd;			/* IA32 stack selector descriptor */
 	__u64 old_k1;			/* old value of ar.k1 */
 	__u64 old_iob;			/* old IOBase value */
 # define INIT_THREAD_IA32	.eflag =	0,			\
@@ -253,28 +252,20 @@
 				.fcr =		0x17800000037fULL,	\
 				.fir =		0,			\
 				.fdr =		0,			\
-				.csd =		0,			\
-				.ssd =		0,			\
 				.old_k1 =	0,			\
 				.old_iob =	0,
 #else
 # define INIT_THREAD_IA32
 #endif /* CONFIG_IA32_SUPPORT */
 #ifdef CONFIG_PERFMON
-	__u64 pmc[IA64_NUM_PMC_REGS];
-	__u64 pmd[IA64_NUM_PMD_REGS];
-	unsigned long pfm_ovfl_block_reset;/* non-zero if we need to block or reset regs on ovfl */
-	void *pfm_context;		/* pointer to detailed PMU context */
-	atomic_t pfm_notifiers_check;	/* when >0, will cleanup ctx_notify_task in tasklist */
-	atomic_t pfm_owners_check;	/* when >0, will cleanup ctx_owner in tasklist */
-	void *pfm_smpl_buf_list;	/* list of sampling buffers to vfree */
-# define INIT_THREAD_PM		.pmc =			{0, },	\
-				.pmd =			{0, },	\
-				.pfm_ovfl_block_reset =	0,	\
-				.pfm_context =		NULL,	\
-				.pfm_notifiers_check =	{ 0 },	\
-				.pfm_owners_check =	{ 0 },	\
-				.pfm_smpl_buf_list =	NULL,
+	__u64 pmcs[IA64_NUM_PMC_REGS];
+	__u64 pmds[IA64_NUM_PMD_REGS];
+	void *pfm_context;		     /* pointer to detailed PMU context */
+	unsigned long pfm_needs_checking;    /* when >0, pending perfmon work on kernel exit */
+# define INIT_THREAD_PM		.pmcs =			{0UL, },  \
+				.pmds =			{0UL, },  \
+				.pfm_context =		NULL,     \
+				.pfm_needs_checking =	0UL,
 #else
 # define INIT_THREAD_PM
 #endif
@@ -288,8 +279,9 @@
 	.on_ustack =	0,			\
 	.ksp =		0,			\
 	.map_base =	DEFAULT_MAP_BASE,	\
+	.rbs_bot =	DEFAULT_USER_STACK_SIZE,	\
 	.task_size =	DEFAULT_TASK_SIZE,	\
-	.last_fph_cpu =  0,			\
+	.last_fph_cpu =  -1,			\
 	INIT_THREAD_IA32			\
 	INIT_THREAD_PM				\
 	.dbr =		{0, },			\
@@ -304,36 +296,18 @@
 	regs->cr_iip = new_ip;									\
 	regs->ar_rsc = 0xf;		/* eager mode, privilege level 3 */			\
 	regs->ar_rnat = 0;									\
-	regs->ar_bspstore = IA64_RBS_BOT;							\
+	regs->ar_bspstore = current->thread.rbs_bot;						\
 	regs->ar_fpsr = FPSR_DEFAULT;								\
 	regs->loadrs = 0;									\
 	regs->r8 = current->mm->dumpable;	/* set "don't zap registers" flag */		\
 	regs->r12 = new_sp - 16;	/* allocate 16 byte scratch area */			\
-	if (unlikely(!current->mm->dumpable)) {					\
+	if (unlikely(!current->mm->dumpable)) {							\
 		/*										\
 		 * Zap scratch regs to avoid leaking bits between processes with different	\
 		 * uid/privileges.								\
 		 */										\
-		regs->ar_pfs = 0;								\
-		regs->pr = 0;									\
-		/*										\
-		 * XXX fix me: everything below can go away once we stop preserving scratch	\
-		 * regs on a system call.							\
-		 */										\
-		regs->b6 = 0;									\
-		regs->r1 = 0; regs->r2 = 0; regs->r3 = 0;					\
-		regs->r13 = 0; regs->r14 = 0; regs->r15 = 0;					\
-		regs->r9  = 0; regs->r11 = 0;							\
-		regs->r16 = 0; regs->r17 = 0; regs->r18 = 0; regs->r19 = 0;			\
-		regs->r20 = 0; regs->r21 = 0; regs->r22 = 0; regs->r23 = 0;			\
-		regs->r24 = 0; regs->r25 = 0; regs->r26 = 0; regs->r27 = 0;			\
-		regs->r28 = 0; regs->r29 = 0; regs->r30 = 0; regs->r31 = 0;			\
-		regs->ar_ccv = 0;								\
-		regs->b0 = 0; regs->b7 = 0;							\
-		regs->f6.u.bits[0] = 0; regs->f6.u.bits[1] = 0;					\
-		regs->f7.u.bits[0] = 0; regs->f7.u.bits[1] = 0;					\
-		regs->f8.u.bits[0] = 0; regs->f8.u.bits[1] = 0;					\
-		regs->f9.u.bits[0] = 0; regs->f9.u.bits[1] = 0;					\
+		regs->ar_pfs = 0; regs->b0 = 0; regs->pr = 0;					\
+		regs->r1 = 0; regs->r9  = 0; regs->r11 = 0; regs->r13 = 0; regs->r15 = 0;	\
 	}											\
 } while (0)
 
@@ -346,11 +320,7 @@
  * parent of DEAD_TASK has collected the exist status of the task via
  * wait().
  */
-#ifdef CONFIG_PERFMON
-  extern void release_thread (struct task_struct *task);
-#else
-# define release_thread(dead_task)
-#endif
+#define release_thread(dead_task)
 
 /* Prepare to copy thread state - unlazy all lazy status */
 #define prepare_to_copy(tsk)	do { } while (0)
@@ -369,7 +339,7 @@
  * do_basic_setup() and the timing is such that free_initmem() has
  * been called already.
  */
-extern int kernel_thread (int (*fn)(void *), void *arg, unsigned long flags);
+extern pid_t kernel_thread (int (*fn)(void *), void *arg, unsigned long flags);
 
 /* Get wait channel for task P.  */
 extern unsigned long get_wchan (struct task_struct *p);
@@ -417,17 +387,28 @@
 	}
 }
 
-static inline struct task_struct *
-ia64_get_fpu_owner (void)
-{
-	return (struct task_struct *) ia64_get_kr(IA64_KR_FPU_OWNER);
-}
+/*
+ * The following three macros can't be inline functions because we don't have struct
+ * task_struct at this point.
+ */
 
-static inline void
-ia64_set_fpu_owner (struct task_struct *t)
-{
-	ia64_set_kr(IA64_KR_FPU_OWNER, (unsigned long) t);
-}
+/* Return TRUE if task T owns the fph partition of the CPU we're running on. */
+#define ia64_is_local_fpu_owner(t)								\
+({												\
+	struct task_struct *__ia64_islfo_task = (t);						\
+	(__ia64_islfo_task->thread.last_fph_cpu == smp_processor_id()				\
+	 && __ia64_islfo_task == (struct task_struct *) ia64_get_kr(IA64_KR_FPU_OWNER));	\
+})
+
+/* Mark task T as owning the fph partition of the CPU we're running on. */
+#define ia64_set_local_fpu_owner(t) do {						\
+	struct task_struct *__ia64_slfo_task = (t);					\
+	__ia64_slfo_task->thread.last_fph_cpu = smp_processor_id();			\
+	ia64_set_kr(IA64_KR_FPU_OWNER, (unsigned long) __ia64_slfo_task);		\
+} while (0)
+
+/* Mark the fph partition of task T as being invalid on all CPUs.  */
+#define ia64_drop_fpu(t)	((t)->thread.last_fph_cpu = -1)
 
 extern void __ia64_init_fpu (void);
 extern void __ia64_save_fpu (struct ia64_fpreg *fph);
@@ -636,8 +617,13 @@
 	asm volatile ("mov cr.lrr0=%0;; srlz.d" :: "r"(val) : "memory");
 }
 
-#define cpu_relax()	barrier()
+static inline void
+ia64_hint_pause (void)
+{
+	asm volatile ("hint @pause" ::: "memory");
+}
 
+#define cpu_relax()	ia64_hint_pause()
 
 static inline void
 ia64_set_lrr1 (unsigned long val)
@@ -916,6 +902,18 @@
 	__u64 result;
 	asm ("tpa %0=%1" : "=r"(result) : "r"(addr));
 	return result;
+}
+
+/*
+ * Take a mapped kernel address and return the equivalent address
+ * in the region 7 identity mapped virtual area.
+ */
+static inline void *
+ia64_imva (void *addr)
+{
+	void *result;
+	asm ("tpa %0=%1" : "=r"(result) : "r"(addr));
+	return __va(result);
 }
 
 #define ARCH_HAS_PREFETCH
diff -Nru a/include/asm-ia64/ptrace.h b/include/asm-ia64/ptrace.h
--- a/include/asm-ia64/ptrace.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/ptrace.h	Wed Jun 18 23:42:08 2003
@@ -5,6 +5,10 @@
  * Copyright (C) 1998-2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  *	Stephane Eranian <eranian@hpl.hp.com>
+ * Copyright (C) 2003 Intel Co
+ *	Suresh Siddha <suresh.b.siddha@intel.com>
+ *	Fenghua Yu <fenghua.yu@intel.com>
+ *	Arun Sharma <arun.sharma@intel.com>
  *
  * 12/07/98	S. Eranian	added pt_regs & switch_stack
  * 12/21/98	D. Mosberger	updated to match latest code
@@ -93,6 +97,16 @@
  */
 struct pt_regs {
 	/* The following registers are saved by SAVE_MIN: */
+	unsigned long b6;		/* scratch */
+	unsigned long b7;		/* scratch */
+
+	unsigned long ar_csd;           /* used by cmp8xchg16 (scratch) */
+	unsigned long ar_ssd;           /* reserved for future use (scratch) */
+
+	unsigned long r8;		/* scratch (return value register 0) */
+	unsigned long r9;		/* scratch (return value register 1) */
+	unsigned long r10;		/* scratch (return value register 2) */
+	unsigned long r11;		/* scratch (return value register 3) */
 
 	unsigned long cr_ipsr;		/* interrupted task's psr */
 	unsigned long cr_iip;		/* interrupted task's instruction pointer */
@@ -106,24 +120,23 @@
 	unsigned long ar_bspstore;	/* RSE bspstore */
 
 	unsigned long pr;		/* 64 predicate registers (1 bit each) */
-	unsigned long b6;		/* scratch */
+	unsigned long b0;		/* return pointer (bp) */
 	unsigned long loadrs;		/* size of dirty partition << 16 */
 
 	unsigned long r1;		/* the gp pointer */
-	unsigned long r2;		/* scratch */
-	unsigned long r3;		/* scratch */
 	unsigned long r12;		/* interrupted task's memory stack pointer */
 	unsigned long r13;		/* thread pointer */
-	unsigned long r14;		/* scratch */
+
+	unsigned long ar_fpsr;		/* floating point status (preserved) */
 	unsigned long r15;		/* scratch */
 
-	unsigned long r8;		/* scratch (return value register 0) */
-	unsigned long r9;		/* scratch (return value register 1) */
-	unsigned long r10;		/* scratch (return value register 2) */
-	unsigned long r11;		/* scratch (return value register 3) */
+	/* The remaining registers are NOT saved for system calls.  */
 
-	/* The following registers are saved by SAVE_REST: */
+	unsigned long r14;		/* scratch */
+	unsigned long r2;		/* scratch */
+	unsigned long r3;		/* scratch */
 
+	/* The following registers are saved by SAVE_REST: */
 	unsigned long r16;		/* scratch */
 	unsigned long r17;		/* scratch */
 	unsigned long r18;		/* scratch */
@@ -142,18 +155,16 @@
 	unsigned long r31;		/* scratch */
 
 	unsigned long ar_ccv;		/* compare/exchange value (scratch) */
-	unsigned long ar_fpsr;		/* floating point status (preserved) */
 
-	unsigned long b0;		/* return pointer (bp) */
-	unsigned long b7;		/* scratch */
 	/*
-	 * Floating point registers that the kernel considers
-	 * scratch:
+	 * Floating point registers that the kernel considers scratch:
 	 */
 	struct ia64_fpreg f6;		/* scratch */
 	struct ia64_fpreg f7;		/* scratch */
 	struct ia64_fpreg f8;		/* scratch */
 	struct ia64_fpreg f9;		/* scratch */
+	struct ia64_fpreg f10;		/* scratch */
+	struct ia64_fpreg f11;		/* scratch */
 };
 
 /*
@@ -170,8 +181,6 @@
 	struct ia64_fpreg f4;		/* preserved */
 	struct ia64_fpreg f5;		/* preserved */
 
-	struct ia64_fpreg f10;		/* scratch, but untouched by kernel */
-	struct ia64_fpreg f11;		/* scratch, but untouched by kernel */
 	struct ia64_fpreg f12;		/* scratch, but untouched by kernel */
 	struct ia64_fpreg f13;		/* scratch, but untouched by kernel */
 	struct ia64_fpreg f14;		/* scratch, but untouched by kernel */
@@ -226,6 +235,20 @@
 	  !user_mode(_regs) && user_stack(_task, _regs);	\
   })
 
+  /*
+   * System call handlers that, upon successful completion, need to return a negative value
+   * should call force_successful_syscall_return() right before returning.  On architectures
+   * where the syscall convention provides for a separate error flag (e.g., alpha, ia64,
+   * ppc{,64}, sparc{,64}, possibly others), this macro can be used to ensure that the error
+   * flag will not get set.  On architectures which do not support a separate error flag,
+   * the macro is a no-op and the spurious error condition needs to be filtered out by some
+   * other means (e.g., in user-level, by passing an extra argument to the syscall handler,
+   * or something along those lines).
+   *
+   * On ia64, we can clear the user's pt_regs->r8 to force a successful syscall.
+   */
+# define force_successful_syscall_return()	(ia64_task_regs(current)->r8 = 0)
+
   struct task_struct;			/* forward decl */
   struct unw_frame_info;		/* forward decl */
 
@@ -249,11 +272,6 @@
 
   extern void ia64_increment_ip (struct pt_regs *pt);
   extern void ia64_decrement_ip (struct pt_regs *pt);
-
-#define force_successful_syscall_return()		\
-	do {						\
-		ia64_task_regs(current)->r8 = 0;	\
-	} while (0)
 
 #endif /* !__KERNEL__ */
 
diff -Nru a/include/asm-ia64/ptrace_offsets.h b/include/asm-ia64/ptrace_offsets.h
--- a/include/asm-ia64/ptrace_offsets.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/ptrace_offsets.h	Wed Jun 18 23:42:07 2003
@@ -2,8 +2,8 @@
 #define _ASM_IA64_PTRACE_OFFSETS_H
 
 /*
- * Copyright (C) 1999 Hewlett-Packard Co
- * Copyright (C) 1999 David Mosberger-Tang <davidm@hpl.hp.com>
+ * Copyright (C) 1999, 2003 Hewlett-Packard Co
+ *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 /*
  * The "uarea" that can be accessed via PEEKUSER and POKEUSER is a
@@ -11,9 +11,59 @@
  *
  *	struct uarea {
  *		struct ia64_fpreg fph[96];		// f32-f127
- *		struct switch_stack sw;
- *		struct pt_regs pt;
- *		unsigned long rsvd1[712];
+ *		unsigned long nat_bits;
+ *		unsigned long empty1;
+ *		struct ia64_fpreg f2;			// f2-f5
+ *			:
+ *		struct ia64_fpreg f5;
+ *		struct ia64_fpreg f10;			// f10-f31
+ *			:
+ *		struct ia64_fpreg f31;
+ *		unsigned long r4;			// r4-r7
+ *			:
+ *		unsigned long r7;
+ *		unsigned long b1;			// b1-b5
+ *			:
+ *		unsigned long b5;
+ *		unsigned long ar_ec;
+ *		unsigned long ar_lc;
+ *		unsigned long empty2[5];
+ *		unsigned long cr_ipsr;
+ *		unsigned long cr_iip;
+ *		unsigned long cfm;
+ *		unsigned long ar_unat;
+ *		unsigned long ar_pfs;
+ *		unsigned long ar_rsc;
+ *		unsigned long ar_rnat;
+ *		unsigned long ar_bspstore;
+ *		unsigned long pr;
+ *		unsigned long b6;
+ *		unsigned long ar_bsp;
+ *		unsigned long r1;
+ *		unsigned long r2;
+ *		unsigned long r3;
+ *		unsigned long r12;
+ *		unsigned long r13;
+ *		unsigned long r14;
+ *		unsigned long r15;
+ *		unsigned long r8;
+ *		unsigned long r9;
+ *		unsigned long r10;
+ *		unsigned long r11;
+ *		unsigned long r16;
+ *			:
+ *		unsigned long r31;
+ *		unsigned long ar_ccv;
+ *		unsigned long ar_fpsr;
+ *		unsigned long b0;
+ *		unsigned long b7;
+ *		unsigned long f6;
+ *		unsigned long f7;
+ *		unsigned long f8;
+ *		unsigned long f9;
+ *		unsigned long ar_csd;
+ *		unsigned long ar_ssd;
+ *		unsigned long rsvd1[710];
  *		unsigned long dbr[8];
  *		unsigned long rsvd2[504];
  *		unsigned long ibr[8];
@@ -119,7 +169,7 @@
 #define PT_F125			0x05d0
 #define PT_F126			0x05e0
 #define PT_F127			0x05f0
-/* switch stack: */
+
 #define PT_NAT_BITS		0x0600
 
 #define PT_F2			0x0610
@@ -162,7 +212,6 @@
 #define PT_AR_EC		0x0800
 #define PT_AR_LC		0x0808
 
-/* pt_regs */
 #define PT_CR_IPSR		0x0830
 #define PT_CR_IIP		0x0838
 #define PT_CFM			0x0840
@@ -209,6 +258,8 @@
 #define PT_F7			0x0990
 #define PT_F8			0x09a0
 #define PT_F9			0x09b0
+#define PT_AR_CSD		0x09c0
+#define PT_AR_SSD		0x09c8
 
 #define PT_DBR			0x2000	/* data breakpoint registers */
 #define PT_IBR			0x3000	/* instruction breakpoint registers */
diff -Nru a/include/asm-ia64/resource.h b/include/asm-ia64/resource.h
--- a/include/asm-ia64/resource.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/resource.h	Wed Jun 18 23:42:08 2003
@@ -8,6 +8,8 @@
  * Copyright (C) 1998, 1999 David Mosberger-Tang <davidm@hpl.hp.com>
  */
 
+#include <asm/ustack.h>
+
 #define RLIMIT_CPU	0		/* CPU time in ms */
 #define RLIMIT_FSIZE	1		/* Maximum filesize */
 #define RLIMIT_DATA	2		/* max data size */
@@ -35,7 +37,7 @@
 	{ RLIM_INFINITY, RLIM_INFINITY },		\
 	{ RLIM_INFINITY, RLIM_INFINITY },		\
 	{ RLIM_INFINITY, RLIM_INFINITY },		\
-	{      _STK_LIM, RLIM_INFINITY },		\
+	{      _STK_LIM, DEFAULT_USER_STACK_SIZE },	\
 	{             0, RLIM_INFINITY },		\
 	{ RLIM_INFINITY, RLIM_INFINITY },		\
 	{             0,             0 },		\
diff -Nru a/include/asm-ia64/sal.h b/include/asm-ia64/sal.h
--- a/include/asm-ia64/sal.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-ia64/sal.h	Wed Jun 18 23:42:09 2003
@@ -23,6 +23,18 @@
  *                      (plus examples of platform error info structures from smariset @ Intel)
  */
 
+#define IA64_SAL_PLATFORM_FEATURE_BUS_LOCK_BIT		0
+#define IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT_BIT	1
+#define IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT_BIT	2
+#define IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT_BIT	 	3
+
+#define IA64_SAL_PLATFORM_FEATURE_BUS_LOCK	  (1<<IA64_SAL_PLATFORM_FEATURE_BUS_LOCK_BIT)
+#define IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT (1<<IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT_BIT)
+#define IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT (1<<IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT_BIT)
+#define IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT	  (1<<IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT_BIT)
+
+#ifndef __ASSEMBLY__
+
 #include <linux/spinlock.h>
 #include <linux/efi.h>
 
@@ -162,11 +174,6 @@
 	u8 oem_reserved[8];
 } ia64_sal_desc_memory_t;
 
-#define IA64_SAL_PLATFORM_FEATURE_BUS_LOCK		(1 << 0)
-#define IA64_SAL_PLATFORM_FEATURE_IRQ_REDIR_HINT	(1 << 1)
-#define IA64_SAL_PLATFORM_FEATURE_IPI_REDIR_HINT	(1 << 2)
-#define IA64_SAL_PLATFORM_FEATURE_ITC_DRIFT	 	(1 << 3)
-
 typedef struct ia64_sal_desc_platform_feature {
 	u8 type;
 	u8 feature_mask;
@@ -789,5 +796,7 @@
 }
 
 extern unsigned long sal_platform_features;
+
+#endif /* __ASSEMBLY__ */
 
 #endif /* _ASM_IA64_PAL_H */
diff -Nru a/include/asm-ia64/sigcontext.h b/include/asm-ia64/sigcontext.h
--- a/include/asm-ia64/sigcontext.h	Wed Jun 18 23:42:05 2003
+++ b/include/asm-ia64/sigcontext.h	Wed Jun 18 23:42:05 2003
@@ -56,7 +56,7 @@
 	unsigned long		sc_rbs_base;	/* NULL or new base of sighandler's rbs */
 	unsigned long		sc_loadrs;	/* see description above */
 
-	unsigned long		sc_ar25;	/* rsvd for scratch use */
+	unsigned long		sc_ar25;	/* cmp8xchg16 uses this */
 	unsigned long		sc_ar26;	/* rsvd for scratch use */
 	unsigned long		sc_rsvd[12];	/* reserved for future use */
 	/*
diff -Nru a/include/asm-ia64/siginfo.h b/include/asm-ia64/siginfo.h
--- a/include/asm-ia64/siginfo.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-ia64/siginfo.h	Wed Jun 18 23:42:09 2003
@@ -69,13 +69,6 @@
 			long _band;	/* POLL_IN, POLL_OUT, POLL_MSG (XPG requires a "long") */
 			int _fd;
 		} _sigpoll;
-
-		/* SIGPROF */
-		struct {
-			pid_t _pid;		/* which child */
-			uid_t _uid;		/* sender's uid */
-			unsigned long _pfm_ovfl_counters[4]; /* which PMU counter overflowed */
-		} _sigprof;
 	} _sifields;
 } siginfo_t;
 
@@ -95,14 +88,6 @@
 #define __ISR_VALID	(1 << __ISR_VALID_BIT)
 
 /*
- * si_code values
- * Positive values for kernel-generated signals.
- */
-#ifdef __KERNEL__
-#define __SI_PROF	(6 << 16)
-#endif
-
-/*
  * SIGILL si_codes
  */
 #define ILL_BADIADDR	(__SI_FAULT|9)	/* unimplemented instruction address */
@@ -137,11 +122,6 @@
 #undef NSIGTRAP
 #define NSIGTRAP	4
 
-/*
- * SIGPROF si_codes
- */
-#define PROF_OVFL	(__SI_PROF|1)  /* some counters overflowed */
-
 #ifdef __KERNEL__
 #include <linux/string.h>
 
@@ -151,8 +131,8 @@
 	if (from->si_code < 0)
 		memcpy(to, from, sizeof(siginfo_t));
 	else
-		/* _sigprof is currently the largest know union member */
-		memcpy(to, from, 4*sizeof(int) + sizeof(from->_sifields._sigprof));
+		/* _sigchld is currently the largest know union member */
+		memcpy(to, from, 4*sizeof(int) + sizeof(from->_sifields._sigchld));
 }
 
 extern int copy_siginfo_from_user(siginfo_t *to, siginfo_t *from);
diff -Nru a/include/asm-ia64/sn/addrs.h b/include/asm-ia64/sn/addrs.h
--- a/include/asm-ia64/sn/addrs.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/sn/addrs.h	Wed Jun 18 23:42:08 2003
@@ -1,26 +1,17 @@
-
 /*
- *
  * 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) 1992-1999,2001 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 1992-1999,2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
-
 #ifndef _ASM_IA64_SN_ADDRS_H
 #define _ASM_IA64_SN_ADDRS_H
 
 #include <linux/config.h>
 
-#if defined (CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/addrs.h>
-#elif defined (CONFIG_IA64_SGI_SN2)
 #include <asm/sn/sn2/addrs.h>
-#else
-#error <<<BOMB! addrs.h defined only for SN1, or SN2 >>>
-#endif /* !SN1 && !SN2 */
 
 #ifndef __ASSEMBLY__
 #include <asm/sn/types.h>
@@ -30,11 +21,7 @@
 
 #define PS_UINT_CAST		(__psunsigned_t)
 #define UINT64_CAST		(uint64_t)
-#ifdef CONFIG_IA64_SGI_SN2
 #define HUBREG_CAST		(volatile mmr_t *)
-#else
-#define HUBREG_CAST		(volatile hubreg_t *)
-#endif
 
 #elif __ASSEMBLY__
 
@@ -52,11 +39,7 @@
  * node's address space.
  */
 
-#ifdef CONFIG_IA64_SGI_SN2	/* SN2 has an extra AS field between node offset and node id (nasid) */
 #define NODE_OFFSET(_n)		(UINT64_CAST (_n) << NASID_SHFT)
-#else
-#define NODE_OFFSET(_n)		(UINT64_CAST (_n) << NODE_SIZE_BITS)
-#endif
 
 #define NODE_CAC_BASE(_n)	(CAC_BASE  + NODE_OFFSET(_n))
 #define NODE_HSPEC_BASE(_n)	(HSPEC_BASE + NODE_OFFSET(_n))
@@ -83,7 +66,7 @@
  */
 
 #define SWIN_SIZE_BITS		24
-#define SWIN_SIZE		(UINT64_CAST 1 << 24)
+#define SWIN_SIZE		(1UL<<24)
 #define	SWIN_SIZEMASK		(SWIN_SIZE - 1)
 #define	SWIN_WIDGET_MASK	0xF
 
@@ -119,44 +102,13 @@
  *			references to the local hub's registers.
  */
 
-#if defined CONFIG_IA64_SGI_SN1
-#define LREG_BASE		(HSPEC_BASE + 0x10000000)
-#define LREG_SIZE		0x8000000  /* 128 MB */
-#define LREG_LIMIT		(LREG_BASE + LREG_SIZE)
-#define LBOOT_BASE		(LREG_LIMIT)
-#define LBOOT_SIZE		0x8000000   /* 128 MB */
-#define LBOOT_LIMIT		(LBOOT_BASE + LBOOT_SIZE)
-#define LBOOT_STRIDE		0x2000000    /* two PROMs, on 32M boundaries */
-#endif
-
 #define	HUB_REGISTER_WIDGET	1
-#ifdef CONFIG_IA64_SGI_SN2
 #define IALIAS_BASE		LOCAL_SWIN_BASE(HUB_REGISTER_WIDGET)
-#else
-#define IALIAS_BASE		NODE_SWIN_BASE(0, HUB_REGISTER_WIDGET)
-#endif
 #define IALIAS_SIZE		0x800000	/* 8 Megabytes */
 #define IS_IALIAS(_a)		(((_a) >= IALIAS_BASE) &&		\
 				 ((_a) < (IALIAS_BASE + IALIAS_SIZE)))
 
 /*
- * Macro for referring to Hub's RBOOT space
- */
-
-#if defined CONFIG_IA64_SGI_SN1
-
-#define NODE_LREG_BASE(_n)	(NODE_HSPEC_BASE(_n) + 0x30000000)
-#define NODE_LREG_LIMIT(_n)	(NODE_LREG_BASE(_n) + LREG_SIZE)
-#define RREG_BASE(_n)		(NODE_LREG_BASE(_n))
-#define RREG_LIMIT(_n)		(NODE_LREG_LIMIT(_n))
-#define RBOOT_SIZE		0x8000000	/* 128 Megabytes */
-#define NODE_RBOOT_BASE(_n)	(NODE_HSPEC_BASE(_n) + 0x38000000)
-#define NODE_RBOOT_LIMIT(_n)	(NODE_RBOOT_BASE(_n) + RBOOT_SIZE)
-
-#endif
-
-
-/*
  * The following macros produce the correct base virtual address for
  * the hub registers.  The LOCAL_HUB_* macros produce the appropriate
  * address for the local registers.  The REMOTE_HUB_* macro produce
@@ -166,11 +118,10 @@
  */
 
 
-#ifdef CONFIG_IA64_SGI_SN2
 /*
- * SN2 has II mmr's located inside small window space like SN0 & SN1,
- * but has all other non-II mmr's located at the top of big window
- * space, unlike SN0 & SN1.
+ * SN2 has II mmr's located inside small window space.
+ * As all other non-II mmr's located at the top of big window
+ * space.
  */
 #define LOCAL_HUB_BASE(_x)	(LOCAL_MMR_ADDR(_x) | (((~(_x)) & BWIN_TOP)>>8))
 #define REMOTE_HUB_BASE(_x)						\
@@ -182,18 +133,6 @@
 #define REMOTE_HUB(_n, _x)						\
 	(HUBREG_CAST (REMOTE_HUB_BASE(_x) | ((((long)(_n))<<NASID_SHFT))))
 
-#else	/* not CONFIG_IA64_SGI_SN2 */
-
-#define LOCAL_HUB(_x)		(HUBREG_CAST (IALIAS_BASE + (_x)))
-#define REMOTE_HUB(_n, _x)	(HUBREG_CAST (NODE_SWIN_BASE(_n, 1) +	\
-					      0x800000 + (_x)))
-#endif
-
-#ifdef CONFIG_IA64_SGI_SN1
-#define LOCAL_HSPEC(_x)		(HUBREG_CAST (LREG_BASE + (_x)))
-#define REMOTE_HSPEC(_n, _x)		(HUBREG_CAST (RREG_BASE(_n) + (_x)))
-#endif /* CONFIG_IA64_SGI_SN1 */
-
 
 /*
  * WARNING:
@@ -203,27 +142,12 @@
  *	Otherwise, the recommended approach is to use *_HUB_L() and *_HUB_S().
  *	They're always safe.
  */
-#ifdef CONFIG_IA64_SGI_SN2
 #define LOCAL_HUB_ADDR(_x)							\
 	(((_x) & BWIN_TOP) ? (HUBREG_CAST (LOCAL_MMR_ADDR(_x)))		\
 	: (HUBREG_CAST (IALIAS_BASE + (_x))))
 #define REMOTE_HUB_ADDR(_n, _x)						\
 	(((_x) & BWIN_TOP) ? (HUBREG_CAST (GLOBAL_MMR_ADDR(_n, _x)))	\
 	: (HUBREG_CAST (NODE_SWIN_BASE(_n, 1) + 0x800000 + (_x))))
-#else
-#define LOCAL_HUB_ADDR(_x)	(HUBREG_CAST (IALIAS_BASE + (_x)))
-#define REMOTE_HUB_ADDR(_n, _x)	(HUBREG_CAST (NODE_SWIN_BASE(_n, 1) +	\
-					      0x800000 + (_x)))
-#endif
-#ifdef CONFIG_IA64_SGI_SN1
-#define REMOTE_HUB_PI_ADDR(_n, _sn, _x)	(HUBREG_CAST (NODE_SWIN_BASE(_n, 1) +	\
-					      0x800000 + PIREG(_x, _sn)))
-#endif
-
-#ifdef CONFIG_IA64_SGI_SN1
-#define LOCAL_HSPEC_ADDR(_x)		(HUBREG_CAST (LREG_BASE + (_x)))
-#define REMOTE_HSPEC_ADDR(_n, _x)	(HUBREG_CAST (RREG_BASE(_n) + (_x)))
-#endif /* CONFIG_IA64_SGI_SN1 */
 
 #ifndef __ASSEMBLY__
 
@@ -237,13 +161,6 @@
 #define REMOTE_HUB_PI_L(_n, _sn, _r)	HUB_L(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)))
 #define REMOTE_HUB_PI_S(_n, _sn, _r, _d) HUB_S(REMOTE_HUB_PI_ADDR((_n), (_sn), (_r)), (_d))
 
-#ifdef CONFIG_IA64_SGI_SN1
-#define LOCAL_HSPEC_L(_r)	     HUB_L(LOCAL_HSPEC_ADDR(_r))
-#define LOCAL_HSPEC_S(_r, _d)	     HUB_S(LOCAL_HSPEC_ADDR(_r), (_d))
-#define REMOTE_HSPEC_L(_n, _r)	     HUB_L(REMOTE_HSPEC_ADDR((_n), (_r)))
-#define REMOTE_HSPEC_S(_n, _r, _d)   HUB_S(REMOTE_HSPEC_ADDR((_n), (_r)), (_d))
-#endif /* CONFIG_IA64_SGI_SN1 */
-
 #endif /* __ASSEMBLY__ */
 
 /*
@@ -311,12 +228,7 @@
 #define	KLD_KERN_XP(nasid)	(KLD_BASE(nasid) + KLI_KERN_XP)
 #define	KLD_KERN_PARTID(nasid)	(KLD_BASE(nasid) + KLI_KERN_PARTID)
 
-#ifndef CONFIG_IA64_SGI_SN2
-#define KLCONFIG_OFFSET(nasid)	KLD_KLCONFIG(nasid)->offset
-#else
-#define KLCONFIG_OFFSET(nasid) \
-	ia64_sn_get_klconfig_addr(nasid)
-#endif /* CONFIG_IA64_SGI_SN2 */
+#define KLCONFIG_OFFSET(nasid)  ia64_sn_get_klconfig_addr(nasid)
 
 #define KLCONFIG_ADDR(nasid)						\
 	TO_NODE_CAC((nasid), KLCONFIG_OFFSET(nasid))
diff -Nru a/include/asm-ia64/sn/alenlist.h b/include/asm-ia64/sn/alenlist.h
--- a/include/asm-ia64/sn/alenlist.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/sn/alenlist.h	Wed Jun 18 23:42:07 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_ALENLIST_H
 #define _ASM_IA64_SN_ALENLIST_H
diff -Nru a/include/asm-ia64/sn/arc/hinv.h b/include/asm-ia64/sn/arc/hinv.h
--- a/include/asm-ia64/sn/arc/hinv.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/arc/hinv.h	Wed Jun 18 23:42:06 2003
@@ -1,12 +1,10 @@
 /*
- *
  * 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) 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
-
 
 /* $Id$
  *
diff -Nru a/include/asm-ia64/sn/arc/types.h b/include/asm-ia64/sn/arc/types.h
--- a/include/asm-ia64/sn/arc/types.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-ia64/sn/arc/types.h	Wed Jun 18 23:42:09 2003
@@ -3,8 +3,8 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
+ * Copyright (c) 1999,2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * Copyright 1999 Ralf Baechle (ralf@gnu.org)
- * Copyright 1999,2001 Silicon Graphics, Inc.
  */
 #ifndef _ASM_SN_ARC_TYPES_H
 #define _ASM_SN_ARC_TYPES_H
diff -Nru a/include/asm-ia64/sn/arch.h b/include/asm-ia64/sn/arch.h
--- a/include/asm-ia64/sn/arch.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/sn/arch.h	Wed Jun 18 23:42:07 2003
@@ -6,7 +6,7 @@
  *
  * SGI specific setup.
  *
- * Copyright (C) 1995-1997,1999,2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (C) 1995-1997,1999,2001-2003 Silicon Graphics, Inc.  All rights reserved.
  * Copyright (C) 1999 Ralf Baechle (ralf@gnu.org)
  */
 #ifndef _ASM_IA64_SN_ARCH_H
@@ -17,23 +17,12 @@
 #include <linux/mmzone.h>
 #include <asm/sn/types.h>
 
-#if defined(CONFIG_IA64_SGI_SN1) 
-#include <asm/sn/sn1/arch.h>
-#elif defined(CONFIG_IA64_SGI_SN2)
 #include <asm/sn/sn2/arch.h>
-#endif
 
-
-#if defined(CONFIG_IA64_SGI_SN1) 
-typedef u64	bdrkreg_t;
-#elif defined(CONFIG_IA64_SGI_SN2)
 typedef u64	shubreg_t;
-#endif
-
 typedef u64	hubreg_t;
 typedef u64	mmr_t;
 typedef u64	nic_t;
-typedef char cnodeid_t;
 
 #define CNODE_TO_CPU_BASE(_cnode)	(NODEPDA(_cnode)->node_first_cpu)
 
diff -Nru a/include/asm-ia64/sn/ate_utils.h b/include/asm-ia64/sn/ate_utils.h
--- a/include/asm-ia64/sn/ate_utils.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/sn/ate_utils.h	Wed Jun 18 23:42:08 2003
@@ -7,7 +7,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 /*
diff -Nru a/include/asm-ia64/sn/bte.h b/include/asm-ia64/sn/bte.h
--- a/include/asm-ia64/sn/bte.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/sn/bte.h	Wed Jun 18 23:42:07 2003
@@ -1,7 +1,7 @@
 /*
  *
  *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
@@ -36,11 +36,28 @@
 #ifndef _ASM_IA64_SN_BTE_H
 #define _ASM_IA64_SN_BTE_H
 
-#ident "$Revision: 1.1 $"
-
+#include <linux/timer.h>
 #include <linux/spinlock.h>
 #include <linux/cache.h>
 #include <asm/sn/io.h>
+#include <asm/delay.h>
+
+
+/* #define BTE_DEBUG */
+/* #define BTE_DEBUG_VERBOSE */
+
+#ifdef BTE_DEBUG
+#  define BTE_PRINTK(x) printk x	/* Terse */
+#  ifdef BTE_DEBUG_VERBOSE
+#    define BTE_PRINTKV(x) printk x	/* Verbose */
+#  else
+#    define BTE_PRINTKV(x)
+#  endif /* BTE_DEBUG_VERBOSE */
+#else
+#  define BTE_PRINTK(x)
+#  define BTE_PRINTKV(x)
+#endif	/* BTE_DEBUG */
+
 
 /* BTE status register only supports 16 bits for length field */
 #define BTE_LEN_BITS (16)
@@ -48,40 +65,60 @@
 #define BTE_MAX_XFER ((1 << BTE_LEN_BITS) * L1_CACHE_BYTES)
 
 
-/*
- * Constants used in determining the best and worst case transfer
- * times. To help explain the two, the following graph of transfer
- * status vs time may help.
- *
- *     active +------------------:-+  :
- *  status    |                  : |  :
- *       idle +__________________:_+=======
- *            0 Time           MaxT  MinT
- *
- *  Therefore, MaxT is the maximum thoeretical rate for transfering
- *  the request block (assuming ideal circumstances)
- *
- *  MinT is the minimum theoretical rate for transferring the
- *  requested block (assuming maximum link distance and contention)
- *
- *  The following defines are the inverse of the above.  They are
- *  used for calculating the MaxT time and MinT time given the 
- *  number of lines in the transfer.
- */
-#define BTE_MAXT_LINES_PER_SECOND 800
-#define BTE_MINT_LINES_PER_SECOND 600
-
-
 /* Define hardware */
 #define BTES_PER_NODE 2
 
+
 /* Define hardware modes */
 #define BTE_NOTIFY (IBCT_NOTIFY)
 #define BTE_NORMAL BTE_NOTIFY
 #define BTE_ZERO_FILL (BTE_NOTIFY | IBCT_ZFIL_MODE)
-
 /* Use a reserved bit to let the caller specify a wait for any BTE */
 #define BTE_WACQUIRE (0x4000)
+/* macro to force the IBCT0 value valid */
+#define BTE_VALID_MODE(x) ((x) & (IBCT_NOTIFY | IBCT_ZFIL_MODE))
+
+
+/*
+ * Handle locking of the bte interfaces.
+ *
+ * All transfers spinlock the interface before setting up the SHUB
+ * registers.  Sync transfers hold the lock until all processing is
+ * complete.  Async transfers release the lock as soon as the transfer
+ * is initiated.
+ *
+ * To determine if an interface is available, we must check both the
+ * busy bit and the spinlock for that interface.
+ */
+#define BTE_LOCK_IF_AVAIL(_x) (\
+	(*pda->cpu_bte_if[_x]->most_rcnt_na & (IBLS_BUSY | IBLS_ERROR)) && \
+	(!(spin_trylock(&(pda->cpu_bte_if[_x]->spinlock)))) \
+	)
+
+/*
+ * Some macros to simplify reading.
+ * Start with macros to locate the BTE control registers.
+ */
+#define BTEREG_LNSTAT_ADDR ((u64 *)(bte->bte_base_addr))
+#define BTEREG_SRC_ADDR ((u64 *)(bte->bte_base_addr + BTEOFF_SRC))
+#define BTEREG_DEST_ADDR ((u64 *)(bte->bte_base_addr + BTEOFF_DEST))
+#define BTEREG_CTRL_ADDR ((u64 *)(bte->bte_base_addr + BTEOFF_CTRL))
+#define BTEREG_NOTIF_ADDR ((u64 *)(bte->bte_base_addr + BTEOFF_NOTIFY))
+
+
+/* Possible results from bte_copy and bte_unaligned_copy */
+typedef enum {
+	BTE_SUCCESS,		/* 0 is success */
+	BTEFAIL_NOTAVAIL,	/* BTE not available */
+	BTEFAIL_POISON,		/* poison page */
+	BTEFAIL_PROT,		/* Protection violation */
+	BTEFAIL_ACCESS,		/* access error */
+	BTEFAIL_TOUT,		/* Time out */
+	BTEFAIL_XTERR,		/* Diretory error */
+	BTEFAIL_DIR,		/* Diretory error */
+	BTEFAIL_ERROR,		/* Generic error */
+} bte_result_t;
+
 
 /*
  * Structure defining a bte.  An instance of this
@@ -90,28 +127,41 @@
  * This structure contains everything necessary
  * to work with a BTE.
  */
-typedef struct bteinfo_s {
+struct bteinfo_s {
 	u64 volatile notify ____cacheline_aligned;
 	char *bte_base_addr ____cacheline_aligned;
 	spinlock_t spinlock;
-	u64 ideal_xfr_tmo;	/* Time out */
-	u64 ideal_xfr_tmo_cnt;
-	/* u64 most_recent_src;
-	 * u64 most_recent_dest;
-	 * u64 most_recent_len;
-	 * u64 most_recent_mode; */
+	cnodeid_t bte_cnode;	/* cnode                            */
+	int bte_error_count;	/* Number of errors encountered     */
+	int bte_num;		/* 0 --> BTE0, 1 --> BTE1           */
+	int cleanup_active;	/* Interface is locked for cleanup  */
+	volatile bte_result_t bh_error;	/* error while processing   */
 	u64 volatile *most_rcnt_na;
-	void *bte_test_buf;
-} bteinfo_t;
+	void *scratch_buf;	/* Node local scratch buffer        */
+};
 
-/* Possible results from bte_copy and bte_unaligned_copy */
-typedef enum {
-	BTE_SUCCESS,		/* 0 is success */
-	BTEFAIL_NOTAVAIL,	/* BTE not available */
-	BTEFAIL_ERROR,		/* Generic error */
-	BTEFAIL_DIR		/* Diretory error */
-} bte_result_t;
 
-void bte_reset_nasid(nasid_t);
+/*
+ * Function prototypes (functions defined in bte.c, used elsewhere)
+ */
+extern bte_result_t bte_copy(u64, u64, u64, u64, void *);
+extern bte_result_t bte_unaligned_copy(u64, u64, u64, u64);
+extern void bte_error_handler(unsigned long);
+
+
+/*
+ * The following is the prefered way of calling bte_unaligned_copy
+ * If the copy is fully cache line aligned, then bte_copy is
+ * used instead.  Since bte_copy is inlined, this saves a call
+ * stack.  NOTE: bte_copy is called synchronously and does block
+ * until the transfer is complete.  In order to get the asynch
+ * version of bte_copy, you must perform this check yourself.
+ */
+#define BTE_UNALIGNED_COPY(src, dest, len, mode)                        \
+	(((len & L1_CACHE_MASK) || (src & L1_CACHE_MASK) ||             \
+	  (dest & L1_CACHE_MASK)) ?                                     \
+	 bte_unaligned_copy(src, dest, len, mode) :              	\
+	 bte_copy(src, dest, len, mode, NULL))
+
 
-#endif				/* _ASM_IA64_SN_BTE_H */
+#endif	/* _ASM_IA64_SN_BTE_H */
diff -Nru a/include/asm-ia64/sn/bte_copy.h b/include/asm-ia64/sn/bte_copy.h
--- a/include/asm-ia64/sn/bte_copy.h	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,385 +0,0 @@
-/*
- *
- *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#ifndef _ASM_IA64_SN_BTE_COPY_H
-#define _ASM_IA64_SN_BTE_COPY_H
-
-#ident "$Revision: 1.1 $"
-
-#include <linux/timer.h>
-#include <linux/cache.h>
-#include <asm/sn/bte.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/pda.h>
-#include <asm/delay.h>
-
-#define L1_CACHE_MASK (L1_CACHE_BYTES - 1)
-
-/*
- * BTE_LOCKING support - When CONFIG_IA64_SGI_BTE_LOCKING is
- * not defined, the bte_copy code supports one bte per cpu in
- * synchronous mode.  Even if bte_copy is called with a
- * notify address, the bte will spin and wait for the transfer
- * to complete.  By defining the following, spin_locks and
- * busy checks are placed around the initiation of a BTE
- * transfer and multiple bte's per cpu are supported.
- */
-#if 0
-#define CONFIG_IA64_SGI_BTE_LOCKING 1
-#endif
-
-/*
- * Handle locking of the bte interfaces.
- *
- * All transfers spinlock the interface before setting up the SHUB
- * registers.  Sync transfers hold the lock until all processing is
- * complete.  Async transfers release the lock as soon as the transfer
- * is initiated.
- *
- * To determine if an interface is available, we must check both the
- * busy bit and the spinlock for that interface.
- */
-#define BTE_LOCK_IF_AVAIL(_x) (\
-	(*pda.cpu_bte_if[_x]->most_rcnt_na & IBLS_BUSY) && \
-	(!(spin_trylock(&(pda.cpu_bte_if[_x]->spinlock)))) \
-	)
-
-/*
- * Some macros to simplify reading.
- *
- * Start with macros to locate the BTE control registers.
- */
-
-#define BTEREG_LNSTAT_ADDR ((u64 *)(bte->bte_base_addr))
-#define BTEREG_SRC_ADDR ((u64 *)(bte->bte_base_addr + BTEOFF_SRC))
-#define BTEREG_DEST_ADDR ((u64 *)(bte->bte_base_addr + BTEOFF_DEST))
-#define BTEREG_CTRL_ADDR ((u64 *)(bte->bte_base_addr + BTEOFF_CTRL))
-#define BTEREG_NOTIF_ADDR ((u64 *)(bte->bte_base_addr + BTEOFF_NOTIFY))
-
-/* Some macros to force the IBCT0 value valid. */
-
-#define BTE_VALID_MODES BTE_NOTIFY
-#define BTE_VLD_MODE(x) (x & BTE_VALID_MODES)
-
-// #define BTE_DEBUG
-// #define BTE_DEBUG_VERBOSE
-// #define BTE_TIME
-
-#ifdef BTE_DEBUG
-#  define BTE_PRINTK(x) printk x	/* Terse */
-#  ifdef BTE_DEBUG_VERBOSE
-#    define BTE_PRINTKV(x) printk x	/* Verbose */
-#  else
-#    define BTE_PRINTKV(x)
-#  endif /* BTE_DEBUG_VERBOSE */
-#else
-#  define BTE_PRINTK(x)
-#  define BTE_PRINTKV(x)
-#endif /* BTE_DEBUG */
-
-#define BTE_IDEAL_TMO(x) (jiffies + \
-	(HZ / BTE_MAXT_LINES_PER_SECOND * x))
-
-#ifdef BTE_TIME
-volatile extern u64 bte_setup_time;
-volatile extern u64 bte_transfer_time;
-volatile extern u64 bte_tear_down_time;
-volatile extern u64 bte_execute_time;
-
-#define BTE_TIME_DECLARE() \
-	u64 btcp_strt_tm = 0; \
-	u64 btcp_cplt_tm = 0; \
-	u64 xfr_strt_tm = 0; \
-	u64 xfr_cplt_tm = 0; \
-
-#define BTE_TIME_START() \
-	btcp_strt_tm = xfr_strt_tm = xfr_cplt_tm = ia64_get_itc();
-
-#define BTE_TIME_XFR_START() \
-	xfr_strt_tm = ia64_get_itc();
-
-#define BTE_TIME_XFR_STOP() \
-	xfr_cplt_tm = ia64_get_itc();
-
-#define BTE_TIME_STOP() \
-	btcp_cplt_tm = ia64_get_itc(); \
-	bte_setup_time = xfr_strt_tm - btcp_strt_tm; \
-	bte_transfer_time = xfr_cplt_tm - xfr_strt_tm; \
-	bte_tear_down_time = btcp_cplt_tm - xfr_cplt_tm; \
-	bte_execute_time = btcp_cplt_tm - btcp_strt_tm; \
-
-#else /* BTE_TIME */
-#define BTE_TIME_DECLARE()
-#define BTE_TIME_START()
-#define BTE_TIME_XFR_START()
-#define BTE_TIME_XFR_STOP()
-#define BTE_TIME_STOP()
-#endif /* BTE_TIME */
-
-/*
- * bte_copy(src, dest, len, mode, notification)
- *
- * use the block transfer engine to move kernel
- * memory from src to dest using the assigned mode.
- *
- * Paramaters:
- *   src - physical address of the transfer source.
- *   dest - physical address of the transfer destination.
- *   len - number of bytes to transfer from source to dest.
- *   mode - hardware defined.  See reference information
- *          for IBCT0/1 in the SHUB Programmers Reference
- *   notification - kernel virtual address of the notification cache
- *                  line.  If NULL, the default is used and
- *                  the bte_copy is synchronous.
- *
- * NOTE:  This function requires src, dest, and len to
- * be cache line aligned.
- */
-extern __inline__ bte_result_t
-bte_copy(u64 src, u64 dest, u64 len, u64 mode, void *notification)
-{
-#ifdef CONFIG_IA64_SGI_BTE_LOCKING
-	int bte_to_use;
-#endif /* CONFIG_IA64_SGI_BTE_LOCKING */
-	u64 transfer_size;
-	u64 lines_remaining;
-	bteinfo_t *bte;
-	BTE_TIME_DECLARE();
-
-	BTE_TIME_START();
-
-	BTE_PRINTK(("bte_copy (0x%lx, 0x%lx, 0x%lx, 0x%lx, 0x%lx)\n",
-		    src, dest, len, mode, notification));
-
-	if (len == 0) {
-		BTE_TIME_STOP();
-		return (BTE_SUCCESS);
-	}
-
-	ASSERT(!((len & L1_CACHE_MASK) ||
-		 (src & L1_CACHE_MASK) || (dest & L1_CACHE_MASK)));
-
-	ASSERT(len < ((BTE_LEN_MASK + 1) << L1_CACHE_SHIFT));
-
-#ifdef CONFIG_IA64_SGI_BTE_LOCKING
-	{
-		bte_to_use = 0;
-
-		/* Attempt to lock one of the BTE interfaces */
-		while ((bte_to_use < BTES_PER_NODE) &&
-		       BTE_LOCK_IF_AVAIL(bte_to_use)) {
-
-			bte_to_use++;
-		}
-
-		if ((bte_to_use >= BTES_PER_NODE) &&
-		    !(mode & BTE_WACQUIRE)) {
-			BTE_TIME_STOP();
-			return (BTEFAIL_NOTAVAIL);
-		}
-
-		/* Wait until a bte is available. */
-	}
-	while (bte_to_use >= BTES_PER_NODE);
-
-	bte = pda.cpu_bte_if[bte_to_use];
-	BTE_PRINTKV(("Got a lock on bte %d\n", bte_to_use));
-#else
-	/* Assuming one BTE per CPU. */
-	bte = pda->cpu_bte_if[0];
-#endif /* CONFIG_IA64_SGI_BTE_LOCKING */
-
-	/*
-	 * The following are removed for optimization but is
-	 * available in the event that the SHUB exhibits
-	 * notification problems similar to the hub, bedrock et al.
-	 *
-	 * bte->mostRecentSrc = src;
-	 * bte->mostRecentDest = dest;
-	 * bte->mostRecentLen = len;
-	 * bte->mostRecentMode = mode;
-	 */
-	if (notification == NULL) {
-		/* User does not want to be notified. */
-		bte->most_rcnt_na = &bte->notify;
-	} else {
-		bte->most_rcnt_na = notification;
-	}
-
-	/* Calculate the number of cache lines to transfer. */
-	transfer_size = ((len >> L1_CACHE_SHIFT) & BTE_LEN_MASK);
-
-	BTE_PRINTKV(("Calculated transfer size of %d cache lines\n",
-		     transfer_size));
-
-	/* Initialize the notification to a known value. */
-	*bte->most_rcnt_na = -1L;
-
-
-	BTE_PRINTKV(("Before, status is 0x%lx and notify is 0x%lx\n",
-		     HUB_L(BTEREG_LNSTAT_ADDR),
-		     *bte->most_rcnt_na));
-
-	/* Set the status reg busy bit and transfer length */
-	BTE_PRINTKV(("IBLS - HUB_S(0x%lx, 0x%lx)\n",
-		     BTEREG_LNSTAT_ADDR, IBLS_BUSY | transfer_size));
-	HUB_S(BTEREG_LNSTAT_ADDR, (IBLS_BUSY | transfer_size));
-
-	/* Set the source and destination registers */
-	BTE_PRINTKV(("IBSA - HUB_S(0x%lx, 0x%lx)\n", BTEREG_SRC_ADDR,
-		     (TO_PHYS(src))));
-	HUB_S(BTEREG_SRC_ADDR, (TO_PHYS(src)));
-	BTE_PRINTKV(("IBDA - HUB_S(0x%lx, 0x%lx)\n", BTEREG_DEST_ADDR,
-		     (TO_PHYS(dest))));
-	HUB_S(BTEREG_DEST_ADDR, (TO_PHYS(dest)));
-
-	/* Set the notification register */
-	BTE_PRINTKV(("IBNA - HUB_S(0x%lx, 0x%lx)\n", BTEREG_NOTIF_ADDR,
-		     (TO_PHYS(__pa(bte->most_rcnt_na)))));
-	HUB_S(BTEREG_NOTIF_ADDR, (TO_PHYS(__pa(bte->most_rcnt_na))));
-
-	/* Initiate the transfer */
-	BTE_PRINTKV(("IBCT - HUB_S(0x%lx, 0x%lx)\n", BTEREG_CTRL_ADDR, mode));
-	BTE_TIME_XFR_START();
-	HUB_S(BTEREG_CTRL_ADDR, BTE_VLD_MODE(mode));
-
-	BTE_PRINTKV(("Initiated, status is 0x%lx and notify is 0x%lx\n",
-		     HUB_L(BTEREG_LNSTAT_ADDR),
-		     *bte->most_rcnt_na));
-
-	if (notification == NULL) {
-		/*
-		 * Calculate our timeout
-		 *
-		 * What are we doing here?  We are trying to determine
-		 * the fastest time the BTE could have transfered our
-		 * block of data.  By takine the clock frequency (ticks/sec)
-		 * divided by the BTE MaxT Transfer Rate (lines/sec)
-		 * times the transfer size (lines), we get a tick
-		 * offset from current time that the transfer should
-		 * complete.
-		 *
-		 * Why do this?  We are watching for a notification
-		 * failure from the BTE.  This behaviour has been
-		 * seen in the SN0 and SN1 hardware on rare circumstances
-		 * and is expected in SN2.  By checking at the
-		 * ideal transfer timeout, we minimize our time
-		 * delay from hardware completing our request and
-		 * our detecting the failure.
-		 */
-		bte->ideal_xfr_tmo = BTE_IDEAL_TMO(transfer_size);
-
-		while (bte->notify == -1UL) {
-			/*
-			 * Notification Workaround: When the max
-			 * theoretical time has elapsed, read the hub
-			 * status register into the notification area.
-			 * This fakes the shub performing the copy.
-			 */
-			BTE_PRINTKV(("  Timing.  IBLS = 0x%lx, "
-				     "notify= 0x%lx\n",
-				     HUB_L(BTEREG_LNSTAT_ADDR),
-				     bte->notify));
-			if (time_after(jiffies, bte->ideal_xfr_tmo)) {
-				lines_remaining = HUB_L(BTEREG_LNSTAT_ADDR) &
-					BTE_LEN_MASK;
-				bte->ideal_xfr_tmo_cnt++;
-				bte->ideal_xfr_tmo =
-					BTE_IDEAL_TMO(lines_remaining);
-
-				BTE_PRINTKV(("  Timeout.  cpu %d "
-					     "IBLS = 0x%lx, "
-					     "notify= 0x%lx, "
-					     "Lines remaining = %d. "
-					     "New timeout = %d.\n",
-					     smp_processor_id(),
-					     HUB_L(BTEREG_LNSTAT_ADDR),
-					     bte->notify,
-					     lines_remaining,
-					     bte->ideal_xfr_tmo));
-			}
-		}
-		BTE_PRINTKV((" Delay Done.  IBLS = 0x%lx, notify= 0x%lx\n",
-			     HUB_L(BTEREG_LNSTAT_ADDR),
-			  bte->notify));
-		BTE_TIME_XFR_STOP();
-		if (bte->notify & IBLS_ERROR) {
-			/* >>> Need to do real error checking. */
-			transfer_size = 0;
-
-#ifdef CONFIG_IA64_SGI_BTE_LOCKING
-			spin_unlock(&(bte->spinlock));
-#endif /* CONFIG_IA64_SGI_BTE_LOCKING */
-			BTE_PRINTKV(("Erroring status is 0x%lx and "
-				     "notify is 0x%lx\n",
-				     HUB_L(BTEREG_LNSTAT_ADDR),
-				     bte->notify));
-
-			BTE_TIME_STOP();
-			bte->notify = 0L;
-			return (BTEFAIL_ERROR);
-		}
-
-	}
-#ifdef CONFIG_IA64_SGI_BTE_LOCKING
-	spin_unlock(&(bte->spinlock));
-#endif /* CONFIG_IA64_SGI_BTE_LOCKING */
-	BTE_TIME_STOP();
-	BTE_PRINTKV(("Returning status is 0x%lx and notify is 0x%lx\n",
-		     HUB_L(BTEREG_LNSTAT_ADDR),
-		     *bte->most_rcnt_na));
-
-	return (BTE_SUCCESS);
-}
-
-/*
- * Define the bte_unaligned_copy as an extern.
- */
-extern bte_result_t bte_unaligned_copy(u64, u64, u64, u64);
-
-/*
- * The following is the prefered way of calling bte_unaligned_copy
- * If the copy is fully cache line aligned, then bte_copy is
- * used instead.  Since bte_copy is inlined, this saves a call
- * stack.  NOTE: bte_copy is called synchronously and does block
- * until the transfer is complete.  In order to get the asynch
- * version of bte_copy, you must perform this check yourself.
- */
-#define BTE_UNALIGNED_COPY(src, dest, len, mode)			\
-	(((len & L1_CACHE_MASK) || (src & L1_CACHE_MASK) ||		\
-	  (dest & L1_CACHE_MASK)) ?					\
-		bte_unaligned_copy(src, dest, len, mode) :		\
-		bte_copy(src, dest, len, mode, NULL))
-
-#endif /* _ASM_IA64_SN_BTE_COPY_H */
diff -Nru a/include/asm-ia64/sn/cdl.h b/include/asm-ia64/sn/cdl.h
--- a/include/asm-ia64/sn/cdl.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/sn/cdl.h	Wed Jun 18 23:42:08 2003
@@ -4,13 +4,20 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_CDL_H
 #define _ASM_IA64_SN_CDL_H
 
 #include <asm/sn/sgi.h>
 
+struct cdl {
+	int part_num;			/* Part part number */
+	int mfg_num;			/* Part MFG number */
+	int (*attach)(vertex_hdl_t);	/* Attach routine */
+};
+
+
 /*
  *	cdl: connection/driver list
  *
@@ -21,175 +28,14 @@
 typedef struct cdl     *cdl_p;
 
 /*
- *	cdl_itr_f is the type for the functions
- *	that are handled by cdl_iterate.
- */
-
-typedef void	
-cdl_iter_f		(devfs_handle_t vhdl);
-
-/*
- *	cdl_drv_f is the type for the functions
- *	that are called by cdl_add_driver and 
- *      cdl_del_driver.
- */
-
-typedef void	
-cdl_drv_f		(devfs_handle_t vhdl, int key1, int key2, int error);
-
-/*
- *	If CDL_PRI_HI is specified in the flags
- *	parameter for cdl_add_driver, then that driver's
- *	attach routine will be called for future connect
- *	points before any (non-CDL_PRI_HI) drivers.
- *
- *	The IOC3 driver uses this facility to make sure
- *	that the ioc3_attach() function is called before
- *	the attach routines of any subdevices.
- *
- *	Drivers for bridge-based crosstalk cards that
- *	are almost but not quite generic can use it to
- *	arrange that their attach() functions get called
- *	before the generic bridge drivers, so they can
- *	leave behind "hint" structures that will
- *	properly configure the generic driver.
- */
-#define	CDL_PRI_HI	0x0001
-
-/*
- *	cdl_new: construct a new connection/driver list
- *
- *	Called once for each "kind" of bus. Returns an
- *	opaque cookie representing the particular list
- *	that will be operated on by the other calls.
- */
-extern cdl_p		cdl_new(char *, char *, char *);
-
-/*
- *	cdl_del: destroy a connection/driver list.
- *
- *	Releases all dynamically allocated resources
- *	associated with the specified list. Forgets what
- *	drivers might be involved in this kind of bus,
- *	forgets what connection points have been noticed
- *	on this kind of bus.
- */
-extern void		cdl_del(cdl_p reg);
-
-/*
- *	cdl_add_driver: register a device driver
- *
- *	Calls the driver's attach routine with all
- *	connection points on the list that have the same
- *	key information as the driver; call-back the 
- *      specified function to notify the driver of the 
- *      attach status for each device.  Place the driver
- *      on the list so that any connection points
- *	discovered in the future that match the driver
- *	can be handed off to the driver's attach
- *	routine.
- *
- *	CDL_PRI_HI may be specified (see above).
- */
-
-extern int		cdl_add_driver(cdl_p reg,
-				       int key1,
-				       int key2,
-				       char *prefix,
-				       int flags,
-				       cdl_drv_f *func);
-
-/*
- *	cdl_del_driver: remove a device driver
- *
- *	Calls the driver's detach routine with all
- *	connection points on the list that match the
- *	driver;  call-back the specified function to
- *      notify the driver of the detach status for each
- *      device.  Then forget about the driver.  Future
- *	calls to cdl_add_connpt with connections that
- *	would match this driver no longer trigger calls
- *	to the driver's attach routine.
- *
- *	NOTE: Yes, I said CONNECTION POINTS, not
- *	verticies that the driver has been attached to
- *	with hwgraph_driver_add(); this gives the driver
- *	a chance to clean up anything it did to the
- *	connection point in its attach routine. Also,
- *	this is done whether or not the attach routine
- *	was successful.
- */
-extern void		cdl_del_driver(cdl_p reg, 
-				       char *prefix,
-				       cdl_drv_f *func);
-
-/*
  *	cdl_add_connpt: add a connection point
  *
  *	Calls the attach routines of all the drivers on
  *	the list that match this connection point, in
- *	the order that they were added to the list,
- *	except that CDL_PRI_HI drivers are called first.
- *
- *	Then the vertex is added to the list, so it can
- *	be presented to any matching drivers that may be
- *	subsequently added to the list.
+ *	the order that they were added to the list.
  */
-extern int		cdl_add_connpt(cdl_p reg,
-				       int key1,
+extern int		cdl_add_connpt(int key1,
 				       int key2,
-				       devfs_handle_t conn,
+				       vertex_hdl_t conn,
 				       int drv_flags);
-
-/*
- *	cdl_del_connpt: delete a connection point
- *
- *	Calls the detach routines of all matching
- *	drivers for this connection point, in the same
- *	order that the attach routines were called; then
- *	forgets about this vertex, so drivers added in
- *	the future will not be told about it.
- *
- *	NOTE: Same caveat here about the detach calls as
- *	in the cdl_del_driver() comment above.
- */
-extern int		cdl_del_connpt(cdl_p reg,
-				       int key1,
-				       int key2,
-				       devfs_handle_t conn,
-				       int drv_flags);
-
-/*
- *	cdl_iterate: find all verticies in the registry
- *	corresponding to the named driver and call them
- *	with the specified function (giving the vertex
- *	as the parameter).
- */
-
-extern void		cdl_iterate(cdl_p reg,
-				    char *prefix,
-				    cdl_iter_f *func);
-
-/*
- * An INFO_LBL_ASYNC_ATTACH label is attached to a vertex, pointing to
- * an instance of async_attach_s to indicate that asynchronous
- * attachment may be applied to that device ... if the corresponding
- * driver allows it.
- */
-
-struct async_attach_s {
-	struct semaphore async_sema;
-	int    async_count;
-};
-typedef struct async_attach_s *async_attach_t;
-
-async_attach_t	async_attach_new(void);
-void		async_attach_free(async_attach_t);
-async_attach_t  async_attach_get_info(devfs_handle_t);
-void            async_attach_add_info(devfs_handle_t, async_attach_t);
-void            async_attach_del_info(devfs_handle_t);
-void		async_attach_signal_start(async_attach_t);
-void		async_attach_signal_done(async_attach_t);
-void		async_attach_waitall(async_attach_t);
-
 #endif /* _ASM_IA64_SN_CDL_H */
diff -Nru a/include/asm-ia64/sn/clksupport.h b/include/asm-ia64/sn/clksupport.h
--- a/include/asm-ia64/sn/clksupport.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/sn/clksupport.h	Wed Jun 18 23:42:08 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 /*
@@ -31,28 +31,10 @@
 typedef long clkreg_t;
 extern unsigned long sn_rtc_cycles_per_second;
 
-
-#if defined(CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/bedrock.h>
-#include <asm/sn/sn1/hubpi_next.h>
-
-extern nasid_t master_nasid;
-
-#define RTC_MASK		(0x007fffffffffffff)
-/* clocks are not synchronized yet on SN1  - used node 0 (problem if no NASID 0) */
-#define RTC_COUNTER_ADDR	((clkreg_t*)REMOTE_HUB_ADDR(master_nasid, PI_RT_COUNTER))
-#define RTC_COMPARE_A_ADDR      ((clkreg_t*)REMOTE_HUB_ADDR(master_nasid, PI_RT_COMPARE_A))
-#define RTC_COMPARE_B_ADDR      ((clkreg_t*)REMOTE_HUB_ADDR(master_nasid, PI_RT_COMPARE_B))
-#define RTC_INT_PENDING_A_ADDR  ((clkreg_t*)REMOTE_HUB_ADDR(master_nasid, PI_RT_INT_PEND_A))
-#define RTC_INT_PENDING_B_ADDR  ((clkreg_t*)REMOTE_HUB_ADDR(master_nasid, PI_RT_INT_PEND_B))
-#define RTC_INT_ENABLED_A_ADDR  ((clkreg_t*)REMOTE_HUB_ADDR(master_nasid, PI_RT_INT_EN_A))
-#define RTC_INT_ENABLED_B_ADDR  ((clkreg_t*)REMOTE_HUB_ADDR(master_nasid, PI_RT_INT_EN_B))
-#else	/* !CONFIG_IA64_SGI_SN1 */
 #include <asm/sn/addrs.h>
 #include <asm/sn/sn2/addrs.h>
 #include <asm/sn/sn2/shubio.h>
 #include <asm/sn/sn2/shub_mmr.h>
-#define RTC_MASK		(SH_RTC_MASK)
 #define RTC_COUNTER_ADDR	((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
 #define RTC_COMPARE_A_ADDR      ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
 #define RTC_COMPARE_B_ADDR      ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
@@ -60,8 +42,6 @@
 #define RTC_INT_PENDING_B_ADDR  ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
 #define RTC_INT_ENABLED_A_ADDR  ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
 #define RTC_INT_ENABLED_B_ADDR  ((clkreg_t*)LOCAL_MMR_ADDR(SH_RTC))
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
 
 #define GET_RTC_COUNTER()	(*RTC_COUNTER_ADDR)
 #define rtc_time()		GET_RTC_COUNTER()
diff -Nru a/include/asm-ia64/sn/dmamap.h b/include/asm-ia64/sn/dmamap.h
--- a/include/asm-ia64/sn/dmamap.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-ia64/sn/dmamap.h	Wed Jun 18 23:42:09 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_DMAMAP_H
 #define _ASM_IA64_SN_DMAMAP_H
@@ -54,9 +54,6 @@
 extern int	dma_map(dmamap_t *, caddr_t, int);
 extern int	dma_map2(dmamap_t *, caddr_t, caddr_t, int);
 extern paddr_t	dma_mapaddr(dmamap_t *, caddr_t);
-#ifdef LATER
-extern int	dma_mapbp(dmamap_t *, buf_t *, int);
-#endif
 extern int	dma_map_alenlist(dmamap_t *, struct alenlist_s *, size_t);
 extern uint	ev_kvtoiopnum(caddr_t);
 
diff -Nru a/include/asm-ia64/sn/driver.h b/include/asm-ia64/sn/driver.h
--- a/include/asm-ia64/sn/driver.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/sn/driver.h	Wed Jun 18 23:42:07 2003
@@ -4,12 +4,12 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_DRIVER_H
 #define _ASM_IA64_SN_DRIVER_H
 
-#include <linux/devfs_fs_kernel.h>
+#include <asm/sn/sgi.h>
 #include <asm/types.h>
 
 /*
@@ -75,7 +75,7 @@
 	/* TBD: allocated badwidth requirements */
 
 	/* interrupt description */
-	devfs_handle_t	intr_target;	/* Hardware locator string */
+	vertex_hdl_t	intr_target;	/* Hardware locator string */
 	int 		intr_policy;	/* TBD */
 	ilvl_t		intr_swlevel;	/* software level for blocking intr */
 	char		*intr_name;	/* name of interrupt, if any */
diff -Nru a/include/asm-ia64/sn/eeprom.h b/include/asm-ia64/sn/eeprom.h
--- a/include/asm-ia64/sn/eeprom.h	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,384 +0,0 @@
-/* $Id$
- *
- * 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.
- *
- * Public interface for reading Atmel EEPROMs via L1 system controllers
- *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_EEPROM_H
-#define _ASM_IA64_SN_EEPROM_H
-
-#include <linux/config.h>
-#include <asm/sn/sgi.h>
-#include <asm/sn/vector.h>
-#include <asm/sn/xtalk/xbow.h>
-#include <asm/sn/pci/bridge.h>
-#include <asm/sn/nic.h>
-
-/*
- * The following structures are an implementation of the EEPROM info
- * areas described in the SN1 EEPROM spec and the IPMI FRU Information
- * Storage definition
- */
-
-/* Maximum lengths for EEPROM fields
- */
-#define EEPROM_PARTNUM_LEN	20
-#define EEPROM_SERNUM_LEN	10
-#define	EEPROM_MANUF_NAME_LEN	10
-#define EEPROM_PROD_NAME_LEN	14
-
-
-
-/* The EEPROM "common header", which contains offsets to the other
- * info areas in the EEPROM
- */
-typedef struct eeprom_common_hdr_t
-{
-    uchar_t	format;		/* common header format byte */
-    uchar_t	internal_use;	/* offsets to various info areas */
-    uchar_t	chassis;	/*  (in doubleword units)        */
-    uchar_t	board;
-    uchar_t	product;
-    uchar_t	multi_record;
-    uchar_t	pad;
-    uchar_t	checksum;
-} eeprom_common_hdr_t;
-
-
-/* The chassis (brick) info area 
- */
-typedef struct eeprom_chassis_ia_t
-{
-    uchar_t	format;		/* format byte */
-    uchar_t	length;		/* info area length in doublewords */
-    uchar_t	type;		/* chassis type (always 0x17 "rack mount") */
-    uchar_t	part_num_tl;	/* type/length of part number field */
-
-    char	part_num[EEPROM_PARTNUM_LEN];
-    				/* ASCII part number */
-
-    uchar_t	serial_num_tl;	/* type/length of serial number field */
-
-    char	serial_num[EEPROM_SERNUM_LEN];
-    				/* ASCII serial number */
-
-    uchar_t	checksum;
-
-} eeprom_chassis_ia_t;
-
-
-/* The board info area
- */
-typedef struct eeprom_board_ia_t
-{
-    uchar_t       format;         /* format byte */
-    uchar_t       length;         /* info area length in doublewords */
-    uchar_t	language;	/* language code, always 0x00 "English" */
-    int		mfg_date;	/* date & time of manufacture, in minutes
-				    since 0:00 1/1/96 */
-    uchar_t	manuf_tl;	/* type/length of manufacturer name field */
-
-    char	manuf[EEPROM_MANUF_NAME_LEN];
-				/* ASCII manufacturer name */
-
-    uchar_t	product_tl;	/* type/length of product name field */
-
-    char	product[EEPROM_PROD_NAME_LEN];
-				/* ASCII product name */
-
-    uchar_t	serial_num_tl;	/* type/length of board serial number */
-
-    char	serial_num[EEPROM_SERNUM_LEN];
-				/* ASCII serial number */
-
-    uchar_t	part_num_tl;	/* type/length of board part number */
-
-    char	part_num[EEPROM_PARTNUM_LEN];
-				/* ASCII part number */
-
-    /*
-     * "custom" fields -- see SN1 EEPROM Spec
-     */
-    uchar_t	board_rev_tl;	/* type/length of board rev (always 0xC2) */
-
-    char	board_rev[2];	/* ASCII board revision */
-
-    uchar_t	eeprom_size_tl; /* type/length of eeprom size field */
-    uchar_t	eeprom_size;	/* size code for eeprom */
-    uchar_t	temp_waiver_tl;	/* type/length of temp waiver field (0xC2) */
-    char	temp_waiver[2];	/* temp waiver */
-
-    
-    /*
-     * these fields only appear in main boards' EEPROMs
-     */
-    uchar_t	ekey_G_tl;	/* type/length of encryption key "G" */
-    uint32_t	ekey_G;		/* encryption key "G" */
-    uchar_t	ekey_P_tl;	/* type/length of encryption key "P" */
-    uint32_t	ekey_P;		/* encryption key "P" */
-    uchar_t	ekey_Y_tl;	/* type/length of encryption key "Y" */
-    uint32_t	ekey_Y;		/* encryption key "Y" */
-
-    
-    /*
-     * these fields are used for I bricks only
-     */
-    uchar_t	mac_addr_tl;	  /* type/length of MAC address */
-    char	mac_addr[12];	  /* MAC address */
-    uchar_t	ieee1394_cfg_tl;  /* type/length of IEEE 1394 info */
-    uchar_t	ieee1394_cfg[32]; /* IEEE 1394 config info */
-    
-
-    /*
-     * all boards have a checksum
-     */
-    uchar_t	checksum;
-
-} eeprom_board_ia_t;
-
-/* given a pointer to the three-byte little-endian EEPROM representation
- * of date-of-manufacture, this function translates to a big-endian
- * integer format
- */
-int eeprom_xlate_board_mfr_date( uchar_t *src );
-
-
-/* EEPROM Serial Presence Detect record (used for DIMMs in IP35)
- */
-typedef struct eeprom_spd_t
-{
-    /* 0*/ uchar_t spd_used; /* # of bytes written to serial memory by manufacturer */
-    /* 1*/ uchar_t spd_size; /* Total # of bytes of SPD memory device */
-    /* 2*/ uchar_t mem_type; /* Fundamental memory type (FPM, EDO, SDRAM..) */
-    /* 3*/ uchar_t num_rows; /* # of row addresses on this assembly */
-    /* 4*/ uchar_t num_cols; /* # Column Addresses on this assembly */
-    /* 5*/ uchar_t mod_rows; /* # Module Rows on this assembly */
-    /* 6*/ uchar_t data_width[2]; /* Data Width of this assembly (16b little-endian) */
-    /* 8*/ uchar_t volt_if; /* Voltage interface standard of this assembly */
-    /* 9*/ uchar_t cyc_time; /* SDRAM Cycle time, CL=X (highest CAS latency) */
-    /* A*/ uchar_t acc_time; /* SDRAM Access from Clock (highest CAS latency) */
-    /* B*/ uchar_t dimm_cfg; /* DIMM Configuration type (non-parity, ECC) */
-    /* C*/ uchar_t refresh_rt; /* Refresh Rate/Type */
-    /* D*/ uchar_t prim_width; /* Primary SDRAM Width */
-    /* E*/ uchar_t ec_width; /* Error Checking SDRAM width */
-    /* F*/ uchar_t min_delay; /* Min Clock Delay Back to Back Random Col Address */
-    /*10*/ uchar_t burst_len; /* Burst Lengths Supported */
-    /*11*/ uchar_t num_banks; /* # of Banks on Each SDRAM Device */
-    /*12*/ uchar_t cas_latencies; /* CAS# Latencies Supported */
-    /*13*/ uchar_t cs_latencies; /* CS# Latencies Supported */
-    /*14*/ uchar_t we_latencies; /* Write Latencies Supported */
-    /*15*/ uchar_t mod_attrib; /* SDRAM Module Attributes */
-    /*16*/ uchar_t dev_attrib; /* SDRAM Device Attributes: General */
-    /*17*/ uchar_t cyc_time2; /* Min SDRAM Cycle time at CL X-1 (2nd highest CAS latency) */
-    /*18*/ uchar_t acc_time2; /* SDRAM Access from Clock at CL X-1 (2nd highest CAS latency) */
-    /*19*/ uchar_t cyc_time3; /* Min SDRAM Cycle time at CL X-2 (3rd highest CAS latency) */
-    /*1A*/ uchar_t acc_time3; /* Max SDRAM Access from Clock at CL X-2 (3nd highest CAS latency) */
-    /*1B*/ uchar_t min_row_prechg; /* Min Row Precharge Time (Trp) */
-    /*1C*/ uchar_t min_ra_to_ra; /* Min Row Active to Row Active (Trrd) */
-    /*1D*/ uchar_t min_ras_to_cas; /* Min RAS to CAS Delay (Trcd) */
-    /*1E*/ uchar_t min_ras_pulse; /* Minimum RAS Pulse Width (Tras) */
-    /*1F*/ uchar_t row_density; /* Density of each row on module */
-    /*20*/ uchar_t ca_setup; /* Command and Address signal input setup time */
-    /*21*/ uchar_t ca_hold; /* Command and Address signal input hold time */
-    /*22*/ uchar_t d_setup; /* Data signal input setup time */
-    /*23*/ uchar_t d_hold; /* Data signal input hold time */
-
-    /*24*/ uchar_t pad0[26]; /* unused */
-    
-    /*3E*/ uchar_t data_rev; /* SPD Data Revision Code */
-    /*3F*/ uchar_t checksum; /* Checksum for bytes 0-62 */
-    /*40*/ uchar_t jedec_id[8]; /* Manufacturer's JEDEC ID code */
-    
-    /*48*/ uchar_t mfg_loc; /* Manufacturing Location */
-    /*49*/ uchar_t part_num[18]; /* Manufacturer's Part Number */
-
-    /*5B*/ uchar_t rev_code[2]; /* Revision Code */
-
-    /*5D*/ uchar_t mfg_date[2]; /* Manufacturing Date */
-
-    /*5F*/ uchar_t ser_num[4]; /* Assembly Serial Number */
-
-    /*63*/ uchar_t manuf_data[27]; /* Manufacturer Specific Data */
-
-    /*7E*/ uchar_t intel_freq; /* Intel specification frequency */
-    /*7F*/ uchar_t intel_100MHz; /* Intel spec details for 100MHz support */
-
-} eeprom_spd_t;
-
-
-#define EEPROM_SPD_RECORD_MAXLEN	256
-
-typedef union eeprom_spd_u
-{
-    eeprom_spd_t fields;
-    char         bytes[EEPROM_SPD_RECORD_MAXLEN];
-
-} eeprom_spd_u;
-
-
-/* EEPROM board record
- */
-typedef struct eeprom_brd_record_t 
-{
-    eeprom_chassis_ia_t		*chassis_ia;
-    eeprom_board_ia_t		*board_ia;
-    eeprom_spd_u		*spd;
-
-} eeprom_brd_record_t;
-
-
-/* End-of-fields marker
- */
-#define EEPROM_EOF	        0xc1
-
-
-/* masks for dissecting the type/length bytes
- */
-#define FIELD_FORMAT_MASK       0xc0
-#define FIELD_LENGTH_MASK       0x3f
-
-
-/* field format codes (used in type/length bytes)
- */
-#define FIELD_FORMAT_BINARY     0x00 /* binary format */
-#define FIELD_FORMAT_BCD        0x40 /* BCD */
-#define FIELD_FORMAT_PACKED     0x80 /* packed 6-bit ASCII */
-#define FIELD_FORMAT_ASCII      0xC0 /* 8-bit ASCII */
-
-
-
-
-/* codes specifying brick and board type
- */
-#define C_BRICK		0x100
-
-#define C_PIMM		(C_BRICK | 0x10)
-#define C_PIMM_0	(C_PIMM) /* | 0x0 */
-#define C_PIMM_1	(C_PIMM | 0x1)
-
-#define C_DIMM		(C_BRICK | 0x20)
-#define C_DIMM_0	(C_DIMM) /* | 0x0 */
-#define C_DIMM_1	(C_DIMM | 0x1)
-#define C_DIMM_2	(C_DIMM | 0x2)
-#define C_DIMM_3	(C_DIMM | 0x3)
-#define C_DIMM_4	(C_DIMM | 0x4)
-#define C_DIMM_5	(C_DIMM | 0x5)
-#define C_DIMM_6	(C_DIMM | 0x6)
-#define C_DIMM_7	(C_DIMM | 0x7)
-
-#define R_BRICK		0x200
-#define R_POWER		(R_BRICK | 0x10)
-
-#define VECTOR		0x300 /* used in vector ops when the destination
-			       * could be a cbrick or an rbrick */
-
-#define IO_BRICK	0x400
-#define IO_POWER	(IO_BRICK | 0x10)
-
-#define BRICK_MASK	0xf00
-#define SUBORD_MASK	0xf0  /* AND with component specification; if the
-			         the result is non-zero, then the component
-			         is a subordinate board of some kind */
-#define COMPT_MASK	0xf   /* if there's more than one instance of a
-				 particular type of subordinate board, this 
-				 masks out which one we're talking about */
-
-
-
-/* functions & macros for obtaining "NIC-like" strings from EEPROMs
- */
-
-#ifdef CONFIG_IA64_SGI_SN1
-
-int eeprom_str( char *nic_str, nasid_t nasid, int component );
-int vector_eeprom_str( char *nic_str, nasid_t nasid,
-		       int component, net_vec_t path );
-
-#define CBRICK_EEPROM_STR(s,n)	eeprom_str((s),(n),C_BRICK)
-#define IOBRICK_EEPROM_STR(s,n)	eeprom_str((s),(n),IO_BRICK)
-#define RBRICK_EEPROM_STR(s,n,p)  vector_eeprom_str((s),(n),R_BRICK,p)
-#define VECTOR_EEPROM_STR(s,n,p)  vector_eeprom_str((s),(n),VECTOR,p)
-
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-
-/* functions for obtaining formatted records from EEPROMs
- */
-
-int cbrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-			int component );
-int iobrick_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-			 int component );
-int vector_eeprom_read( eeprom_brd_record_t *buf, nasid_t nasid,
-			net_vec_t path, int component );
-
-
-
-/* retrieve the ethernet MAC address for an I-brick
- */
-
-int ibrick_mac_addr_get( nasid_t nasid, char *eaddr );
-
-
-/* error codes
- */
-
-#define EEP_OK			0
-#define EEP_L1			1
-#define EEP_FAIL		2
-#define EEP_BAD_CHECKSUM	3
-#define EEP_NICIFY		4
-#define EEP_PARAM		6
-#define EEP_NOMEM		7
-
-
-
-/* given a hardware graph vertex and an indication of the brick type,
- * brick and board to be read, this functions reads the eeprom and
- * attaches a "NIC"-format string of manufacturing information to the 
- * vertex.  If the vertex already has the string, just returns the
- * string.  If component is not VECTOR or R_BRICK, the path parameter
- * is ignored.
- */
-
-#ifdef LATER
-char *eeprom_vertex_info_set( int component, int nasid, devfs_handle_t v,
-			      net_vec_t path );
-#endif
-
-
-
-/* We may need to differentiate between an XBridge and other types of
- * bridges during discovery to tell whether the bridge in question
- * is part of an IO brick.  The following function reads the WIDGET_ID
- * register of the bridge under examination and returns a positive value
- * if the part and mfg numbers stored there indicate that this widget
- * is an XBridge (and so must be part of a brick).
- */
-#ifdef LATER
-int is_iobrick( int nasid, int widget_num );
-#endif
-
-/* the following macro derives the widget number from the register
- * address passed to it and uses is_iobrick to determine whether
- * the widget in question is part of an SN1 IO brick.
- */
-#define IS_IOBRICK(rg)	is_iobrick( NASID_GET((rg)), SWIN_WIDGETNUM((rg)) )
-
-
-
-/* macros for NIC compatibility */
-/* always invoked on "this" cbrick */
-#define HUB_VERTEX_MFG_INFO(v) \
-    eeprom_vertex_info_set( C_BRICK, get_nasid(), (v), 0 )
-
-#define BRIDGE_VERTEX_MFG_INFO(v, r) \
-    ( IS_IOBRICK((r)) ? eeprom_vertex_info_set \
-		          ( IO_BRICK, NASID_GET((r)), (v), 0 ) \
-		      : nic_bridge_vertex_info((v), (r)) )
-
-#endif /* _ASM_IA64_SN_EEPROM_H */
diff -Nru a/include/asm-ia64/sn/fetchop.h b/include/asm-ia64/sn/fetchop.h
--- a/include/asm-ia64/sn/fetchop.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/sn/fetchop.h	Wed Jun 18 23:42:07 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_FETCHOP_H
@@ -39,28 +39,10 @@
 #ifdef __KERNEL__
 
 /*
- * Initialize a FETCHOP line. The argument should point to the beginning
- * of the line.
- * 	SN1 - region mask is in word 0, data in word 1
- * 	SN2 - no region mask. Data in word 0
- */
-#ifdef CONFIG_IA64_SGI_SN1
-#define FETCHOP_INIT_LINE(p)	*(p) = 0xffffffffffffffffUL
-#elif CONFIG_IA64_SGI_SN2
-#define FETCHOP_INIT_LINE(p)
-#endif
-
-/*
- * Convert a region 7 (kaddr) address to the address of the fetchop variable
+ * Convert a region 6 (kaddr) address to the address of the fetchop variable
  */
 #define FETCHOP_KADDR_TO_MSPEC_ADDR(kaddr)	TO_MSPEC(kaddr)
 
-/*
- * Convert a page struct (page) address to the address of the first
- * fetchop variable in the page
- */
-#define FETCHOP_PAGE_TO_MSPEC_ADDR(page)	FETCHOP_KADDR_TO_MSPEC_ADDR(__pa(page_address(page)))
-
 
 /*
  * Each Atomic Memory Operation (AMO formerly known as fetchop)
@@ -80,19 +62,19 @@
  * inconsistency.
  */
 typedef struct {
-
-#ifdef CONFIG_IA64_SGI_SN1
-	u64 permissions;
-#endif
         u64 variable;
-
-#ifdef CONFIG_IA64_SGI_SN1
-        u64 unused[6];
-#else
         u64 unused[7];
-#endif
-
 } AMO_t;
+
+
+/*
+ * The following APIs are externalized to the kernel to allocate/free fetchop variables.
+ * 	fetchop_kalloc_one	- Allocate/initialize 1 fetchop variable on the specified cnode.
+ * 	fetchop_kfree_one	- Free a previously allocated fetchop variable 
+ */
+
+unsigned long fetchop_kalloc_one(int nid);
+void fetchop_kfree_one(unsigned long maddr);
 
 
 #endif /* __KERNEL__ */
diff -Nru a/include/asm-ia64/sn/gda.h b/include/asm-ia64/sn/gda.h
--- a/include/asm-ia64/sn/gda.h	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,109 +0,0 @@
-/* $Id$
- *
- * 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.
- *
- * Derived from IRIX <sys/SN/gda.h>.
- *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- *
- * gda.h -- Contains the data structure for the global data area,
- * 	The GDA contains information communicated between the
- *	PROM, SYMMON, and the kernel. 
- */
-#ifndef _ASM_IA64_SN_GDA_H
-#define _ASM_IA64_SN_GDA_H
-
-#include <asm/sn/addrs.h>
-#include <asm/sn/sn_cpuid.h>
-
-#define GDA_MAGIC	0x58464552
-
-/*
- * GDA Version History
- *
- * Version #	| Change
- * -------------+-------------------------------------------------------
- * 	1	| Initial IP27 version 
- * 	2	| Prom sets g_partid field to the partition number. 0 IS
- *		| a valid partition #. 
- */
-
-#define GDA_VERSION	2	/* Current GDA version # */
-
-#define G_MAGICOFF	0
-#define G_VERSIONOFF	4
-#define G_PROMOPOFF	6
-#define G_MASTEROFF	8
-#define G_VDSOFF	12
-#define G_HKDNORMOFF	16
-#define G_HKDUTLBOFF	24
-#define G_HKDXUTLBOFF	32
-#define G_PARTIDOFF	40
-#define G_TABLEOFF	128
-
-#ifndef __ASSEMBLY__
-
-typedef struct gda {
-	u32	g_magic;	/* GDA magic number */
-	u16	g_version;	/* Version of this structure */
-	u16	g_masterid;	/* The NASID:CPUNUM of the master cpu */
-	u32	g_promop;	/* Passes requests from the kernel to prom */
-	u32	g_vds;		/* Store the virtual dipswitches here */
-	void	**g_hooked_norm;/* ptr to pda loc for norm hndlr */
-	void	**g_hooked_utlb;/* ptr to pda loc for utlb hndlr */
-	void	**g_hooked_xtlb;/* ptr to pda loc for xtlb hndlr */
-	int	g_partid;	/* partition id */
-	int	g_symmax;	/* Max symbols in name table. */
-	void	*g_dbstab;	/* Address of idbg symbol table */
-	char	*g_nametab;	/* Address of idbg name table */
-	void	*g_ktext_repmask;
-				/* Pointer to a mask of nodes with copies
-				 * of the kernel. */
-	char	g_padding[56];	/* pad out to 128 bytes */
-	nasid_t	g_nasidtable[MAX_COMPACT_NODES+1]; /* NASID of each node,
-						  * indexed by cnodeid.
-						  */
-} gda_t;
-
-#define GDA ((gda_t*) GDA_ADDR(get_nasid()))
-
-#endif /* __ASSEMBLY__ */
-/*
- * Define:	PART_GDA_VERSION
- * Purpose:	Define the minimum version of the GDA required, lower 
- *		revisions assume GDA is NOT set up, and read partition
- *		information from the board info.
- */
-#define	PART_GDA_VERSION	2
-
-/*
- * The following requests can be sent to the PROM during startup.
- */
-
-#define PROMOP_MAGIC		0x0ead0000
-#define PROMOP_MAGIC_MASK	0x0fff0000
-
-#define PROMOP_BIST_SHIFT       11
-#define PROMOP_BIST_MASK        (0x3 << 11)
-
-#define PROMOP_REG		PI_ERR_STACK_ADDR_A
-
-#define PROMOP_INVALID		(PROMOP_MAGIC | 0x00)
-#define PROMOP_HALT             (PROMOP_MAGIC | 0x10)
-#define PROMOP_POWERDOWN        (PROMOP_MAGIC | 0x20)
-#define PROMOP_RESTART          (PROMOP_MAGIC | 0x30)
-#define PROMOP_REBOOT           (PROMOP_MAGIC | 0x40)
-#define PROMOP_IMODE            (PROMOP_MAGIC | 0x50)
-
-#define PROMOP_CMD_MASK		0x00f0
-#define PROMOP_OPTIONS_MASK	0xfff0
-
-#define PROMOP_SKIP_DIAGS	0x0100		/* don't bother running diags */
-#define PROMOP_SKIP_MEMINIT	0x0200		/* don't bother initing memory */
-#define PROMOP_SKIP_DEVINIT	0x0400		/* don't bother initing devices */
-#define PROMOP_BIST1		0x0800		/* keep track of which BIST ran */
-#define PROMOP_BIST2		0x1000		/* keep track of which BIST ran */
-
-#endif /* _ASM_IA64_SN_GDA_H */
diff -Nru a/include/asm-ia64/sn/geo.h b/include/asm-ia64/sn/geo.h
--- a/include/asm-ia64/sn/geo.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/sn/geo.h	Wed Jun 18 23:42:08 2003
@@ -17,15 +17,7 @@
  *   GEO_MAX_LEN:	The maximum length of a geoid, formatted for printing
  */
 
-#include <linux/config.h>
-
-#ifdef CONFIG_IA64_SGI_SN2
 #include <asm/sn/sn2/geo.h>
-#else
-
-#error <<BOMB! need geo.h for this platform >>
-
-#endif /* !SN2 && ... */
 
 /* Declarations applicable to all platforms */
 
diff -Nru a/include/asm-ia64/sn/hack.h b/include/asm-ia64/sn/hack.h
--- a/include/asm-ia64/sn/hack.h	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,69 +0,0 @@
-/*
- *
- * 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) 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-#ifndef _ASM_IA64_SN_HACK_H
-#define _ASM_IA64_SN_HACK_H
-
-#include <linux/mmzone.h>
-#include <asm/sn/arch.h>
-#include <asm/sn/types.h>
-#include <asm/uaccess.h>		/* for copy_??_user */
-
-/******************************************
- * Definitions that do not exist in linux *
- ******************************************/
-
-typedef int cred_t;	/* This is for compilation reasons */
-struct cred { int x; };
-
-
-/*
- * Hardware Graph routines that are currently stubbed!
- */
-#include <linux/devfs_fs_kernel.h>
-
-#define DELAY(a)
-
-/************************************************
- * Routines redefined to use linux equivalents. *
- ************************************************/
-
-/* #define FIXME(s) printk("FIXME: [ %s ] in %s at %s:%d\n", s, __FUNCTION__, __FILE__, __LINE__) */
-
-#define FIXME(s)
-
-extern devfs_handle_t dummy_vrtx;
-#define cpuid_to_vertex(cpuid) dummy_vrtx /* (pdaindr[cpuid].pda->p_vertex) */
-
-#define PUTBUF_LOCK(a) { FIXME("PUTBUF_LOCK"); }
-#define PUTBUF_UNLOCK(a) { FIXME("PUTBUF_UNLOCK"); }
-
-typedef int (*splfunc_t)(void);
-
-/* move to stubs.c yet */
-#define dev_to_vhdl(dev) 0
-#define get_timestamp() 0
-#define us_delay(a)
-#define v_mapphys(a,b,c) 0    // printk("Fixme: v_mapphys - soft->base 0x%p\n", b);
-#define splhi()  0
-#define spl7	splhi()
-#define splx(s)
-
-extern void * snia_kmem_alloc_node(register size_t, register int, cnodeid_t);
-extern void * snia_kmem_zalloc(size_t, int);
-extern void * snia_kmem_zalloc_node(register size_t, register int, cnodeid_t );
-extern void * snia_kmem_zone_alloc(register struct zone *, int);
-extern struct zone * snia_kmem_zone_init(register int , char *);
-extern void snia_kmem_zone_free(register struct zone *, void *);
-extern int is_specified(char *);
-extern int cap_able(uint64_t);
-extern int compare_and_swap_ptr(void **, void *, void *);
-
-#endif /* _ASM_IA64_SN_HACK_H */
diff -Nru a/include/asm-ia64/sn/hcl.h b/include/asm-ia64/sn/hcl.h
--- a/include/asm-ia64/sn/hcl.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/hcl.h	Wed Jun 18 23:42:06 2003
@@ -4,18 +4,15 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_HCL_H
 #define _ASM_IA64_SN_HCL_H
 
 #include <asm/sn/sgi.h>
-#include <asm/sn/invent.h>
-#include <linux/devfs_fs_kernel.h>
 
-extern devfs_handle_t hcl_handle; /* HCL driver */
-extern devfs_handle_t hwgraph_root;
-extern devfs_handle_t linux_busnum;
+extern vertex_hdl_t hwgraph_root;
+extern vertex_hdl_t linux_busnum;
 
 
 typedef long            labelcl_info_place_t;
@@ -58,58 +55,56 @@
 /*
  * External declarations of EXPORTED SYMBOLS in hcl.c
  */
-extern devfs_handle_t hwgraph_register(devfs_handle_t, const char *,
+extern vertex_hdl_t hwgraph_register(vertex_hdl_t, const char *,
 	unsigned int, unsigned int, unsigned int, unsigned int,
 	umode_t, uid_t, gid_t, struct file_operations *, void *);
 
-extern int hwgraph_mk_symlink(devfs_handle_t, const char *, unsigned int,
-	unsigned int, const char *, unsigned int, devfs_handle_t *, void *);
+extern int hwgraph_mk_symlink(vertex_hdl_t, const char *, unsigned int,
+	unsigned int, const char *, unsigned int, vertex_hdl_t *, void *);
 
-extern int hwgraph_vertex_destroy(devfs_handle_t);
+extern int hwgraph_vertex_destroy(vertex_hdl_t);
 
-extern int hwgraph_edge_add(devfs_handle_t, devfs_handle_t, char *);
-extern int hwgraph_edge_get(devfs_handle_t, char *, devfs_handle_t *);
+extern int hwgraph_edge_add(vertex_hdl_t, vertex_hdl_t, char *);
+extern int hwgraph_edge_get(vertex_hdl_t, char *, vertex_hdl_t *);
 
-extern arbitrary_info_t hwgraph_fastinfo_get(devfs_handle_t);
-extern void hwgraph_fastinfo_set(devfs_handle_t, arbitrary_info_t );
-extern devfs_handle_t hwgraph_mk_dir(devfs_handle_t, const char *, unsigned int, void *);
+extern arbitrary_info_t hwgraph_fastinfo_get(vertex_hdl_t);
+extern void hwgraph_fastinfo_set(vertex_hdl_t, arbitrary_info_t );
+extern vertex_hdl_t hwgraph_mk_dir(vertex_hdl_t, const char *, unsigned int, void *);
 
-extern int hwgraph_connectpt_set(devfs_handle_t, devfs_handle_t);
-extern devfs_handle_t hwgraph_connectpt_get(devfs_handle_t);
-extern int hwgraph_edge_get_next(devfs_handle_t, char *, devfs_handle_t *, uint *);
-extern graph_error_t hwgraph_edge_remove(devfs_handle_t, char *, devfs_handle_t *);
+extern int hwgraph_connectpt_set(vertex_hdl_t, vertex_hdl_t);
+extern vertex_hdl_t hwgraph_connectpt_get(vertex_hdl_t);
+extern int hwgraph_edge_get_next(vertex_hdl_t, char *, vertex_hdl_t *, uint *);
+extern graph_error_t hwgraph_edge_remove(vertex_hdl_t, char *, vertex_hdl_t *);
 
-extern graph_error_t hwgraph_traverse(devfs_handle_t, char *, devfs_handle_t *);
+extern graph_error_t hwgraph_traverse(vertex_hdl_t, char *, vertex_hdl_t *);
 
-extern int hwgraph_vertex_get_next(devfs_handle_t *, devfs_handle_t *);
-extern int hwgraph_inventory_get_next(devfs_handle_t, invplace_t *, 
+extern int hwgraph_vertex_get_next(vertex_hdl_t *, vertex_hdl_t *);
+extern int hwgraph_inventory_get_next(vertex_hdl_t, invplace_t *, 
 				      inventory_t **);
-extern int hwgraph_inventory_add(devfs_handle_t, int, int, major_t, minor_t, int);
-extern int hwgraph_inventory_remove(devfs_handle_t, int, int, major_t, minor_t, int);
-extern int hwgraph_controller_num_get(devfs_handle_t);
-extern void hwgraph_controller_num_set(devfs_handle_t, int);
-extern int hwgraph_path_ad(devfs_handle_t, char *, devfs_handle_t *);
-extern devfs_handle_t hwgraph_path_to_vertex(char *);
-extern devfs_handle_t hwgraph_path_to_dev(char *);
-extern devfs_handle_t hwgraph_block_device_get(devfs_handle_t);
-extern devfs_handle_t hwgraph_char_device_get(devfs_handle_t);
-extern graph_error_t hwgraph_char_device_add(devfs_handle_t, char *, char *, devfs_handle_t *);
-extern int hwgraph_path_add(devfs_handle_t, char *, devfs_handle_t *);
-extern int hwgraph_info_add_LBL(devfs_handle_t, char *, arbitrary_info_t);
-extern int hwgraph_info_get_LBL(devfs_handle_t, char *, arbitrary_info_t *);
-extern int hwgraph_info_replace_LBL(devfs_handle_t, char *, arbitrary_info_t,
+extern int hwgraph_inventory_add(vertex_hdl_t, int, int, major_t, minor_t, int);
+extern int hwgraph_inventory_remove(vertex_hdl_t, int, int, major_t, minor_t, int);
+extern int hwgraph_controller_num_get(vertex_hdl_t);
+extern void hwgraph_controller_num_set(vertex_hdl_t, int);
+extern int hwgraph_path_ad(vertex_hdl_t, char *, vertex_hdl_t *);
+extern vertex_hdl_t hwgraph_path_to_vertex(char *);
+extern vertex_hdl_t hwgraph_path_to_dev(char *);
+extern vertex_hdl_t hwgraph_block_device_get(vertex_hdl_t);
+extern vertex_hdl_t hwgraph_char_device_get(vertex_hdl_t);
+extern graph_error_t hwgraph_char_device_add(vertex_hdl_t, char *, char *, vertex_hdl_t *);
+extern int hwgraph_path_add(vertex_hdl_t, char *, vertex_hdl_t *);
+extern int hwgraph_info_add_LBL(vertex_hdl_t, char *, arbitrary_info_t);
+extern int hwgraph_info_get_LBL(vertex_hdl_t, char *, arbitrary_info_t *);
+extern int hwgraph_info_replace_LBL(vertex_hdl_t, char *, arbitrary_info_t,
 				    arbitrary_info_t *);
-extern int hwgraph_info_get_exported_LBL(devfs_handle_t, char *, int *, arbitrary_info_t *);
-extern int hwgraph_info_get_next_LBL(devfs_handle_t, char *, arbitrary_info_t *,
+extern int hwgraph_info_get_exported_LBL(vertex_hdl_t, char *, int *, arbitrary_info_t *);
+extern int hwgraph_info_get_next_LBL(vertex_hdl_t, char *, arbitrary_info_t *,
                                 labelcl_info_place_t *);
-
-extern int hwgraph_path_lookup(devfs_handle_t, char *, devfs_handle_t *, char **);
-extern int hwgraph_info_export_LBL(devfs_handle_t, char *, int);
-extern int hwgraph_info_unexport_LBL(devfs_handle_t, char *);
-extern int hwgraph_info_remove_LBL(devfs_handle_t, char *, arbitrary_info_t *);
-extern char * vertex_to_name(devfs_handle_t, char *, uint);
-extern graph_error_t hwgraph_vertex_unref(devfs_handle_t);
-
+extern int hwgraph_path_lookup(vertex_hdl_t, char *, vertex_hdl_t *, char **);
+extern int hwgraph_info_export_LBL(vertex_hdl_t, char *, int);
+extern int hwgraph_info_unexport_LBL(vertex_hdl_t, char *);
+extern int hwgraph_info_remove_LBL(vertex_hdl_t, char *, arbitrary_info_t *);
+extern char * vertex_to_name(vertex_hdl_t, char *, uint);
+extern graph_error_t hwgraph_vertex_unref(vertex_hdl_t);
 
 
 #endif /* _ASM_IA64_SN_HCL_H */
diff -Nru a/include/asm-ia64/sn/hcl_util.h b/include/asm-ia64/sn/hcl_util.h
--- a/include/asm-ia64/sn/hcl_util.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/hcl_util.h	Wed Jun 18 23:42:06 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_HCL_UTIL_H
@@ -12,11 +12,11 @@
 
 #include <linux/devfs_fs_kernel.h>
 
-extern char * dev_to_name(devfs_handle_t, char *, uint);
-extern int device_master_set(devfs_handle_t, devfs_handle_t);
-extern devfs_handle_t device_master_get(devfs_handle_t);
-extern cnodeid_t master_node_get(devfs_handle_t);
-extern cnodeid_t nodevertex_to_cnodeid(devfs_handle_t);
-extern void mark_nodevertex_as_node(devfs_handle_t, cnodeid_t);
+extern char * dev_to_name(vertex_hdl_t, char *, uint);
+extern int device_master_set(vertex_hdl_t, vertex_hdl_t);
+extern vertex_hdl_t device_master_get(vertex_hdl_t);
+extern cnodeid_t master_node_get(vertex_hdl_t);
+extern cnodeid_t nodevertex_to_cnodeid(vertex_hdl_t);
+extern void mark_nodevertex_as_node(vertex_hdl_t, cnodeid_t);
 
 #endif /* _ASM_IA64_SN_HCL_UTIL_H */
diff -Nru a/include/asm-ia64/sn/hires_clock.h b/include/asm-ia64/sn/hires_clock.h
--- a/include/asm-ia64/sn/hires_clock.h	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,52 +0,0 @@
-/*
- * 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) 2001 Silicon Graphics, Inc. All rights reserved.
- *
- * SGI Hi Resolution Clock
- *
- * SGI SN platforms provide a high resolution clock that is
- * synchronized across all nodes. The clock can be memory mapped
- * and directly read from user space.
- *
- * Access to the clock is thru the following:
- *       (error checking not shown)
- *
- * (Note: should library routines be provided to encapsulate this??)
- *
- *	int		fd:
- *	volatile long	*clk;
- *
- *	fd = open (HIRES_FULLNAME, O_RDONLY);
- *	clk = mmap(0, getpagesize(), PROT_READ, MAP_SHARED, fd, 0);
- *	clk += ioctl(fd, HIRES_IOCQGETOFFSET, 0);
- *
- * At this point, clk is a pointer to the high resolution clock.
- *
- * The clock period can be obtained via:
- *
- *	long	picosec_per_tick;
- *	picosec_per_tick = ioctl(fd, HIRES_IOCQGETPICOSEC, 0);
- */
-
-#ifndef _ASM_IA64_SN_HIRES_CLOCK_H
-#define _ASM_IA64_SN_HIRES_CLOCK_H
-
-
-#define HIRES_BASENAME	"sgi_hires_clock"
-#define HIRES_FULLNAME  "/dev/sgi_hires_clock"
-#define HIRES_IOC_BASE	's'
-
-
-/* Get page offset of hires timer */
-#define HIRES_IOCQGETOFFSET	_IO( HIRES_IOC_BASE, 0 )
-
-/* get clock period in picoseconds per tick */
-#define HIRES_IOCQGETPICOSEC	_IO( HIRES_IOC_BASE, 1 )
-
-/* get number of significant bits in clock counter */
-#define HIRES_IOCQGETCLOCKBITS	_IO( HIRES_IOC_BASE, 2 )
-
-#endif /* _ASM_IA64_SN_HIRES_CLOCK_H */
diff -Nru a/include/asm-ia64/sn/hwgfs.h b/include/asm-ia64/sn/hwgfs.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ia64/sn/hwgfs.h	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,35 @@
+#ifndef _ASM_IA64_SN_HWGFS_H
+#define _ASM_IA64_SN_HWGFS_H
+
+/* $Id$
+ *
+ * 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) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
+ */
+
+typedef struct dentry *hwgfs_handle_t;
+
+extern hwgfs_handle_t hwgfs_register(hwgfs_handle_t dir, const char *name,
+				     unsigned int flags,
+				     unsigned int major, unsigned int minor,
+				     umode_t mode, void *ops, void *info);
+extern int hwgfs_mk_symlink(hwgfs_handle_t dir, const char *name,
+			     unsigned int flags, const char *link,
+			     hwgfs_handle_t *handle, void *info);
+extern hwgfs_handle_t hwgfs_mk_dir(hwgfs_handle_t dir, const char *name,
+				    void *info);
+extern void hwgfs_unregister(hwgfs_handle_t de);
+
+extern hwgfs_handle_t hwgfs_find_handle(hwgfs_handle_t dir, const char *name,
+					unsigned int major,unsigned int minor,
+					char type, int traverse_symlinks);
+extern hwgfs_handle_t hwgfs_get_parent(hwgfs_handle_t de);
+extern int hwgfs_generate_path(hwgfs_handle_t de, char *path, int buflen);
+
+extern void *hwgfs_get_info(hwgfs_handle_t de);
+extern int hwgfs_set_info(hwgfs_handle_t de, void *info);
+
+#endif
diff -Nru a/include/asm-ia64/sn/idle.h b/include/asm-ia64/sn/idle.h
--- a/include/asm-ia64/sn/idle.h	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,57 +0,0 @@
-#ifndef _ASM_IA64_SN_IDLE_H
-#define _ASM_IA64_SN_IDLE_H
-
-/*
- * 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) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#include <linux/config.h>
-#include <asm/sn/leds.h>
-#include <asm/sn/simulator.h>
-
-static __inline__ void
-snidle(void) {
-#if 0
-#ifdef CONFIG_IA64_SGI_AUTOTEST
-	{
-		extern int	autotest_enabled;
-		if (autotest_enabled) {
-			extern void llsc_main(int);
-			llsc_main(smp_processor_id());
-		}
-	}
-#endif
-	
-	if (pda.idle_flag == 0) {
-		/* 
-		 * Turn the activity LED off.
-		 */
-		set_led_bits(0, LED_CPU_ACTIVITY);
-	}
-
-#ifdef CONFIG_IA64_SGI_SN_SIM
-	if (IS_RUNNING_ON_SIMULATOR())
-		SIMULATOR_SLEEP();
-#endif
-
-	pda.idle_flag = 1;
-#endif
-}
-
-static __inline__ void
-snidleoff(void) {
-#if 0
-	/* 
-	 * Turn the activity LED on.
-	 */
-	set_led_bits(LED_CPU_ACTIVITY, LED_CPU_ACTIVITY);
-
-	pda.idle_flag = 0;
-#endif
-}
-
-#endif /* _ASM_IA64_SN_IDLE_H */
diff -Nru a/include/asm-ia64/sn/ifconfig_net.h b/include/asm-ia64/sn/ifconfig_net.h
--- a/include/asm-ia64/sn/ifconfig_net.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/ifconfig_net.h	Wed Jun 18 23:42:06 2003
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_IFCONFIG_NET_H
diff -Nru a/include/asm-ia64/sn/intr.h b/include/asm-ia64/sn/intr.h
--- a/include/asm-ia64/sn/intr.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/intr.h	Wed Jun 18 23:42:06 2003
@@ -4,21 +4,18 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_INTR_H
 #define _ASM_IA64_SN_INTR_H
 
 #include <linux/config.h>
-
-#if defined(CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/intr.h>
-#elif defined(CONFIG_IA64_SGI_SN2)
 #include <asm/sn/sn2/intr.h>
-#endif
 
 extern void sn_send_IPI_phys(long, int, int);
 
-#define CPU_VECTOR_TO_IRQ(cpuid,vector) ((cpuid) << 8 | (vector))
+#define CPU_VECTOR_TO_IRQ(cpuid,vector) (vector)
+#define SN_CPU_FROM_IRQ(irq)	(0)
+#define SN_IVEC_FROM_IRQ(irq)	(irq)
 
 #endif /* _ASM_IA64_SN_INTR_H */
diff -Nru a/include/asm-ia64/sn/intr_public.h b/include/asm-ia64/sn/intr_public.h
--- a/include/asm-ia64/sn/intr_public.h	Wed Jun 18 23:42:09 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,19 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_INTR_PUBLIC_H
-#define _ASM_IA64_SN_INTR_PUBLIC_H
-
-#include <linux/config.h>
-
-#if defined(CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/intr_public.h>
-#elif defined(CONFIG_IA64_SGI_SN2)
-#endif
-
-#endif /* _ASM_IA64_SN_INTR_PUBLIC_H */
diff -Nru a/include/asm-ia64/sn/invent.h b/include/asm-ia64/sn/invent.h
--- a/include/asm-ia64/sn/invent.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/invent.h	Wed Jun 18 23:42:06 2003
@@ -4,14 +4,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_INVENT_H
 #define _ASM_IA64_SN_INVENT_H
 
 #include <linux/types.h>
-#include <linux/devfs_fs_kernel.h>
-
+#include <asm/sn/sgi.h>
 /*
  * sys/sn/invent.h --  Kernel Hardware Inventory
  *
@@ -31,7 +30,7 @@
 #define minor_t int
 #define app32_ptr_t unsigned long
 #define graph_vertex_place_t long
-#define GRAPH_VERTEX_NONE ((devfs_handle_t)-1)
+#define GRAPH_VERTEX_NONE ((vertex_hdl_t)-1)
 #define GRAPH_EDGE_PLACE_NONE ((graph_edge_place_t)0)
 #define GRAPH_INFO_PLACE_NONE ((graph_info_place_t)0)
 #define GRAPH_VERTEX_PLACE_NONE ((graph_vertex_place_t)0)
@@ -713,8 +712,8 @@
 } irix5_inventory_t;
 
 typedef struct invplace_s {
-	devfs_handle_t		invplace_vhdl;		/* current vertex */
-	devfs_handle_t		invplace_vplace;	/* place in vertex list */
+	vertex_hdl_t		invplace_vhdl;		/* current vertex */
+	vertex_hdl_t		invplace_vplace;	/* place in vertex list */
 	inventory_t		*invplace_inv;		/* place in inv list on vertex */
 } invplace_t; /* Magic cookie placeholder in inventory list */
 
@@ -730,7 +729,7 @@
 extern int	    scaninvent(int (*)(inventory_t *, void *), void *);
 extern int	    get_sizeof_inventory(int);
 
-extern void device_inventory_add(	devfs_handle_t device, 
+extern void device_inventory_add(	vertex_hdl_t device, 
 					int class, 
 					int type, 
 					major_t ctlr, 
@@ -738,11 +737,11 @@
 					int state);
 
 
-extern inventory_t *device_inventory_get_next(	devfs_handle_t device,
+extern inventory_t *device_inventory_get_next(	vertex_hdl_t device,
 						invplace_t *);
 
-extern void device_controller_num_set(	devfs_handle_t,
+extern void device_controller_num_set(	vertex_hdl_t,
 					int);
-extern int device_controller_num_get(	devfs_handle_t);
+extern int device_controller_num_get(	vertex_hdl_t);
 #endif /* __KERNEL__ */
 #endif /* _ASM_IA64_SN_INVENT_H */
diff -Nru a/include/asm-ia64/sn/io.h b/include/asm-ia64/sn/io.h
--- a/include/asm-ia64/sn/io.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/io.h	Wed Jun 18 23:42:06 2003
@@ -56,27 +56,8 @@
 			(_x) : \
 			(_x) - (HUB_WIDGET_ID_MIN-1)) << 3) )
 
-#if defined(CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/bedrock.h>
-#include <asm/sn/sn1/hubio.h>
-#include <asm/sn/sn1/hubio_next.h>
-#include <asm/sn/sn1/hubmd.h>
-#include <asm/sn/sn1/hubmd_next.h>
-#include <asm/sn/sn1/hubpi.h>
-#include <asm/sn/sn1/hubpi_next.h>
-#include <asm/sn/sn1/hublb.h>
-#include <asm/sn/sn1/hublb_next.h>
-#include <asm/sn/sn1/hubni.h>
-#include <asm/sn/sn1/hubni_next.h>
-#include <asm/sn/sn1/hubxb.h>
-#include <asm/sn/sn1/hubxb_next.h>
-#include <asm/sn/sn1/hubstat.h>
-#include <asm/sn/sn1/hubdev.h>
-#include <asm/sn/sn1/synergy.h>
-#elif defined(CONFIG_IA64_SGI_SN2)
 #include <asm/sn/sn2/shub.h>
 #include <asm/sn/sn2/shubio.h>
-#endif
 
 /*
  * Used to ensure write ordering (like mb(), but for I/O space)
diff -Nru a/include/asm-ia64/sn/ioc3.h b/include/asm-ia64/sn/ioc3.h
--- a/include/asm-ia64/sn/ioc3.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/ioc3.h	Wed Jun 18 23:42:06 2003
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * 
  * This program is free software; you can redistribute it and/or modify it 
  * under the terms of version 2 of the GNU General Public License 
diff -Nru a/include/asm-ia64/sn/ioc4.h b/include/asm-ia64/sn/ioc4.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ia64/sn/ioc4.h	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,801 @@
+/*
+ * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ */
+
+#ifndef _ASM_IA64_SN_IOC4_H
+#define _ASM_IA64_SN_IOC4_H
+
+#if 0
+
+/*
+ * ioc4.h - IOC4 chip header file
+ */
+
+/* Notes:
+ * The IOC4 chip is a 32-bit PCI device that provides 4 serial ports,
+ * an IDE bus interface, a PC keyboard/mouse interface, and a real-time
+ * external interrupt interface.
+ *
+ * It includes an optimized DMA buffer management, and a store-and-forward
+ * buffer RAM.
+ *
+ * All IOC4 registers are 32 bits wide.
+ */
+typedef __uint32_t ioc4reg_t;
+
+/*
+ * PCI Configuration Space Register Address Map, use offset from IOC4 PCI
+ * configuration base such that this can be used for multiple IOC4s
+ */
+#define IOC4_PCI_ID		0x0	/* ID */
+
+#define IOC4_VENDOR_ID_NUM	0x10A9
+#define IOC4_DEVICE_ID_NUM	0x100A 
+#define IOC4_ADDRSPACE_MASK	0xfff00000ULL
+
+#define IOC4_PCI_SCR		0x4 /* Status/Command */
+#define IOC4_PCI_REV		0x8 /* Revision */
+#define IOC4_PCI_LAT		0xC /* Latency Timer */
+#define IOC4_PCI_BAR0		0x10 /* IOC4 base address 0 */
+#define IOC4_PCI_SIDV		0x2c /* Subsys ID and vendor */
+#define IOC4_PCI_CAP 		0x34 /* Capability pointer */
+#define IOC4_PCI_LATGNTINT      0x3c /* Max_lat, min_gnt, int_pin, int_line */
+
+/*
+ * PCI Memory Space Map 
+ */
+#define IOC4_PCI_ERR_ADDR_L     0x000	/* Low Error Address */
+#define IOC4_PCI_ERR_ADDR_VLD	     (0x1 << 0)
+#define IOC4_PCI_ERR_ADDR_MST_ID_MSK (0xf << 1)
+#define IOC4_PCI_ERR_ADDR_MUL_ERR    (0x1 << 5)
+#define IOC4_PCI_ERR_ADDR_ADDR_MSK   (0x3ffffff << 6)
+
+/* Master IDs contained in PCI_ERR_ADDR_MST_ID_MSK */
+#define IOC4_MST_ID_S0_TX		0
+#define IOC4_MST_ID_S0_RX		1
+#define IOC4_MST_ID_S1_TX		2
+#define IOC4_MST_ID_S1_RX		3
+#define IOC4_MST_ID_S2_TX		4
+#define IOC4_MST_ID_S2_RX		5
+#define IOC4_MST_ID_S3_TX		6
+#define IOC4_MST_ID_S3_RX		7
+#define IOC4_MST_ID_ATA 		8
+
+#define IOC4_PCI_ERR_ADDR_H	0x004	/* High Error Address */
+
+#define IOC4_SIO_IR	        0x008	/* SIO Interrupt Register */
+#define IOC4_OTHER_IR	        0x00C	/* Other Interrupt Register */
+
+/* These registers are read-only for general kernel code. To modify
+ * them use the functions in ioc4.c
+ */
+#define IOC4_SIO_IES_RO         0x010	/* SIO Interrupt Enable Set Reg */
+#define IOC4_OTHER_IES_RO       0x014	/* Other Interrupt Enable Set Reg */
+#define IOC4_SIO_IEC_RO         0x018	/* SIO Interrupt Enable Clear Reg */
+#define IOC4_OTHER_IEC_RO       0x01C	/* Other Interrupt Enable Clear Reg */
+
+#define IOC4_SIO_CR	        0x020	/* SIO Control Reg */
+#define IOC4_INT_OUT	        0x028	/* INT_OUT Reg (realtime interrupt) */
+#define IOC4_GPCR_S	        0x030	/* GenericPIO Cntrl Set Register */
+#define IOC4_GPCR_C	        0x034	/* GenericPIO Cntrl Clear Register */
+#define IOC4_GPDR	        0x038	/* GenericPIO Data Register */
+#define IOC4_GPPR_0	        0x040	/* GenericPIO Pin Registers */
+#define IOC4_GPPR_OFF	        0x4
+#define IOC4_GPPR(x)	        (IOC4_GPPR_0+(x)*IOC4_GPPR_OFF)
+
+/* ATAPI Registers */
+#define IOC4_ATA_0              0x100	/* Data w/timing */
+#define IOC4_ATA_1              0x104	/* Error/Features w/timing */
+#define IOC4_ATA_2              0x108	/* Sector Count w/timing */
+#define IOC4_ATA_3              0x10C	/* Sector Number w/timing */
+#define IOC4_ATA_4              0x110   /* Cyliner Low w/timing */
+#define IOC4_ATA_5              0x114	/* Cylinder High w/timing */
+#define IOC4_ATA_6              0x118	/* Device/Head w/timing */
+#define IOC4_ATA_7              0x11C	/* Status/Command w/timing */
+#define IOC4_ATA_0_AUX          0x120	/* Aux Status/Device Cntrl w/timing */
+#define IOC4_ATA_TIMING       	0x140	/* Timing value register 0 */
+#define IOC4_ATA_DMA_PTR_L      0x144   /* Low Memory Pointer to DMA List */
+#define IOC4_ATA_DMA_PTR_H      0x148   /* High Memory Pointer to DMA List */
+#define IOC4_ATA_DMA_ADDR_L     0x14C   /* Low Memory DMA Address */
+#define IOC4_ATA_DMA_ADDR_H     0x150   /* High Memory DMA Addresss */
+#define IOC4_ATA_BC_DEV         0x154	/* DMA Byte Count at Device */
+#define IOC4_ATA_BC_MEM         0x158	/* DMA Byte Count at Memory */
+#define IOC4_ATA_DMA_CTRL       0x15C	/* DMA Control/Status */
+
+/* Keyboard and Mouse Registers */
+#define IOC4_KM_CSR	        0x200	/* Kbd and Mouse Cntrl/Status Reg */
+#define IOC4_K_RD	        0x204	/* Kbd Read Data Register */
+#define IOC4_M_RD	        0x208	/* Mouse Read Data Register */
+#define IOC4_K_WD	        0x20C	/* Kbd Write Data Register */
+#define IOC4_M_WD	        0x210	/* Mouse Write Data Register */
+
+/* Serial Port Registers used for DMA mode serial I/O */
+#define IOC4_SBBR01_H	        0x300	/* Serial Port Ring Buffers 
+                                           Base Reg High for Channels 0 1*/
+#define IOC4_SBBR01_L	        0x304	/* Serial Port Ring Buffers 
+                                           Base Reg Low for Channels 0 1 */
+#define IOC4_SBBR23_H	        0x308	/* Serial Port Ring Buffers 
+                                           Base Reg High for Channels 2 3*/
+#define IOC4_SBBR23_L	        0x30C	/* Serial Port Ring Buffers 
+                                           Base Reg Low for Channels 2 3 */
+
+#define IOC4_SSCR_0	        0x310	/* Serial Port 0 Control */
+#define IOC4_STPIR_0	        0x314	/* Serial Port 0 TX Produce */
+#define IOC4_STCIR_0	        0x318	/* Serial Port 0 TX Consume */
+#define IOC4_SRPIR_0	        0x31C	/* Serial Port 0 RX Produce */
+#define IOC4_SRCIR_0	        0x320	/* Serial Port 0 RX Consume */
+#define IOC4_SRTR_0	        0x324	/* Serial Port 0 Receive Timer Reg */
+#define IOC4_SHADOW_0		0x328	/* Serial Port 0 16550 Shadow Reg */
+
+#define IOC4_SSCR_1	        0x32C	/* Serial Port 1 Control */
+#define IOC4_STPIR_1	        0x330	/* Serial Port 1 TX Produce */
+#define IOC4_STCIR_1	        0x334	/* Serial Port 1 TX Consume */
+#define IOC4_SRPIR_1	        0x338   /* Serial Port 1 RX Produce */
+#define IOC4_SRCIR_1	        0x33C	/* Serial Port 1 RX Consume */
+#define IOC4_SRTR_1	        0x340	/* Serial Port 1 Receive Timer Reg */
+#define IOC4_SHADOW_1		0x344	/* Serial Port 1 16550 Shadow Reg */
+
+#define IOC4_SSCR_2	        0x348	/* Serial Port 2 Control */
+#define IOC4_STPIR_2	        0x34C	/* Serial Port 2 TX Produce */
+#define IOC4_STCIR_2	        0x350	/* Serial Port 2 TX Consume */
+#define IOC4_SRPIR_2	        0x354	/* Serial Port 2 RX Produce */
+#define IOC4_SRCIR_2	        0x358	/* Serial Port 2 RX Consume */
+#define IOC4_SRTR_2	        0x35C	/* Serial Port 2 Receive Timer Reg */
+#define IOC4_SHADOW_2		0x360	/* Serial Port 2 16550 Shadow Reg */
+
+#define IOC4_SSCR_3	        0x364	/* Serial Port 3 Control */
+#define IOC4_STPIR_3	        0x368	/* Serial Port 3 TX Produce */
+#define IOC4_STCIR_3	        0x36C	/* Serial Port 3 TX Consume */
+#define IOC4_SRPIR_3	        0x370	/* Serial Port 3 RX Produce */
+#define IOC4_SRCIR_3	        0x374	/* Serial Port 3 RX Consume */
+#define IOC4_SRTR_3	        0x378	/* Serial Port 3 Receive Timer Reg */
+#define IOC4_SHADOW_3		0x37C	/* Serial Port 3 16550 Shadow Reg */
+
+#define IOC4_UART0_BASE         0x380   /* UART 0 */
+#define IOC4_UART1_BASE         0x388   /* UART 1 */
+#define IOC4_UART2_BASE         0x390   /* UART 2 */
+#define IOC4_UART3_BASE         0x398   /* UART 3 */
+
+/* Private page address aliases for usermode mapping */
+#define IOC4_INT_OUT_P	        0x04000	/* INT_OUT Reg */
+
+#define IOC4_SSCR_0_P	        0x08000 /* Serial Port 0 */
+#define IOC4_STPIR_0_P	        0x08004
+#define IOC4_STCIR_0_P	        0x08008	/* (read-only) */
+#define IOC4_SRPIR_0_P	        0x0800C	/* (read-only) */
+#define IOC4_SRCIR_0_P	        0x08010
+#define IOC4_SRTR_0_P	        0x08014
+#define IOC4_UART_LSMSMCR_0_P   0x08018	/* (read-only) */
+
+#define IOC4_SSCR_1_P	        0x0C000	/* Serial Port 1 */
+#define IOC4_STPIR_1_P	        0x0C004
+#define IOC4_STCIR_1_P	        0x0C008	/* (read-only) */
+#define IOC4_SRPIR_1_P	        0x0C00C	/* (read-only) */
+#define IOC4_SRCIR_1_P	        0x0C010
+#define IOC4_SRTR_1_P	        0x0C014
+#define IOC4_UART_LSMSMCR_1_P   0x0C018	/* (read-only) */
+
+#define IOC4_SSCR_2_P	        0x10000	/* Serial Port 2 */
+#define IOC4_STPIR_2_P	        0x10004
+#define IOC4_STCIR_2_P	        0x10008	/* (read-only) */
+#define IOC4_SRPIR_2_P	        0x1000C	/* (read-only) */
+#define IOC4_SRCIR_2_P	        0x10010
+#define IOC4_SRTR_2_P	        0x10014
+#define IOC4_UART_LSMSMCR_2_P   0x10018	/* (read-only) */
+
+#define IOC4_SSCR_3_P	        0x14000	/* Serial Port 3 */
+#define IOC4_STPIR_3_P	        0x14004
+#define IOC4_STCIR_3_P	        0x14008	/* (read-only) */
+#define IOC4_SRPIR_3_P	        0x1400C	/* (read-only) */
+#define IOC4_SRCIR_3_P	        0x14010
+#define IOC4_SRTR_3_P	        0x14014
+#define IOC4_UART_LSMSMCR_3_P   0x14018	/* (read-only) */
+
+#define IOC4_ALIAS_PAGE_SIZE	0x4000
+
+/* Interrupt types */
+typedef enum ioc4_intr_type_e {
+    ioc4_sio_intr_type,
+    ioc4_other_intr_type,
+    ioc4_num_intr_types
+} ioc4_intr_type_t;
+#define ioc4_first_intr_type    ioc4_sio_intr_type
+
+/* Bitmasks for IOC4_SIO_IR, IOC4_SIO_IEC, and IOC4_SIO_IES  */
+#define IOC4_SIO_IR_S0_TX_MT		0x00000001 /* Serial port 0 TX empty */
+#define IOC4_SIO_IR_S0_RX_FULL		0x00000002 /* Port 0 RX buf full */
+#define IOC4_SIO_IR_S0_RX_HIGH		0x00000004 /* Port 0 RX hiwat */
+#define IOC4_SIO_IR_S0_RX_TIMER		0x00000008 /* Port 0 RX timeout */
+#define IOC4_SIO_IR_S0_DELTA_DCD	0x00000010 /* Port 0 delta DCD */
+#define IOC4_SIO_IR_S0_DELTA_CTS	0x00000020 /* Port 0 delta CTS */
+#define IOC4_SIO_IR_S0_INT	        0x00000040 /* Port 0 pass-thru intr */
+#define IOC4_SIO_IR_S0_TX_EXPLICIT	0x00000080 /* Port 0 explicit TX thru */
+#define IOC4_SIO_IR_S1_TX_MT		0x00000100 /* Serial port 1 */
+#define IOC4_SIO_IR_S1_RX_FULL		0x00000200 /* */
+#define IOC4_SIO_IR_S1_RX_HIGH		0x00000400 /* */
+#define IOC4_SIO_IR_S1_RX_TIMER		0x00000800 /* */
+#define IOC4_SIO_IR_S1_DELTA_DCD	0x00001000 /* */
+#define IOC4_SIO_IR_S1_DELTA_CTS	0x00002000 /* */
+#define IOC4_SIO_IR_S1_INT		0x00004000 /* */
+#define IOC4_SIO_IR_S1_TX_EXPLICIT	0x00008000 /* */
+#define IOC4_SIO_IR_S2_TX_MT		0x00010000 /* Serial port 2 */
+#define IOC4_SIO_IR_S2_RX_FULL		0x00020000 /* */
+#define IOC4_SIO_IR_S2_RX_HIGH		0x00040000 /* */
+#define IOC4_SIO_IR_S2_RX_TIMER		0x00080000 /* */
+#define IOC4_SIO_IR_S2_DELTA_DCD	0x00100000 /* */
+#define IOC4_SIO_IR_S2_DELTA_CTS	0x00200000 /* */
+#define IOC4_SIO_IR_S2_INT		0x00400000 /* */
+#define IOC4_SIO_IR_S2_TX_EXPLICIT	0x00800000 /* */
+#define IOC4_SIO_IR_S3_TX_MT		0x01000000 /* Serial port 3 */
+#define IOC4_SIO_IR_S3_RX_FULL		0x02000000 /* */
+#define IOC4_SIO_IR_S3_RX_HIGH		0x04000000 /* */
+#define IOC4_SIO_IR_S3_RX_TIMER		0x08000000 /* */
+#define IOC4_SIO_IR_S3_DELTA_DCD	0x10000000 /* */
+#define IOC4_SIO_IR_S3_DELTA_CTS	0x20000000 /* */
+#define IOC4_SIO_IR_S3_INT		0x40000000 /* */
+#define IOC4_SIO_IR_S3_TX_EXPLICIT	0x80000000 /* */
+
+/* Per device interrupt masks */
+#define IOC4_SIO_IR_S0		(IOC4_SIO_IR_S0_TX_MT | \
+				 IOC4_SIO_IR_S0_RX_FULL | \
+				 IOC4_SIO_IR_S0_RX_HIGH | \
+				 IOC4_SIO_IR_S0_RX_TIMER | \
+				 IOC4_SIO_IR_S0_DELTA_DCD | \
+				 IOC4_SIO_IR_S0_DELTA_CTS | \
+				 IOC4_SIO_IR_S0_INT | \
+				 IOC4_SIO_IR_S0_TX_EXPLICIT)
+#define IOC4_SIO_IR_S1		(IOC4_SIO_IR_S1_TX_MT | \
+				 IOC4_SIO_IR_S1_RX_FULL | \
+				 IOC4_SIO_IR_S1_RX_HIGH | \
+				 IOC4_SIO_IR_S1_RX_TIMER | \
+				 IOC4_SIO_IR_S1_DELTA_DCD | \
+				 IOC4_SIO_IR_S1_DELTA_CTS | \
+				 IOC4_SIO_IR_S1_INT | \
+				 IOC4_SIO_IR_S1_TX_EXPLICIT)
+#define IOC4_SIO_IR_S2		(IOC4_SIO_IR_S2_TX_MT | \
+				 IOC4_SIO_IR_S2_RX_FULL | \
+				 IOC4_SIO_IR_S2_RX_HIGH | \
+				 IOC4_SIO_IR_S2_RX_TIMER | \
+				 IOC4_SIO_IR_S2_DELTA_DCD | \
+				 IOC4_SIO_IR_S2_DELTA_CTS | \
+				 IOC4_SIO_IR_S2_INT | \
+				 IOC4_SIO_IR_S2_TX_EXPLICIT)
+#define IOC4_SIO_IR_S3		(IOC4_SIO_IR_S3_TX_MT | \
+				 IOC4_SIO_IR_S3_RX_FULL | \
+				 IOC4_SIO_IR_S3_RX_HIGH | \
+				 IOC4_SIO_IR_S3_RX_TIMER | \
+				 IOC4_SIO_IR_S3_DELTA_DCD | \
+				 IOC4_SIO_IR_S3_DELTA_CTS | \
+				 IOC4_SIO_IR_S3_INT | \
+				 IOC4_SIO_IR_S3_TX_EXPLICIT)
+
+/* Bitmasks for IOC4_OTHER_IR, IOC4_OTHER_IEC, and IOC4_OTHER_IES  */
+#define IOC4_OTHER_IR_ATA_INT           0x00000001 /* ATAPI intr pass-thru */
+#define IOC4_OTHER_IR_ATA_MEMERR        0x00000002 /* ATAPI DMA PCI error */
+#define IOC4_OTHER_IR_S0_MEMERR         0x00000004 /* Port 0 PCI error */
+#define IOC4_OTHER_IR_S1_MEMERR         0x00000008 /* Port 1 PCI error */
+#define IOC4_OTHER_IR_S2_MEMERR         0x00000010 /* Port 2 PCI error */
+#define IOC4_OTHER_IR_S3_MEMERR         0x00000020 /* Port 3 PCI error */
+#define IOC4_OTHER_IR_KBD_INT		0x00000040 /* Kbd/mouse intr */
+#define IOC4_OTHER_IR_ATA_DMAINT        0x00000089 /* ATAPI DMA intr */
+#define IOC4_OTHER_IR_RT_INT		0x00800000 /* RT output pulse */
+#define IOC4_OTHER_IR_GEN_INT1		0x02000000 /* RT input pulse */
+#define IOC4_OTHER_IR_GEN_INT_SHIFT	        25
+
+/* Per device interrupt masks */
+#define IOC4_OTHER_IR_ATA       (IOC4_OTHER_IR_ATA_INT | \
+				 IOC4_OTHER_IR_ATA_MEMERR | \
+				 IOC4_OTHER_IR_ATA_DMAINT)
+#define IOC4_OTHER_IR_RT	(IOC4_OTHER_IR_RT_INT | IOC4_OTHER_IR_GEN_INT1)
+
+/* Macro to load pending interrupts */
+#define IOC4_PENDING_SIO_INTRS(mem)     (PCI_INW(&((mem)->sio_ir)) & \
+				         PCI_INW(&((mem)->sio_ies_ro)))
+#define IOC4_PENDING_OTHER_INTRS(mem)   (PCI_INW(&((mem)->other_ir)) & \
+				         PCI_INW(&((mem)->other_ies_ro)))
+
+/* Bitmasks for IOC4_SIO_CR */
+#define IOC4_SIO_SR_CMD_PULSE		0x00000004 /* Byte bus strobe length */
+#define IOC4_SIO_CR_CMD_PULSE_SHIFT              0
+#define IOC4_SIO_CR_ARB_DIAG		0x00000070 /* Current non-ATA PCI bus
+                                                      requester (ro) */
+#define IOC4_SIO_CR_ARB_DIAG_TX0	0x00000000
+#define IOC4_SIO_CR_ARB_DIAG_RX0	0x00000010
+#define IOC4_SIO_CR_ARB_DIAG_TX1	0x00000020
+#define IOC4_SIO_CR_ARB_DIAG_RX1	0x00000030
+#define IOC4_SIO_CR_ARB_DIAG_TX2	0x00000040
+#define IOC4_SIO_CR_ARB_DIAG_RX2	0x00000050
+#define IOC4_SIO_CR_ARB_DIAG_TX3	0x00000060
+#define IOC4_SIO_CR_ARB_DIAG_RX3	0x00000070
+#define IOC4_SIO_CR_SIO_DIAG_IDLE	0x00000080 /* 0 -> active request among
+                                                      serial ports (ro) */
+#define IOC4_SIO_CR_ATA_DIAG_IDLE	0x00000100 /* 0 -> active request from
+                                                      ATA port */
+#define IOC4_SIO_CR_ATA_DIAG_ACTIVE     0x00000200 /* 1 -> ATA request is winner */ 
+
+/* Bitmasks for IOC4_INT_OUT */
+#define IOC4_INT_OUT_COUNT	        0x0000ffff /* Pulse interval timer */
+#define IOC4_INT_OUT_MODE	        0x00070000 /* Mode mask */
+#define IOC4_INT_OUT_MODE_0             0x00000000 /* Set output to 0 */
+#define IOC4_INT_OUT_MODE_1             0x00040000 /* Set output to 1 */
+#define IOC4_INT_OUT_MODE_1PULSE        0x00050000 /* Send 1 pulse */
+#define IOC4_INT_OUT_MODE_PULSES        0x00060000 /* Send 1 pulse every interval */
+#define IOC4_INT_OUT_MODE_SQW           0x00070000 /* Toggle output every interval */
+#define IOC4_INT_OUT_DIAG	        0x40000000 /* Diag mode */
+#define IOC4_INT_OUT_INT_OUT            0x80000000 /* Current state of INT_OUT */
+
+/* Time constants for IOC4_INT_OUT */
+#define IOC4_INT_OUT_NS_PER_TICK        (15 * 520) /* 15 ns PCI clock, multi=520 */
+#define IOC4_INT_OUT_TICKS_PER_PULSE             3 /* Outgoing pulse lasts 3
+                                                      ticks */
+#define IOC4_INT_OUT_US_TO_COUNT(x)	           /* Convert uS to a count value */ \
+	(((x) * 10 + IOC4_INT_OUT_NS_PER_TICK / 200) *	\
+	 100 / IOC4_INT_OUT_NS_PER_TICK - 1)
+#define IOC4_INT_OUT_COUNT_TO_US(x)	           /* Convert count value to uS */ \
+	(((x) + 1) * IOC4_INT_OUT_NS_PER_TICK / 1000)
+#define IOC4_INT_OUT_MIN_TICKS                   3 /* Min period is width of
+                                                      pulse in "ticks" */
+#define IOC4_INT_OUT_MAX_TICKS  IOC4_INT_OUT_COUNT /* Largest possible count */
+
+/* Bitmasks for IOC4_GPCR */
+#define IOC4_GPCR_DIR	                0x000000ff /* Tristate pin in or out */
+#define IOC4_GPCR_DIR_PIN(x)              (1<<(x)) /* Access one of the DIR bits */
+#define IOC4_GPCR_EDGE	                0x0000ff00 /* Extint edge or level
+                                                      sensitive */
+#define IOC4_GPCR_EDGE_PIN(x)        (1<<((x)+7 )) /* Access one of the EDGE bits */
+
+/* Values for IOC4_GPCR */
+#define IOC4_GPCR_INT_OUT_EN            0x00100000 /* Enable INT_OUT to pin 0 */
+#define IOC4_GPCR_DIR_SER0_XCVR         0x00000010 /* Port 0 Transceiver select
+                                                      enable */
+#define IOC4_GPCR_DIR_SER1_XCVR         0x00000020 /* Port 1 Transceiver select
+                                                      enable */
+#define IOC4_GPCR_DIR_SER2_XCVR         0x00000040 /* Port 2 Transceiver select
+                                                      enable */
+#define IOC4_GPCR_DIR_SER3_XCVR         0x00000080 /* Port 3 Transceiver select
+                                                      enable */
+
+/* Defs for some of the generic I/O pins */
+#define IOC4_GPCR_UART0_MODESEL	              0x10 /* Pin is output to port 0
+                                                      mode sel */
+#define IOC4_GPCR_UART1_MODESEL	              0x20 /* Pin is output to port 1
+                                                      mode sel */
+#define IOC4_GPCR_UART2_MODESEL	              0x40 /* Pin is output to port 2
+                                                      mode sel */
+#define IOC4_GPCR_UART3_MODESEL	              0x80 /* Pin is output to port 3
+                                                      mode sel */
+
+#define IOC4_GPPR_UART0_MODESEL_PIN	         4 /* GIO pin controlling
+                                                      uart 0 mode select */
+#define IOC4_GPPR_UART1_MODESEL_PIN	         5 /* GIO pin controlling
+                                                      uart 1 mode select */
+#define IOC4_GPPR_UART2_MODESEL_PIN	         6 /* GIO pin controlling
+                                                      uart 2 mode select */
+#define IOC4_GPPR_UART3_MODESEL_PIN	         7 /* GIO pin controlling
+                                                      uart 3 mode select */
+
+/* Bitmasks for IOC4_ATA_TIMING */
+#define IOC4_ATA_TIMING_ADR_SETUP	0x00000003 /* Clocks of addr set-up */
+#define IOC4_ATA_TIMING_PULSE_WIDTH	0x000001f8 /* Clocks of read or write
+                                                      pulse width */
+#define IOC4_ATA_TIMING_RECOVERY	0x0000fe00 /* Clocks before next read
+                                                      or write */
+#define IOC4_ATA_TIMING_USE_IORDY	0x00010000 /* PIO uses IORDY */
+
+/* Bitmasks for address list elements pointed to by IOC4_ATA_DMA_PTR_<L|H> */
+#define IOC4_ATA_ALE_DMA_ADDRESS        0xfffffffffffffffe
+
+/* Bitmasks for byte count list elements pointed to by IOC4_ATA_DMA_PTR_<L|H> */
+#define IOC4_ATA_BCLE_BYTE_COUNT        0x000000000000fffe
+#define IOC4_ATA_BCLE_LIST_END          0x0000000080000000
+
+/* Bitmasks for IOC4_ATA_BC_<DEV|MEM> */
+#define IOC4_ATA_BC_BYTE_CNT            0x0001fffe /* Byte count */
+
+/* Bitmasks for IOC4_ATA_DMA_CTRL */
+#define IOC4_ATA_DMA_CTRL_STRAT		0x00000001 /* 1 -> start DMA engine */
+#define IOC4_ATA_DMA_CTRL_STOP		0x00000002 /* 1 -> stop DMA engine */
+#define IOC4_ATA_DMA_CTRL_DIR		0x00000004 /* 1 -> ATA bus data copied
+                                                      to memory */
+#define IOC4_ATA_DMA_CTRL_ACTIVE	0x00000008 /* DMA channel is active */
+#define IOC4_ATA_DMA_CTRL_MEM_ERROR	0x00000010 /* DMA engine encountered 
+						      a PCI error */
+/* Bitmasks for IOC4_KM_CSR */
+#define IOC4_KM_CSR_K_WRT_PEND  0x00000001 /* Kbd port xmitting or resetting */
+#define IOC4_KM_CSR_M_WRT_PEND  0x00000002 /* Mouse port xmitting or resetting */
+#define IOC4_KM_CSR_K_LCB       0x00000004 /* Line Cntrl Bit for last KBD write */
+#define IOC4_KM_CSR_M_LCB       0x00000008 /* Same for mouse */
+#define IOC4_KM_CSR_K_DATA      0x00000010 /* State of kbd data line */
+#define IOC4_KM_CSR_K_CLK       0x00000020 /* State of kbd clock line */
+#define IOC4_KM_CSR_K_PULL_DATA 0x00000040 /* Pull kbd data line low */
+#define IOC4_KM_CSR_K_PULL_CLK  0x00000080 /* Pull kbd clock line low */
+#define IOC4_KM_CSR_M_DATA      0x00000100 /* State of mouse data line */
+#define IOC4_KM_CSR_M_CLK       0x00000200 /* State of mouse clock line */
+#define IOC4_KM_CSR_M_PULL_DATA 0x00000400 /* Pull mouse data line low */
+#define IOC4_KM_CSR_M_PULL_CLK  0x00000800 /* Pull mouse clock line low */
+#define IOC4_KM_CSR_EMM_MODE	0x00001000 /* Emulation mode */
+#define IOC4_KM_CSR_SIM_MODE	0x00002000 /* Clock X8 */
+#define IOC4_KM_CSR_K_SM_IDLE   0x00004000 /* Keyboard is idle */
+#define IOC4_KM_CSR_M_SM_IDLE   0x00008000 /* Mouse is idle */
+#define IOC4_KM_CSR_K_TO	0x00010000 /* Keyboard trying to send/receive */
+#define IOC4_KM_CSR_M_TO        0x00020000 /* Mouse trying to send/receive */
+#define IOC4_KM_CSR_K_TO_EN     0x00040000 /* KM_CSR_K_TO + KM_CSR_K_TO_EN =
+                                              cause SIO_IR to assert */
+#define IOC4_KM_CSR_M_TO_EN	0x00080000 /* KM_CSR_M_TO + KM_CSR_M_TO_EN =
+                                              cause SIO_IR to assert */
+#define IOC4_KM_CSR_K_CLAMP_ONE	0x00100000 /* Pull K_CLK low after rec. one char */
+#define IOC4_KM_CSR_M_CLAMP_ONE	0x00200000 /* Pull M_CLK low after rec. one char */
+#define IOC4_KM_CSR_K_CLAMP_THREE \
+                           	0x00400000 /* Pull K_CLK low after rec. three chars */
+#define IOC4_KM_CSR_M_CLAMP_THREE \
+                            	0x00800000 /* Pull M_CLK low after rec. three char */
+
+/* Bitmasks for IOC4_K_RD and IOC4_M_RD */
+#define IOC4_KM_RD_DATA_2       0x000000ff /* 3rd char recvd since last read */
+#define IOC4_KM_RD_DATA_2_SHIFT          0
+#define IOC4_KM_RD_DATA_1       0x0000ff00 /* 2nd char recvd since last read */
+#define IOC4_KM_RD_DATA_1_SHIFT          8
+#define IOC4_KM_RD_DATA_0	0x00ff0000 /* 1st char recvd since last read */
+#define IOC4_KM_RD_DATA_0_SHIFT         16
+#define IOC4_KM_RD_FRAME_ERR_2  0x01000000 /* Framing or parity error in byte 2 */
+#define IOC4_KM_RD_FRAME_ERR_1  0x02000000 /* Same for byte 1 */
+#define IOC4_KM_RD_FRAME_ERR_0  0x04000000 /* Same for byte 0 */
+
+#define IOC4_KM_RD_KBD_MSE      0x08000000 /* 0 if from kbd, 1 if from mouse */
+#define IOC4_KM_RD_OFLO	        0x10000000 /* 4th char recvd before this read */
+#define IOC4_KM_RD_VALID_2      0x20000000 /* DATA_2 valid */
+#define IOC4_KM_RD_VALID_1      0x40000000 /* DATA_1 valid */
+#define IOC4_KM_RD_VALID_0      0x80000000 /* DATA_0 valid */
+#define IOC4_KM_RD_VALID_ALL    (IOC4_KM_RD_VALID_0 | IOC4_KM_RD_VALID_1 | \
+                                 IOC4_KM_RD_VALID_2)
+
+/* Bitmasks for IOC4_K_WD & IOC4_M_WD */
+#define IOC4_KM_WD_WRT_DATA     0x000000ff /* Write to keyboard/mouse port */
+#define IOC4_KM_WD_WRT_DATA_SHIFT        0
+
+/* Bitmasks for serial RX status byte */
+#define IOC4_RXSB_OVERRUN       0x01       /* Char(s) lost */
+#define IOC4_RXSB_PAR_ERR	0x02	   /* Parity error */
+#define IOC4_RXSB_FRAME_ERR	0x04	   /* Framing error */
+#define IOC4_RXSB_BREAK	        0x08	   /* Break character */
+#define IOC4_RXSB_CTS	        0x10	   /* State of CTS */
+#define IOC4_RXSB_DCD	        0x20	   /* State of DCD */
+#define IOC4_RXSB_MODEM_VALID   0x40	   /* DCD, CTS, and OVERRUN are valid */
+#define IOC4_RXSB_DATA_VALID    0x80	   /* Data byte, FRAME_ERR PAR_ERR & BREAK valid */
+
+/* Bitmasks for serial TX control byte */
+#define IOC4_TXCB_INT_WHEN_DONE 0x20       /* Interrupt after this byte is sent */
+#define IOC4_TXCB_INVALID	0x00	   /* Byte is invalid */
+#define IOC4_TXCB_VALID	        0x40	   /* Byte is valid */
+#define IOC4_TXCB_MCR	        0x80	   /* Data<7:0> to modem control register */
+#define IOC4_TXCB_DELAY	        0xc0	   /* Delay data<7:0> mSec */
+
+/* Bitmasks for IOC4_SBBR_L */
+#define IOC4_SBBR_L_SIZE	0x00000001 /* 0 == 1KB rings, 1 == 4KB rings */
+#define IOC4_SBBR_L_BASE	0xfffff000 /* Lower serial ring base addr */
+
+/* Bitmasks for IOC4_SSCR_<3:0> */
+#define IOC4_SSCR_RX_THRESHOLD  0x000001ff /* Hiwater mark */
+#define IOC4_SSCR_TX_TIMER_BUSY 0x00010000 /* TX timer in progress */
+#define IOC4_SSCR_HFC_EN	0x00020000 /* Hardware flow control enabled */
+#define IOC4_SSCR_RX_RING_DCD   0x00040000 /* Post RX record on delta-DCD */
+#define IOC4_SSCR_RX_RING_CTS   0x00080000 /* Post RX record on delta-CTS */
+#define IOC4_SSCR_DIAG	        0x00200000 /* Bypass clock divider for sim */
+#define IOC4_SSCR_RX_DRAIN	0x08000000 /* Drain RX buffer to memory */
+#define IOC4_SSCR_DMA_EN	0x10000000 /* Enable ring buffer DMA */
+#define IOC4_SSCR_DMA_PAUSE	0x20000000 /* Pause DMA */
+#define IOC4_SSCR_PAUSE_STATE   0x40000000 /* Sets when PAUSE takes effect */
+#define IOC4_SSCR_RESET	        0x80000000 /* Reset DMA channels */
+
+/* All producer/comsumer pointers are the same bitfield */
+#define IOC4_PROD_CONS_PTR_4K   0x00000ff8 /* For 4K buffers */
+#define IOC4_PROD_CONS_PTR_1K   0x000003f8 /* For 1K buffers */
+#define IOC4_PROD_CONS_PTR_OFF           3
+
+/* Bitmasks for IOC4_STPIR_<3:0> */
+/* Reserved for future register definitions */
+
+/* Bitmasks for IOC4_STCIR_<3:0> */
+#define IOC4_STCIR_BYTE_CNT     0x0f000000 /* Bytes in unpacker */
+#define IOC4_STCIR_BYTE_CNT_SHIFT       24
+
+/* Bitmasks for IOC4_SRPIR_<3:0> */
+#define IOC4_SRPIR_BYTE_CNT	0x0f000000 /* Bytes in packer */
+#define IOC4_SRPIR_BYTE_CNT_SHIFT       24
+
+/* Bitmasks for IOC4_SRCIR_<3:0> */
+#define IOC4_SRCIR_ARM	        0x80000000 /* Arm RX timer */
+
+/* Bitmasks for IOC4_SHADOW_<3:0> */
+#define IOC4_SHADOW_DR          0x00000001  /* Data ready */
+#define IOC4_SHADOW_OE          0x00000002  /* Overrun error */
+#define IOC4_SHADOW_PE          0x00000004  /* Parity error */
+#define IOC4_SHADOW_FE          0x00000008  /* Framing error */
+#define IOC4_SHADOW_BI          0x00000010  /* Break interrupt */
+#define IOC4_SHADOW_THRE        0x00000020  /* Xmit holding register empty */
+#define IOC4_SHADOW_TEMT        0x00000040  /* Xmit shift register empty */
+#define IOC4_SHADOW_RFCE        0x00000080  /* Char in RX fifo has an error */
+#define IOC4_SHADOW_DCTS        0x00010000  /* Delta clear to send */
+#define IOC4_SHADOW_DDCD        0x00080000  /* Delta data carrier detect */
+#define IOC4_SHADOW_CTS         0x00100000  /* Clear to send */
+#define IOC4_SHADOW_DCD         0x00800000  /* Data carrier detect */
+#define IOC4_SHADOW_DTR         0x01000000  /* Data terminal ready */
+#define IOC4_SHADOW_RTS         0x02000000  /* Request to send */
+#define IOC4_SHADOW_OUT1        0x04000000  /* 16550 OUT1 bit */
+#define IOC4_SHADOW_OUT2        0x08000000  /* 16550 OUT2 bit */
+#define IOC4_SHADOW_LOOP        0x10000000  /* Loopback enabled */
+
+/* Bitmasks for IOC4_SRTR_<3:0> */
+#define IOC4_SRTR_CNT	        0x00000fff /* Reload value for RX timer */
+#define IOC4_SRTR_CNT_VAL	0x0fff0000 /* Current value of RX timer */
+#define IOC4_SRTR_CNT_VAL_SHIFT         16
+#define IOC4_SRTR_HZ                 16000 /* SRTR clock frequency */
+
+/* Serial port register map used for DMA and PIO serial I/O */
+typedef volatile struct ioc4_serialregs {
+    ioc4reg_t		    sscr;
+    ioc4reg_t		    stpir;
+    ioc4reg_t		    stcir;
+    ioc4reg_t		    srpir;
+    ioc4reg_t		    srcir;
+    ioc4reg_t		    srtr;
+    ioc4reg_t		    shadow;
+} ioc4_sregs_t;
+
+/* IOC4 UART register map */
+typedef volatile struct ioc4_uartregs {
+    union {
+        char                    rbr;    /* read only, DLAB == 0 */
+        char                    thr;    /* write only, DLAB == 0 */
+        char                    dll;    /* DLAB == 1 */
+    } u1;
+    union {
+        char                    ier;    /* DLAB == 0 */
+        char                    dlm;    /* DLAB == 1 */
+    } u2;
+    union {
+        char                    iir;    /* read only */
+        char                    fcr;    /* write only */
+    } u3;
+    char                    i4u_lcr;
+    char                    i4u_mcr;
+    char                    i4u_lsr;
+    char                    i4u_msr;
+    char                    i4u_scr;
+} ioc4_uart_t;
+
+#define i4u_rbr u1.rbr
+#define i4u_thr u1.thr
+#define i4u_dll u1.dll
+#define i4u_ier u2.ier
+#define i4u_dlm u2.dlm
+#define i4u_iir u3.iir
+#define i4u_fcr u3.fcr
+
+/* PCI config space register map */
+typedef volatile struct ioc4_configregs {
+    ioc4reg_t		    pci_id;
+    ioc4reg_t		    pci_scr;
+    ioc4reg_t		    pci_rev;
+    ioc4reg_t		    pci_lat;
+    ioc4reg_t		    pci_bar0;
+    ioc4reg_t		    pci_bar1;
+    ioc4reg_t               pci_bar2_not_implemented;
+    ioc4reg_t               pci_cis_ptr_not_implemented;
+    ioc4reg_t		    pci_sidv;
+    ioc4reg_t		    pci_rom_bar_not_implemented;
+    ioc4reg_t		    pci_cap;
+    ioc4reg_t		    pci_rsv;
+    ioc4reg_t		    pci_latgntint;
+
+    char                    pci_fill1[0x58 - 0x3c - 4];
+
+    ioc4reg_t               pci_pcix;
+    ioc4reg_t               pci_pcixstatus;
+} ioc4_cfg_t;
+
+/* PCI memory space register map addressed using pci_bar0 */
+typedef volatile struct ioc4_memregs {
+
+    /* Miscellaneous IOC4  registers */
+    ioc4reg_t		    pci_err_addr_l;
+    ioc4reg_t		    pci_err_addr_h;
+    ioc4reg_t		    sio_ir;
+    ioc4reg_t		    other_ir;
+
+    /* These registers are read-only for general kernel code.  To
+     * modify them use the functions in ioc4.c.
+     */
+    ioc4reg_t		    sio_ies_ro;
+    ioc4reg_t		    other_ies_ro;
+    ioc4reg_t		    sio_iec_ro;
+    ioc4reg_t		    other_iec_ro;
+    ioc4reg_t		    sio_cr;
+    ioc4reg_t		    misc_fill1;
+    ioc4reg_t		    int_out;
+    ioc4reg_t		    misc_fill2;
+    ioc4reg_t		    gpcr_s;
+    ioc4reg_t		    gpcr_c;
+    ioc4reg_t		    gpdr;
+    ioc4reg_t		    misc_fill3;
+    ioc4reg_t		    gppr_0;
+    ioc4reg_t		    gppr_1;
+    ioc4reg_t		    gppr_2;
+    ioc4reg_t		    gppr_3;
+    ioc4reg_t		    gppr_4;
+    ioc4reg_t		    gppr_5;
+    ioc4reg_t		    gppr_6;
+    ioc4reg_t		    gppr_7;
+
+    char		    misc_fill4[0x100 - 0x5C - 4];
+
+    /* ATA/ATAP registers */
+    ioc4reg_t		    ata_0;
+    ioc4reg_t		    ata_1;
+    ioc4reg_t		    ata_2;
+    ioc4reg_t		    ata_3;
+    ioc4reg_t		    ata_4;
+    ioc4reg_t		    ata_5;
+    ioc4reg_t		    ata_6;
+    ioc4reg_t		    ata_7;
+    ioc4reg_t		    ata_aux;
+
+    char		    ata_fill1[0x140 - 0x120 - 4];
+
+    ioc4reg_t		    ata_timing;
+    ioc4reg_t		    ata_dma_ptr_l;
+    ioc4reg_t		    ata_dma_ptr_h;
+    ioc4reg_t		    ata_dma_addr_l;
+    ioc4reg_t		    ata_dma_addr_h;
+    ioc4reg_t		    ata_bc_dev;
+    ioc4reg_t		    ata_bc_mem;
+    ioc4reg_t		    ata_dma_ctrl;
+
+    char		    ata_fill2[0x200 - 0x15C - 4];
+
+    /* Keyboard and mouse registers */
+    ioc4reg_t		    km_csr;
+    ioc4reg_t		    k_rd;
+    ioc4reg_t		    m_rd;
+    ioc4reg_t		    k_wd;
+    ioc4reg_t		    m_wd;
+
+    char		    km_fill1[0x300 - 0x210 - 4];
+
+    /* Serial port registers used for DMA serial I/O */
+    ioc4reg_t		    sbbr01_l;
+    ioc4reg_t		    sbbr01_h;
+    ioc4reg_t		    sbbr23_l;
+    ioc4reg_t		    sbbr23_h;
+
+    ioc4_sregs_t	    port_0;
+    ioc4_sregs_t	    port_1;
+    ioc4_sregs_t	    port_2;
+    ioc4_sregs_t	    port_3;
+
+    ioc4_uart_t		    uart_0;
+    ioc4_uart_t		    uart_1;
+    ioc4_uart_t		    uart_2;
+    ioc4_uart_t		    uart_3;
+} ioc4_mem_t;
+
+#endif	/* 0 */
+
+/*
+ * Bytebus device space
+ */
+#define IOC4_BYTEBUS_DEV0	0x80000L  /* Addressed using pci_bar0 */ 
+#define IOC4_BYTEBUS_DEV1	0xA0000L  /* Addressed using pci_bar0 */
+#define IOC4_BYTEBUS_DEV2	0xC0000L  /* Addressed using pci_bar0 */
+#define IOC4_BYTEBUS_DEV3	0xE0000L  /* Addressed using pci_bar0 */
+
+#if 0
+/* UART clock speed */
+#define IOC4_SER_XIN_CLK        66000000
+
+typedef enum ioc4_subdevs_e {
+    ioc4_subdev_generic,
+    ioc4_subdev_kbms,
+    ioc4_subdev_tty0,
+    ioc4_subdev_tty1,
+    ioc4_subdev_tty2,
+    ioc4_subdev_tty3,
+    ioc4_subdev_rt,
+    ioc4_nsubdevs
+} ioc4_subdev_t;
+
+/* Subdevice disable bits,
+ * from the standard INFO_LBL_SUBDEVS
+ */
+#define IOC4_SDB_TTY0		(1 << ioc4_subdev_tty0)
+#define IOC4_SDB_TTY1		(1 << ioc4_subdev_tty1)
+#define IOC4_SDB_TTY2		(1 << ioc4_subdev_tty2)
+#define IOC4_SDB_TTY3		(1 << ioc4_subdev_tty3)
+#define IOC4_SDB_KBMS		(1 << ioc4_subdev_kbms)
+#define IOC4_SDB_RT		(1 << ioc4_subdev_rt)
+#define IOC4_SDB_GENERIC	(1 << ioc4_subdev_generic)
+
+#define IOC4_ALL_SUBDEVS	((1 << ioc4_nsubdevs) - 1)
+
+#define IOC4_SDB_SERIAL		(IOC4_SDB_TTY0 | IOC4_SDB_TTY1 | IOC4_SDB_TTY2 | IOC4_SDB_TTY3)
+
+#define IOC4_STD_SUBDEVS	IOC4_ALL_SUBDEVS
+
+#define IOC4_INTA_SUBDEVS	(IOC4_SDB_SERIAL | IOC4_SDB_KBMS | IOC4_SDB_RT | IOC4_SDB_GENERIC)
+
+extern int		ioc4_subdev_enabled(vertex_hdl_t, ioc4_subdev_t);
+extern void		ioc4_subdev_enables(vertex_hdl_t, ulong_t);
+extern void		ioc4_subdev_enable(vertex_hdl_t, ioc4_subdev_t);
+extern void		ioc4_subdev_disable(vertex_hdl_t, ioc4_subdev_t);
+
+/* Macros to read and write the SIO_IEC and SIO_IES registers (see the
+ * comments in ioc4.c for details on why this is necessary
+ */
+#define IOC4_W_IES	0
+#define IOC4_W_IEC	1
+extern void		ioc4_write_ireg(void *, ioc4reg_t, int, ioc4_intr_type_t);
+
+#define IOC4_WRITE_IES(ioc4, val, type)	ioc4_write_ireg(ioc4, val, IOC4_W_IES, type)
+#define IOC4_WRITE_IEC(ioc4, val, type)	ioc4_write_ireg(ioc4, val, IOC4_W_IEC, type)
+
+typedef void
+ioc4_intr_func_f	(intr_arg_t, ioc4reg_t);
+
+typedef void
+ioc4_intr_connect_f	(vertex_hdl_t conn_vhdl,
+			 ioc4_intr_type_t,
+			 ioc4reg_t,
+			 ioc4_intr_func_f *,
+			 intr_arg_t info,
+			 vertex_hdl_t owner_vhdl,
+			 vertex_hdl_t intr_dev_vhdl,
+			 int (*)(intr_arg_t));
+
+typedef void
+ioc4_intr_disconnect_f	(vertex_hdl_t conn_vhdl,
+			 ioc4_intr_type_t,
+			 ioc4reg_t,
+			 ioc4_intr_func_f *,
+			 intr_arg_t info,
+			 vertex_hdl_t owner_vhdl);
+
+ioc4_intr_disconnect_f	ioc4_intr_disconnect;
+ioc4_intr_connect_f	ioc4_intr_connect;
+
+extern int		ioc4_is_console(vertex_hdl_t conn_vhdl);
+
+extern void		ioc4_mlreset(ioc4_cfg_t *, ioc4_mem_t *);
+
+extern intr_func_f	ioc4_intr;
+
+extern ioc4_mem_t      *ioc4_mem_ptr(void *ioc4_fastinfo);
+
+typedef ioc4_intr_func_f *ioc4_intr_func_t;
+
+#endif	/* 0 */
+#endif				/* _ASM_IA64_SN_IOC4_H */
diff -Nru a/include/asm-ia64/sn/ioerror.h b/include/asm-ia64/sn/ioerror.h
--- a/include/asm-ia64/sn/ioerror.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/sn/ioerror.h	Wed Jun 18 23:42:08 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_IOERROR_H
 #define _ASM_IA64_SN_IOERROR_H
@@ -108,7 +108,7 @@
  *        we have a single structure, and the appropriate fields get filled in
  *        at each layer.
  *      - This provides a way to dump all error related information in any layer
- *        of error handling (debugging aid).
+ *        of erorr handling (debugging aid).
  *
  * A second possibility is to allow each layer to define its own error
  * data structure, and fill in the proper fields. This has the advantage
diff -Nru a/include/asm-ia64/sn/ioerror_handling.h b/include/asm-ia64/sn/ioerror_handling.h
--- a/include/asm-ia64/sn/ioerror_handling.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/sn/ioerror_handling.h	Wed Jun 18 23:42:07 2003
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_IOERROR_HANDLING_H
 #define _ASM_IA64_SN_IOERROR_HANDLING_H
@@ -207,26 +207,17 @@
 
 /* Error state interfaces */
 #if defined(CONFIG_SGI_IO_ERROR_HANDLING)
-extern error_return_code_t	error_state_set(devfs_handle_t,error_state_t);
-extern error_state_t		error_state_get(devfs_handle_t);
+extern error_return_code_t	error_state_set(vertex_hdl_t,error_state_t);
+extern error_state_t		error_state_get(vertex_hdl_t);
 #endif
 
-/* System critical graph interfaces */
-
-extern boolean_t		is_sys_critical_vertex(devfs_handle_t);
-extern devfs_handle_t		sys_critical_first_child_get(devfs_handle_t);
-extern devfs_handle_t		sys_critical_next_child_get(devfs_handle_t);
-extern devfs_handle_t		sys_critical_parent_get(devfs_handle_t);
-extern error_return_code_t	sys_critical_graph_vertex_add(devfs_handle_t,
-							     devfs_handle_t new);
-
 /* Error action interfaces */
 
-extern error_return_code_t	error_action_set(devfs_handle_t,
+extern error_return_code_t	error_action_set(vertex_hdl_t,
 						 error_action_f,
 						 error_context_t,
 						 error_priority_t);
-extern error_return_code_t	error_action_perform(devfs_handle_t);
+extern error_return_code_t	error_action_perform(vertex_hdl_t);
 
 
 #define INFO_LBL_ERROR_SKIP_ENV	"error_skip_env"
@@ -243,14 +234,14 @@
 hwgraph_info_remove_LBL(v, INFO_LBL_ERROR_SKIP_ENV, 0)
 
 /* Skip point interfaces */
-extern error_return_code_t	error_skip_point_jump(devfs_handle_t, boolean_t);
-extern error_return_code_t	error_skip_point_clear(devfs_handle_t);
+extern error_return_code_t	error_skip_point_jump(vertex_hdl_t, boolean_t);
+extern error_return_code_t	error_skip_point_clear(vertex_hdl_t);
 
 /* REFERENCED */
 #if defined(CONFIG_SGI_IO_ERROR_HANDLING)
 
 inline static int
-error_skip_point_mark(devfs_handle_t  v)  			 
+error_skip_point_mark(vertex_hdl_t  v)  			 
 {									
 	label_t		*error_env = NULL;	 			
 	int		code = 0;		
@@ -283,10 +274,10 @@
 
 typedef uint64_t		counter_t;
 
-extern counter_t		error_retry_count_get(devfs_handle_t);
-extern error_return_code_t	error_retry_count_set(devfs_handle_t,counter_t);
-extern counter_t		error_retry_count_increment(devfs_handle_t);
-extern counter_t		error_retry_count_decrement(devfs_handle_t);
+extern counter_t		error_retry_count_get(vertex_hdl_t);
+extern error_return_code_t	error_retry_count_set(vertex_hdl_t,counter_t);
+extern counter_t		error_retry_count_increment(vertex_hdl_t);
+extern counter_t		error_retry_count_decrement(vertex_hdl_t);
 
 /* Except for the PIO Read error typically the other errors are handled in
  * the context of an asynchronous error interrupt.
@@ -298,7 +289,7 @@
  * thru the calls the io error handling layer.
  */
 #if defined(CONFIG_SGI_IO_ERROR_HANDLING)
-extern boolean_t		is_device_shutdown(devfs_handle_t);
+extern boolean_t		is_device_shutdown(vertex_hdl_t);
 #define IS_DEVICE_SHUTDOWN(_d) 	(is_device_shutdown(_d))
 #endif
 
diff -Nru a/include/asm-ia64/sn/iograph.h b/include/asm-ia64/sn/iograph.h
--- a/include/asm-ia64/sn/iograph.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/iograph.h	Wed Jun 18 23:42:06 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_IOGRAPH_H
 #define _ASM_IA64_SN_IOGRAPH_H
@@ -77,7 +77,7 @@
 #define EDGE_LBL_IOC3			"ioc3"
 #define EDGE_LBL_LUN                    "lun"
 #define EDGE_LBL_LINUX                  "linux"
-#define EDGE_LBL_LINUX_BUS              EDGE_LBL_LINUX "/busnum"
+#define EDGE_LBL_LINUX_BUS              EDGE_LBL_LINUX "/bus/pci-x"
 #define EDGE_LBL_MACE                   "mace" 		/* O2 mace */
 #define EDGE_LBL_MACHDEP                "machdep"       /* Platform depedent devices */
 #define EDGE_LBL_MASTER			".master"
@@ -127,8 +127,12 @@
 #define EDGE_LBL_XBOX_RPS               "xbox_rps"      /* redundant power supply for xbox unit */ 
 #define EDGE_LBL_IOBRICK		"iobrick"
 #define EDGE_LBL_PBRICK			"Pbrick"
+#define EDGE_LBL_PEBRICK		"PEbrick"
+#define EDGE_LBL_PXBRICK		"PXbrick"
+#define EDGE_LBL_IXBRICK		"IXbrick"
 #define EDGE_LBL_IBRICK			"Ibrick"
 #define EDGE_LBL_XBRICK			"Xbrick"
+#define EDGE_LBL_CGBRICK		"CGbrick"
 #define EDGE_LBL_CPUBUS			"cpubus"	/* CPU Interfaces (SysAd) */
 
 /* vertex info labels in hwgraph */
@@ -211,7 +215,7 @@
 #include <asm/sn/xtalk/xbow.h>	/* For get MAX_PORT_NUM */
 
 int io_brick_map_widget(int, int);
-int io_path_map_widget(devfs_handle_t);
+int io_path_map_widget(vertex_hdl_t);
 
 /*
  * Map a brick's widget number to a meaningful int
diff -Nru a/include/asm-ia64/sn/klclock.h b/include/asm-ia64/sn/klclock.h
--- a/include/asm-ia64/sn/klclock.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/sn/klclock.h	Wed Jun 18 23:42:07 2003
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1996, 2001 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1996, 2001-2003 Silicon Graphics, Inc. All rights reserved.
  * Copyright (C) 2001 by Ralf Baechle
  */
 #ifndef _ASM_IA64_SN_KLCLOCK_H
diff -Nru a/include/asm-ia64/sn/klconfig.h b/include/asm-ia64/sn/klconfig.h
--- a/include/asm-ia64/sn/klconfig.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/klconfig.h	Wed Jun 18 23:42:06 2003
@@ -6,7 +6,7 @@
  *
  * Derived from IRIX <sys/SN/klconfig.h>.
  *
- * Copyright (C) 1992-1997,1999,2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997,1999,2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * Copyright (C) 1999 by Ralf Baechle
  */
 #ifndef _ASM_IA64_SN_KLCONFIG_H
@@ -46,18 +46,8 @@
 #include <asm/sn/xtalk/xtalk.h>
 #include <asm/sn/kldir.h>
 #include <asm/sn/sn_fru.h>
-
-#ifdef CONFIG_IA64_SGI_SN1
-#include <asm/sn/sn1/hubmd_next.h>
-#endif
-
-#ifdef CONFIG_IA64_SGI_SN2
 #include <asm/sn/sn2/shub_md.h>
-#endif
-
-#ifdef CONFIG_IA64_SGI_SN2
 #include <asm/sn/geo.h>
-#endif
 
 #define KLCFGINFO_MAGIC	0xbeedbabe
 
@@ -398,6 +388,12 @@
 #define KLTYPE_IBRICK		(KLCLASS_IOBRICK | 0x1)
 #define KLTYPE_PBRICK		(KLCLASS_IOBRICK | 0x2)
 #define KLTYPE_XBRICK		(KLCLASS_IOBRICK | 0x3)
+#define KLTYPE_NBRICK		(KLCLASS_IOBRICK | 0x4)
+#define KLTYPE_PEBRICK		(KLCLASS_IOBRICK | 0x5)
+#define KLTYPE_PXBRICK		(KLCLASS_IOBRICK | 0x6)
+#define KLTYPE_IXBRICK		(KLCLASS_IOBRICK | 0x7)
+#define KLTYPE_CGBRICK		(KLCLASS_IOBRICK | 0x8)
+
 
 #define KLTYPE_PBRICK_BRIDGE	KLTYPE_PBRICK
 
@@ -437,11 +433,7 @@
  	unsigned char 	brd_flags;        /* Enabled, Disabled etc */
 	unsigned char 	brd_slot;         /* slot number */
 	unsigned short	brd_debugsw;      /* Debug switches */
-#ifdef CONFIG_IA64_SGI_SN2
 	geoid_t		brd_geoid;	  /* geo id */
-#else
-	moduleid_t	brd_module;       /* module to which it belongs */
-#endif
 	partid_t 	brd_partition;    /* Partition number */
         unsigned short 	brd_diagval;      /* diagnostic value */
         unsigned short 	brd_diagparm;     /* diagnostic parameter */
@@ -452,13 +444,11 @@
 	klconf_off_t 	brd_compts[MAX_COMPTS_PER_BRD]; /* pointers to COMPONENTS */
 	klconf_off_t 	brd_errinfo;      /* Board's error information */
 	struct lboard_s *brd_parent;	  /* Logical parent for this brd */
-	devfs_handle_t	brd_graph_link;   /* vertex hdl to connect extern compts */
+	vertex_hdl_t	brd_graph_link;   /* vertex hdl to connect extern compts */
 	confidence_t	brd_confidence;	  /* confidence that the board is bad */
 	nasid_t		brd_owner;        /* who owns this board */
 	unsigned char 	brd_nic_flags;    /* To handle 8 more NICs */
-#ifdef CONFIG_IA64_SGI_SN2
 	char		pad[32];	  /* future expansion */
-#endif
 	char		brd_name[32];
 } lboard_t;
 
@@ -491,7 +481,8 @@
         ((_brd)->brd_next ?     \
          (NODE_OFFSET_TO_LBOARD(NASID_GET(_brd), (_brd)->brd_next)): NULL)
 #define KLCF_COMP(_brd, _ndx)   \
-                (NODE_OFFSET_TO_KLINFO(NASID_GET(_brd), (_brd)->brd_compts[(_ndx)]))
+                ((((_brd)->brd_compts[(_ndx)]) == 0) ? 0 : \
+			(NODE_OFFSET_TO_KLINFO(NASID_GET(_brd), (_brd)->brd_compts[(_ndx)])))
 
 #define KLCF_COMP_ERROR(_brd, _comp)    \
                 (NODE_OFFSET_TO_K0(NASID_GET(_brd), (_comp)->errinfo))
@@ -626,9 +617,7 @@
 	nasid_t		port_nasid;
 	unsigned char	port_flag;
 	klconf_off_t	port_offset;
-#ifdef CONFIG_IA64_SGI_SN2
 	short		port_num;
-#endif
 } klport_t;
 
 typedef struct klcpu_s {                          /* CPU */
@@ -638,9 +627,7 @@
     	unsigned short 	cpu_speed;	/* Speed in MHZ */
     	unsigned short 	cpu_scachesz;	/* secondary cache size in MB */
     	unsigned short 	cpu_scachespeed;/* secondary cache speed in MHz */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klcpu_t ;
 
 #define CPU_STRUCT_VERSION   2
@@ -648,28 +635,20 @@
 typedef struct klhub_s {			/* HUB */
 	klinfo_t 	hub_info;
 	uint 		hub_flags;		/* PCFG_HUB_xxx flags */
-#ifdef CONFIG_IA64_SGI_SN2
 #define MAX_NI_PORTS                    2
 	klport_t	hub_port[MAX_NI_PORTS + 1];/* hub is connected to this */
-#else
-	klport_t	hub_port;		/* hub is connected to this */
-#endif
 	nic_t		hub_box_nic;		/* nic of containing box */
 	klconf_off_t	hub_mfg_nic;		/* MFG NIC string */
 	u64		hub_speed;		/* Speed of hub in HZ */
-#ifdef CONFIG_IA64_SGI_SN2
 	moduleid_t	hub_io_module;		/* attached io module */
 	unsigned long	pad;
-#endif
 } klhub_t ;
 
 typedef struct klhub_uart_s {			/* HUB */
 	klinfo_t 	hubuart_info;
 	uint 		hubuart_flags;		/* PCFG_HUB_xxx flags */
 	nic_t		hubuart_box_nic;	/* nic of containing box */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klhub_uart_t ;
 
 #define MEMORY_STRUCT_VERSION   2
@@ -680,9 +659,7 @@
 	short		membnk_dimm_select; /* bank to physical addr mapping*/
 	short		membnk_bnksz[MD_MEM_BANKS]; /* Memory bank sizes */
 	short		membnk_attr;
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klmembnk_t ;
 
 #define KLCONFIG_MEMBNK_SIZE(_info, _bank)	\
@@ -701,9 +678,7 @@
               char snum_str[MAX_SERIAL_NUM_SIZE];
               unsigned long long       snum_int;
       } snum;
-#ifdef CONFIG_IA64_SGI_SN2
       unsigned long   pad;
-#endif
 } klmod_serial_num_t;
 
 /* Macros needed to access serial number structure in lboard_t.
@@ -721,9 +696,7 @@
     	klport_t	xbow_port_info[MAX_XBOW_LINKS] ; /* Module number */
         int		xbow_master_hub_link;
         /* type of brd connected+component struct ptr+flags */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klxbow_t ;
 
 #define MAX_PCI_SLOTS 8
@@ -742,9 +715,7 @@
     	pci_t    	pci_specific  ;    /* PCI Board config info */
 	klpci_device_t	bri_devices[MAX_PCI_DEVS] ;	/* PCI IDs */
 	klconf_off_t	bri_mfg_nic ;
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klbri_t ;
 
 #define MAX_IOC3_TTY	2
@@ -758,9 +729,7 @@
 	klinfo_t	ioc3_enet ;
 	klconf_off_t	ioc3_enet_off ;
 	klconf_off_t	ioc3_kbd_off ;
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klioc3_t ;
 
 #define MAX_VME_SLOTS 8
@@ -769,18 +738,14 @@
 	klinfo_t 	vmeb_info ;
 	vmeb_t		vmeb_specific ;
     	klconf_off_t   	vmeb_brdinfo[MAX_VME_SLOTS]   ;    /* VME Board config info */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klvmeb_t ;
 
 typedef struct klvmed_s {                          /* VME DEVICE - VME BOARD */
 	klinfo_t	vmed_info ;
 	vmed_t		vmed_specific ;
     	klconf_off_t   	vmed_brdinfo[MAX_VME_SLOTS]   ;    /* VME Board config info */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klvmed_t ;
 
 #define ROUTER_VECTOR_VERS	2
@@ -793,9 +758,7 @@
     	klport_t 	rou_port[MAX_ROUTER_PORTS + 1] ; /* array index 1 to 6 */
 	klconf_off_t	rou_mfg_nic ;     /* MFG NIC string */
 	u64	rou_vector;	  /* vector from master node */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long   pad;
-#endif
 } klrou_t ;
 
 /*
@@ -820,25 +783,19 @@
 	graphics_t	gfx_specific;
 	klconf_off_t    pad0;		/* for compatibility with older proms */
 	klconf_off_t    gfx_mfg_nic;
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klgfx_t;
 
 typedef struct klxthd_s {   
 	klinfo_t 	xthd_info ;
 	klconf_off_t	xthd_mfg_nic ;        /* MFG NIC string */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klxthd_t ;
 
 typedef struct kltpu_s {                     /* TPU board */
 	klinfo_t 	tpu_info ;
 	klconf_off_t	tpu_mfg_nic ;        /* MFG NIC string */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } kltpu_t ;
 
 typedef struct klgsn_s {                     /* GSN board */
@@ -860,9 +817,7 @@
     	scsi_t       	scsi_specific   ; 
 	unsigned char 	scsi_numdevs ;
 	klconf_off_t	scsi_devinfo[MAX_SCSI_DEVS] ; 
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klscsi_t ;
 
 typedef struct klscctl_s {                          /* SCSI Controller */
@@ -870,49 +825,37 @@
 	uint		type;
 	uint		scsi_buscnt;                        /* # busses this cntlr */
 	void		*scsi_bus[2];                       /* Pointer to 2 klscsi_t's */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klscctl_t ;
 
 typedef struct klscdev_s {                          /* SCSI device */
 	klinfo_t 	scdev_info ;
 	struct scsidisk_data *scdev_cfg ; /* driver fills up this */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klscdev_t ;
 
 typedef struct klttydev_s {                          /* TTY device */
 	klinfo_t 	ttydev_info ;
 	struct terminal_data *ttydev_cfg ; /* driver fills up this */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klttydev_t ;
 
 typedef struct klenetdev_s {                          /* ENET device */
 	klinfo_t 	enetdev_info ;
 	struct net_data *enetdev_cfg ; /* driver fills up this */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klenetdev_t ;
 
 typedef struct klkbddev_s {                          /* KBD device */
 	klinfo_t 	kbddev_info ;
 	struct keyboard_data *kbddev_cfg ; /* driver fills up this */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klkbddev_t ;
 
 typedef struct klmsdev_s {                          /* mouse device */
         klinfo_t        msdev_info ;
         void 		*msdev_cfg ; 
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klmsdev_t ;
 
 #define MAX_FDDI_DEVS 10 /* XXX Is this true */
@@ -921,17 +864,13 @@
 	klinfo_t 	fddi_info ;
     	fddi_t        	fddi_specific ;       
 	klconf_off_t	fddi_devinfo[MAX_FDDI_DEVS] ;
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klfddi_t ;
 
 typedef struct klmio_s {                          /* MIO */
 	klinfo_t 	mio_info ;
     	mio_t       	mio_specific   ; 
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klmio_t ;
 
 /*
@@ -942,9 +881,7 @@
 	klinfo_t	usb_info;	/* controller info */
 	void		*usb_bus;	/* handle to usb_bus_t */
 	uint64_t	usb_controller;	/* ptr to controller info */
-#ifdef CONFIG_IA64_SGI_SN2
 	unsigned long	pad;
-#endif
 } klusb_t ; 
 
 typedef union klcomp_s {
@@ -1028,37 +965,18 @@
 extern klcpu_t *nasid_slice_to_cpuinfo(nasid_t, int);
 
 
-extern xwidgetnum_t nodevertex_widgetnum_get(devfs_handle_t node_vtx);
-extern devfs_handle_t nodevertex_xbow_peer_get(devfs_handle_t node_vtx);
 extern lboard_t *find_gfxpipe(int pipenum);
-extern void setup_gfxpipe_link(devfs_handle_t vhdl,int pipenum);
 extern lboard_t *find_lboard_class(lboard_t *start, unsigned char brd_class);
-#ifdef CONFIG_IA64_SGI_SN2
-extern lboard_t *find_lboard_module_class(lboard_t *start, geoid_t geoid,
-						unsigned char brd_class);
-#else
-extern lboard_t *find_lboard_module_class(lboard_t *start, moduleid_t mod,
-                                               unsigned char brd_class);
-#endif
 extern lboard_t *find_nic_lboard(lboard_t *, nic_t);
 extern lboard_t *find_nic_type_lboard(nasid_t, unsigned char, nic_t);
-#ifdef CONFIG_IA64_SGI_SN2
 extern lboard_t *find_lboard_modslot(lboard_t *start, geoid_t geoid);
 extern lboard_t *find_lboard_module(lboard_t *start, geoid_t geoid);
-extern lboard_t *get_board_name(nasid_t nasid, geoid_t geoid, slotid_t slot, char *name);
-#else
-extern lboard_t *find_lboard_modslot(lboard_t *start, moduleid_t mod, slotid_t slot);
-extern lboard_t *find_lboard_module(lboard_t *start, moduleid_t mod);
-extern lboard_t *get_board_name(nasid_t nasid, moduleid_t mod, slotid_t slot, char *name);
-#endif
 extern int	config_find_nic_router(nasid_t, nic_t, lboard_t **, klrou_t**);
 extern int	config_find_nic_hub(nasid_t, nic_t, lboard_t **, klhub_t**);
 extern int	config_find_xbow(nasid_t, lboard_t **, klxbow_t**);
 extern int 	update_klcfg_cpuinfo(nasid_t, int);
 extern void 	board_to_path(lboard_t *brd, char *path);
-#ifdef CONFIG_IA64_SGI_SN2
 extern moduleid_t get_module_id(nasid_t nasid);
-#endif
 extern void 	nic_name_convert(char *old_name, char *new_name);
 extern int 	module_brds(nasid_t nasid, lboard_t **module_brds, int n);
 extern lboard_t *brd_from_key(uint64_t key);
diff -Nru a/include/asm-ia64/sn/kldir.h b/include/asm-ia64/sn/kldir.h
--- a/include/asm-ia64/sn/kldir.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/sn/kldir.h	Wed Jun 18 23:42:07 2003
@@ -5,7 +5,7 @@
  *
  * Derived from IRIX <sys/SN/kldir.h>, revision 1.21.
  *
- * Copyright (C) 1992-1997,1999,2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997,1999,2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * Copyright (C) 1999 by Ralf Baechle
  */
 #ifndef _ASM_IA64_SN_KLDIR_H
diff -Nru a/include/asm-ia64/sn/ksys/elsc.h b/include/asm-ia64/sn/ksys/elsc.h
--- a/include/asm-ia64/sn/ksys/elsc.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/sn/ksys/elsc.h	Wed Jun 18 23:42:08 2003
@@ -4,89 +4,13 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 #ifndef _ASM_SN_KSYS_ELSC_H
 #define _ASM_SN_KSYS_ELSC_H
 
 #include <linux/config.h>
 #include <asm/sn/ksys/l1.h>
-
-#ifdef CONFIG_IA64_SGI_SN1
-
-#define ELSC_ACP_MAX		86		/* 84+cr+lf */
-#define ELSC_LINE_MAX		(ELSC_ACP_MAX - 2)
-
-typedef sc_cq_t elsc_cq_t;
-
-/*
- * ELSC structure passed around as handle
- */
-
-typedef l1sc_t elsc_t;
-
-void	elsc_init(elsc_t *e, nasid_t nasid);
-
-int	elsc_process(elsc_t *e);
-int	elsc_msg_check(elsc_t *e, char *msg, int msg_max);
-int	elsc_msg_callback(elsc_t *e,
-			  void (*callback)(void *callback_data, char *msg),
-			  void *callback_data);
-char   *elsc_errmsg(int code);
-
-int	elsc_nvram_write(elsc_t *e, int addr, char *buf, int len);
-int	elsc_nvram_read(elsc_t *e, int addr, char *buf, int len);
-int	elsc_nvram_magic(elsc_t *e);
-int	elsc_command(elsc_t *e, int only_if_message);
-int	elsc_parse(elsc_t *e, char *p1, char *p2, char *p3);
-int	elsc_ust_write(elsc_t *e, uchar_t c);
-int 	elsc_ust_read(elsc_t *e, char *c);
-
-
-
-/*
- * System controller commands
- */
-
-int	elsc_version(elsc_t *e, char *result);
-int	elsc_debug_set(elsc_t *e, u_char byte1, u_char byte2);
-int	elsc_debug_get(elsc_t *e, u_char *byte1, u_char *byte2);
-int	elsc_module_set(elsc_t *e, int module);
-int	elsc_module_get(elsc_t *e);
-int	elsc_partition_set(elsc_t *e, int partition);
-int	elsc_partition_get(elsc_t *e);
-int	elsc_domain_set(elsc_t *e, int domain);
-int	elsc_domain_get(elsc_t *e);
-int	elsc_cluster_set(elsc_t *e, int cluster);
-int	elsc_cluster_get(elsc_t *e);
-int	elsc_cell_set(elsc_t *e, int cell);
-int	elsc_cell_get(elsc_t *e);
-int	elsc_bist_set(elsc_t *e, char bist_status);
-char	elsc_bist_get(elsc_t *e);
-int	elsc_lock(elsc_t *e, int retry_interval_usec, int timeout_usec, u_char lock_val);
-int	elsc_unlock(elsc_t *e);
-int	elsc_display_char(elsc_t *e, int led, int chr);
-int	elsc_display_digit(elsc_t *e, int led, int num, int l_case);
-int	elsc_display_mesg(elsc_t *e, char *chr);	/* 8-char input */
-int	elsc_password_set(elsc_t *e, char *password);	/* 4-char input */
-int	elsc_password_get(elsc_t *e, char *password);	/* 4-char output */
-int	elsc_rpwr_query(elsc_t *e, int is_master);
-int	elsc_power_query(elsc_t *e);
-int	elsc_power_down(elsc_t *e, int sec);
-int	elsc_power_cycle(elsc_t *e);
-int	elsc_system_reset(elsc_t *e);
-int	elsc_dip_switches(elsc_t *e);
-
-int	_elsc_hbt(elsc_t *e, int ival, int rdly);
-
-#define	elsc_hbt_enable(e, ival, rdly)	_elsc_hbt(e, ival, rdly)
-#define	elsc_hbt_disable(e)		_elsc_hbt(e, 0, 0)
-#define	elsc_hbt_send(e)		_elsc_hbt(e, 0, 1)
-
-elsc_t	       *get_elsc(void);
-
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
 
 /*
  * Error codes
diff -Nru a/include/asm-ia64/sn/ksys/l1.h b/include/asm-ia64/sn/ksys/l1.h
--- a/include/asm-ia64/sn/ksys/l1.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/ksys/l1.h	Wed Jun 18 23:42:06 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 
 #ifndef _ASM_SN_KSYS_L1_H
@@ -16,162 +16,6 @@
 #include <asm/atomic.h>
 #include <asm/sn/sv.h>
 
-
-#ifdef CONFIG_IA64_SGI_SN1
-
-#define BRL1_QSIZE	128	/* power of 2 is more efficient */
-#define BRL1_BUFSZ	264	/* needs to be large enough
-				 * to hold 2 flags, escaped
-				 * CRC, type/subchannel byte,
-				 * and escaped payload
-				 */
-
-#define BRL1_IQS          32
-#define BRL1_OQS          4
-
-
-typedef struct sc_cq_s {
-    u_char              buf[BRL1_QSIZE];
-    int                 ipos, opos, tent_next;
-} sc_cq_t;
-
-/* An l1sc_t struct can be associated with the local (C-brick) L1 or an L1
- * on an R-brick.  In the R-brick case, the l1sc_t records a vector path
- * to the R-brick's junk bus UART.  In the C-brick case, we just use the
- * following flag to denote the local uart.
- *
- * This value can't be confused with a network vector because the least-
- * significant nibble of a network vector cannot be greater than 8.
- */
-#define BRL1_LOCALHUB_UART	((net_vec_t)0xf)
-
-/* L1<->Bedrock reserved subchannels */
-
-/* console channels */
-#define SC_CONS_CPU0    0x00
-#define SC_CONS_CPU1    0x01
-#define SC_CONS_CPU2    0x02
-#define SC_CONS_CPU3    0x03
-
-#define L1_ELSCUART_SUBCH(p)	(p)
-#define L1_ELSCUART_CPU(ch)	(ch)
-
-#define SC_CONS_SYSTEM  CPUS_PER_NODE
-
-/* mapping subchannels to queues */
-#define MAP_IQ(s)       (s)
-#define MAP_OQ(s)       (s)
-     
-#define BRL1_NUM_SUBCHANS 32
-#define BRL1_CMD_SUBCH	  16
-#define BRL1_EVENT_SUBCH  (BRL1_NUM_SUBCHANS - 1)
-#define BRL1_SUBCH_RSVD   0
-#define BRL1_SUBCH_FREE   (-1)
-
-/* constants for L1 hwgraph vertex info */
-#define CBRICK_L1	(__psint_t)1
-#define IOBRICK_L1	(__psint_t)2
-#define RBRICK_L1	(__psint_t)3
-
-
-struct l1sc_s;     
-/* Saved off interrupt frame */
-typedef struct brl1_intr_frame {
-	int bf_irq;		/* irq received */
-	void *bf_dev_id;	/* device information */
-	struct pt_regs *bf_regs; /* register frame */
-} brl1_intr_frame_t;
-
-typedef void (*brl1_notif_t)(int, void *, struct pt_regs *, struct l1sc_s *, int);
-typedef int  (*brl1_uartf_t)(struct l1sc_s *);
-
-/* structure for controlling a subchannel */
-typedef struct brl1_sch_s {
-    int		use;		/* if this subchannel is free,
-				 * use == BRL1_SUBCH_FREE */
-    uint	target;		/* type, rack and slot of component to
-				 * which this subchannel is directed */
-    atomic_t	packet_arrived; /* true if packet arrived on
-				 * this subchannel */
-    sc_cq_t *	iqp;		/* input queue for this subchannel */
-    sv_t	arrive_sv;	/* used to wait for a packet */
-    spinlock_t	data_lock;	/* synchronize access to input queues and
-				 * other fields of the brl1_sch_s struct */
-    brl1_notif_t tx_notify;     /* notify higher layer that transmission may 
-				 * continue */
-    brl1_notif_t rx_notify;	/* notify higher layer that a packet has been
-				 * received */
-    brl1_intr_frame_t irq_frame; /* saved off irq information */
-} brl1_sch_t;
-
-/* br<->l1 protocol states */
-#define BRL1_IDLE	0
-#define BRL1_FLAG	1
-#define BRL1_HDR	2
-#define BRL1_BODY	3
-#define BRL1_ESC	4
-#define BRL1_RESET	7
-
-
-/*
- * l1sc_t structure-- tracks protocol state, open subchannels, etc.
- */
-typedef struct l1sc_s {
-    nasid_t	 nasid;		/* nasid with which this instance
-				 * of the structure is associated */
-    moduleid_t	 modid;         /* module id of this brick */
-    u_char	 verbose;	/* non-zero if elscuart routines should
-				 * prefix output */
-    net_vec_t    uart;		/* vector path to UART, or BRL1_LOCALUART */
-    int		 sent;		/* number of characters sent */
-    int		 send_len;	/* number of characters in send buf */
-    brl1_uartf_t putc_f;	/* pointer to UART putc function */
-    brl1_uartf_t getc_f;	/* pointer to UART getc function */
-
-    spinlock_t   send_lock;     /* arbitrates send synchronization */
-    spinlock_t   recv_lock;     /* arbitrates uart receive access */
-    spinlock_t	 subch_lock;	/* arbitrates subchannel allocation */
-    cpuid_t	 intr_cpu;	/* cpu that receives L1 interrupts */
-
-    u_char	 send_in_use;	/* non-zero if send buffer contains an
-				 * unsent or partially-sent  packet */
-    u_char	 fifo_space;	/* current depth of UART send FIFO */
-
-    u_char	 brl1_state;	/* current state of the receive side */
-    u_char	 brl1_last_hdr;	/* last header byte received */
-
-    char	 send[BRL1_BUFSZ]; /* send buffer */
-
-    int		 sol;		/* "start of line" (see elscuart routines) */
-    int		 cons_listen;	/* non-zero if the elscuart interface should
-				 * also check the system console subchannel */
-    brl1_sch_t	 subch[BRL1_NUM_SUBCHANS];
-    				/* subchannels provided by link */
-
-    sc_cq_t	 garbage_q;	/* a place to put unsolicited packets */
-    sc_cq_t	 oq[BRL1_OQS];	/* elscuart output queues */
-} l1sc_t;
-
-
-/* error codes */
-#define BRL1_VALID	  0
-#define BRL1_FULL_Q	(-1)
-#define BRL1_CRC	(-2)
-#define BRL1_PROTOCOL	(-3)
-#define BRL1_NO_MESSAGE	(-4)
-#define BRL1_LINK	(-5)
-#define BRL1_BUSY	(-6)
-
-#define SC_SUCCESS      BRL1_VALID
-#define SC_NMSG         BRL1_NO_MESSAGE
-#define SC_BUSY         BRL1_BUSY
-#define SC_NOPEN        (-7)
-#define SC_BADSUBCH     (-8)
-#define SC_TIMEDOUT	(-9)
-#define SC_NSUBCH	(-10)
-
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
 /* L1 Target Addresses */
 /*
  * L1 commands and responses use source/target addresses that are
@@ -181,39 +25,11 @@
  * id (L1 functionality is divided into several independent "tasks"
  * that can each receive command requests and transmit responses)
  */
-#ifdef CONFIG_IA64_SGI_SN1
-#define L1_ADDR_TYPE_SHFT	28
-#define L1_ADDR_TYPE_MASK	0xF0000000
-#else
-#define L1_ADDR_TYPE_SHFT	8
-#define L1_ADDR_TYPE_MASK	0xFF00
-#endif	/* CONFIG_IA64_SGI_SN1 */
 #define L1_ADDR_TYPE_L1		0x00	/* L1 system controller */
 #define L1_ADDR_TYPE_L2		0x01	/* L2 system controller */
 #define L1_ADDR_TYPE_L3		0x02	/* L3 system controller */
 #define L1_ADDR_TYPE_CBRICK	0x03	/* attached C brick	*/
 #define L1_ADDR_TYPE_IOBRICK	0x04	/* attached I/O brick	*/
-
-#ifdef CONFIG_IA64_SGI_SN1
-#define L1_ADDR_RACK_SHFT	18
-#define L1_ADDR_RACK_MASK	0x0FFC0000
-#define	L1_ADDR_RACK_LOCAL	0x3ff	/* local brick's rack	*/
-#else
-#define L1_ADDR_RACK_SHFT	16
-#define L1_ADDR_RACK_MASK	0xFFFF00
-#define	L1_ADDR_RACK_LOCAL	0xffff	/* local brick's rack	*/
-#endif /* CONFIG_IA64_SGI_SN1 */
-
-#ifdef CONFIG_IA64_SGI_SN1
-#define L1_ADDR_BAY_SHFT	12
-#define L1_ADDR_BAY_MASK	0x0003F000
-#define	L1_ADDR_BAY_LOCAL	0x3f	/* local brick's bay	*/
-#else
-#define L1_ADDR_BAY_SHFT	0
-#define L1_ADDR_BAY_MASK	0xFF
-#define	L1_ADDR_BAY_LOCAL	0xff	/* local brick's bay	*/
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
 #define L1_ADDR_TASK_SHFT	0
 #define L1_ADDR_TASK_MASK	0x0000001F
 #define L1_ADDR_TASK_INVALID	0x00	/* invalid task 	*/
@@ -296,7 +112,9 @@
 #define L1_BRICKTYPE_X          0x58            /* X */
 #define L1_BRICKTYPE_X2         0x59            /* Y */
 #define L1_BRICKTYPE_N          0x4e            /* N */
+#define L1_BRICKTYPE_PE		0x25		/* % */
 #define L1_BRICKTYPE_PX		0x23		/* # */
+#define L1_BRICKTYPE_IX		0x3d		/* = */
 
 /* EEPROM codes (for the "read EEPROM" request) */
 /* c brick */
@@ -339,50 +157,10 @@
 
 #define bzero(d, n)	memset((d), 0, (n))
 
-#ifdef CONFIG_IA64_SGI_SN1
-
-#define SC_EVENT_CLASS_MASK ((unsigned short)0xff00)
-
-/* public interfaces to L1 system controller */
-
-int	sc_open( l1sc_t *sc, uint target );
-int	sc_close( l1sc_t *sc, int ch );
-int	sc_construct_msg( l1sc_t *sc, int ch, 
-			  char *msg, int msg_len,
-			  uint addr_task, short req_code,
-			  int req_nargs, ... );
-int	sc_interpret_resp( char *resp, int resp_nargs, ... );
-int	sc_send( l1sc_t *sc, int ch, char *msg, int len, int wait );
-int	sc_recv( l1sc_t *sc, int ch, char *msg, int *len, uint64_t block );
-int	sc_command( l1sc_t *sc, int ch, char *cmd, char *resp, int *len );
-int	sc_command_kern( l1sc_t *sc, int ch, char *cmd, char *resp, int *len );
-int	sc_poll( l1sc_t *sc, int ch );
-void	sc_init( l1sc_t *sc, nasid_t nasid, net_vec_t uart );
-void	sc_intr_enable( l1sc_t *sc );
-
-int	elsc_rack_bay_get(l1sc_t *e, uint *rack, uint *bay);
-int	elsc_rack_bay_type_get(l1sc_t *e, uint *rack, 
-			       uint *bay, uint *brick_type);
-int	elsc_cons_subch(l1sc_t *e, uint ch);
-int	elsc_cons_node(l1sc_t *e);
-int	elsc_display_line(l1sc_t *e, char *line, int lnum);
-
-extern l1sc_t *get_elsc( void );
-#define get_l1sc	get_elsc
-#define get_master_l1sc get_l1sc
-
-int	iobrick_rack_bay_type_get( l1sc_t *sc, uint *rack,
-				   uint *bay, uint *brick_type );
-int	iobrick_module_get( l1sc_t *sc );
-int	iobrick_pci_slot_pwr( l1sc_t *sc, int bus, int slot, int up );
-int	iobrick_pci_bus_pwr( l1sc_t *sc, int bus, int up );
-int	iobrick_sc_version( l1sc_t *sc, char *result );
-#else
 int	elsc_display_line(nasid_t nasid, char *line, int lnum);
 int	iobrick_rack_bay_type_get( nasid_t nasid, uint *rack,
 				   uint *bay, uint *brick_type );
 int	iobrick_module_get( nasid_t nasid );
-#endif	/* CONFIG_IA64_SGI_SN1 */
 
 
 #endif /* _ASM_SN_KSYS_L1_H */
diff -Nru a/include/asm-ia64/sn/labelcl.h b/include/asm-ia64/sn/labelcl.h
--- a/include/asm-ia64/sn/labelcl.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/sn/labelcl.h	Wed Jun 18 23:42:08 2003
@@ -4,13 +4,11 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_LABELCL_H
 #define _ASM_IA64_SN_LABELCL_H
 
-#include <asm/sn/hcl.h>
-
 #define LABELCL_MAGIC 0x4857434c	/* 'HWLC' */
 #define LABEL_LENGTH_MAX 256		/* Includes NULL char */
 #define INFO_DESC_PRIVATE (-1)      	/* default */
@@ -77,18 +75,18 @@
 
 extern labelcl_info_t *labelcl_info_create(void);
 extern int labelcl_info_destroy(labelcl_info_t *);
-extern int labelcl_info_add_LBL(struct devfs_entry *, char *, arb_info_desc_t, arbitrary_info_t);
-extern int labelcl_info_remove_LBL(struct devfs_entry *, char *, arb_info_desc_t *, arbitrary_info_t *);
-extern int labelcl_info_replace_LBL(struct devfs_entry *, char *, arb_info_desc_t,
+extern int labelcl_info_add_LBL(vertex_hdl_t, char *, arb_info_desc_t, arbitrary_info_t);
+extern int labelcl_info_remove_LBL(vertex_hdl_t, char *, arb_info_desc_t *, arbitrary_info_t *);
+extern int labelcl_info_replace_LBL(vertex_hdl_t, char *, arb_info_desc_t,
                         arbitrary_info_t, arb_info_desc_t *, arbitrary_info_t *);
-extern int labelcl_info_get_LBL(struct devfs_entry *, char *, arb_info_desc_t *,
+extern int labelcl_info_get_LBL(vertex_hdl_t, char *, arb_info_desc_t *,
                       arbitrary_info_t *);
-extern int labelcl_info_get_next_LBL(struct devfs_entry *, char *, arb_info_desc_t *,
+extern int labelcl_info_get_next_LBL(vertex_hdl_t, char *, arb_info_desc_t *,
                            arbitrary_info_t *, labelcl_info_place_t *);
-extern int labelcl_info_replace_IDX(struct devfs_entry *, int, arbitrary_info_t, 
+extern int labelcl_info_replace_IDX(vertex_hdl_t, int, arbitrary_info_t, 
 			arbitrary_info_t *);
-extern int labelcl_info_connectpt_set(struct devfs_entry *, struct devfs_entry *);
-extern int labelcl_info_get_IDX(struct devfs_entry *, int, arbitrary_info_t *);
-extern struct devfs_entry *device_info_connectpt_get(struct devfs_entry *);
+extern int labelcl_info_connectpt_set(vertex_hdl_t, vertex_hdl_t);
+extern int labelcl_info_get_IDX(vertex_hdl_t, int, arbitrary_info_t *);
+extern struct devfs_handle_t device_info_connectpt_get(vertex_hdl_t);
 
 #endif /* _ASM_IA64_SN_LABELCL_H */
diff -Nru a/include/asm-ia64/sn/leds.h b/include/asm-ia64/sn/leds.h
--- a/include/asm-ia64/sn/leds.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/leds.h	Wed Jun 18 23:42:06 2003
@@ -5,7 +5,7 @@
  * 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) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/config.h>
@@ -13,25 +13,14 @@
 #include <asm/sn/addrs.h>
 #include <asm/sn/sn_cpuid.h>
 #include <asm/sn/pda.h>
-
-#ifdef CONFIG_IA64_SGI_SN1
-#define LED0		0xc0000b00100000c0LL
-#define LED_CPU_SHIFT	3
-#else
 #include <asm/sn/sn2/shub.h>
+
 #define LED0		(LOCAL_MMR_ADDR(SH_REAL_JUNK_BUS_LED0))
 #define LED_CPU_SHIFT	16
-#endif
 
 #define LED_CPU_HEARTBEAT	0x01
 #define LED_CPU_ACTIVITY	0x02
-#ifdef LED_WAR
-#define LED_ALWAYS_SET		0x64	/* SN2 hw workaround: always set 0x60 */
-#define LED_MASK_AUTOTEST	0x9e
-#else /* LED_WAR */
 #define LED_ALWAYS_SET		0x00
-#define LED_MASK_AUTOTEST	0xfe
-#endif /* LED_WAR */
 
 /*
  * Basic macros for flashing the LEDS on an SGI, SN1.
@@ -40,14 +29,8 @@
 static __inline__ void
 set_led_bits(u8 value, u8 mask)
 {
-#if 0
-	pda.led_state = (pda.led_state & ~mask) | (value & mask);
-#ifdef CONFIG_IA64_SGI_SN1
-	*pda.led_address = (long) pda.led_state;
-#else
-	*pda.led_address = (short) pda.led_state;
-#endif
-#endif
+	pda->led_state = (pda->led_state & ~mask) | (value & mask);
+	*pda->led_address = (short) pda->led_state;
 }
 
 #endif /* _ASM_IA64_SN_LEDS_H */
diff -Nru a/include/asm-ia64/sn/mca.h b/include/asm-ia64/sn/mca.h
--- a/include/asm-ia64/sn/mca.h	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,128 +0,0 @@
-/*
- * File:	mca.h
- * Purpose:	Machine check handling specific to the SN platform defines
- *
- * Copyright (C) 2001-2002 Silicon Graphics, Inc. All rights reserved.
- * 
- * This program is free software; you can redistribute it and/or modify it 
- * under the terms of version 2 of the GNU General Public License 
- * as published by the Free Software Foundation.
- * 
- * This program is distributed in the hope that it would be useful, but 
- * WITHOUT ANY WARRANTY; without even the implied warranty of 
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
- * 
- * Further, this software is distributed without any warranty that it is 
- * free of the rightful claim of any third person regarding infringement 
- * or the like.  Any license provided herein, whether implied or 
- * otherwise, applies only to this software file.  Patent licenses, if 
- * any, provided herein do not apply to combinations of this program with 
- * other software, or any other product whatsoever.
- * 
- * You should have received a copy of the GNU General Public 
- * License along with this program; if not, write the Free Software 
- * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
- * 
- * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
- * Mountain View, CA  94043, or:
- * 
- * http://www.sgi.com 
- * 
- * For further information regarding this notice, see: 
- * 
- * http://oss.sgi.com/projects/GenInfo/NoticeExplan
- */
-
-#include <linux/config.h>
-#include <linux/types.h>
-#include <asm/sal.h>
-#include <asm/mca.h>
-
-#ifdef CONFIG_IA64_SGI_SN
-
-typedef u64 __uint64_t;
-
-typedef struct {
-	__uint64_t sh_event_occurred;
-	__uint64_t sh_first_error;
-	__uint64_t sh_event_overflow;
-	__uint64_t sh_pi_first_error;
-	__uint64_t sh_pi_error_summary;
-	__uint64_t sh_pi_error_overflow;
-	__uint64_t sh_pi_error_detail_1;
-	__uint64_t sh_pi_error_detail_2;
-	__uint64_t sh_pi_hw_time_stamp;
-	__uint64_t sh_pi_uncorrected_detail_1;
-	__uint64_t sh_pi_uncorrected_detail_2;
-	__uint64_t sh_pi_uncorrected_detail_3;
-	__uint64_t sh_pi_uncorrected_detail_4;
-	__uint64_t sh_pi_uncor_time_stamp;
-	__uint64_t sh_pi_corrected_detail_1;
-	__uint64_t sh_pi_corrected_detail_2;
-	__uint64_t sh_pi_corrected_detail_3;
-	__uint64_t sh_pi_corrected_detail_4;
-	__uint64_t sh_pi_cor_time_stamp;
-	__uint64_t sh_mem_error_summary;
-	__uint64_t sh_mem_error_overflow;
-	__uint64_t sh_misc_err_hdr_lower;
-	__uint64_t sh_misc_err_hdr_upper;
-	__uint64_t sh_dir_uc_err_hdr_lower;
-	__uint64_t sh_dir_uc_err_hdr_upper;
-	__uint64_t sh_dir_cor_err_hdr_lower;
-	__uint64_t sh_dir_cor_err_hdr_upper;
-	__uint64_t sh_mem_error_mask;
-	__uint64_t sh_md_uncor_time_stamp;
-	__uint64_t sh_md_cor_time_stamp;
-	__uint64_t sh_md_hw_time_stamp;
-	__uint64_t sh_xn_error_summary;
-	__uint64_t sh_xn_first_error;
-	__uint64_t sh_xn_error_overflow;
-	__uint64_t sh_xniilb_error_summary;
-	__uint64_t sh_xniilb_first_error;
-	__uint64_t sh_xniilb_error_overflow;
-	__uint64_t sh_xniilb_error_detail_1;
-	__uint64_t sh_xniilb_error_detail_2;
-	__uint64_t sh_xniilb_error_detail_3;
-	__uint64_t sh_xnpi_error_summary;
-	__uint64_t sh_xnpi_first_error;
-	__uint64_t sh_xnpi_error_overflow;
-	__uint64_t sh_xnpi_error_detail_1;
-	__uint64_t sh_xnmd_error_summary;
-	__uint64_t sh_xnmd_first_error;
-	__uint64_t sh_xnmd_error_overflow;
-	__uint64_t sh_xnmd_ecc_err_report;
-	__uint64_t sh_xnmd_error_detail_1;
-	__uint64_t sh_lb_error_summary;
-	__uint64_t sh_lb_first_error;
-	__uint64_t sh_lb_error_overflow;
-	__uint64_t sh_lb_error_detail_1;
-	__uint64_t sh_lb_error_detail_2;
-	__uint64_t sh_lb_error_detail_3;
-	__uint64_t sh_lb_error_detail_4;
-	__uint64_t sh_lb_error_detail_5;
-} sal_log_shub_state_t;
-
-typedef struct {
-sal_log_section_hdr_t header;
-	struct
-	{
-		__uint64_t    err_status      : 1,
-		guid            : 1,
-		oem_data        : 1,
-		reserved        : 61;
-	} valid;
-	__uint64_t             err_status;
-	efi_guid_t      guid;
-	__uint64_t shub_nic;
-	sal_log_shub_state_t    shub_state;
-} sal_log_plat_info_t;
-
-
-extern void sal_log_plat_print(int header_len, int sect_len, u8 *p_data, prfunc_t prfunc);
-
-#ifdef platform_plat_specific_err_print
-#undef platform_plat_specific_err_print
-#endif
-#define platform_plat_specific_err_print sal_log_plat_print
-
-#endif /* CONFIG_IA64_SGI_SN */
diff -Nru a/include/asm-ia64/sn/mmtimer_private.h b/include/asm-ia64/sn/mmtimer_private.h
--- a/include/asm-ia64/sn/mmtimer_private.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/mmtimer_private.h	Wed Jun 18 23:42:06 2003
@@ -5,7 +5,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
  *
  * Helper file for the SN implementation of mmtimers
  *
diff -Nru a/include/asm-ia64/sn/module.h b/include/asm-ia64/sn/module.h
--- a/include/asm-ia64/sn/module.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/module.h	Wed Jun 18 23:42:06 2003
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_MODULE_H
 #define _ASM_IA64_SN_MODULE_H
@@ -32,9 +32,6 @@
 #define MODULE_FORMAT_BRIEF	1
 #define MODULE_FORMAT_LONG	2
 
-
-#ifdef CONFIG_IA64_SGI_SN2
-
 /*
  *	Module id format
  *
@@ -141,6 +138,7 @@
 #define MODULE_NBRICK           7
 #define MODULE_PEBRICK          8
 #define MODULE_PXBRICK          9
+#define MODULE_IXBRICK          10
 
 /*
  * Moduleid_t comparison macros
@@ -150,118 +148,6 @@
                                  ((_m2)&(MODULE_RACK_MASK|MODULE_BPOS_MASK)))
 #define MODULE_MATCH(_m1, _m2)  (MODULE_CMP((_m1),(_m2)) == 0)
 
-
-#else
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-
-/*
- *	Module id format
- *
- *	  15-12 Brick type (enumerated)
- *	   11-6	Rack ID	(encoded class, group, number)
- *	    5-0 Brick position in rack (0-63)
- */
-/*
- * Macros for getting the brick type
- */
-#define MODULE_BTYPE_MASK	0xf000
-#define MODULE_BTYPE_SHFT	12
-#define MODULE_GET_BTYPE(_m)	(((_m) & MODULE_BTYPE_MASK) >> MODULE_BTYPE_SHFT)
-#define MODULE_BT_TO_CHAR(_b)	(brick_types[(_b)])
-#define MODULE_GET_BTCHAR(_m)	(MODULE_BT_TO_CHAR(MODULE_GET_BTYPE(_m)))
-
-/*
- * Macros for getting the rack ID.
- */
-#define MODULE_RACK_MASK	0x0fc0
-#define MODULE_RACK_SHFT	6
-#define MODULE_GET_RACK(_m)	(((_m) & MODULE_RACK_MASK) >> MODULE_RACK_SHFT)
-
-/*
- * Macros for getting the brick position
- */
-#define MODULE_BPOS_MASK	0x003f
-#define MODULE_BPOS_SHFT	0
-#define MODULE_GET_BPOS(_m)	(((_m) & MODULE_BPOS_MASK) >> MODULE_BPOS_SHFT)
-
-/*
- * Macros for constructing moduleid_t's
- */
-#define RBT_TO_MODULE(_r, _b, _t) ((_r) << MODULE_RACK_SHFT | \
-				   (_b) << MODULE_BPOS_SHFT | \
-				   (_t) << MODULE_BTYPE_SHFT)
-
-/*
- * Macros for encoding and decoding rack IDs
- * A rack number consists of three parts:
- *   class	1 bit, 0==CPU/mixed, 1==I/O
- *   group	2 bits for CPU/mixed, 3 bits for I/O
- *   number	3 bits for CPU/mixed, 2 bits for I/O (1 based)
- */
-#define RACK_GROUP_BITS(_r)	(RACK_GET_CLASS(_r) ? 3 : 2)
-#define RACK_NUM_BITS(_r)	(RACK_GET_CLASS(_r) ? 2 : 3)
-
-#define RACK_CLASS_MASK(_r)	0x20
-#define RACK_CLASS_SHFT(_r)	5
-#define RACK_GET_CLASS(_r)	\
-	(((_r) & RACK_CLASS_MASK(_r)) >> RACK_CLASS_SHFT(_r))
-#define RACK_ADD_CLASS(_r, _c)	\
-	((_r) |= (_c) << RACK_CLASS_SHFT(_r) & RACK_CLASS_MASK(_r))
-
-#define RACK_GROUP_SHFT(_r)	RACK_NUM_BITS(_r)
-#define RACK_GROUP_MASK(_r)	\
-	( (((unsigned)1<<RACK_GROUP_BITS(_r)) - 1) << RACK_GROUP_SHFT(_r) )
-#define RACK_GET_GROUP(_r)	\
-	(((_r) & RACK_GROUP_MASK(_r)) >> RACK_GROUP_SHFT(_r))
-#define RACK_ADD_GROUP(_r, _g)	\
-	((_r) |= (_g) << RACK_GROUP_SHFT(_r) & RACK_GROUP_MASK(_r))
-
-#define RACK_NUM_SHFT(_r)	0
-#define RACK_NUM_MASK(_r)	\
-	( (((unsigned)1<<RACK_NUM_BITS(_r)) - 1) << RACK_NUM_SHFT(_r) )
-#define RACK_GET_NUM(_r)	\
-	( (((_r) & RACK_NUM_MASK(_r)) >> RACK_NUM_SHFT(_r)) + 1 )
-#define RACK_ADD_NUM(_r, _n)	\
-	((_r) |= ((_n) - 1) << RACK_NUM_SHFT(_r) & RACK_NUM_MASK(_r))
-
-/*
- * Brick type definitions
- */
-#define MAX_BRICK_TYPES		16 /* 1 << (MODULE_RACK_SHFT - MODULE_BTYPE_SHFT */
-
-extern char brick_types[];
-
-#define MODULE_CBRICK		0
-#define MODULE_RBRICK		1
-#define MODULE_IBRICK		2
-#define MODULE_KBRICK		3
-#define MODULE_XBRICK		4
-#define MODULE_DBRICK		5
-#define MODULE_PBRICK		6
-#define MODULE_NBRICK           7
-#define MODULE_PEBRICK          8
-#define MODULE_PXBRICK          9
-
-/*
- * Moduleid_t comparison macros
- */
-/* Don't compare the brick type:  only the position is significant */
-#define MODULE_CMP(_m1, _m2)	(((_m1)&(MODULE_RACK_MASK|MODULE_BPOS_MASK)) -\
-				 ((_m2)&(MODULE_RACK_MASK|MODULE_BPOS_MASK)))
-#define MODULE_MATCH(_m1, _m2)	(MODULE_CMP((_m1),(_m2)) == 0)
-
-#else
-
-/*
- * Some code that uses this macro will not be conditionally compiled.
- */
-#define MODULE_GET_BTCHAR(_m)	('?')
-#define MODULE_CMP(_m1, _m2)	((_m1) - (_m2))
-#define MODULE_MATCH(_m1, _m2)	(MODULE_CMP((_m1),(_m2)) == 0)
-
-#endif /* SN1 */
-#endif /* SN2 */
-
 typedef struct module_s module_t;
 
 struct module_s {
@@ -271,23 +157,15 @@
 
     /* List of nodes in this module */
     cnodeid_t		nodes[MODULE_MAX_NODES];
-#ifdef CONFIG_IA64_SGI_SN2
     geoid_t		geoid[MODULE_MAX_NODES];
     struct {
 		char	moduleid[8];
     } io[MODULE_MAX_NODES];
-#endif
     int			nodecnt;	/* Number of nodes in array        */
-
     /* Fields for Module System Controller */
     int			mesgpend;	/* Message pending                 */
     int			shutdown;	/* Shutdown in progress            */
     struct semaphore	thdcnt;		/* Threads finished counter        */
-
-#ifdef CONFIG_IA64_SGI_SN1
-    elsc_t		elsc;
-    spinlock_t		elsclock;
-#endif
     time_t		intrhist[MODULE_HIST_CNT];
     int			histptr;
 
@@ -314,10 +192,6 @@
 extern int		nummodules;
 
 extern module_t	       *module_lookup(moduleid_t id);
-
-#if defined(CONFIG_IA64_SGI_SN1)
-extern elsc_t	       *get_elsc(void);
-#endif
 
 extern int		get_kmod_info(cmoduleid_t cmod,
 				      module_info_t *mod_info);
diff -Nru a/include/asm-ia64/sn/nag.h b/include/asm-ia64/sn/nag.h
--- a/include/asm-ia64/sn/nag.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/sn/nag.h	Wed Jun 18 23:42:07 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
 */
 
 
diff -Nru a/include/asm-ia64/sn/nic.h b/include/asm-ia64/sn/nic.h
--- a/include/asm-ia64/sn/nic.h	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,129 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_NIC_H
-#define _ASM_IA64_SN_NIC_H
-
-#include <asm/types.h>
-#include <asm/sn/types.h>
-#include <linux/devfs_fs_kernel.h>
-
-#define MCR_DATA(x)			((int) ((x) & 1))
-#define MCR_DONE(x)			((x) & 2)
-#define MCR_PACK(pulse, sample)		((pulse) << 10 | (sample) << 2)
-
-typedef __psunsigned_t	nic_data_t;
-
-typedef int		
-nic_access_f(nic_data_t data,
-	     int pulse, int sample, int delay);
-
-typedef nic_access_f   *nic_access_t;
-
-typedef struct nic_vmce_s      *nic_vmce_t;
-typedef void			nic_vmc_func(devfs_handle_t v);
-
-/*
- * PRIVATE data for Dallas NIC
- */
-
-typedef struct nic_state_t {
-    nic_access_t	access;
-    nic_data_t		data;
-    int			last_disc;
-    int			done;
-    int			bit_index;
-    int			disc_marker;
-    uchar_t		bits[64];
-} nic_state_t;
-
-/*
- * Public interface for Dallas NIC
- *
- *
- *   Access Routine
- *
- *   nic_setup requires an access routine that pulses the NIC line for a
- *   specified duration, samples the NIC line after a specified duration,
- *   then delays for a third specified duration (for precharge).
- *
- *   This general scheme allows us to access NICs through any medium
- *   (e.g. hub regs, bridge regs, vector writes, system ctlr commands).
- *
- *   The access routine should return the sample value 0 or 1, or if an
- *   error occurs, return a negative error code.  Negative error codes from
- *   the access routine will abort the NIC operation and be propagated
- *   through out of the top-level NIC call.
- */
-
-#define NIC_OK			0
-#define NIC_DONE		1
-#define NIC_FAIL		2
-#define NIC_BAD_CRC		3
-#define NIC_NOT_PRESENT		4
-#define NIC_REDIR_LOOP		5
-#define NIC_PARAM		6
-#define NIC_NOMEM		7
-
-uint64_t nic_get_phase_bits(void);
-
-extern int nic_setup(nic_state_t *ns,
-		     nic_access_t access,
-		     nic_data_t data);
-
-extern int nic_next(nic_state_t *ns,
-		    char *serial,
-		    char *family,
-		    char *crc);
-
-extern int nic_read_one_page(nic_state_t *ns,
-			     char *family,
-			     char *serial,
-			     char *crc,
-			     int start,
-			     uchar_t *redirect,
-			     uchar_t *byte);
-
-extern int nic_read_mfg(nic_state_t *ns,
-			char *family,
-			char *serial,
-			char *crc,
-			uchar_t *pageA,
-			uchar_t *pageB);
-
-extern int nic_info_get(nic_access_t access,
-			nic_data_t data,
-			char *info);
-
-extern int nic_item_info_get(char *buf, char *item, char **item_info);
-
-nic_access_f	nic_access_mcr32;
-
-extern char *nic_vertex_info_get(devfs_handle_t v);
-
-extern char *nic_vertex_info_set(nic_access_t access,
-				 nic_data_t data, 
-				 devfs_handle_t v);
-
-extern int nic_vertex_info_match(devfs_handle_t vertex,
-				 char *name);
-
-extern char *nic_bridge_vertex_info(devfs_handle_t vertex,
-				    nic_data_t	data);
-extern char *nic_hq4_vertex_info(devfs_handle_t vertex,
-				 nic_data_t data);
-extern char *nic_ioc3_vertex_info(devfs_handle_t vertex,
-				    nic_data_t	data,
-				    int32_t *gpcr_s);
-
-extern char *nic_hub_vertex_info(devfs_handle_t vertex);
-
-extern nic_vmce_t	nic_vmc_add(char *, nic_vmc_func *);
-extern void		nic_vmc_del(nic_vmce_t);
-
-#endif /* _ASM_IA64_SN_NIC_H */
diff -Nru a/include/asm-ia64/sn/nodepda.h b/include/asm-ia64/sn/nodepda.h
--- a/include/asm-ia64/sn/nodepda.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/nodepda.h	Wed Jun 18 23:42:06 2003
@@ -3,27 +3,21 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_NODEPDA_H
 #define _ASM_IA64_SN_NODEPDA_H
 
 
 #include <linux/config.h>
+#include <asm/sn/sgi.h>
 #include <asm/irq.h>
 #include <asm/sn/intr.h>
 #include <asm/sn/router.h>
-#if defined(CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/synergy.h>
-#endif
 #include <asm/sn/pda.h>
 #include <asm/sn/module.h>
 #include <asm/sn/bte.h>
 
-#if defined(CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/hubstat.h>
-#endif
-
 /*
  * NUMA Node-Specific Data structures are defined in this file.
  * In particular, this is the location of the node PDA.
@@ -31,23 +25,6 @@
  */
 
 /*
- * Subnode PDA structures. Each node needs a few data structures that 
- * correspond to the PIs on the HUB chip that supports the node.
- */
-#if defined(CONFIG_IA64_SGI_SN1)
-struct subnodepda_s {
-	intr_vecblk_t	intr_dispatch0;
-	intr_vecblk_t	intr_dispatch1;
-};
-
-typedef struct subnodepda_s subnode_pda_t;
-
-
-struct synergy_perf_s;
-#endif
-
-
-/*
  * Node-specific data structure.
  *
  * One of these structures is allocated on each node of a NUMA system.
@@ -66,24 +43,20 @@
 					/*  the second cpu on a node is */
 					/*  node_first_cpu+1.           */
 
-	devfs_handle_t 	xbow_vhdl;
+	vertex_hdl_t 	xbow_vhdl;
 	nasid_t		xbow_peer;	/* NASID of our peer hub on xbow */
 	struct semaphore xbow_sema;	/* Sema for xbow synchronization */
 	slotid_t	slotdesc;
-#ifdef CONFIG_IA64_SGI_SN2
 	geoid_t		geoid;
-#else
-	moduleid_t	module_id;	/* Module ID (redundant local copy) */
-#endif
 	module_t	*module;	/* Pointer to containing module */
 	xwidgetnum_t 	basew_id;
-	devfs_handle_t 	basew_xc;
+	vertex_hdl_t 	basew_xc;
 	int		hubticks;
 	int		num_routers;	/* XXX not setup! Total routers in the system */
 
 	
 	char		*hwg_node_name;	/* hwgraph node name */
-	devfs_handle_t	node_vertex;	/* Hwgraph vertex for this node */
+	vertex_hdl_t	node_vertex;	/* Hwgraph vertex for this node */
 
 	void 		*pdinfo;	/* Platform-dependent per-node info */
 
@@ -95,27 +68,9 @@
 	/*
 	 * The BTEs on this node are shared by the local cpus
 	 */
-	bteinfo_t	bte_if[BTES_PER_NODE];	/* Virtual Interface */
-	char		bte_cleanup[5 * L1_CACHE_BYTES] ____cacheline_aligned;
-
-#if defined(CONFIG_IA64_SGI_SN1)
-	subnode_pda_t	snpda[NUM_SUBNODES];
-	/*
-	 * New extended memory reference counters
- 	 */
-	void			*migr_refcnt_counterbase;
-	void			*migr_refcnt_counterbuffer;
-	size_t			migr_refcnt_cbsize;
-	int			migr_refcnt_numsets;
-	hubstat_t		hubstats;
-	int			synergy_perf_enabled;
-        int       		synergy_perf_freq;
-	spinlock_t		synergy_perf_lock;
-        uint64_t       		synergy_inactive_intervals;
-        uint64_t       		synergy_active_intervals;
-        struct synergy_perf_s	*synergy_perf_data;
-        struct synergy_perf_s	*synergy_perf_first; /* reporting consistency .. */
-#endif /* CONFIG_IA64_SGI_SN1 */
+	struct bteinfo_s	bte_if[BTES_PER_NODE];	/* Virtual Interface */
+	struct timer_list	bte_recovery_timer;
+	spinlock_t		bte_recovery_lock;
 
 	/* 
 	 * Array of pointers to the nodepdas for each node.
@@ -126,18 +81,16 @@
 
 typedef struct nodepda_s nodepda_t;
 
-#ifdef CONFIG_IA64_SGI_SN2
-#define NR_IVECS 256
 struct irqpda_s {
 	int num_irq_used;
-	char irq_flags[NR_IVECS];
+	char irq_flags[NR_IRQS];
+	struct pci_dev *device_dev[NR_IRQS];
+	char share_count[NR_IRQS];
+	struct pci_dev *current;
 };
 
 typedef struct irqpda_s irqpda_t;
 
-#endif /* CONFIG_IA64_SGI_SN2 */
-
-
 
 /*
  * Access Functions for node PDA.
@@ -156,21 +109,11 @@
 #define	nodepda		pda->p_nodepda		/* Ptr to this node's PDA */
 #define	NODEPDA(cnode)		(nodepda->pernode_pdaindr[cnode])
 
-#if defined(CONFIG_IA64_SGI_SN1)
-#define subnodepda	pda.p_subnodepda	/* Ptr to this node's subnode PDA */
-#define	SUBNODEPDA(cnode,sn)	(&(NODEPDA(cnode)->snpda[sn]))
-#define	SNPDA(npda,sn)		(&(npda)->snpda[sn])
-#endif
-
 
 /*
  * Macros to access data structures inside nodepda 
  */
-#ifdef CONFIG_IA64_SGI_SN2
 #define NODE_MODULEID(cnode)    geo_module((NODEPDA(cnode)->geoid))
-#else
-#define NODE_MODULEID(cnode)	(NODEPDA(cnode)->module_id)
-#endif
 #define NODE_SLOTID(cnode)	(NODEPDA(cnode)->slotdesc)
 
 
@@ -184,8 +127,8 @@
  * Check if given a compact node id the corresponding node has all the
  * cpus disabled. 
  */
-#define is_headless_node(cnode)		0 /*((cnode == CNODEID_NONE) ||			\
-					    (node_data(cnode)->active_cpu_count == 0)) */
+#define is_headless_node(cnode)		((cnode == CNODEID_NONE) ||			\
+					 (node_data(cnode)->active_cpu_count == 0))
 
 /*
  * Check if given a node vertex handle the corresponding node has all the
diff -Nru a/include/asm-ia64/sn/pci/bridge.h b/include/asm-ia64/sn/pci/bridge.h
--- a/include/asm-ia64/sn/pci/bridge.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/pci/bridge.h	Wed Jun 18 23:42:06 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_BRIDGE_H
 #define _ASM_SN_PCI_BRIDGE_H
@@ -36,7 +36,6 @@
 
 #include <linux/config.h>
 #include <asm/sn/xtalk/xwidget.h>
-#ifndef CONFIG_IA64_SGI_SN1
 #include <asm/sn/pci/pic.h>
 
 extern int io_get_sh_swapper(nasid_t);
@@ -45,7 +44,6 @@
 
 #define BRIDGE_REG_SET32(reg) \
                 *(volatile uint32_t *) (((uint64_t)reg)^4)
-#endif	/* CONFIG_IA64_SGI_SN1 */
 
 /* I/O page size */
 
@@ -111,7 +109,6 @@
  * Generated from Bridge spec dated 04oct95
  */
 
-#ifndef CONFIG_IA64_SGI_SN1
 
 /*
  * pic_widget_cfg_s is a local definition of widget_cfg_t but with
@@ -605,292 +602,6 @@
     } b_external_flash;
 } bridge_t;
 
-#else	/* CONFIG_IA64_SGI_SN1 */
-
-
-typedef volatile struct bridge_s {
-
-    /* Local Registers				       0x000000-0x00FFFF */
-
-    /* standard widget configuration		       0x000000-0x000057 */
-    widget_cfg_t	    b_widget;		    /* 0x000000 */
-
-    /* helper fieldnames for accessing bridge widget */
-
-#define b_wid_id			b_widget.w_id
-#define b_wid_stat			b_widget.w_status
-#define b_wid_err_upper			b_widget.w_err_upper_addr
-#define b_wid_err_lower			b_widget.w_err_lower_addr
-#define b_wid_control			b_widget.w_control
-#define b_wid_req_timeout		b_widget.w_req_timeout
-#define b_wid_int_upper			b_widget.w_intdest_upper_addr
-#define b_wid_int_lower			b_widget.w_intdest_lower_addr
-#define b_wid_err_cmdword		b_widget.w_err_cmd_word
-#define b_wid_llp			b_widget.w_llp_cfg
-#define b_wid_tflush			b_widget.w_tflush
-
-    /*
-     * we access these through synergy unswizzled space, so the address
-     * gets twiddled (i.e. references to 0x4 actually go to 0x0 and vv.)
-     * That's why we put the register first and filler second.
-     */
-    /* bridge-specific widget configuration	       0x000058-0x00007F */
-    bridgereg_t             b_wid_aux_err;          /* 0x00005C */
-    bridgereg_t		    _pad_000058;
-
-    bridgereg_t             b_wid_resp_upper;       /* 0x000064 */
-    bridgereg_t             _pad_000060;
-
-    bridgereg_t             b_wid_resp_lower;       /* 0x00006C */
-    bridgereg_t             _pad_000068;
-
-    bridgereg_t             b_wid_tst_pin_ctrl;     /* 0x000074 */
-    bridgereg_t             _pad_000070;
-
-    bridgereg_t		    _pad_000078[2];
-
-    /* PMU & Map				       0x000080-0x00008F */
-    bridgereg_t             b_dir_map;              /* 0x000084 */
-    bridgereg_t             _pad_000080;
-    bridgereg_t		    _pad_000088[2];
-
-    /* SSRAM					       0x000090-0x00009F */
-    bridgereg_t             b_ram_perr_or_map_fault;/* 0x000094 */
-    bridgereg_t             _pad_000090;
-#define b_ram_perr  b_ram_perr_or_map_fault	/* Bridge */
-#define b_map_fault b_ram_perr_or_map_fault	/* Xbridge */
-    bridgereg_t		    _pad_000098[2];
-
-    /* Arbitration				       0x0000A0-0x0000AF */
-    bridgereg_t             b_arb;                  /* 0x0000A4 */
-    bridgereg_t             _pad_0000A0;
-    bridgereg_t		    _pad_0000A8[2];
-
-    /* Number In A Can				       0x0000B0-0x0000BF */
-    bridgereg_t             b_nic;                  /* 0x0000B4 */
-    bridgereg_t             _pad_0000B0;
-    bridgereg_t		    _pad_0000B8[2];
-
-    /* PCI/GIO					       0x0000C0-0x0000FF */
-    bridgereg_t             b_bus_timeout;          /* 0x0000C4 */
-    bridgereg_t             _pad_0000C0;
-#define b_pci_bus_timeout b_bus_timeout
-
-    bridgereg_t             b_pci_cfg;              /* 0x0000CC */
-    bridgereg_t             _pad_0000C8;
-
-    bridgereg_t             b_pci_err_upper;        /* 0x0000D4 */
-    bridgereg_t             _pad_0000D0;
-
-    bridgereg_t             b_pci_err_lower;        /* 0x0000DC */
-    bridgereg_t             _pad_0000D8;
-    bridgereg_t		    _pad_0000E0[8];
-#define b_gio_err_lower b_pci_err_lower
-#define b_gio_err_upper b_pci_err_upper
-
-    /* Interrupt				       0x000100-0x0001FF */
-    bridgereg_t             b_int_status;           /* 0x000104 */
-    bridgereg_t             _pad_000100;
-
-    bridgereg_t             b_int_enable;           /* 0x00010C */
-    bridgereg_t             _pad_000108;
-
-    bridgereg_t             b_int_rst_stat;         /* 0x000114 */
-    bridgereg_t             _pad_000110;
-
-    bridgereg_t             b_int_mode;             /* 0x00011C */
-    bridgereg_t             _pad_000118;
-
-    bridgereg_t             b_int_device;           /* 0x000124 */
-    bridgereg_t             _pad_000120;
-
-    bridgereg_t             b_int_host_err;         /* 0x00012C */
-    bridgereg_t             _pad_000128;
-
-    struct {
-        bridgereg_t             addr;               /* 0x0001{34,,,6C} */
-        bridgereg_t             __pad;              /* 0x0001{30,,,68} */
-    } b_int_addr[8];				    /* 0x000130 */
-
-    bridgereg_t             b_err_int_view;         /* 0x000174 */
-    bridgereg_t             _pad_000170;
-
-    bridgereg_t             b_mult_int;             /* 0x00017c */
-    bridgereg_t             _pad_000178;
-
-    struct {
-        bridgereg_t             intr;               /* 0x0001{84,,,BC} */
-        bridgereg_t             __pad;              /* 0x0001{80,,,B8} */
-    } b_force_always[8];			    /* 0x000180 */
-
-    struct {
-        bridgereg_t             intr;               /* 0x0001{C4,,,FC} */
-        bridgereg_t             __pad;              /* 0x0001{C0,,,F8} */
-    } b_force_pin[8];			    	    /* 0x0001C0 */
-
-    /* Device					       0x000200-0x0003FF */
-    struct {
-        bridgereg_t             reg;                /* 0x0002{04,,,3C} */
-        bridgereg_t             __pad;              /* 0x0002{00,,,38} */
-    } b_device[8];				    /* 0x000200 */
-
-    struct {
-        bridgereg_t             reg;                /* 0x0002{44,,,7C} */
-        bridgereg_t             __pad;              /* 0x0002{40,,,78} */
-    } b_wr_req_buf[8];				    /* 0x000240 */
-
-    struct {
-        bridgereg_t             reg;                /* 0x0002{84,,,8C} */
-        bridgereg_t             __pad;              /* 0x0002{80,,,88} */
-    } b_rrb_map[2];				    /* 0x000280 */
-#define	b_even_resp	b_rrb_map[0].reg	    /* 0x000284 */
-#define	b_odd_resp	b_rrb_map[1].reg	    /* 0x00028C */
-
-    bridgereg_t             b_resp_status;          /* 0x000294 */
-    bridgereg_t             _pad_000290;
-
-    bridgereg_t             b_resp_clear;           /* 0x00029C */
-    bridgereg_t             _pad_000298;
-
-    bridgereg_t		    _pad_0002A0[24];
-
-    /* Xbridge only */
-    struct {
-	bridgereg_t	        upper;              /* 0x0003{04,,,F4} */
-	bridgereg_t             __pad1;		    /* 0x0003{00,,,F0} */
-	bridgereg_t             lower;              /* 0x0003{0C,,,FC} */
-	bridgereg_t             __pad2;             /* 0x0003{08,,,F8} */
-    } b_buf_addr_match[16];
-
-    /* Performance Monitor Registers (even only) */
-    struct {
-        bridgereg_t             flush_w_touch;      /* 0x000404,,,5C4 */
-        bridgereg_t             __pad1;             /* 0x000400,,,5C0 */
-
-        bridgereg_t             flush_wo_touch;     /* 0x00040C,,,5CC */
-        bridgereg_t             __pad2;             /* 0x000408,,,5C8 */
-
-        bridgereg_t             inflight;           /* 0x000414,,,5D4 */
-        bridgereg_t             __pad3;             /* 0x000410,,,5D0 */
-
-        bridgereg_t             prefetch;           /* 0x00041C,,,5DC */
-        bridgereg_t             __pad4;             /* 0x000418,,,5D8 */
-
-        bridgereg_t             total_pci_retry;    /* 0x000424,,,5E4 */
-        bridgereg_t             __pad5;             /* 0x000420,,,5E0 */
-
-        bridgereg_t             max_pci_retry;      /* 0x00042C,,,5EC */
-        bridgereg_t             __pad6;             /* 0x000428,,,5E8 */
-
-        bridgereg_t             max_latency;        /* 0x000434,,,5F4 */
-        bridgereg_t             __pad7;             /* 0x000430,,,5F0 */
-
-        bridgereg_t             clear_all;          /* 0x00043C,,,5FC */
-        bridgereg_t             __pad8;             /* 0x000438,,,5F8 */
-    } b_buf_count[8];
-
-    char                    _pad_000600[0x010000 - 0x000600];
-
-    /*
-     * The Xbridge has 1024 internal ATE's and the Bridge has 128.
-     * Make enough room for the Xbridge ATE's and depend on runtime
-     * checks to limit access to bridge ATE's.
-     */
-
-    /* Internal Address Translation Entry RAM	       0x010000-0x011fff */
-    union {
-	bridge_ate_t		wr;		/* write-only */
-	struct {
-	    bridgereg_t             rd;         /* read-only */
-            bridgereg_t             _p_pad;
-	}			hi;
-    }			    b_int_ate_ram[XBRIDGE_INTERNAL_ATES];
-
-#define b_int_ate_ram_lo(idx) b_int_ate_ram[idx+512].hi.rd
-
-    /* the xbridge read path for internal ates starts at 0x12000.
-     * I don't believe we ever try to read the ates.
-     */
-    /* Internal Address Translation Entry RAM LOW       0x012000-0x013fff */
-    struct {
-	bridgereg_t             rd; 
-        bridgereg_t             _p_pad;
-    }			    xb_int_ate_ram_lo[XBRIDGE_INTERNAL_ATES];
-
-    char		    _pad_014000[0x20000 - 0x014000];
-
-    /* PCI Device Configuration Spaces		       0x020000-0x027FFF */
-    union {				/* make all access sizes available. */
-	uchar_t			c[0x1000 / 1];
-	uint16_t		s[0x1000 / 2];
-	uint32_t		l[0x1000 / 4];
-	uint64_t		d[0x1000 / 8];
-	union {
-	    uchar_t		c[0x100 / 1];
-	    uint16_t		s[0x100 / 2];
-	    uint32_t		l[0x100 / 4];
-	    uint64_t		d[0x100 / 8];
-	}			f[8];
-    } b_type0_cfg_dev[8];			    /* 0x020000 */
-
-    /* PCI Type 1 Configuration Space		       0x028000-0x028FFF */
-    union {				/* make all access sizes available. */
-	uchar_t			c[0x1000 / 1];
-	uint16_t		s[0x1000 / 2];
-	uint32_t		l[0x1000 / 4];
-	uint64_t		d[0x1000 / 8];
-        union {
-            uchar_t         c[0x100 / 1];
-            uint16_t        s[0x100 / 2];
-            uint32_t        l[0x100 / 4];
-            uint64_t        d[0x100 / 8];
-	} f[8];
-    } b_type1_cfg;				    /* 0x028000-0x029000 */
-
-    char		    _pad_029000[0x007000];  /* 0x029000-0x030000 */
-
-    /* PCI Interrupt Acknowledge Cycle		       0x030000 */
-    union {
-	uchar_t			c[8 / 1];
-	uint16_t		s[8 / 2];
-	uint32_t		l[8 / 4];
-	uint64_t		d[8 / 8];
-    } b_pci_iack;				    /* 0x030000 */
-
-    uchar_t		    _pad_030007[0x04fff8];  /* 0x030008-0x07FFFF */
-
-    /* External Address Translation Entry RAM	       0x080000-0x0FFFFF */
-    bridge_ate_t	    b_ext_ate_ram[0x10000];
-
-    /* Reserved					       0x100000-0x1FFFFF */
-    char		    _pad_100000[0x200000-0x100000];
-
-    /* PCI/GIO Device Spaces			       0x200000-0xBFFFFF */
-    union {				/* make all access sizes available. */
-	uchar_t			c[0x100000 / 1];
-	uint16_t		s[0x100000 / 2];
-	uint32_t		l[0x100000 / 4];
-	uint64_t		d[0x100000 / 8];
-    } b_devio_raw[10];			/* 0x200000 */
-
-    /* b_devio macro is a bit strange; it reflects the
-     * fact that the Bridge ASIC provides 2M for the
-     * first two DevIO windows and 1M for the other six.
-     */
-#define b_devio(n)	b_devio_raw[((n)<2)?(n*2):(n+2)]
-
-    /* External Flash Proms 1,0			       0xC00000-0xFFFFFF */
-    union {				/* make all access sizes available. */
-	uchar_t			c[0x400000 / 1];	/* read-only */
-	uint16_t		s[0x400000 / 2];	/* read-write */
-	uint32_t		l[0x400000 / 4];	/* read-only */
-	uint64_t		d[0x400000 / 8];	/* read-only */
-    } b_external_flash;			/* 0xC00000 */
-} bridge_t;
-
-#endif	/* CONFIG_IA64_SGI_SN1 */
-
-
 #define berr_field	berr_un.berr_st
 #endif				/* __ASSEMBLY__ */
 
@@ -1428,8 +1139,7 @@
 #define BRIDGE_ISR_ERRORS		\
 		(BRIDGE_ISR_LINK_ERROR|BRIDGE_ISR_PCIBUS_ERROR|		\
 		 BRIDGE_ISR_XTALK_ERROR|BRIDGE_ISR_SSRAM_PERR|		\
-		 BRIDGE_ISR_PMU_ESIZE_FAULT|PIC_ISR_PCIX_ARB_ERR|	\
-		 PIC_ISR_INT_RAM_PERR)
+		 BRIDGE_ISR_PMU_ESIZE_FAULT|PIC_ISR_INT_RAM_PERR)
 
 /*
  * List of Errors which are fatal and kill the sytem
@@ -1598,22 +1308,6 @@
 
 #define BRIDGE_TMO_PCI_RETRY_CNT_MAX	0x3ff
 
-#ifdef SN0
-/*
- * The NASID should be shifted by this amount and stored into the
- * interrupt(x) register.
- */
-#define BRIDGE_INT_ADDR_NASID_SHFT	8
-
-/*
- * The BRIDGE_INT_ADDR_DEST_IO bit should be set to send an interrupt to
- * memory.
- */
-#define BRIDGE_INT_ADDR_DEST_IO		(1 << 17)
-#define BRIDGE_INT_ADDR_DEST_MEM	0
-#define BRIDGE_INT_ADDR_MASK		(1 << 17)
-#endif
-
 /* Bridge device(x) register bits definition */
 #define BRIDGE_DEV_ERR_LOCK_EN		(1ull << 28)
 #define BRIDGE_DEV_PAGE_CHK_DIS		(1ull << 27)
@@ -1728,6 +1422,38 @@
 #define BRIDGE_PCI_IO_LIMIT		BRIDGE_PCIIO_XTALK_ALIAS_LIMIT
 
 /*
+ * Macros for Xtalk to Bridge bus (PCI) PIO
+ * refer to section 5.2.1 Figure 4 of the "PCI Interface Chip (PIC) Volume II
+ * Programmer's Reference" (Revision 0.8 as of this writing).
+ *
+ * These are PIC bridge specific.  A separate set of macros was defined
+ * because PIC deviates from Bridge/Xbridge by not supporting a big-window
+ * alias for PCI I/O space, and also redefines XTALK addresses
+ * 0x0000C0000000L and 0x000100000000L to be PCI MEM aliases for the second
+ * bus.
+ */
+
+/* XTALK addresses that map into PIC Bridge Bus addr space */
+#define PICBRIDGE0_PIO32_XTALK_ALIAS_BASE	0x000040000000L
+#define PICBRIDGE0_PIO32_XTALK_ALIAS_LIMIT	0x00007FFFFFFFL
+#define PICBRIDGE0_PIO64_XTALK_ALIAS_BASE	0x000080000000L
+#define PICBRIDGE0_PIO64_XTALK_ALIAS_LIMIT	0x0000BFFFFFFFL
+#define PICBRIDGE1_PIO32_XTALK_ALIAS_BASE	0x0000C0000000L
+#define PICBRIDGE1_PIO32_XTALK_ALIAS_LIMIT	0x0000FFFFFFFFL
+#define PICBRIDGE1_PIO64_XTALK_ALIAS_BASE	0x000100000000L
+#define PICBRIDGE1_PIO64_XTALK_ALIAS_LIMIT	0x00013FFFFFFFL
+
+/* XTALK addresses that map into PCI addresses */
+#define PICBRIDGE0_PCI_MEM32_BASE	PICBRIDGE0_PIO32_XTALK_ALIAS_BASE
+#define PICBRIDGE0_PCI_MEM32_LIMIT	PICBRIDGE0_PIO32_XTALK_ALIAS_LIMIT
+#define PICBRIDGE0_PCI_MEM64_BASE	PICBRIDGE0_PIO64_XTALK_ALIAS_BASE
+#define PICBRIDGE0_PCI_MEM64_LIMIT	PICBRIDGE0_PIO64_XTALK_ALIAS_LIMIT
+#define PICBRIDGE1_PCI_MEM32_BASE	PICBRIDGE1_PIO32_XTALK_ALIAS_BASE
+#define PICBRIDGE1_PCI_MEM32_LIMIT	PICBRIDGE1_PIO32_XTALK_ALIAS_LIMIT
+#define PICBRIDGE1_PCI_MEM64_BASE	PICBRIDGE1_PIO64_XTALK_ALIAS_BASE
+#define PICBRIDGE1_PCI_MEM64_LIMIT	PICBRIDGE1_PIO64_XTALK_ALIAS_LIMIT
+
+/*
  * Macros for Bridge bus (PCI/GIO) to Xtalk DMA
  */
 /* Bridge Bus DMA addresses */
@@ -1844,9 +1570,6 @@
 #define ATE_SWAPSHIFT		29
 #define ATE_SWAP_ON(x)		((x) |= (1 << ATE_SWAPSHIFT))
 #define ATE_SWAP_OFF(x)		((x) &= ~(1 << ATE_SWAPSHIFT))
-
-#define is_xbridge(bridge) IS_XBRIDGE(bridge->b_wid_id)
-#define is_pic(bridge) IS_PIC_BRIDGE(bridge->b_wid_id)
 
 /* extern declarations */
 
diff -Nru a/include/asm-ia64/sn/pci/pci_bus_cvlink.h b/include/asm-ia64/sn/pci/pci_bus_cvlink.h
--- a/include/asm-ia64/sn/pci/pci_bus_cvlink.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-ia64/sn/pci/pci_bus_cvlink.h	Wed Jun 18 23:42:09 2003
@@ -4,13 +4,12 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_CVLINK_H
 #define _ASM_SN_PCI_CVLINK_H
 
 #include <asm/sn/types.h>
-#include <asm/sn/hack.h>
 #include <asm/sn/sgi.h>
 #include <asm/sn/driver.h>
 #include <asm/sn/iograph.h>
@@ -50,11 +49,11 @@
 	(((struct sn_widget_sysdata *)((pci_bus)->sysdata))->vhdl)
 
 struct sn_widget_sysdata {
-        devfs_handle_t  vhdl;
+        vertex_hdl_t  vhdl;
 };
 
 struct sn_device_sysdata {
-        devfs_handle_t  vhdl;
+        vertex_hdl_t  vhdl;
 	int		isa64;
 	int		isPIC;
 	volatile unsigned int *dma_buf_sync;
diff -Nru a/include/asm-ia64/sn/pci/pci_defs.h b/include/asm-ia64/sn/pci/pci_defs.h
--- a/include/asm-ia64/sn/pci/pci_defs.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/pci/pci_defs.h	Wed Jun 18 23:42:06 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (c) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_PCI_DEFS_H
 #define _ASM_SN_PCI_PCI_DEFS_H
@@ -321,6 +321,112 @@
 
 #ifndef __ASSEMBLY__
 
+#ifdef LITTLE_ENDIAN
+
+/*
+ * PCI config space definition
+ */
+typedef volatile struct pci_cfg_s {
+	uint16_t	vendor_id;
+	uint16_t	dev_id;
+	uint16_t	cmd;
+	uint16_t	status;
+	uchar_t		rev;
+        uchar_t         prog_if;
+	uchar_t		sub_class;
+	uchar_t		class;
+	uchar_t		line_size;
+	uchar_t		lt;
+	uchar_t		hdr_type;
+	uchar_t		bist;
+	uint32_t	bar[6];
+	uint32_t	cardbus;
+	uint16_t	subsys_vendor_id;
+	uint16_t	subsys_dev_id;
+	uint32_t	exp_rom;
+	uint32_t	res[2];
+	uchar_t		int_line;
+	uchar_t		int_pin;
+	uchar_t		min_gnt;
+	uchar_t		max_lat;
+} pci_cfg_t;
+
+/*
+ * PCI Type 1 config space definition for PCI to PCI Bridges (PPBs)
+ */
+typedef volatile struct pci_cfg1_s {
+	uint16_t	vendor_id;
+	uint16_t	dev_id;
+	uint16_t	cmd;
+	uint16_t	status;
+	uchar_t		rev;
+	uchar_t		prog_if;
+	uchar_t		sub_class;
+	uchar_t		class;
+	uchar_t		line_size;
+	uchar_t		lt;
+	uchar_t		hdr_type;
+	uchar_t		bist;
+	uint32_t	bar[2];
+	uchar_t		pri_bus_num;
+	uchar_t		snd_bus_num;
+	uchar_t		sub_bus_num;
+	uchar_t		slt;
+	uchar_t		io_base;
+	uchar_t		io_limit;
+	uint16_t	snd_status;
+	uint16_t	mem_base;
+	uint16_t	mem_limit;
+	uint16_t	pmem_base;
+	uint16_t	pmem_limit;
+	uint32_t	pmem_base_upper;
+	uint32_t	pmem_limit_upper;
+	uint16_t	io_base_upper;
+	uint16_t	io_limit_upper;
+	uint32_t	res;
+	uint32_t	exp_rom;
+	uchar_t		int_line;
+	uchar_t		int_pin;
+	uint16_t	ppb_control;
+
+} pci_cfg1_t;
+
+/*
+ * PCI-X Capability
+ */
+typedef volatile struct cap_pcix_cmd_reg_s {
+	uint16_t	data_parity_enable:	1,
+			enable_relaxed_order:	1,
+			max_mem_read_cnt:	2,
+			max_split:		3,
+			reserved1:		9;
+} cap_pcix_cmd_reg_t;
+
+typedef volatile struct cap_pcix_stat_reg_s {
+	uint32_t	func_num:		3,
+			dev_num:		5,
+			bus_num:		8,
+			bit64_device:		1,
+			mhz133_capable:		1,
+			split_complt_discard:	1,
+			unexpect_split_complt:	1,
+			device_complex:		1,
+			max_mem_read_cnt:	2,
+			max_out_split:		3,
+			max_cum_read:		3,
+			split_complt_err:	1,
+			reserved1:		2;
+} cap_pcix_stat_reg_t;
+
+typedef volatile struct cap_pcix_type0_s {
+	uchar_t			pcix_cap_id;
+	uchar_t			pcix_cap_nxt;
+	cap_pcix_cmd_reg_t	pcix_type0_command;
+	cap_pcix_stat_reg_t	pcix_type0_status;
+} cap_pcix_type0_t;
+
+#else
+
 /*
  * PCI config space definition
  */
@@ -388,6 +494,8 @@
 	uchar_t		int_line;
 } pci_cfg1_t;
 
+
+
 /*
  * PCI-X Capability
  */
@@ -422,5 +530,6 @@
 	cap_pcix_stat_reg_t	pcix_type0_status;
 } cap_pcix_type0_t;
 
+#endif
 #endif	/* __ASSEMBLY__ */
 #endif /* _ASM_SN_PCI_PCI_DEFS_H */
diff -Nru a/include/asm-ia64/sn/pci/pciba.h b/include/asm-ia64/sn/pci/pciba.h
--- a/include/asm-ia64/sn/pci/pciba.h	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,121 +0,0 @@
-/* 
- * 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) 1997, 2001 Silicon Graphics, Inc. All rights reserved.
- *
- */
-
-#ifndef _ASM_SN_PCI_PCIBA_H
-#define _ASM_SN_PCI_PCIBA_H
-
-#include <linux/ioctl.h>
-#include <linux/types.h>
-#include <linux/pci.h>
-
-/* for application compatibility with IRIX (why do I bother?) */
-
-#ifndef __KERNEL__
-typedef u_int8_t uint8_t;
-typedef u_int16_t uint16_t;
-typedef u_int32_t uint32_t;
-#endif
-
-#define PCI_CFG_VENDOR_ID	PCI_VENDOR_ID
-#define PCI_CFG_COMMAND		PCI_COMMAND
-#define PCI_CFG_REV_ID		PCI_REVISION_ID
-#define PCI_CFG_HEADER_TYPE	PCI_HEADER_TYPE
-#define PCI_CFG_BASE_ADDR(n)	PCI_BASE_ADDRESS_##n
-
-
-/* /hw/.../pci/[slot]/config accepts ioctls to read
- * and write specific registers as follows:
- *
- * "t" is the native type (char, short, uint32, uint64)
- * to read from CFG space; results will be arranged in
- * byte significance (ie. first byte from PCI is lowest
- * or last byte in result).
- *
- * "r" is the byte offset in PCI CFG space of the first
- * byte of the register (it's least significant byte,
- * in the little-endian PCI numbering). This can actually
- * be as much as 16 bits wide, and is intended to match
- * the layout of a "Type 1 Configuration Space" address:
- * the register number in the low eight bits, then three
- * bits for the function number and five bits for the
- * slot number.
- */
-#define	PCIIOCCFGRD(t,r)	_IOR(0,(r),t)
-#define	PCIIOCCFGWR(t,r)	_IOW(0,(r),t)
-
-/* Some common config register access commands.
- * Use these as examples of how to construct
- * values for other registers you want to access.
- */
-
-/* PCIIOCGETID: arg is ptr to 32-bit int,
- * returns the 32-bit ID value with VENDOR
- * in the bottom 16 bits and DEVICE in the top.
- */
-#define	PCIIOCGETID		PCIIOCCFGRD(uint32_t,PCI_CFG_VENDOR_ID)
-
-/* PCIIOCSETCMD: arg is ptr to a 16-bit short,
- * which will be written to the CMD register.
- */
-#define	PCIIOCSETCMD		PCIIOCCFGWR(uint16_t,PCI_CFG_COMMAND)
-
-/* PCIIOCGETREV: arg is ptr to an 8-bit char,
- * which will get the 8-bit revision number.
- */
-#define	PCIIOCGETREV		PCIIOCCFGRD(uint8_t,PCI_CFG_REV_ID)
-
-/* PCIIOCGETHTYPE: arg is ptr to an 8-bit char,
- * which will get the 8-bit header type.
- */
-#define	PCIIOCGETHTYPE		PCIIOCCFGRD(uint8_t,PCI_CFG_HEADER_TYPE)
-
-/* PCIIOCGETBASE(n): arg is ptr to a 32-bit int,
- * which will get the value of the BASE<n> register.
- */
-
-/* FIXME chadt: this doesn't tell me whether or not this will work
-   with non-constant 'n.'  */
-#define	PCIIOCGETBASE(n)	PCIIOCCFGRD(uint32_t,PCI_CFG_BASE_ADDR(n))
-
-
-/* /hw/.../pci/[slot]/dma accepts ioctls to allocate
- * and free physical memory for use in user-triggered
- * DMA operations.
- */
-#define	PCIIOCDMAALLOC		_IOWR(0,1,uint64_t)
-#define	PCIIOCDMAFREE		_IOW(0,1,uint64_t)
-
-/* pio cache-mode ioctl defines.  current only uncached accelerated */
-#define PCIBA_CACHE_MODE_SET	1
-#define PCIBA_CACHE_MODE_CLEAR	2
-#ifdef PIOMAP_UNC_ACC
-#define PCIBA_UNCACHED_ACCEL	PIOMAP_UNC_ACC
-#endif
-
-/* The parameter for PCIIOCDMAALLOC needs to contain
- * both the size of the request and the flag values
- * to be used in setting up the DMA.
- *
-
-FIXME chadt: gonna have to revisit this: what flags would an IRIXer like to
- have available?
-
- * Any flags normally useful in pciio_dmamap
- * or pciio_dmatrans function calls can6 be used here.  */
-#define	PCIIOCDMAALLOC_REQUEST_PACK(flags,size)		\
-	((((uint64_t)(flags))<<32)|			\
-	 (((uint64_t)(size))&0xFFFFFFFF))
-
-
-#ifdef __KERNEL__
-extern int pciba_init(void);
-#endif
-
-
-#endif	/* _ASM_SN_PCI_PCIBA_H */
diff -Nru a/include/asm-ia64/sn/pci/pcibr.h b/include/asm-ia64/sn/pci/pcibr.h
--- a/include/asm-ia64/sn/pci/pcibr.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/sn/pci/pcibr.h	Wed Jun 18 23:42:08 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_PCIBR_H
 #define _ASM_SN_PCI_PCIBR_H
@@ -59,9 +59,7 @@
  *	code and part number registered by pcibr_init().
  */
 
-extern void		pcibr_init(void);
-
-extern int		pcibr_attach(devfs_handle_t);
+extern int		pcibr_attach(vertex_hdl_t);
 
 /* =====================================================================
  *    bus provider function table
@@ -94,7 +92,7 @@
  *	smarts on the part of the compilation system).
  */
 
-extern pcibr_piomap_t	pcibr_piomap_alloc(devfs_handle_t dev,
+extern pcibr_piomap_t	pcibr_piomap_alloc(vertex_hdl_t dev,
 					   device_desc_t dev_desc,
 					   pciio_space_t space,
 					   iopaddr_t pci_addr,
@@ -110,24 +108,24 @@
 
 extern void		pcibr_piomap_done(pcibr_piomap_t piomap);
 
-extern caddr_t		pcibr_piotrans_addr(devfs_handle_t dev,
+extern caddr_t		pcibr_piotrans_addr(vertex_hdl_t dev,
 					    device_desc_t dev_desc,
 					    pciio_space_t space,
 					    iopaddr_t pci_addr,
 					    size_t byte_count,
 					    unsigned flags);
 
-extern iopaddr_t	pcibr_piospace_alloc(devfs_handle_t dev,
+extern iopaddr_t	pcibr_piospace_alloc(vertex_hdl_t dev,
 					     device_desc_t dev_desc,
 					     pciio_space_t space,
 					     size_t byte_count,
 					     size_t alignment);
-extern void		pcibr_piospace_free(devfs_handle_t dev,
+extern void		pcibr_piospace_free(vertex_hdl_t dev,
 					    pciio_space_t space,
 					    iopaddr_t pciaddr,
 					    size_t byte_count);
 
-extern pcibr_dmamap_t	pcibr_dmamap_alloc(devfs_handle_t dev,
+extern pcibr_dmamap_t	pcibr_dmamap_alloc(vertex_hdl_t dev,
 					   device_desc_t dev_desc,
 					   size_t byte_count_max,
 					   unsigned flags);
@@ -150,109 +148,97 @@
  * (This node id can be different for each PCI bus.) 
  */
 
-extern cnodeid_t	pcibr_get_dmatrans_node(devfs_handle_t pconn_vhdl);
+extern cnodeid_t	pcibr_get_dmatrans_node(vertex_hdl_t pconn_vhdl);
 
-extern iopaddr_t	pcibr_dmatrans_addr(devfs_handle_t dev,
+extern iopaddr_t	pcibr_dmatrans_addr(vertex_hdl_t dev,
 					    device_desc_t dev_desc,
 					    paddr_t paddr,
 					    size_t byte_count,
 					    unsigned flags);
 
-extern alenlist_t	pcibr_dmatrans_list(devfs_handle_t dev,
+extern alenlist_t	pcibr_dmatrans_list(vertex_hdl_t dev,
 					    device_desc_t dev_desc,
 					    alenlist_t palenlist,
 					    unsigned flags);
 
 extern void		pcibr_dmamap_drain(pcibr_dmamap_t map);
 
-extern void		pcibr_dmaaddr_drain(devfs_handle_t vhdl,
+extern void		pcibr_dmaaddr_drain(vertex_hdl_t vhdl,
 					    paddr_t addr,
 					    size_t bytes);
 
-extern void		pcibr_dmalist_drain(devfs_handle_t vhdl,
+extern void		pcibr_dmalist_drain(vertex_hdl_t vhdl,
 					    alenlist_t list);
 
 typedef unsigned	pcibr_intr_ibit_f(pciio_info_t info,
 					  pciio_intr_line_t lines);
 
-extern void		pcibr_intr_ibit_set(devfs_handle_t, pcibr_intr_ibit_f *);
+extern void		pcibr_intr_ibit_set(vertex_hdl_t, pcibr_intr_ibit_f *);
 
-extern pcibr_intr_t	pcibr_intr_alloc(devfs_handle_t dev,
+extern pcibr_intr_t	pcibr_intr_alloc(vertex_hdl_t dev,
 					 device_desc_t dev_desc,
 					 pciio_intr_line_t lines,
-					 devfs_handle_t owner_dev);
+					 vertex_hdl_t owner_dev);
 
 extern void		pcibr_intr_free(pcibr_intr_t intr);
 
-#ifdef CONFIG_IA64_SGI_SN1
-extern int		pcibr_intr_connect(pcibr_intr_t intr);
-#else
 extern int		pcibr_intr_connect(pcibr_intr_t intr, intr_func_t, intr_arg_t);
-#endif
 
 extern void		pcibr_intr_disconnect(pcibr_intr_t intr);
 
-extern devfs_handle_t	pcibr_intr_cpu_get(pcibr_intr_t intr);
+extern vertex_hdl_t	pcibr_intr_cpu_get(pcibr_intr_t intr);
 
-extern void		pcibr_provider_startup(devfs_handle_t pcibr);
+extern void		pcibr_provider_startup(vertex_hdl_t pcibr);
 
-extern void		pcibr_provider_shutdown(devfs_handle_t pcibr);
+extern void		pcibr_provider_shutdown(vertex_hdl_t pcibr);
 
-extern int		pcibr_reset(devfs_handle_t dev);
+extern int		pcibr_reset(vertex_hdl_t dev);
 
-extern int              pcibr_write_gather_flush(devfs_handle_t dev);
+extern int              pcibr_write_gather_flush(vertex_hdl_t dev);
 
-extern pciio_endian_t	pcibr_endian_set(devfs_handle_t dev,
+extern pciio_endian_t	pcibr_endian_set(vertex_hdl_t dev,
 					 pciio_endian_t device_end,
 					 pciio_endian_t desired_end);
 
-extern pciio_priority_t pcibr_priority_set(devfs_handle_t dev,
+extern pciio_priority_t pcibr_priority_set(vertex_hdl_t dev,
 					   pciio_priority_t device_prio);
 
-extern uint64_t		pcibr_config_get(devfs_handle_t conn,
+extern uint64_t		pcibr_config_get(vertex_hdl_t conn,
 					 unsigned reg,
 					 unsigned size);
 
-extern void		pcibr_config_set(devfs_handle_t conn,
+extern void		pcibr_config_set(vertex_hdl_t conn,
 					 unsigned reg,
 					 unsigned size,
 					 uint64_t value);
 
-extern int		pcibr_error_devenable(devfs_handle_t pconn_vhdl,
+extern int		pcibr_error_devenable(vertex_hdl_t pconn_vhdl,
 					      int error_code);
 
-#ifdef PIC_LATER
-extern pciio_slot_t	pcibr_error_extract(devfs_handle_t pcibr_vhdl,
-					    pciio_space_t *spacep,
-					    iopaddr_t *addrp);
-#endif
-
-extern int		pcibr_wrb_flush(devfs_handle_t pconn_vhdl);
-extern int		pcibr_rrb_check(devfs_handle_t pconn_vhdl,
+extern int		pcibr_wrb_flush(vertex_hdl_t pconn_vhdl);
+extern int		pcibr_rrb_check(vertex_hdl_t pconn_vhdl,
 					int *count_vchan0,
 					int *count_vchan1,
 					int *count_reserved,
 					int *count_pool);
 
-#ifndef CONFIG_IA64_SGI_SN1
-extern int		pcibr_alloc_all_rrbs(devfs_handle_t vhdl, int even_odd,
+extern int		pcibr_alloc_all_rrbs(vertex_hdl_t vhdl, int even_odd,
 					     int dev_1_rrbs, int virt1,
 					     int dev_2_rrbs, int virt2,
 					     int dev_3_rrbs, int virt3,
 					     int dev_4_rrbs, int virt4);
-#endif
 
 typedef void
-rrb_alloc_funct_f	(devfs_handle_t xconn_vhdl,
+rrb_alloc_funct_f	(vertex_hdl_t xconn_vhdl,
 			 int *vendor_list);
 
 typedef rrb_alloc_funct_f      *rrb_alloc_funct_t;
 
-void			pcibr_set_rrb_callback(devfs_handle_t xconn_vhdl,
+void			pcibr_set_rrb_callback(vertex_hdl_t xconn_vhdl,
 					       rrb_alloc_funct_f *func);
 
-extern int		pcibr_device_unregister(devfs_handle_t);
-extern int		pcibr_dma_enabled(devfs_handle_t);
+extern int		pcibr_device_unregister(vertex_hdl_t);
+extern int		pcibr_dma_enabled(vertex_hdl_t);
 /*
  * Bridge-specific flags that can be set via pcibr_device_flags_set
  * and cleared via pcibr_device_flags_clear.  Other flags are
@@ -320,7 +306,7 @@
  * "flags" are defined above. NOTE: this includes turning
  * things *OFF* as well as turning them *ON* ...
  */
-extern int		pcibr_device_flags_set(devfs_handle_t dev,
+extern int		pcibr_device_flags_set(vertex_hdl_t dev,
 					     pcibr_device_flags_t flags);
 
 /*
@@ -331,7 +317,7 @@
  * <0 on failure, which occurs when we're unable to allocate any
  * buffers to a channel that desires at least one buffer.
  */
-extern int		pcibr_rrb_alloc(devfs_handle_t pconn_vhdl,
+extern int		pcibr_rrb_alloc(vertex_hdl_t pconn_vhdl,
 					int *count_vchan0,
 					int *count_vchan1);
 
@@ -345,19 +331,15 @@
 
 extern xwidget_intr_preset_f pcibr_xintr_preset;
 
-extern void		pcibr_hints_fix_rrbs(devfs_handle_t);
-extern void		pcibr_hints_dualslot(devfs_handle_t, pciio_slot_t, pciio_slot_t);
-extern void		pcibr_hints_subdevs(devfs_handle_t, pciio_slot_t, ulong);
-extern void		pcibr_hints_handsoff(devfs_handle_t);
-
-#ifdef CONFIG_IA64_SGI_SN1
-typedef unsigned	pcibr_intr_bits_f(pciio_info_t, pciio_intr_line_t);
-#else
+extern void		pcibr_hints_fix_rrbs(vertex_hdl_t);
+extern void		pcibr_hints_dualslot(vertex_hdl_t, pciio_slot_t, pciio_slot_t);
+extern void		pcibr_hints_subdevs(vertex_hdl_t, pciio_slot_t, ulong);
+extern void		pcibr_hints_handsoff(vertex_hdl_t);
+
 typedef unsigned	pcibr_intr_bits_f(pciio_info_t, pciio_intr_line_t, int);
-#endif
-extern void		pcibr_hints_intr_bits(devfs_handle_t, pcibr_intr_bits_f *);
+extern void		pcibr_hints_intr_bits(vertex_hdl_t, pcibr_intr_bits_f *);
 
-extern int		pcibr_asic_rev(devfs_handle_t);
+extern int		pcibr_asic_rev(vertex_hdl_t);
 
 #endif 	/* __ASSEMBLY__ */
 #endif	/* #if defined(__KERNEL__) */
@@ -433,7 +415,7 @@
     short		    resp_bs_bridge_mode;
     int                     resp_has_host;
     char                    resp_host_slot;
-    devfs_handle_t            resp_slot_conn;
+    vertex_hdl_t            resp_slot_conn;
     char                    resp_slot_conn_name[MAXDEVNAME];
     int                     resp_slot_status;
     int                     resp_l1_bus_num;
@@ -460,10 +442,8 @@
     bridgereg_t             resp_b_int_device;
     bridgereg_t             resp_b_int_enable;
     bridgereg_t             resp_b_int_host;
-#ifndef CONFIG_IA64_SGI_SN1
     picreg_t		    resp_p_int_enable;
     picreg_t		    resp_p_int_host;
-#endif
     struct pcibr_slot_func_info_resp_s {
         int                     resp_f_status;
         char                    resp_f_slot_name[MAXDEVNAME];
diff -Nru a/include/asm-ia64/sn/pci/pcibr_private.h b/include/asm-ia64/sn/pci/pcibr_private.h
--- a/include/asm-ia64/sn/pci/pcibr_private.h	Wed Jun 18 23:42:05 2003
+++ b/include/asm-ia64/sn/pci/pcibr_private.h	Wed Jun 18 23:42:05 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_PCIBR_PRIVATE_H
 #define _ASM_SN_PCI_PCIBR_PRIVATE_H
@@ -16,6 +16,7 @@
  */
 
 #include <linux/config.h>
+#include <linux/pci.h>
 #include <asm/sn/pci/pcibr.h>
 #include <asm/sn/pci/pciio_private.h>
 #include <asm/sn/ksys/l1.h>
@@ -45,7 +46,7 @@
 cfg_p pcibr_func_config_addr(bridge_t *, pciio_bus_t bus, pciio_slot_t, pciio_function_t, int);
 unsigned pcibr_slot_config_get(bridge_t *, pciio_slot_t, int);
 unsigned pcibr_func_config_get(bridge_t *, pciio_slot_t, pciio_function_t, int);
-void pcibr_debug(uint32_t, devfs_handle_t, char *, ...);
+void pcibr_debug(uint32_t, vertex_hdl_t, char *, ...);
 void pcibr_slot_config_set(bridge_t *, pciio_slot_t, int, unsigned);
 void pcibr_func_config_set(bridge_t *, pciio_slot_t, pciio_function_t, int, 
 								unsigned);
@@ -171,6 +172,7 @@
     unsigned                bi_ibits;	/* which Bridge interrupt bit(s) */
     pcibr_soft_t            bi_soft;	/* shortcut to soft info */
     struct pcibr_intr_cbuf_s bi_ibuf;	/* circular buffer of wrap ptrs */
+    unsigned		bi_last_intr;	/* For Shub lb lost intr. bug */
 };
 
 
@@ -254,11 +256,7 @@
 struct pcibr_intr_wrap_s {
     pcibr_soft_t            iw_soft;	/* which bridge */
     volatile bridgereg_t   *iw_stat;	/* ptr to b_int_status */
-#ifdef CONFIG_IA64_SGI_SN1
-    bridgereg_t             iw_intr;	/* bit in b_int_status */
-#else
     bridgereg_t             iw_ibit;	/* bit in b_int_status */
-#endif
     pcibr_intr_list_t       iw_list;	/* ghostbusters! */
     int			    iw_hdlrcnt;	/* running handler count */
     int			    iw_shared;  /* if Bridge bit is shared */
@@ -293,6 +291,8 @@
 #define PCIBR_BRIDGETYPE_PIC		2
 #define IS_XBRIDGE_SOFT(ps) (ps->bs_bridge_type == PCIBR_BRIDGETYPE_XBRIDGE)
 #define IS_PIC_SOFT(ps)     (ps->bs_bridge_type == PCIBR_BRIDGETYPE_PIC)
+#define IS_PIC_BUSNUM_SOFT(ps, bus)	\
+		(IS_PIC_SOFT(ps) && ((ps)->bs_busnum == (bus)))
 #define IS_BRIDGE_SOFT(ps)  (ps->bs_bridge_type == PCIBR_BRIDGETYPE_BRIDGE)
 #define IS_XBRIDGE_OR_PIC_SOFT(ps) (IS_XBRIDGE_SOFT(ps) || IS_PIC_SOFT(ps))
 
@@ -348,13 +348,13 @@
  */
 
 struct pcibr_soft_s {
-    devfs_handle_t          bs_conn;		/* xtalk connection point */
-    devfs_handle_t          bs_vhdl;		/* vertex owned by pcibr */
+    vertex_hdl_t          bs_conn;		/* xtalk connection point */
+    vertex_hdl_t          bs_vhdl;		/* vertex owned by pcibr */
     uint64_t                bs_int_enable;	/* Mask of enabled intrs */
     bridge_t               *bs_base;		/* PIO pointer to Bridge chip */
     char                   *bs_name;		/* hw graph name */
     xwidgetnum_t            bs_xid;		/* Bridge's xtalk ID number */
-    devfs_handle_t          bs_master;		/* xtalk master vertex */
+    vertex_hdl_t          bs_master;		/* xtalk master vertex */
     xwidgetnum_t            bs_mxid;		/* master's xtalk ID number */
     pciio_slot_t            bs_first_slot;      /* first existing slot */
     pciio_slot_t            bs_last_slot;       /* last existing slot */
@@ -372,9 +372,6 @@
     short		    bs_int_ate_size;	/* number of internal ates */
     short		    bs_bridge_type;	/* see defines above */
     short		    bs_bridge_mode;	/* see defines above */
-#ifdef CONFIG_IA64_SGI_SN1
-#define bs_xbridge	    bs_bridge_type
-#endif
     int                     bs_rev_num;		/* revision number of Bridge */
 
     /* bs_dma_flags are the forced dma flags used on all DMAs. Used for
@@ -382,9 +379,6 @@
      */
     unsigned                bs_dma_flags;	/* forced DMA flags */
 
-#ifdef CONFIG_IA64_SGI_SN1
-    l1sc_t                 *bs_l1sc;            /* io brick l1 system cntr */
-#endif
     moduleid_t		    bs_moduleid;	/* io brick moduleid */
     short		    bs_bricktype;	/* io brick type */
 
@@ -394,7 +388,7 @@
      */
     spinlock_t              bs_lock;
     
-    devfs_handle_t	    bs_noslot_conn;	/* NO-SLOT connection point */
+    vertex_hdl_t	    bs_noslot_conn;	/* NO-SLOT connection point */
     pcibr_info_t	    bs_noslot_info;
     struct pcibr_soft_slot_s {
 	/* information we keep about each CFG slot */
@@ -411,7 +405,7 @@
 	 */
 	int                     has_host;
 	pciio_slot_t            host_slot;
-	devfs_handle_t		slot_conn;
+	vertex_hdl_t		slot_conn;
 
         /* PCI Hot-Plug status word */
         int 			slot_status;
@@ -531,13 +525,8 @@
     int                     bs_rrb_avail[2];
     int                     bs_rrb_res[8];
     int                     bs_rrb_res_dflt[8];
-#ifdef CONFIG_IA64_SGI_SN1
-    int                     bs_rrb_valid[16];
-    int                     bs_rrb_valid_dflt[16];
-#else
     int			    bs_rrb_valid[8][4];
     int			    bs_rrb_valid_dflt[8][4];
-#endif
     struct {
 	/* Each Bridge interrupt bit has a single XIO
 	 * interrupt channel allocated.
@@ -578,7 +567,7 @@
 #ifdef LATER
 	toid_t                  bserr_toutid;	/* Timeout started by errintr */
 #endif	/* LATER */
-	iopaddr_t               bserr_addr;	/* Address where error occurred */
+	iopaddr_t               bserr_addr;	/* Address where error occured */
 	uint64_t		bserr_intstat;	/* interrupts active at error dump */
     } bs_errinfo;
 
@@ -599,16 +588,6 @@
      * in Megabytes), and they generally tend to take once and never
      * release. 
      */
-#ifdef CONFIG_IA64_SGI_SN1
-    struct br_pcisp_info {
-        iopaddr_t               pci_io_base;
-        iopaddr_t               pci_io_last;
-        iopaddr_t               pci_swin_base;
-        iopaddr_t               pci_swin_last;
-        iopaddr_t               pci_mem_base;
-        iopaddr_t               pci_mem_last;
-    } bs_spinfo;
-#endif	/* CONFIG_IA64_SGI_SN1 */
     struct pciio_win_map_s	bs_io_win_map;	/* I/O addr space */
     struct pciio_win_map_s	bs_swin_map;	/* Small window addr space */
     struct pciio_win_map_s	bs_mem_win_map;	/* Memory addr space */
@@ -655,8 +634,6 @@
     pcibr_intr_bits_f	   *ph_intr_bits;	/* map PCI INT[ABCD] to Bridge Int(n) */
 };
 
-extern int              pcibr_prefetch_enable_rev, pcibr_wg_enable_rev;
-
 /*
  * Number of bridge non-fatal error interrupts we can see before
  * we decide to disable that interrupt.
@@ -689,7 +666,6 @@
 #define NEW(ptr)	NEWA(ptr,1)
 #define DEL(ptr)	DELA(ptr,1)
 
-#ifndef CONFIG_IA64_SGI_SN1
 /*
  * Additional PIO spaces per slot are
  * recorded in this structure.
@@ -701,7 +677,6 @@
     iopaddr_t               start;	/* Starting address of the PIO space */
     size_t                  count;	/* size of PIO space */
 };
-#endif	/* CONFIG_IA64_SGI_SN1 */
 
 /* Use io spin locks. This ensures that all the PIO writes from a particular
  * CPU to a particular IO device are synched before the start of the next
@@ -715,11 +690,9 @@
 #define pcibr_unlock(pcibr_soft, s)	
 #endif	/* PCI_LATER */
 
-#ifndef CONFIG_IA64_SGI_SN1
 #define PCIBR_VALID_SLOT(ps, s)     (s < PCIBR_NUM_SLOTS(ps))
 #define PCIBR_D64_BASE_UNSET    (0xFFFFFFFFFFFFFFFF)
 #define PCIBR_D32_BASE_UNSET    (0xFFFFFFFF)
-#endif
 #define INFO_LBL_PCIBR_ASIC_REV "_pcibr_asic_rev"
 
 #define PCIBR_SOFT_LIST 1
@@ -728,8 +701,35 @@
 struct pcibr_list_s {
 	pcibr_list_p            bl_next;
 	pcibr_soft_t            bl_soft;
-	devfs_handle_t          bl_vhdl;
+	vertex_hdl_t          bl_vhdl;
 };
 #endif /* PCIBR_SOFT_LIST */
+
+
+// Devices per widget: 2 buses, 2 slots per bus, 8 functions per slot.
+#define DEV_PER_WIDGET (2*2*8)
+
+struct sn_flush_device_list {
+	int bus;
+	int pin;
+	struct bar_list {
+		unsigned long start;
+		unsigned long end;
+	} bar_list[PCI_ROM_RESOURCE];
+	unsigned long force_int_addr;
+	volatile unsigned long flush_addr;
+	spinlock_t flush_lock;
+};
+
+struct sn_flush_nasid_entry  {
+        struct sn_flush_device_list **widget_p;
+        unsigned long        iio_itte1;
+        unsigned long        iio_itte2;
+        unsigned long        iio_itte3;
+        unsigned long        iio_itte4;
+        unsigned long        iio_itte5;
+        unsigned long        iio_itte6;
+        unsigned long        iio_itte7;
+};
 
 #endif				/* _ASM_SN_PCI_PCIBR_PRIVATE_H */
diff -Nru a/include/asm-ia64/sn/pci/pciio.h b/include/asm-ia64/sn/pci/pciio.h
--- a/include/asm-ia64/sn/pci/pciio.h	Wed Jun 18 23:42:05 2003
+++ b/include/asm-ia64/sn/pci/pciio.h	Wed Jun 18 23:42:05 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_PCIIO_H
 #define _ASM_SN_PCI_PCIIO_H
@@ -277,7 +277,7 @@
 #define PCIIO_PIOMAP_WIN(n)	(0x8+(n))
 
 typedef pciio_piomap_t
-pciio_piomap_alloc_f    (devfs_handle_t dev,	/* set up mapping for this device */
+pciio_piomap_alloc_f    (vertex_hdl_t dev,	/* set up mapping for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 pciio_space_t space,	/* which address space */
 			 iopaddr_t pcipio_addr,		/* starting address */
@@ -297,7 +297,7 @@
 pciio_piomap_done_f     (pciio_piomap_t pciio_piomap);
 
 typedef caddr_t
-pciio_piotrans_addr_f   (devfs_handle_t dev,	/* translate for this device */
+pciio_piotrans_addr_f   (vertex_hdl_t dev,	/* translate for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 pciio_space_t space,	/* which address space */
 			 iopaddr_t pciio_addr,	/* starting address */
@@ -305,7 +305,7 @@
 			 unsigned flags);
 
 typedef caddr_t
-pciio_pio_addr_f        (devfs_handle_t dev,	/* translate for this device */
+pciio_pio_addr_f        (vertex_hdl_t dev,	/* translate for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 pciio_space_t space,	/* which address space */
 			 iopaddr_t pciio_addr,	/* starting address */
@@ -314,14 +314,14 @@
 			 unsigned flags);
 
 typedef iopaddr_t
-pciio_piospace_alloc_f  (devfs_handle_t dev,	/* PIO space for this device */
+pciio_piospace_alloc_f  (vertex_hdl_t dev,	/* PIO space for this device */
 			 device_desc_t dev_desc,	/* Device descriptor   */
 			 pciio_space_t space,	/* which address space  */
 			 size_t byte_count,	/* Number of bytes of space */
 			 size_t alignment);	/* Alignment of allocation  */
 
 typedef void
-pciio_piospace_free_f   (devfs_handle_t dev,	/* Device freeing space */
+pciio_piospace_free_f   (vertex_hdl_t dev,	/* Device freeing space */
 			 pciio_space_t space,	/* Which space is freed */
 			 iopaddr_t pci_addr,	/* Address being freed */
 			 size_t size);	/* Size freed           */
@@ -329,7 +329,7 @@
 /* DMA MANAGEMENT */
 
 typedef pciio_dmamap_t
-pciio_dmamap_alloc_f    (devfs_handle_t dev,	/* set up mappings for this device */
+pciio_dmamap_alloc_f    (vertex_hdl_t dev,	/* set up mappings for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 size_t byte_count_max,		/* max size of a mapping */
 			 unsigned flags);	/* defined in dma.h */
@@ -342,123 +342,107 @@
 			 paddr_t paddr,	/* map for this address */
 			 size_t byte_count);	/* map this many bytes */
 
-typedef alenlist_t
-pciio_dmamap_list_f     (pciio_dmamap_t dmamap,		/* use these mapping resources */
-			 alenlist_t alenlist,	/* map this address/length list */
-			 unsigned flags);
-
 typedef void
 pciio_dmamap_done_f     (pciio_dmamap_t dmamap);
 
 typedef iopaddr_t
-pciio_dmatrans_addr_f   (devfs_handle_t dev,	/* translate for this device */
+pciio_dmatrans_addr_f   (vertex_hdl_t dev,	/* translate for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 paddr_t paddr,	/* system physical address */
 			 size_t byte_count,	/* length */
 			 unsigned flags);	/* defined in dma.h */
 
-typedef alenlist_t
-pciio_dmatrans_list_f   (devfs_handle_t dev,	/* translate for this device */
-			 device_desc_t dev_desc,	/* device descriptor */
-			 alenlist_t palenlist,	/* system address/length list */
-			 unsigned flags);	/* defined in dma.h */
-
 typedef void
 pciio_dmamap_drain_f	(pciio_dmamap_t map);
 
 typedef void
-pciio_dmaaddr_drain_f	(devfs_handle_t vhdl,
+pciio_dmaaddr_drain_f	(vertex_hdl_t vhdl,
 			 paddr_t addr,
 			 size_t bytes);
 
 typedef void
-pciio_dmalist_drain_f	(devfs_handle_t vhdl,
+pciio_dmalist_drain_f	(vertex_hdl_t vhdl,
 			 alenlist_t list);
 
 /* INTERRUPT MANAGEMENT */
 
 typedef pciio_intr_t
-pciio_intr_alloc_f      (devfs_handle_t dev,	/* which PCI device */
+pciio_intr_alloc_f      (vertex_hdl_t dev,	/* which PCI device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 pciio_intr_line_t lines,	/* which line(s) will be used */
-			 devfs_handle_t owner_dev);	/* owner of this intr */
+			 vertex_hdl_t owner_dev);	/* owner of this intr */
 
 typedef void
 pciio_intr_free_f       (pciio_intr_t intr_hdl);
 
-#ifdef CONFIG_IA64_SGI_SN1
-typedef int
-pciio_intr_connect_f    (pciio_intr_t intr_hdl);	/* pciio intr resource handle */
-#else
 typedef int
 pciio_intr_connect_f    (pciio_intr_t intr_hdl, intr_func_t intr_func, intr_arg_t intr_arg);	/* pciio intr resource handle */
-#endif
 
 typedef void
 pciio_intr_disconnect_f (pciio_intr_t intr_hdl);
 
-typedef devfs_handle_t
+typedef vertex_hdl_t
 pciio_intr_cpu_get_f    (pciio_intr_t intr_hdl);	/* pciio intr resource handle */
 
 /* CONFIGURATION MANAGEMENT */
 
 typedef void
-pciio_provider_startup_f (devfs_handle_t pciio_provider);
+pciio_provider_startup_f (vertex_hdl_t pciio_provider);
 
 typedef void
-pciio_provider_shutdown_f (devfs_handle_t pciio_provider);
+pciio_provider_shutdown_f (vertex_hdl_t pciio_provider);
 
 typedef int	
-pciio_reset_f		(devfs_handle_t conn);	/* pci connection point */
+pciio_reset_f		(vertex_hdl_t conn);	/* pci connection point */
 
 typedef int
-pciio_write_gather_flush_f (devfs_handle_t dev);    /* Device flushing buffers */
+pciio_write_gather_flush_f (vertex_hdl_t dev);    /* Device flushing buffers */
 
 typedef pciio_endian_t			/* actual endianness */
-pciio_endian_set_f      (devfs_handle_t dev,	/* specify endianness for this device */
+pciio_endian_set_f      (vertex_hdl_t dev,	/* specify endianness for this device */
 			 pciio_endian_t device_end,	/* endianness of device */
 			 pciio_endian_t desired_end);	/* desired endianness */
 
 typedef pciio_priority_t
-pciio_priority_set_f    (devfs_handle_t pcicard,
+pciio_priority_set_f    (vertex_hdl_t pcicard,
 			 pciio_priority_t device_prio);
 
 typedef uint64_t
-pciio_config_get_f	(devfs_handle_t conn,	/* pci connection point */
+pciio_config_get_f	(vertex_hdl_t conn,	/* pci connection point */
 			 unsigned reg,		/* register byte offset */
 			 unsigned size);	/* width in bytes (1..4) */
 
 typedef void
-pciio_config_set_f	(devfs_handle_t conn,	/* pci connection point */
+pciio_config_set_f	(vertex_hdl_t conn,	/* pci connection point */
 			 unsigned reg,		/* register byte offset */
 			 unsigned size,		/* width in bytes (1..4) */
 			 uint64_t value);	/* value to store */
 
 typedef int
-pciio_error_devenable_f (devfs_handle_t pconn_vhdl, int error_code);
+pciio_error_devenable_f (vertex_hdl_t pconn_vhdl, int error_code);
 
 typedef pciio_slot_t
-pciio_error_extract_f	(devfs_handle_t vhdl,
+pciio_error_extract_f	(vertex_hdl_t vhdl,
 			 pciio_space_t *spacep,
 			 iopaddr_t *addrp);
 
 typedef void
-pciio_driver_reg_callback_f	(devfs_handle_t conn,
+pciio_driver_reg_callback_f	(vertex_hdl_t conn,
 				int key1,
 				int key2,
 				int error);
 
 typedef void
-pciio_driver_unreg_callback_f	(devfs_handle_t conn, /* pci connection point */
+pciio_driver_unreg_callback_f	(vertex_hdl_t conn, /* pci connection point */
 				 int key1,
 				 int key2,
 				 int error);
 
 typedef int
-pciio_device_unregister_f	(devfs_handle_t conn);
+pciio_device_unregister_f	(vertex_hdl_t conn);
 
 typedef int
-pciio_dma_enabled_f		(devfs_handle_t conn);
+pciio_dma_enabled_f		(vertex_hdl_t conn);
 
 /*
  * Adapters that provide a PCI interface adhere to this software interface.
@@ -477,10 +461,8 @@
     pciio_dmamap_alloc_f   *dmamap_alloc;
     pciio_dmamap_free_f    *dmamap_free;
     pciio_dmamap_addr_f    *dmamap_addr;
-    pciio_dmamap_list_f    *dmamap_list;
     pciio_dmamap_done_f    *dmamap_done;
     pciio_dmatrans_addr_f  *dmatrans_addr;
-    pciio_dmatrans_list_f  *dmatrans_list;
     pciio_dmamap_drain_f   *dmamap_drain;
     pciio_dmaaddr_drain_f  *dmaaddr_drain;
     pciio_dmalist_drain_f  *dmalist_drain;
@@ -525,10 +507,8 @@
 extern pciio_dmamap_alloc_f pciio_dmamap_alloc;
 extern pciio_dmamap_free_f pciio_dmamap_free;
 extern pciio_dmamap_addr_f pciio_dmamap_addr;
-extern pciio_dmamap_list_f pciio_dmamap_list;
 extern pciio_dmamap_done_f pciio_dmamap_done;
 extern pciio_dmatrans_addr_f pciio_dmatrans_addr;
-extern pciio_dmatrans_list_f pciio_dmatrans_list;
 extern pciio_dmamap_drain_f pciio_dmamap_drain;
 extern pciio_dmaaddr_drain_f pciio_dmaaddr_drain;
 extern pciio_dmalist_drain_f pciio_dmalist_drain;
@@ -580,34 +560,31 @@
 			unsigned flags);
 
 extern void
-pciio_error_register   (devfs_handle_t pconn,	/* which slot */
+pciio_error_register   (vertex_hdl_t pconn,	/* which slot */
 			error_handler_f *efunc,	/* function to call */
 			error_handler_arg_t einfo);	/* first parameter */
 
 extern void             pciio_driver_unregister(char *driver_prefix);
 
-typedef void		pciio_iter_f(devfs_handle_t pconn);	/* a connect point */
-
-extern void             pciio_iterate(char *driver_prefix,
-				      pciio_iter_f *func);
+typedef void		pciio_iter_f(vertex_hdl_t pconn);	/* a connect point */
 
 /* Interfaces used by PCI Bus Providers to talk to
  * the Generic PCI layer.
  */
-extern devfs_handle_t
-pciio_device_register  (devfs_handle_t connectpt,	/* vertex at center of bus */
-			devfs_handle_t master,	/* card's master ASIC (pci provider) */
+extern vertex_hdl_t
+pciio_device_register  (vertex_hdl_t connectpt,	/* vertex at center of bus */
+			vertex_hdl_t master,	/* card's master ASIC (pci provider) */
 			pciio_slot_t slot,	/* card's slot (0..?) */
 			pciio_function_t func,	/* card's func (0..?) */
 			pciio_vendor_id_t vendor,	/* card's vendor number */
 			pciio_device_id_t device);	/* card's device number */
 
 extern void
-pciio_device_unregister(devfs_handle_t connectpt);
+pciio_device_unregister(vertex_hdl_t connectpt);
 
 extern pciio_info_t
 pciio_device_info_new  (pciio_info_t pciio_info,	/* preallocated info struct */
-			devfs_handle_t master,	/* card's master ASIC (pci provider) */
+			vertex_hdl_t master,	/* card's master ASIC (pci provider) */
 			pciio_slot_t slot,	/* card's slot (0..?) */
 			pciio_function_t func,	/* card's func (0..?) */
 			pciio_vendor_id_t vendor,	/* card's vendor number */
@@ -616,24 +593,24 @@
 extern void
 pciio_device_info_free(pciio_info_t pciio_info);
 
-extern devfs_handle_t
+extern vertex_hdl_t
 pciio_device_info_register(
-			devfs_handle_t connectpt,	/* vertex at center of bus */
+			vertex_hdl_t connectpt,	/* vertex at center of bus */
 			pciio_info_t pciio_info);	/* details about conn point */
 
 extern void
 pciio_device_info_unregister(
-			devfs_handle_t connectpt,	/* vertex at center of bus */
+			vertex_hdl_t connectpt,	/* vertex at center of bus */
 			pciio_info_t pciio_info);	/* details about conn point */
 
 
 extern int              
 pciio_device_attach(
-			devfs_handle_t pcicard,   /* vertex created by pciio_device_register */
+			vertex_hdl_t pcicard,   /* vertex created by pciio_device_register */
 			int drv_flags);
 extern int
 pciio_device_detach(
-			devfs_handle_t pcicard,   /* vertex created by pciio_device_register */
+			vertex_hdl_t pcicard,   /* vertex created by pciio_device_register */
                         int drv_flags);
 
 
@@ -654,20 +631,12 @@
 			  size_t size);			/* size of free range */
 
 /* allocate window from mapping resource */
-#ifdef CONFIG_IA64_SGI_SN1
-extern iopaddr_t
-pciio_device_win_alloc(pciio_win_map_t win_map,		/* win map */
-		       pciio_win_alloc_t win_alloc,	/* opaque allocation cookie */
-		       size_t size,			/* size of allocation */
-		       size_t align);			/* alignment of allocation */
-#else
 extern iopaddr_t
 pciio_device_win_alloc(pciio_win_map_t win_map,		/* win map */
 		       pciio_win_alloc_t win_alloc,	/* opaque allocation cookie */
 		       size_t start,			/* start unit, or 0 */
 		       size_t size,			/* size of allocation */
 		       size_t align);			/* alignment of allocation */
-#endif
 
 /* free previously allocated window */
 extern void
@@ -680,11 +649,11 @@
  */
 
 /* Generic PCI interrupt interfaces */
-extern devfs_handle_t     pciio_intr_dev_get(pciio_intr_t pciio_intr);
-extern devfs_handle_t     pciio_intr_cpu_get(pciio_intr_t pciio_intr);
+extern vertex_hdl_t     pciio_intr_dev_get(pciio_intr_t pciio_intr);
+extern vertex_hdl_t     pciio_intr_cpu_get(pciio_intr_t pciio_intr);
 
 /* Generic PCI pio interfaces */
-extern devfs_handle_t     pciio_pio_dev_get(pciio_piomap_t pciio_piomap);
+extern vertex_hdl_t     pciio_pio_dev_get(pciio_piomap_t pciio_piomap);
 extern pciio_slot_t     pciio_pio_slot_get(pciio_piomap_t pciio_piomap);
 extern pciio_space_t    pciio_pio_space_get(pciio_piomap_t pciio_piomap);
 extern iopaddr_t        pciio_pio_pciaddr_get(pciio_piomap_t pciio_piomap);
@@ -692,26 +661,26 @@
 extern caddr_t          pciio_pio_kvaddr_get(pciio_piomap_t pciio_piomap);
 
 /* Generic PCI dma interfaces */
-extern devfs_handle_t     pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap);
+extern vertex_hdl_t     pciio_dma_dev_get(pciio_dmamap_t pciio_dmamap);
 
 /* Register/unregister PCI providers and get implementation handle */
-extern void             pciio_provider_register(devfs_handle_t provider, pciio_provider_t *pciio_fns);
-extern void             pciio_provider_unregister(devfs_handle_t provider);
-extern pciio_provider_t *pciio_provider_fns_get(devfs_handle_t provider);
+extern void             pciio_provider_register(vertex_hdl_t provider, pciio_provider_t *pciio_fns);
+extern void             pciio_provider_unregister(vertex_hdl_t provider);
+extern pciio_provider_t *pciio_provider_fns_get(vertex_hdl_t provider);
 
 /* Generic pci slot information access interface */
-extern pciio_info_t     pciio_info_chk(devfs_handle_t vhdl);
-extern pciio_info_t     pciio_info_get(devfs_handle_t vhdl);
-extern pciio_info_t     pciio_hostinfo_get(devfs_handle_t vhdl);
-extern void             pciio_info_set(devfs_handle_t vhdl, pciio_info_t widget_info);
-extern devfs_handle_t     pciio_info_dev_get(pciio_info_t pciio_info);
-extern devfs_handle_t     pciio_info_hostdev_get(pciio_info_t pciio_info);
+extern pciio_info_t     pciio_info_chk(vertex_hdl_t vhdl);
+extern pciio_info_t     pciio_info_get(vertex_hdl_t vhdl);
+extern pciio_info_t     pciio_hostinfo_get(vertex_hdl_t vhdl);
+extern void             pciio_info_set(vertex_hdl_t vhdl, pciio_info_t widget_info);
+extern vertex_hdl_t     pciio_info_dev_get(pciio_info_t pciio_info);
+extern vertex_hdl_t     pciio_info_hostdev_get(pciio_info_t pciio_info);
 extern pciio_bus_t	pciio_info_bus_get(pciio_info_t pciio_info);
 extern pciio_slot_t     pciio_info_slot_get(pciio_info_t pciio_info);
 extern pciio_function_t	pciio_info_function_get(pciio_info_t pciio_info);
 extern pciio_vendor_id_t pciio_info_vendor_id_get(pciio_info_t pciio_info);
 extern pciio_device_id_t pciio_info_device_id_get(pciio_info_t pciio_info);
-extern devfs_handle_t     pciio_info_master_get(pciio_info_t pciio_info);
+extern vertex_hdl_t     pciio_info_master_get(pciio_info_t pciio_info);
 extern arbitrary_info_t pciio_info_mfast_get(pciio_info_t pciio_info);
 extern pciio_provider_t *pciio_info_pops_get(pciio_info_t pciio_info);
 extern error_handler_f *pciio_info_efunc_get(pciio_info_t);
@@ -722,8 +691,8 @@
 extern iopaddr_t	pciio_info_rom_base_get(pciio_info_t);
 extern size_t		pciio_info_rom_size_get(pciio_info_t);
 extern int		pciio_info_type1_get(pciio_info_t);
-extern int              pciio_error_handler(devfs_handle_t, int, ioerror_mode_t, ioerror_t *);
-extern int		pciio_dma_enabled(devfs_handle_t);
+extern int              pciio_error_handler(vertex_hdl_t, int, ioerror_mode_t, ioerror_t *);
+extern int		pciio_dma_enabled(vertex_hdl_t);
 
 #endif				/* C or C++ */
 #endif				/* _ASM_SN_PCI_PCIIO_H */
diff -Nru a/include/asm-ia64/sn/pci/pciio_private.h b/include/asm-ia64/sn/pci/pciio_private.h
--- a/include/asm-ia64/sn/pci/pciio_private.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/sn/pci/pciio_private.h	Wed Jun 18 23:42:07 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_SN_PCI_PCIIO_PRIVATE_H
 #define _ASM_SN_PCI_PCIIO_PRIVATE_H
@@ -24,7 +24,7 @@
  */
 struct pciio_piomap_s {
     unsigned                pp_flags;	/* PCIIO_PIOMAP flags */
-    devfs_handle_t            pp_dev;	/* associated pci card */
+    vertex_hdl_t            pp_dev;	/* associated pci card */
     pciio_slot_t            pp_slot;	/* which slot the card is in */
     pciio_space_t           pp_space;	/* which address space */
     iopaddr_t               pp_pciaddr;		/* starting offset of mapping */
@@ -37,7 +37,7 @@
  */
 struct pciio_dmamap_s {
     unsigned                pd_flags;	/* PCIIO_DMAMAP flags */
-    devfs_handle_t            pd_dev;	/* associated pci card */
+    vertex_hdl_t            pd_dev;	/* associated pci card */
     pciio_slot_t            pd_slot;	/* which slot the card is in */
 };
 
@@ -47,7 +47,7 @@
 
 struct pciio_intr_s {
     unsigned                pi_flags;	/* PCIIO_INTR flags */
-    devfs_handle_t            pi_dev;	/* associated pci card */
+    vertex_hdl_t            pi_dev;	/* associated pci card */
     device_desc_t	    pi_dev_desc;	/* override device descriptor */
     pciio_intr_line_t       pi_lines;	/* which interrupt line(s) */
     intr_func_t             pi_func;	/* handler function (when connected) */
@@ -100,13 +100,13 @@
 
 struct pciio_info_s {
     char                   *c_fingerprint;
-    devfs_handle_t            c_vertex;	/* back pointer to vertex */
+    vertex_hdl_t            c_vertex;	/* back pointer to vertex */
     pciio_bus_t             c_bus;	/* which bus the card is in */
     pciio_slot_t            c_slot;	/* which slot the card is in */
     pciio_function_t        c_func;	/* which func (on multi-func cards) */
     pciio_vendor_id_t       c_vendor;	/* PCI card "vendor" code */
     pciio_device_id_t       c_device;	/* PCI card "device" code */
-    devfs_handle_t            c_master;	/* PCI bus provider */
+    vertex_hdl_t            c_master;	/* PCI bus provider */
     arbitrary_info_t        c_mfast;	/* cached fastinfo from c_master */
     pciio_provider_t       *c_pops;	/* cached provider from c_master */
     error_handler_f        *c_efunc;	/* error handling function */
diff -Nru a/include/asm-ia64/sn/pda.h b/include/asm-ia64/sn/pda.h
--- a/include/asm-ia64/sn/pda.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-ia64/sn/pda.h	Wed Jun 18 23:42:09 2003
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_PDA_H
 #define _ASM_IA64_SN_PDA_H
@@ -26,15 +26,6 @@
  * all SN per-cpu data structures. 
  */
 
-#ifdef BUS_INT_WAR
-#define POLL_ENTRIES	50
-typedef struct {
-	int	irq;
-	int	interval;
-	short	tick;
-} sn_poll_entry_t;
-#endif
-
 typedef struct pda_s {
 
 	/* Having a pointer in the begining of PDA tends to increase
@@ -48,31 +39,27 @@
 	/*
 	 * Support for SN LEDs
 	 */
-#ifdef CONFIG_IA64_SGI_SN1
-	volatile long	*led_address;
-#else
 	volatile short	*led_address;
-#endif
 	u8		led_state;
 	u8		hb_state;	/* supports blinking heartbeat leds */
+	u8		shub_1_1_found;
 	unsigned int	hb_count;
 
 	unsigned int	idle_flag;
 	
-#ifdef CONFIG_IA64_SGI_SN2
-	struct irqpda_s *p_irqpda;			/* Pointer to CPU irq data */
-#endif
 	volatile unsigned long *bedrock_rev_id;
 	volatile unsigned long *pio_write_status_addr;
 	volatile unsigned long *pio_shub_war_cam_addr;
 	volatile unsigned long *mem_write_status_addr;
 
-	bteinfo_t *cpu_bte_if[BTES_PER_NODE];	/* cpu interface order */
+	struct bteinfo_s *cpu_bte_if[BTES_PER_NODE];	/* cpu interface order */
 
-#ifdef BUS_INT_WAR
-	sn_poll_entry_t	pda_poll_entries[POLL_ENTRIES];
-	int		pda_poll_entry_count;
-#endif
+	unsigned long	sn_soft_irr[4];
+	unsigned long	sn_in_service_ivecs[4];
+	short		cnodeid_to_nasid_table[NR_NODES];	
+	int		sn_lb_int_war_ticks;
+	int		sn_last_irq;
+	int		sn_first_irq;
 } pda_t;
 
 
@@ -96,5 +83,9 @@
 
 #define pdacpu(cpu)	(&per_cpu(pda_percpu, cpu))
 
+/*
+ * Use this macro to test if shub 1.1 wars should be enabled
+ */
+#define enable_shub_wars_1_1()	(pda->shub_1_1_found)
 
 #endif /* _ASM_IA64_SN_PDA_H */
diff -Nru a/include/asm-ia64/sn/pio.h b/include/asm-ia64/sn/pio.h
--- a/include/asm-ia64/sn/pio.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/pio.h	Wed Jun 18 23:42:06 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_PIO_H
 #define _ASM_IA64_SN_PIO_H
@@ -32,19 +32,11 @@
 typedef struct piomap {
 	uint		pio_bus;
 	uint		pio_adap;
-#ifdef LATER
-	iospace_t	pio_iospace;
-#endif
 	int		pio_flag;
 	int		pio_reg;
 	char		pio_name[7];	/* to identify the mapped device */
 	struct piomap	*pio_next;	/* dlist to link active piomap's */
 	struct piomap	*pio_prev;	/* for debug and error reporting */
-#ifdef LATER
-	void		(*pio_errfunc)(); /* Pointer to an error function */
-					  /* Used only for piomaps allocated
-					   * in user level vme driver     */
-#endif
 	iopaddr_t	pio_iopmask;	/* valid iop address bit mask */
 	iobush_t	pio_bushandle;	/* bus-level handle */
 } piomap_t;
@@ -57,54 +49,6 @@
 /* Macro to get/set PIO error function */
 #define	pio_seterrf(p,f)	(p)->pio_errfunc = (f)
 #define	pio_geterrf(p)		(p)->pio_errfunc
-
-
-/*
- * pio_mapalloc() - allocates a handle that specifies a mapping from kernel
- *		    virtual to io space. The returned handle piomap is used
- *		    with the access functions to make sure that the mapping
- *		    to the iospace exists.
- * pio_mapfree()  - frees the mapping as specified in the piomap handle.
- * pio_mapaddr()  - returns the kv address that maps to piomap'ed io address.
- */
-#ifdef LATER
-extern piomap_t	*pio_mapalloc(uint,uint,iospace_t*,int,char*);
-extern void	 pio_mapfree(piomap_t*);
-extern caddr_t	 pio_mapaddr(piomap_t*,iopaddr_t);
-extern piomap_t *pio_ioaddr(int, iobush_t, iopaddr_t, piomap_t *);
-
-/*
- * PIO access functions.
- */
-extern int  pio_badaddr(piomap_t*,iopaddr_t,int);
-extern int  pio_badaddr_val(piomap_t*,iopaddr_t,int,void*);
-extern int  pio_wbadaddr(piomap_t*,iopaddr_t,int);
-extern int  pio_wbadaddr_val(piomap_t*,iopaddr_t,int,int);
-extern int  pio_bcopyin(piomap_t*,iopaddr_t,void *,int, int, int);
-extern int  pio_bcopyout(piomap_t*,iopaddr_t,void *,int, int, int);
-
-
-/*
- * PIO RMW functions using piomap.
- */
-extern void pio_orb_rmw(piomap_t*, iopaddr_t, unsigned char);
-extern void pio_orh_rmw(piomap_t*, iopaddr_t, unsigned short);
-extern void pio_orw_rmw(piomap_t*, iopaddr_t, unsigned long);
-extern void pio_andb_rmw(piomap_t*, iopaddr_t, unsigned char);
-extern void pio_andh_rmw(piomap_t*, iopaddr_t, unsigned short); 
-extern void pio_andw_rmw(piomap_t*, iopaddr_t, unsigned long); 
-
-
-/*
- * Old RMW function interface
- */
-extern void orb_rmw(volatile void*, unsigned int);
-extern void orh_rmw(volatile void*, unsigned int);
-extern void orw_rmw(volatile void*, unsigned int);
-extern void andb_rmw(volatile void*, unsigned int);
-extern void andh_rmw(volatile void*, unsigned int);
-extern void andw_rmw(volatile void*, unsigned int);
-#endif	/* LATER */
 
 
 /*
diff -Nru a/include/asm-ia64/sn/pio_flush.h b/include/asm-ia64/sn/pio_flush.h
--- a/include/asm-ia64/sn/pio_flush.h	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,65 +0,0 @@
-/*
- *
- * 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) 2001-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-#include <linux/config.h>
-
-#ifndef _ASM_IA64_PIO_FLUSH_H
-#define _ASM_IA64_PIO_FLUSH_H
-
-/*
- * This macro flushes all outstanding PIOs performed by this cpu to the 
- * intended destination SHUB.  This in essence ensures that all PIO's
- * issues by this cpu has landed at it's destination.
- *
- * This macro expects the caller:
- *	1.  The thread is locked.
- *	2.  All prior PIO operations has been fenced.
- *
- */
-
-#if defined (CONFIG_IA64_SGI_SN)
-
-#include <asm/sn/pda.h>
-
-#if defined (CONFIG_IA64_SGI_SN2)
-
-#define PIO_FLUSH() \
-	{ \
-	while ( !((volatile unsigned long) (*pda.pio_write_status_addr)) & 0x8000000000000000) { \
-			udelay(5); \
-	} \
-	__ia64_mf_a(); \
-	}
-
-#elif defined (CONFIG_IA64_SGI_SN1)
-
-/*
- * For SN1 we need to first read any local Bedrock's MMR and then poll on the 
- * Synergy MMR.
- */
-#define PIO_FLUSH() \
-	{ \
-	(volatile unsigned long) (*pda.bedrock_rev_id); \
-	while (!(volatile unsigned long) (*pda.pio_write_status_addr)) { \
-		udelay(5); \
-	} \
-	__ia64_mf_a(); \
-	} 
-#endif
-#else
-/*
- * For all ARCHITECTURE type, this is a NOOP.
- */
-
-#define PIO_FLUSH()
-
-#endif
-
-#endif /* _ASM_IA64_PIO_FLUSH_H */
diff -Nru a/include/asm-ia64/sn/prio.h b/include/asm-ia64/sn/prio.h
--- a/include/asm-ia64/sn/prio.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/sn/prio.h	Wed Jun 18 23:42:07 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_PRIO_H
 #define _ASM_IA64_SN_PRIO_H
diff -Nru a/include/asm-ia64/sn/router.h b/include/asm-ia64/sn/router.h
--- a/include/asm-ia64/sn/router.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/router.h	Wed Jun 18 23:42:06 2003
@@ -5,7 +5,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_ROUTER_H
@@ -494,7 +494,7 @@
 	slotid_t	ri_slotnum;	/* Which slot are we in?	    */
 	router_reg_t	ri_glbl_parms[GLBL_PARMS_REGS];
 					/* Global parms0&1 register contents*/
-	devfs_handle_t	ri_vertex;	/* hardware graph vertex            */
+	vertex_hdl_t	ri_vertex;	/* hardware graph vertex            */
 	router_reg_t	ri_prot_conf;	/* protection config. register	    */
 	int64_t	ri_per_minute;	/* Ticks per minute		    */
 
@@ -506,7 +506,7 @@
  	 * the bottom of the structure, below the user stuff.
 	 */
 	char		ri_hist_type;   /* histogram type		    */
-	devfs_handle_t	ri_guardian;	/* guardian node for the router	    */
+	vertex_hdl_t	ri_guardian;	/* guardian node for the router	    */
 	int64_t	ri_last_print;	/* When did we last print	    */
 	char		ri_print;	/* Should we print 		    */
 	char 		ri_just_blink;	/* Should we blink the LEDs         */
@@ -549,7 +549,7 @@
  * Router info hanging in the nodepda 
  */
 typedef struct nodepda_router_info_s {
-	devfs_handle_t 	router_vhdl;	/* vertex handle of the router 	    */
+	vertex_hdl_t 	router_vhdl;	/* vertex handle of the router 	    */
 	short		router_port;	/* port thru which we entered       */
 	short		router_portmask;
 	moduleid_t	router_module;	/* module in which router is there  */
@@ -593,9 +593,9 @@
 		 */
 		struct {
 			/* vertex handle for the router */
-			devfs_handle_t	vhdl;
+			vertex_hdl_t	vhdl;
 			/* guardian for this router */
-			devfs_handle_t	guard;	
+			vertex_hdl_t	guard;	
 			/* vector router from the guardian to the router */
 			net_vec_t	vec;
 		} k_elt;
@@ -648,8 +648,7 @@
 
 int router_reg_read(router_info_t *rip, int regno, router_reg_t *val);
 int router_reg_write(router_info_t *rip, int regno, router_reg_t val);
-int router_get_info(devfs_handle_t routerv, router_info_t *, int);
-int router_init(cnodeid_t cnode,int writeid, nodepda_router_info_t *npda_rip);
+int router_get_info(vertex_hdl_t routerv, router_info_t *, int);
 int router_set_leds(router_info_t *rip);
 void router_print_state(router_info_t *rip, int level,
 		   void (*pf)(int, char *, ...),int print_where);
@@ -658,7 +657,7 @@
 
 int 	probe_routers(void);
 void 	get_routername(unsigned char brd_type,char *rtrname);
-void 	router_guardians_set(devfs_handle_t hwgraph_root);
+void 	router_guardians_set(vertex_hdl_t hwgraph_root);
 int 	router_hist_reselect(router_info_t *, int64_t);
 #endif /* __ASSEMBLY__ */
 
diff -Nru a/include/asm-ia64/sn/sgi.h b/include/asm-ia64/sn/sgi.h
--- a/include/asm-ia64/sn/sgi.h	Wed Jun 18 23:42:05 2003
+++ b/include/asm-ia64/sn/sgi.h	Wed Jun 18 23:42:05 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -17,14 +17,15 @@
 #include <asm/uaccess.h>		/* for copy_??_user */
 #include <linux/mm.h>
 #include <linux/devfs_fs_kernel.h>
+#include <linux/fs.h>
+#include <asm/sn/hwgfs.h>
+
+typedef hwgfs_handle_t vertex_hdl_t;
 
 typedef int64_t  __psint_t;	/* needed by klgraph.c */
 
 typedef enum { B_FALSE, B_TRUE } boolean_t;
 
-#define ctob(x)			((uint64_t)(x)*NBPC)
-#define btoc(x)			(((uint64_t)(x)+(NBPC-1))/NBPC)
-
 
 /*
 ** Possible return values from graph routines.
@@ -50,28 +51,13 @@
 typedef uint64_t vhandl_t;
 
 
-#ifndef NBPP
-#define NBPP 4096
-#endif
-
-#ifndef D_MP
-#define D_MP 1
-#endif
+#define NBPP PAGE_SIZE
+#define _PAGESZ PAGE_SIZE
 
 #ifndef MAXDEVNAME
 #define MAXDEVNAME 256
 #endif
 
-#ifndef NBPC
-#define NBPC 0
-#endif
-
-#ifndef _PAGESZ
-#define _PAGESZ 4096
-#endif
-
-typedef uint64_t mrlock_t;	/* needed by devsupport.c */
-
 #define HUB_PIO_CONVEYOR 0x1
 #define CNODEID_NONE ((cnodeid_t)-1)
 #define XTALK_PCI_PART_NUM "030-1275-"
@@ -81,10 +67,6 @@
 #define COPYIN(a, b, c)		copy_from_user(b,a,c)
 #define COPYOUT(a, b, c)	copy_to_user(b,a,c)
 
-#define kvtophys(x)		(alenaddr_t) (x)
-#define POFFMASK		(NBPP - 1)
-#define poff(X)			((__psunsigned_t)(X) & POFFMASK)
-
 #define BZERO(a,b)		memset(a, 0, b)
 
 #define kern_malloc(x)		kmalloc(x, GFP_KERNEL)
@@ -141,12 +123,6 @@
 
 #define PRINT_PANIC		panic
 
-#ifdef CONFIG_SMP
-#define cpu_enabled(cpu)        (test_bit(cpu, &cpu_online_map))
-#else
-#define cpu_enabled(cpu)	(1)
-#endif
-
 /* print_register() defs */
 
 /*
@@ -172,6 +148,31 @@
 
 extern void print_register(unsigned long long, struct reg_desc *);
 
-#include <asm/sn/hack.h>	/* for now */
+/******************************************
+ * Definitions that do not exist in linux *
+ ******************************************/
+
+#define DELAY(a)
+
+/************************************************
+ * Routines redefined to use linux equivalents. *
+ ************************************************/
+
+/* #define FIXME(s) printk("FIXME: [ %s ] in %s at %s:%d\n", s, __FUNCTION__, __FILE__, __LINE__) */
+
+#define FIXME(s)
+
+/* move to stubs.c yet */
+#define dev_to_vhdl(dev) 0
+#define get_timestamp() 0
+#define us_delay(a)
+#define v_mapphys(a,b,c) 0    // printk("Fixme: v_mapphys - soft->base 0x%p\n", b);
+#define splhi()  0
+#define splx(s)
+
+extern void * snia_kmem_alloc_node(register size_t, register int, cnodeid_t);
+extern void * snia_kmem_zalloc(size_t, int);
+extern void * snia_kmem_zalloc_node(register size_t, register int, cnodeid_t );
+extern int is_specified(char *);
 
 #endif /* _ASM_IA64_SN_SGI_H */
diff -Nru a/include/asm-ia64/sn/simulator.h b/include/asm-ia64/sn/simulator.h
--- a/include/asm-ia64/sn/simulator.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-ia64/sn/simulator.h	Wed Jun 18 23:42:09 2003
@@ -5,7 +5,7 @@
  * 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) 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #include <linux/config.h>
diff -Nru a/include/asm-ia64/sn/slotnum.h b/include/asm-ia64/sn/slotnum.h
--- a/include/asm-ia64/sn/slotnum.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-ia64/sn/slotnum.h	Wed Jun 18 23:42:09 2003
@@ -4,23 +4,14 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_SLOTNUM_H
 #define _ASM_IA64_SN_SLOTNUM_H
 
-#include <linux/config.h>
 
 typedef	unsigned char slotid_t;
 
-#if defined (CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/slotnum.h>
-#elif defined (CONFIG_IA64_SGI_SN2)
 #include <asm/sn/sn2/slotnum.h>
-#else
-
-#error <<BOMB! slotnum defined only for SN0 and SN1 >>
-
-#endif /* !CONFIG_IA64_SGI_SN1 */
 
 #endif /* _ASM_IA64_SN_SLOTNUM_H */
diff -Nru a/include/asm-ia64/sn/sn1/addrs.h b/include/asm-ia64/sn/sn1/addrs.h
--- a/include/asm-ia64/sn/sn1/addrs.h	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,275 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_SN1_ADDRS_H
-#define _ASM_IA64_SN_SN1_ADDRS_H
-
-#include <linux/config.h>
-
-#ifdef CONFIG_IA64_SGI_SN1
-/*
- * SN1 (on a TRex) Address map
- *
- * This file contains a set of definitions and macros which are used
- * to reference into the major address spaces (CAC, HSPEC, IO, MSPEC,
- * and UNCAC) used by the SN1 architecture.  It also contains addresses
- * for "major" statically locatable PROM/Kernel data structures, such as
- * the partition table, the configuration data structure, etc.
- * We make an implicit assumption that the processor using this file
- * follows the R12K's provisions for specifying uncached attributes;
- * should this change, the base registers may very well become processor-
- * dependent.
- *
- * For more information on the address spaces, see the "Local Resources"
- * chapter of the Hub specification.
- *
- * NOTE: This header file is included both by C and by assembler source
- *	 files.  Please bracket any language-dependent definitions
- *	 appropriately.
- */
-
-
-/*
- * Some of the macros here need to be casted to appropriate types when used
- * from C.  They definitely must not be casted from assembly language so we
- * use some new ANSI preprocessor stuff to paste these on where needed.
- */
-
-#define CACHEABLE_MEM_SPACE     0xe000000000000000
-#define CAC_BASE		CACHEABLE_MEM_SPACE
-#define HSPEC_BASE              0xc0000b0000000000
-#define HSPEC_SWIZ_BASE         0xc000030000000000
-#define IO_BASE                 0xc0000a0000000000
-#define IO_SWIZ_BASE            0xc000020000000000
-#define MSPEC_BASE              0xc000090000000000
-#define UNCAC_BASE              0xc000000000000000
-#define TO_PHYS_MASK		0x000000ffffffffff
-
-#define TO_PHYS(x)		(	      ((x) & TO_PHYS_MASK))
-#define TO_CAC(x)		(CAC_BASE   | ((x) & TO_PHYS_MASK))
-#define TO_UNCAC(x)		(UNCAC_BASE | ((x) & TO_PHYS_MASK))
-#define TO_MSPEC(x)		(MSPEC_BASE | ((x) & TO_PHYS_MASK))
-#define TO_HSPEC(x)		(HSPEC_BASE | ((x) & TO_PHYS_MASK))
-
-
-/*
- * The following couple of definitions will eventually need to be variables,
- * since the amount of address space assigned to each node depends on
- * whether the system is running in N-mode (more nodes with less memory)
- * or M-mode (fewer nodes with more memory).  We expect that it will
- * be a while before we need to make this decision dynamically, though,
- * so for now we just use defines bracketed by an ifdef.
- */
-
-#if defined(N_MODE)
-
-#define NODE_SIZE_BITS		32
-#define BWIN_SIZE_BITS		28
-
-#define NASID_BITS		8
-#define NASID_BITMASK		(0xffLL)
-#define NASID_SHFT		32
-#define NASID_META_BITS		1
-#define NASID_LOCAL_BITS	7
-
-#define BDDIR_UPPER_MASK	(UINT64_CAST 0x1ffffff << 4)
-#define BDECC_UPPER_MASK	(UINT64_CAST 0x1fffffff )
-
-#else /* !defined(N_MODE), assume that M-mode is desired */
-
-#define NODE_SIZE_BITS		33
-#define BWIN_SIZE_BITS		29
-
-#define NASID_BITMASK		(0x7fLL)
-#define NASID_BITS		7
-#define NASID_SHFT		33
-#define NASID_META_BITS		0
-#define NASID_LOCAL_BITS	7
-
-#define BDDIR_UPPER_MASK	(UINT64_CAST 0x3ffffff << 4)
-#define BDECC_UPPER_MASK	(UINT64_CAST 0x3fffffff)
-
-#endif /* defined(N_MODE) */
-
-#define NODE_ADDRSPACE_SIZE	(UINT64_CAST 1 << NODE_SIZE_BITS)
-
-#define NASID_MASK		(UINT64_CAST NASID_BITMASK << NASID_SHFT)
-#define NASID_GET(_pa)		(int) ((UINT64_CAST (_pa) >>		\
-					NASID_SHFT) & NASID_BITMASK)
-
-#ifndef __ASSEMBLY__
-#define NODE_SWIN_BASE(nasid, widget)					\
-	((widget == 0) ? NODE_BWIN_BASE((nasid), SWIN0_BIGWIN)		\
-	: RAW_NODE_SWIN_BASE(nasid, widget))
-#else
-#define NODE_SWIN_BASE(nasid, widget) \
-     (NODE_IO_BASE(nasid) + (UINT64_CAST (widget) << SWIN_SIZE_BITS))
-#endif /* __ASSEMBLY__ */
-
-/*
- * The following definitions pertain to the IO special address
- * space.  They define the location of the big and little windows
- * of any given node.
- */
-
-#define BWIN_INDEX_BITS		3
-#define BWIN_SIZE		(UINT64_CAST 1 << BWIN_SIZE_BITS)
-#define	BWIN_SIZEMASK		(BWIN_SIZE - 1)
-#define	BWIN_WIDGET_MASK	0x7
-#define NODE_BWIN_BASE0(nasid)	(NODE_IO_BASE(nasid) + BWIN_SIZE)
-#define NODE_BWIN_BASE(nasid, bigwin)	(NODE_BWIN_BASE0(nasid) + 	\
-			(UINT64_CAST (bigwin) << BWIN_SIZE_BITS))
-
-#define	BWIN_WIDGETADDR(addr)	((addr) & BWIN_SIZEMASK)
-#define	BWIN_WINDOWNUM(addr)	(((addr) >> BWIN_SIZE_BITS) & BWIN_WIDGET_MASK)
-/*
- * Verify if addr belongs to large window address of node with "nasid"
- *
- *
- * NOTE: "addr" is expected to be XKPHYS address, and NOT physical
- * address
- *
- *
- */
-
-#define	NODE_BWIN_ADDR(nasid, addr)	\
-		(((addr) >= NODE_BWIN_BASE0(nasid)) && \
-		 ((addr) < (NODE_BWIN_BASE(nasid, HUB_NUM_BIG_WINDOW) + \
-				BWIN_SIZE)))
-
-/*
- * The following define the major position-independent aliases used
- * in SN1.
- *	CALIAS -- Varies in size, points to the first n bytes of memory
- *		  	on the reader's node.
- */
-
-#define CALIAS_BASE		CAC_BASE
-
-
-
-#define BRIDGE_REG_PTR(_base, _off)	((volatile bridgereg_t *) \
-	((__psunsigned_t)(_base) + (__psunsigned_t)(_off)))
-
-#define SN0_WIDGET_BASE(_nasid, _wid)	(NODE_SWIN_BASE((_nasid), (_wid)))
-
-
-
-/*
- * needed by symmon so it needs to be outside #if PROM
- * (see also POD_ELSCSIZE)
- */
-#define IP27PROM_ELSC_BASE_A	PHYS_TO_K0(0x020e0000)
-#define IP27PROM_ELSC_BASE_B	PHYS_TO_K0(0x020e0800)
-#define IP27PROM_ELSC_BASE_C	PHYS_TO_K0(0x020e1000)
-#define IP27PROM_ELSC_BASE_D	PHYS_TO_K0(0x020e1800)
-#define IP27PROM_ELSC_SHFT	11
-#define IP27PROM_ELSC_SIZE	(1 << IP27PROM_ELSC_SHFT)
-
-#define FREEMEM_BASE		PHYS_TO_K0(0x4000000)
-
-#define IO6PROM_STACK_SHFT	14	/* stack per cpu */
-#define IO6PROM_STACK_SIZE	(1 << IO6PROM_STACK_SHFT)
-
-
-#define KL_UART_BASE	LOCAL_HSPEC(HSPEC_UART_0)	/* base of UART regs */
-#define KL_UART_CMD	LOCAL_HSPEC(HSPEC_UART_0)	/* UART command reg */
-#define KL_UART_DATA	LOCAL_HSPEC(HSPEC_UART_1)	/* UART data reg */
-
-#if !__ASSEMBLY__
-/* Address 0x400 to 0x1000 ualias points to cache error eframe + misc
- * CACHE_ERR_SP_PTR could either contain an address to the stack, or
- * the stack could start at CACHE_ERR_SP_PTR
- */
-#define CACHE_ERR_EFRAME	0x400
-
-#define CACHE_ERR_ECCFRAME	(CACHE_ERR_EFRAME + EF_SIZE)
-#define CACHE_ERR_SP_PTR	(0x1000 - 32)	/* why -32? TBD */
-#define CACHE_ERR_IBASE_PTR	(0x1000 - 40)
-#define CACHE_ERR_SP		(CACHE_ERR_SP_PTR - 16)
-#define CACHE_ERR_AREA_SIZE	(ARCS_SPB_OFFSET - CACHE_ERR_EFRAME)
-
-#endif	/* !__ASSEMBLY__ */
-
-
-
-#define _ARCSPROM
-
-#ifdef _STANDALONE
-
-/*
- * The PROM needs to pass the device base address and the
- * device pci cfg space address to the device drivers during
- * install. The COMPONENT->Key field is used for this purpose.
- * Macros needed by SN1 device drivers to convert the
- * COMPONENT->Key field to the respective base address.
- * Key field looks as follows:
- *
- *  +----------------------------------------------------+
- *  |devnasid | widget  |pciid |hubwidid|hstnasid | adap |
- *  |   2     |   1     |  1   |   1    |    2    |   1  |
- *  +----------------------------------------------------+
- *  |         |         |      |        |         |      |
- *  64        48        40     32       24        8      0
- *
- * These are used by standalone drivers till the io infrastructure
- * is in place.
- */
-
-#ifndef __ASSEMBLY__
-
-#define uchar unsigned char
-
-#define KEY_DEVNASID_SHFT  48
-#define KEY_WIDID_SHFT	   40
-#define KEY_PCIID_SHFT	   32
-#define KEY_HUBWID_SHFT	   24
-#define KEY_HSTNASID_SHFT  8
-
-#define MK_SN0_KEY(nasid, widid, pciid) \
-			((((__psunsigned_t)nasid)<< KEY_DEVNASID_SHFT |\
-				((__psunsigned_t)widid) << KEY_WIDID_SHFT) |\
-				((__psunsigned_t)pciid) << KEY_PCIID_SHFT)
-
-#define ADD_HUBWID_KEY(key,hubwid)\
-			(key|=((__psunsigned_t)hubwid << KEY_HUBWID_SHFT))
-
-#define ADD_HSTNASID_KEY(key,hstnasid)\
-			(key|=((__psunsigned_t)hstnasid << KEY_HSTNASID_SHFT))
-
-#define GET_DEVNASID_FROM_KEY(key)	((short)(key >> KEY_DEVNASID_SHFT))
-#define GET_WIDID_FROM_KEY(key)		((uchar)(key >> KEY_WIDID_SHFT))
-#define GET_PCIID_FROM_KEY(key)		((uchar)(key >> KEY_PCIID_SHFT))
-#define GET_HUBWID_FROM_KEY(key)	((uchar)(key >> KEY_HUBWID_SHFT))
-#define GET_HSTNASID_FROM_KEY(key)	((short)(key >> KEY_HSTNASID_SHFT))
-
-#define PCI_64_TARGID_SHFT		60
-
-#define GET_PCIBASE_FROM_KEY(key)  (NODE_SWIN_BASE(GET_DEVNASID_FROM_KEY(key),\
-					GET_WIDID_FROM_KEY(key))\
-					| BRIDGE_DEVIO(GET_PCIID_FROM_KEY(key)))
-
-#define GET_PCICFGBASE_FROM_KEY(key) \
-			(NODE_SWIN_BASE(GET_DEVNASID_FROM_KEY(key),\
-			      GET_WIDID_FROM_KEY(key))\
-			| BRIDGE_TYPE0_CFG_DEV(GET_PCIID_FROM_KEY(key)))
-
-#define GET_WIDBASE_FROM_KEY(key) \
-                        (NODE_SWIN_BASE(GET_DEVNASID_FROM_KEY(key),\
-                              GET_WIDID_FROM_KEY(key)))
-
-#define PUT_INSTALL_STATUS(c,s)		c->Revision = s
-#define GET_INSTALL_STATUS(c)		c->Revision
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _STANDALONE */
-#endif /* CONFIG_IA64_SGI_SN1 */
-
-#endif /* _ASM_IA64_SN_SN1_ADDRS_H */
diff -Nru a/include/asm-ia64/sn/sn1/arch.h b/include/asm-ia64/sn/sn1/arch.h
--- a/include/asm-ia64/sn/sn1/arch.h	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,89 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_ARCH_H
-#define _ASM_IA64_SN_SN1_ARCH_H
-
-#if defined(N_MODE)
-#error "ERROR constants defined only for M-mode"
-#endif
-
-#include <linux/threads.h>
-#include <asm/types.h>
-
-#define CPUS_PER_NODE           4       /* CPUs on a single hub */
-#define CPUS_PER_SUBNODE        2       /* CPUs on a single hub PI */
-
-/*
- * This is the maximum number of NASIDS that can be present in a system.
- * This include ALL nodes in ALL partitions connected via NUMALINK.
- * (Highest NASID plus one.)
- */
-#define MAX_NASIDS              128
-
-/*
- * This is the maximum number of nodes that can be part of a kernel.
- * Effectively, it's the maximum number of compact node ids (cnodeid_t).
- * This is not necessarily the same as MAX_NASIDS.
- */
-#define MAX_COMPACT_NODES       128
-
-/*
- * MAX_REGIONS refers to the maximum number of hardware partitioned regions.
- */
-#define	MAX_REGIONS		64
-#define MAX_NONPREMIUM_REGIONS  16
-#define MAX_PREMIUM_REGIONS     MAX_REGIONS
-
-/*
- * Slot constants for IP35
- */
-
-#define MAX_MEM_SLOTS    8                     /* max slots per node */
-
-#if defined(N_MODE)
-#error "N-mode not supported"
-#endif
-
-#define SLOT_SHIFT              (30)
-#define SLOT_MIN_MEM_SIZE       (64*1024*1024)
-
-
-/*
- * MAX_PARITIONS refers to the maximum number of logically defined 
- * partitions the system can support.
- */
-#define MAX_PARTITIONS		MAX_REGIONS
-
-
-#define NASID_MASK_BYTES	((MAX_NASIDS + 7) / 8)
-
-/*
- * New stuff in here from Irix sys/pfdat.h.
- */
-#define SLOT_PFNSHIFT           (SLOT_SHIFT - PAGE_SHIFT)
-#define PFN_NASIDSHFT           (NASID_SHFT - PAGE_SHIFT)
-#define slot_getbasepfn(node,slot)  (mkpfn(COMPACT_TO_NASID_NODEID(node), slot<<SLOT_PFNSHIFT))
-#define mkpfn(nasid, off)       (((pfn_t)(nasid) << PFN_NASIDSHFT) | (off))
-
-
-
-/*
- * two PIs per bedrock, two CPUs per PI
- */
-#define NUM_SUBNODES	2
-#define SUBNODE_SHFT	1
-#define SUBNODE_MASK	(0x1 << SUBNODE_SHFT)
-#define LOCALCPU_SHFT	0
-#define LOCALCPU_MASK	(0x1 << LOCALCPU_SHFT)
-#define SUBNODE(slice)	(((slice) & SUBNODE_MASK) >> SUBNODE_SHFT)
-#define LOCALCPU(slice)	(((slice) & LOCALCPU_MASK) >> LOCALCPU_SHFT)
-#define TO_SLICE(subn, local)	(((subn) << SUBNODE_SHFT) | \
-				 ((local) << LOCALCPU_SHFT))
-
-#endif /* _ASM_IA64_SN_SN1_ARCH_H */
diff -Nru a/include/asm-ia64/sn/sn1/bedrock.h b/include/asm-ia64/sn/sn1/bedrock.h
--- a/include/asm-ia64/sn/sn1/bedrock.h	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,74 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_SN1_BEDROCK_H
-#define _ASM_IA64_SN_SN1_BEDROCK_H
-
-
-/* The secret password; used to release protection */
-#define HUB_PASSWORD		0x53474972756c6573ull
-
-#define CHIPID_HUB		0x3012
-#define CHIPID_ROUTER		0x3017
-
-#define BEDROCK_REV_1_0		1
-#define BEDROCK_REV_1_1		2
-
-#define MAX_HUB_PATH		80
-
-#include <asm/sn/arch.h>
-#include <asm/sn/sn1/addrs.h>
-#include <asm/sn/sn1/hubpi.h>
-#include <asm/sn/sn1/hubmd.h>
-#include <asm/sn/sn1/hubio.h>
-#include <asm/sn/sn1/hubni.h>
-#include <asm/sn/sn1/hublb.h>
-#include <asm/sn/sn1/hubxb.h>
-#include <asm/sn/sn1/hubpi_next.h>
-#include <asm/sn/sn1/hubmd_next.h>
-#include <asm/sn/sn1/hubio_next.h>
-#include <asm/sn/sn1/hubni_next.h>
-#include <asm/sn/sn1/hublb_next.h>
-#include <asm/sn/sn1/hubxb_next.h>
-
-/* Translation of uncached attributes */
-#define	UATTR_HSPEC	0
-#define	UATTR_IO	1
-#define	UATTR_MSPEC	2
-#define	UATTR_UNCAC	3
-
-#if __ASSEMBLY__
-
-/*
- * Get nasid into register, r (uses at)
- */
-#define GET_NASID_ASM(r)				\
-	dli	r, LOCAL_HUB_ADDR(LB_REV_ID);	\
-	ld	r, (r);					\
-	and	r, LRI_NODEID_MASK;			\
-	dsrl	r, LRI_NODEID_SHFT
-
-#endif /* __ASSEMBLY__ */
-
-#ifndef __ASSEMBLY__
-
-#include <asm/sn/xtalk/xwidget.h>
-
-/* hub-as-widget iograph info, labelled by INFO_LBL_XWIDGET */
-typedef struct v_hub_s *v_hub_t;
-typedef uint64_t      rtc_time_t;
-
-struct nodepda_s;
-int hub_check_pci_equiv(void *addra, void *addrb);
-void capture_hub_stats(cnodeid_t, struct nodepda_s *);
-void init_hub_stats(cnodeid_t, struct nodepda_s *);
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _ASM_IA64_SN_SN1_BEDROCK_H */
diff -Nru a/include/asm-ia64/sn/sn1/hubdev.h b/include/asm-ia64/sn/sn1/hubdev.h
--- a/include/asm-ia64/sn/sn1/hubdev.h	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,21 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_SN1_HUBDEV_H
-#define _ASM_IA64_SN_SN1_HUBDEV_H
-
-extern void hubdev_init(void);
-extern void hubdev_register(int (*attach_method)(devfs_handle_t));
-extern int hubdev_unregister(int (*attach_method)(devfs_handle_t));
-extern int hubdev_docallouts(devfs_handle_t hub);
-
-extern caddr_t hubdev_prombase_get(devfs_handle_t hub);
-extern cnodeid_t hubdev_cnodeid_get(devfs_handle_t hub);
-
-#endif /* _ASM_IA64_SN_SN1_HUBDEV_H */
diff -Nru a/include/asm-ia64/sn/sn1/hubio.h b/include/asm-ia64/sn/sn1/hubio.h
--- a/include/asm-ia64/sn/sn1/hubio.h	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,5016 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-
-/************************************************************************
- *                                                                      *
- *      WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!      *
- *                                                                      *
- * This file is created by an automated script. Any (minimal) changes   *
- * made manually to this  file should be made with care.                *
- *                                                                      *
- *               MAKE ALL ADDITIONS TO THE END OF THIS FILE             *
- *                                                                      *
- ************************************************************************/
-
-
-#ifndef _ASM_IA64_SN_SN1_HUBIO_H
-#define _ASM_IA64_SN_SN1_HUBIO_H
-
-
-#define    IIO_WID                   0x00400000    /*
-                                                    * Crosstalk Widget
-                                                    * Identification This
-                                                    * register is also
-                                                    * accessible from
-                                                    * Crosstalk at
-                                                    * address 0x0.
-                                                    */
-
-
-
-#define    IIO_WSTAT                 0x00400008    /*
-                                                    * Crosstalk Widget
-                                                    * Status
-                                                    */
-
-
-
-#define    IIO_WCR                   0x00400020    /*
-                                                    * Crosstalk Widget
-                                                    * Control Register
-                                                    */
-
-
-
-#define    IIO_ILAPR                 0x00400100    /*
-                                                    * IO Local Access
-                                                    * Protection Register
-                                                    */
-
-
-
-#define    IIO_ILAPO                 0x00400108    /*
-                                                    * IO Local Access
-                                                    * Protection Override
-                                                    */
-
-
-
-#define    IIO_IOWA                  0x00400110    /*
-                                                    * IO Outbound Widget
-                                                    * Access
-                                                    */
-
-
-
-#define    IIO_IIWA                  0x00400118    /*
-                                                    * IO Inbound Widget
-                                                    * Access
-                                                    */
-
-
-
-#define    IIO_IIDEM                 0x00400120    /*
-                                                    * IO Inbound Device
-                                                    * Error Mask
-                                                    */
-
-
-
-#define    IIO_ILCSR                 0x00400128    /*
-                                                    * IO LLP Control and
-                                                    * Status Register
-                                                    */
-
-
-
-#define    IIO_ILLR                  0x00400130    /* IO LLP Log Register    */
-
-
-
-#define    IIO_IIDSR                 0x00400138    /*
-                                                    * IO Interrupt
-                                                    * Destination
-                                                    */
-
-
-
-#define    IIO_IGFX0                 0x00400140    /*
-                                                    * IO Graphics
-                                                    * Node-Widget Map 0
-                                                    */
-
-
-
-#define    IIO_IGFX1                 0x00400148    /*
-                                                    * IO Graphics
-                                                    * Node-Widget Map 1
-                                                    */
-
-
-
-#define    IIO_ISCR0                 0x00400150    /*
-                                                    * IO Scratch Register
-                                                    * 0
-                                                    */
-
-
-
-#define    IIO_ISCR1                 0x00400158    /*
-                                                    * IO Scratch Register
-                                                    * 1
-                                                    */
-
-
-
-#define    IIO_ITTE1                 0x00400160    /*
-                                                    * IO Translation
-                                                    * Table Entry 1
-                                                    */
-
-
-
-#define    IIO_ITTE2                 0x00400168    /*
-                                                    * IO Translation
-                                                    * Table Entry 2
-                                                    */
-
-
-
-#define    IIO_ITTE3                 0x00400170    /*
-                                                    * IO Translation
-                                                    * Table Entry 3
-                                                    */
-
-
-
-#define    IIO_ITTE4                 0x00400178    /*
-                                                    * IO Translation
-                                                    * Table Entry 4
-                                                    */
-
-
-
-#define    IIO_ITTE5                 0x00400180    /*
-                                                    * IO Translation
-                                                    * Table Entry 5
-                                                    */
-
-
-
-#define    IIO_ITTE6                 0x00400188    /*
-                                                    * IO Translation
-                                                    * Table Entry 6
-                                                    */
-
-
-
-#define    IIO_ITTE7                 0x00400190    /*
-                                                    * IO Translation
-                                                    * Table Entry 7
-                                                    */
-
-
-
-#define    IIO_IPRB0                 0x00400198    /* IO PRB Entry 0         */
-
-
-
-#define    IIO_IPRB8                 0x004001A0    /* IO PRB Entry 8         */
-
-
-
-#define    IIO_IPRB9                 0x004001A8    /* IO PRB Entry 9         */
-
-
-
-#define    IIO_IPRBA                 0x004001B0    /* IO PRB Entry A         */
-
-
-
-#define    IIO_IPRBB                 0x004001B8    /* IO PRB Entry B         */
-
-
-
-#define    IIO_IPRBC                 0x004001C0    /* IO PRB Entry C         */
-
-
-
-#define    IIO_IPRBD                 0x004001C8    /* IO PRB Entry D         */
-
-
-
-#define    IIO_IPRBE                 0x004001D0    /* IO PRB Entry E         */
-
-
-
-#define    IIO_IPRBF                 0x004001D8    /* IO PRB Entry F         */
-
-
-
-#define    IIO_IXCC                  0x004001E0    /*
-                                                    * IO Crosstalk Credit
-                                                    * Count Timeout
-                                                    */
-
-
-
-#define    IIO_IMEM                  0x004001E8    /*
-                                                    * IO Miscellaneous
-                                                    * Error Mask
-                                                    */
-
-
-
-#define    IIO_IXTT                  0x004001F0    /*
-                                                    * IO Crosstalk
-                                                    * Timeout Threshold
-                                                    */
-
-
-
-#define    IIO_IECLR                 0x004001F8    /*
-                                                    * IO Error Clear
-                                                    * Register
-                                                    */
-
-
-
-#define    IIO_IBCR                  0x00400200    /*
-                                                    * IO BTE Control
-                                                    * Register
-                                                    */
-
-
-
-#define    IIO_IXSM                  0x00400208    /*
-                                                    * IO Crosstalk
-                                                    * Spurious Message
-                                                    */
-
-
-
-#define    IIO_IXSS                  0x00400210    /*
-                                                    * IO Crosstalk
-                                                    * Spurious Sideband
-                                                    */
-
-
-
-#define    IIO_ILCT                  0x00400218    /* IO LLP Channel Test    */
-
-
-
-#define    IIO_IIEPH1                0x00400220    /*
-                                                    * IO Incoming Error
-                                                    * Packet Header, Part
-                                                    * 1
-                                                    */
-
-
-
-#define    IIO_IIEPH2                0x00400228    /*
-                                                    * IO Incoming Error
-                                                    * Packet Header, Part
-                                                    * 2
-                                                    */
-
-
-
-#define    IIO_IPCA                  0x00400300    /*
-                                                    * IO PRB Counter
-                                                    * Adjust
-                                                    */
-
-
-
-#define    IIO_IPRTE0                0x00400308    /*
-                                                    * IO PIO Read Address
-                                                    * Table Entry 0
-                                                    */
-
-
-
-#define    IIO_IPRTE1                0x00400310    /*
-                                                    * IO PIO Read Address
-                                                    * Table Entry 1
-                                                    */
-
-
-
-#define    IIO_IPRTE2                0x00400318    /*
-                                                    * IO PIO Read Address
-                                                    * Table Entry 2
-                                                    */
-
-
-
-#define    IIO_IPRTE3                0x00400320    /*
-                                                    * IO PIO Read Address
-                                                    * Table Entry 3
-                                                    */
-
-
-
-#define    IIO_IPRTE4                0x00400328    /*
-                                                    * IO PIO Read Address
-                                                    * Table Entry 4
-                                                    */
-
-
-
-#define    IIO_IPRTE5                0x00400330    /*
-                                                    * IO PIO Read Address
-                                                    * Table Entry 5
-                                                    */
-
-
-
-#define    IIO_IPRTE6                0x00400338    /*
-                                                    * IO PIO Read Address
-                                                    * Table Entry 6
-                                                    */
-
-
-
-#define    IIO_IPRTE7                0x00400340    /*
-                                                    * IO PIO Read Address
-                                                    * Table Entry 7
-                                                    */
-
-
-
-#define    IIO_IPDR                  0x00400388    /*
-                                                    * IO PIO Deallocation
-                                                    * Register
-                                                    */
-
-
-
-#define    IIO_ICDR                  0x00400390    /*
-                                                    * IO CRB Entry
-                                                    * Deallocation
-                                                    * Register
-                                                    */
-
-
-
-#define    IIO_IFDR                  0x00400398    /*
-                                                    * IO IOQ FIFO Depth
-                                                    * Register
-                                                    */
-
-
-
-#define    IIO_IIAP                  0x004003A0    /*
-                                                    * IO IIQ Arbitration
-                                                    * Parameters
-                                                    */
-
-
-
-#define    IIO_ICMR                  0x004003A8    /*
-                                                    * IO CRB Management
-                                                    * Register
-                                                    */
-
-
-
-#define    IIO_ICCR                  0x004003B0    /*
-                                                    * IO CRB Control
-                                                    * Register
-                                                    */
-
-
-
-#define    IIO_ICTO                  0x004003B8    /* IO CRB Timeout         */
-
-
-
-#define    IIO_ICTP                  0x004003C0    /*
-                                                    * IO CRB Timeout
-                                                    * Prescalar
-                                                    */
-
-
-
-#define    IIO_ICRB0_A               0x00400400    /* IO CRB Entry 0_A       */
-
-
-
-#define    IIO_ICRB0_B               0x00400408    /* IO CRB Entry 0_B       */
-
-
-
-#define    IIO_ICRB0_C               0x00400410    /* IO CRB Entry 0_C       */
-
-
-
-#define    IIO_ICRB0_D               0x00400418    /* IO CRB Entry 0_D       */
-
-
-
-#define    IIO_ICRB1_A               0x00400420    /* IO CRB Entry 1_A       */
-
-
-
-#define    IIO_ICRB1_B               0x00400428    /* IO CRB Entry 1_B       */
-
-
-
-#define    IIO_ICRB1_C               0x00400430    /* IO CRB Entry 1_C       */
-
-
-
-#define    IIO_ICRB1_D               0x00400438    /* IO CRB Entry 1_D       */
-
-
-
-#define    IIO_ICRB2_A               0x00400440    /* IO CRB Entry 2_A       */
-
-
-
-#define    IIO_ICRB2_B               0x00400448    /* IO CRB Entry 2_B       */
-
-
-
-#define    IIO_ICRB2_C               0x00400450    /* IO CRB Entry 2_C       */
-
-
-
-#define    IIO_ICRB2_D               0x00400458    /* IO CRB Entry 2_D       */
-
-
-
-#define    IIO_ICRB3_A               0x00400460    /* IO CRB Entry 3_A       */
-
-
-
-#define    IIO_ICRB3_B               0x00400468    /* IO CRB Entry 3_B       */
-
-
-
-#define    IIO_ICRB3_C               0x00400470    /* IO CRB Entry 3_C       */
-
-
-
-#define    IIO_ICRB3_D               0x00400478    /* IO CRB Entry 3_D       */
-
-
-
-#define    IIO_ICRB4_A               0x00400480    /* IO CRB Entry 4_A       */
-
-
-
-#define    IIO_ICRB4_B               0x00400488    /* IO CRB Entry 4_B       */
-
-
-
-#define    IIO_ICRB4_C               0x00400490    /* IO CRB Entry 4_C       */
-
-
-
-#define    IIO_ICRB4_D               0x00400498    /* IO CRB Entry 4_D       */
-
-
-
-#define    IIO_ICRB5_A               0x004004A0    /* IO CRB Entry 5_A       */
-
-
-
-#define    IIO_ICRB5_B               0x004004A8    /* IO CRB Entry 5_B       */
-
-
-
-#define    IIO_ICRB5_C               0x004004B0    /* IO CRB Entry 5_C       */
-
-
-
-#define    IIO_ICRB5_D               0x004004B8    /* IO CRB Entry 5_D       */
-
-
-
-#define    IIO_ICRB6_A               0x004004C0    /* IO CRB Entry 6_A       */
-
-
-
-#define    IIO_ICRB6_B               0x004004C8    /* IO CRB Entry 6_B       */
-
-
-
-#define    IIO_ICRB6_C               0x004004D0    /* IO CRB Entry 6_C       */
-
-
-
-#define    IIO_ICRB6_D               0x004004D8    /* IO CRB Entry 6_D       */
-
-
-
-#define    IIO_ICRB7_A               0x004004E0    /* IO CRB Entry 7_A       */
-
-
-
-#define    IIO_ICRB7_B               0x004004E8    /* IO CRB Entry 7_B       */
-
-
-
-#define    IIO_ICRB7_C               0x004004F0    /* IO CRB Entry 7_C       */
-
-
-
-#define    IIO_ICRB7_D               0x004004F8    /* IO CRB Entry 7_D       */
-
-
-
-#define    IIO_ICRB8_A               0x00400500    /* IO CRB Entry 8_A       */
-
-
-
-#define    IIO_ICRB8_B               0x00400508    /* IO CRB Entry 8_B       */
-
-
-
-#define    IIO_ICRB8_C               0x00400510    /* IO CRB Entry 8_C       */
-
-
-
-#define    IIO_ICRB8_D               0x00400518    /* IO CRB Entry 8_D       */
-
-
-
-#define    IIO_ICRB9_A               0x00400520    /* IO CRB Entry 9_A       */
-
-
-
-#define    IIO_ICRB9_B               0x00400528    /* IO CRB Entry 9_B       */
-
-
-
-#define    IIO_ICRB9_C               0x00400530    /* IO CRB Entry 9_C       */
-
-
-
-#define    IIO_ICRB9_D               0x00400538    /* IO CRB Entry 9_D       */
-
-
-
-#define    IIO_ICRBA_A               0x00400540    /* IO CRB Entry A_A       */
-
-
-
-#define    IIO_ICRBA_B               0x00400548    /* IO CRB Entry A_B       */
-
-
-
-#define    IIO_ICRBA_C               0x00400550    /* IO CRB Entry A_C       */
-
-
-
-#define    IIO_ICRBA_D               0x00400558    /* IO CRB Entry A_D       */
-
-
-
-#define    IIO_ICRBB_A               0x00400560    /* IO CRB Entry B_A       */
-
-
-
-#define    IIO_ICRBB_B               0x00400568    /* IO CRB Entry B_B       */
-
-
-
-#define    IIO_ICRBB_C               0x00400570    /* IO CRB Entry B_C       */
-
-
-
-#define    IIO_ICRBB_D               0x00400578    /* IO CRB Entry B_D       */
-
-
-
-#define    IIO_ICRBC_A               0x00400580    /* IO CRB Entry C_A       */
-
-
-
-#define    IIO_ICRBC_B               0x00400588    /* IO CRB Entry C_B       */
-
-
-
-#define    IIO_ICRBC_C               0x00400590    /* IO CRB Entry C_C       */
-
-
-
-#define    IIO_ICRBC_D               0x00400598    /* IO CRB Entry C_D       */
-
-
-
-#define    IIO_ICRBD_A               0x004005A0    /* IO CRB Entry D_A       */
-
-
-
-#define    IIO_ICRBD_B               0x004005A8    /* IO CRB Entry D_B       */
-
-
-
-#define    IIO_ICRBD_C               0x004005B0    /* IO CRB Entry D_C       */
-
-
-
-#define    IIO_ICRBD_D               0x004005B8    /* IO CRB Entry D_D       */
-
-
-
-#define    IIO_ICRBE_A               0x004005C0    /* IO CRB Entry E_A       */
-
-
-
-#define    IIO_ICRBE_B               0x004005C8    /* IO CRB Entry E_B       */
-
-
-
-#define    IIO_ICRBE_C               0x004005D0    /* IO CRB Entry E_C       */
-
-
-
-#define    IIO_ICRBE_D               0x004005D8    /* IO CRB Entry E_D       */
-
-
-
-#define    IIO_ICSML                 0x00400600    /*
-                                                    * IO CRB Spurious
-                                                    * Message Low
-                                                    */
-
-
-
-#define    IIO_ICSMH                 0x00400608    /*
-                                                    * IO CRB Spurious
-                                                    * Message High
-                                                    */
-
-
-
-#define    IIO_IDBSS                 0x00400610    /*
-                                                    * IO Debug Submenu
-                                                    * Select
-                                                    */
-
-
-
-#define    IIO_IBLS0                 0x00410000    /*
-                                                    * IO BTE Length
-                                                    * Status 0
-                                                    */
-
-
-
-#define    IIO_IBSA0                 0x00410008    /*
-                                                    * IO BTE Source
-                                                    * Address 0
-                                                    */
-
-
-
-#define    IIO_IBDA0                 0x00410010    /*
-                                                    * IO BTE Destination
-                                                    * Address 0
-                                                    */
-
-
-
-#define    IIO_IBCT0                 0x00410018    /*
-                                                    * IO BTE Control
-                                                    * Terminate 0
-                                                    */
-
-
-
-#define    IIO_IBNA0                 0x00410020    /*
-                                                    * IO BTE Notification
-                                                    * Address 0
-                                                    */
-
-
-
-#define    IIO_IBIA0                 0x00410028    /*
-                                                    * IO BTE Interrupt
-                                                    * Address 0
-                                                    */
-
-
-
-#define    IIO_IBLS1                 0x00420000    /*
-                                                    * IO BTE Length
-                                                    * Status 1
-                                                    */
-
-
-
-#define    IIO_IBSA1                 0x00420008    /*
-                                                    * IO BTE Source
-                                                    * Address 1
-                                                    */
-
-
-
-#define    IIO_IBDA1                 0x00420010    /*
-                                                    * IO BTE Destination
-                                                    * Address 1
-                                                    */
-
-
-
-#define    IIO_IBCT1                 0x00420018    /*
-                                                    * IO BTE Control
-                                                    * Terminate 1
-                                                    */
-
-
-
-#define    IIO_IBNA1                 0x00420020    /*
-                                                    * IO BTE Notification
-                                                    * Address 1
-                                                    */
-
-
-
-#define    IIO_IBIA1                 0x00420028    /*
-                                                    * IO BTE Interrupt
-                                                    * Address 1
-                                                    */
-
-
-
-#define    IIO_IPCR                  0x00430000    /*
-                                                    * IO Performance
-                                                    * Control
-                                                    */
-
-
-
-#define    IIO_IPPR                  0x00430008    /*
-                                                    * IO Performance
-                                                    * Profiling
-                                                    */
-
-
-
-
-
-#ifndef __ASSEMBLY__
-
-/************************************************************************
- *                                                                      *
- * Description:  This register echoes some information from the         *
- * LB_REV_ID register. It is available through Crosstalk as described   *
- * above. The REV_NUM and MFG_NUM fields receive their values from      *
- * the REVISION and MANUFACTURER fields in the LB_REV_ID register.      *
- * The PART_NUM field's value is the Crosstalk device ID number that    *
- * Steve Miller assigned to the Bedrock chip.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_wid_u {
-	bdrkreg_t	ii_wid_regval;
-	struct	{
-		bdrkreg_t	w_rsvd_1		  :	 1;
-		bdrkreg_t	w_mfg_num		  :	11;
-		bdrkreg_t	w_part_num		  :	16;
-		bdrkreg_t	w_rev_num		  :	 4;
-		bdrkreg_t	w_rsvd			  :	32;
-	} ii_wid_fld_s;
-} ii_wid_u_t;
-
-#else
-
-typedef union ii_wid_u {
-	bdrkreg_t	ii_wid_regval;
-	struct  {
-		bdrkreg_t	w_rsvd                    :	32;
-		bdrkreg_t	w_rev_num                 :	 4;
-		bdrkreg_t	w_part_num                :	16;
-		bdrkreg_t	w_mfg_num                 :	11;
-		bdrkreg_t	w_rsvd_1                  :	 1;
-	} ii_wid_fld_s;
-} ii_wid_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  The fields in this register are set upon detection of an error      *
- * and cleared by various mechanisms, as explained in the               *
- * description.                                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_wstat_u {
-	bdrkreg_t	ii_wstat_regval;
-	struct	{
-		bdrkreg_t	w_pending		  :	 4;
-		bdrkreg_t	w_xt_crd_to		  :	 1;
-		bdrkreg_t	w_xt_tail_to		  :	 1;
-		bdrkreg_t	w_rsvd_3		  :	 3;
-		bdrkreg_t       w_tx_mx_rty               :      1;
-		bdrkreg_t	w_rsvd_2		  :	 6;
-		bdrkreg_t	w_llp_tx_cnt		  :	 8;
-		bdrkreg_t	w_rsvd_1		  :	 8;
-		bdrkreg_t	w_crazy			  :	 1;
-		bdrkreg_t	w_rsvd			  :	31;
-	} ii_wstat_fld_s;
-} ii_wstat_u_t;
-
-#else
-
-typedef union ii_wstat_u {
-	bdrkreg_t	ii_wstat_regval;
-	struct  {
-		bdrkreg_t	w_rsvd                    :	31;
-		bdrkreg_t	w_crazy                   :	 1;
-		bdrkreg_t	w_rsvd_1                  :	 8;
-		bdrkreg_t	w_llp_tx_cnt              :	 8;
-		bdrkreg_t	w_rsvd_2                  :	 6;
-		bdrkreg_t	w_tx_mx_rty               :	 1;
-		bdrkreg_t	w_rsvd_3                  :	 3;
-		bdrkreg_t	w_xt_tail_to              :	 1;
-		bdrkreg_t	w_xt_crd_to               :	 1;
-		bdrkreg_t	w_pending                 :	 4;
-	} ii_wstat_fld_s;
-} ii_wstat_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This is a read-write enabled register. It controls     *
- * various aspects of the Crosstalk flow control.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_wcr_u {
-	bdrkreg_t	ii_wcr_regval;
-	struct	{
-		bdrkreg_t	w_wid			  :	 4;
-		bdrkreg_t	w_tag			  :	 1;
-		bdrkreg_t	w_rsvd_1		  :	 8;
-		bdrkreg_t	w_dst_crd		  :	 3;
-		bdrkreg_t	w_f_bad_pkt		  :	 1;
-		bdrkreg_t	w_dir_con		  :	 1;
-		bdrkreg_t	w_e_thresh		  :	 5;
-		bdrkreg_t	w_rsvd			  :	41;
-	} ii_wcr_fld_s;
-} ii_wcr_u_t;
-
-#else
-
-typedef union ii_wcr_u {
-	bdrkreg_t	ii_wcr_regval;
-	struct  {
-		bdrkreg_t	w_rsvd                    :	41;
-		bdrkreg_t	w_e_thresh                :	 5;
-		bdrkreg_t	w_dir_con                 :	 1;
-		bdrkreg_t	w_f_bad_pkt               :	 1;
-		bdrkreg_t	w_dst_crd                 :	 3;
-		bdrkreg_t	w_rsvd_1                  :	 8;
-		bdrkreg_t	w_tag                     :	 1;
-		bdrkreg_t	w_wid                     :	 4;
-	} ii_wcr_fld_s;
-} ii_wcr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register's value is a bit vector that guards      *
- * access to local registers within the II as well as to external       *
- * Crosstalk widgets. Each bit in the register corresponds to a         *
- * particular region in the system; a region consists of one, two or    *
- * four nodes (depending on the value of the REGION_SIZE field in the   *
- * LB_REV_ID register, which is documented in Section 8.3.1.1). The     *
- * protection provided by this register applies to PIO read             *
- * operations as well as PIO write operations. The II will perform a    *
- * PIO read or write request only if the bit for the requestor's        *
- * region is set; otherwise, the II will not perform the requested      *
- * operation and will return an error response. When a PIO read or      *
- * write request targets an external Crosstalk widget, then not only    *
- * must the bit for the requestor's region be set in the ILAPR, but     *
- * also the target widget's bit in the IOWA register must be set in     *
- * order for the II to perform the requested operation; otherwise,      *
- * the II will return an error response. Hence, the protection          *
- * provided by the IOWA register supplements the protection provided    *
- * by the ILAPR for requests that target external Crosstalk widgets.    *
- * This register itself can be accessed only by the nodes whose         *
- * region ID bits are enabled in this same register. It can also be     *
- * accessed through the IAlias space by the local processors.           *
- * The reset value of this register allows access by all nodes.         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union ii_ilapr_u {
-	bdrkreg_t	ii_ilapr_regval;
-	struct  {
-		bdrkreg_t	i_region                  :	64;
-	} ii_ilapr_fld_s;
-} ii_ilapr_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  A write to this register of the 64-bit value           *
- * "SGIrules" in ASCII, will cause the bit in the ILAPR register        *
- * corresponding to the region of the requestor to be set (allow        *
- * access). A write of any other value will be ignored. Access          *
- * protection for this register is "SGIrules".                          *
- * This register can also be accessed through the IAlias space.         *
- * However, this access will not change the access permissions in the   *
- * ILAPR.                                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ilapo_u {
-	bdrkreg_t	ii_ilapo_regval;
-	struct	{
-		bdrkreg_t	i_io_ovrride		  :	 9;
-		bdrkreg_t	i_rsvd			  :	55;
-	} ii_ilapo_fld_s;
-} ii_ilapo_u_t;
-
-#else
-
-typedef union ii_ilapo_u {
-	bdrkreg_t	ii_ilapo_regval;
-	struct  {
-		bdrkreg_t	i_rsvd                    :	55;
-		bdrkreg_t	i_io_ovrride              :	 9;
-	} ii_ilapo_fld_s;
-} ii_ilapo_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register qualifies all the PIO and Graphics writes launched    *
- * from the Bedrock towards a widget.                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iowa_u {
-	bdrkreg_t	ii_iowa_regval;
-	struct	{
-		bdrkreg_t	i_w0_oac		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-                bdrkreg_t       i_wx_oac                  :      8;
-		bdrkreg_t	i_rsvd			  :	48;
-	} ii_iowa_fld_s;
-} ii_iowa_u_t;
-
-#else
-
-typedef union ii_iowa_u {
-	bdrkreg_t	ii_iowa_regval;
-	struct  {
-		bdrkreg_t	i_rsvd                    :	48;
-		bdrkreg_t	i_wx_oac                  :	 8;
-		bdrkreg_t	i_rsvd_1                  :	 7;
-		bdrkreg_t	i_w0_oac                  :	 1;
-	} ii_iowa_fld_s;
-} ii_iowa_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register qualifies all the requests launched      *
- * from a widget towards the Bedrock. This register is intended to be   *
- * used by software in case of misbehaving widgets.                     *
- *                                                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iiwa_u {
-	bdrkreg_t	ii_iiwa_regval;
-	struct  {
-		bdrkreg_t	i_w0_iac                  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-		bdrkreg_t	i_wx_iac		  :	 8;
-		bdrkreg_t	i_rsvd			  :	48;
-	} ii_iiwa_fld_s;
-} ii_iiwa_u_t;
-
-#else
-
-typedef union ii_iiwa_u {
-	bdrkreg_t	ii_iiwa_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	48;
-		bdrkreg_t	i_wx_iac		  :	 8;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-		bdrkreg_t	i_w0_iac		  :	 1;
-	} ii_iiwa_fld_s;
-} ii_iiwa_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register qualifies all the operations launched    *
- * from a widget towards the Bedrock. It allows individual access       *
- * control for up to 8 devices per widget. A device refers to           *
- * individual DMA master hosted by a widget.                            *
- * The bits in each field of this register are cleared by the Bedrock   *
- * upon detection of an error which requires the device to be           *
- * disabled. These fields assume that 0=TNUM=7 (i.e., Bridge-centric    *
- * Crosstalk). Whether or not a device has access rights to this        *
- * Bedrock is determined by an AND of the device enable bit in the      *
- * appropriate field of this register and the corresponding bit in      *
- * the Wx_IAC field (for the widget which this device belongs to).      *
- * The bits in this field are set by writing a 1 to them. Incoming      *
- * replies from Crosstalk are not subject to this access control        *
- * mechanism.                                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iidem_u {
-	bdrkreg_t	ii_iidem_regval;
-	struct	{
-		bdrkreg_t	i_w8_dxs		  :	 8;
-		bdrkreg_t	i_w9_dxs		  :	 8;
-		bdrkreg_t	i_wa_dxs		  :	 8;
-		bdrkreg_t	i_wb_dxs		  :	 8;
-		bdrkreg_t	i_wc_dxs		  :	 8;
-		bdrkreg_t	i_wd_dxs		  :	 8;
-		bdrkreg_t	i_we_dxs		  :	 8;
-		bdrkreg_t	i_wf_dxs		  :	 8;
-	} ii_iidem_fld_s;
-} ii_iidem_u_t;
-
-#else
-
-typedef union ii_iidem_u {
-	bdrkreg_t	ii_iidem_regval;
-	struct  {
-		bdrkreg_t	i_wf_dxs                  :	 8;
-		bdrkreg_t	i_we_dxs                  :	 8;
-		bdrkreg_t	i_wd_dxs                  :	 8;
-		bdrkreg_t	i_wc_dxs                  :	 8;
-		bdrkreg_t	i_wb_dxs                  :	 8;
-		bdrkreg_t	i_wa_dxs                  :	 8;
-		bdrkreg_t	i_w9_dxs                  :	 8;
-		bdrkreg_t	i_w8_dxs                  :	 8;
-	} ii_iidem_fld_s;
-} ii_iidem_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the various programmable fields necessary    *
- * for controlling and observing the LLP signals.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ilcsr_u {
-	bdrkreg_t	ii_ilcsr_regval;
-	struct  {
-		bdrkreg_t	i_nullto                  :	 6;
-		bdrkreg_t	i_rsvd_4		  :	 2;
-		bdrkreg_t	i_wrmrst		  :	 1;
-		bdrkreg_t	i_rsvd_3		  :	 1;
-		bdrkreg_t	i_llp_en		  :	 1;
-		bdrkreg_t	i_bm8			  :	 1;
-		bdrkreg_t	i_llp_stat		  :	 2;
-		bdrkreg_t	i_remote_power		  :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 1;
-		bdrkreg_t	i_maxrtry		  :	10;
-		bdrkreg_t	i_d_avail_sel		  :	 2;
-		bdrkreg_t	i_rsvd_1		  :	 4;
-		bdrkreg_t	i_maxbrst		  :	10;
-                bdrkreg_t       i_rsvd                    :     22;
-
-	} ii_ilcsr_fld_s;
-} ii_ilcsr_u_t;
-
-#else
-
-typedef union ii_ilcsr_u {
-	bdrkreg_t	ii_ilcsr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	22;
-		bdrkreg_t	i_maxbrst		  :	10;
-		bdrkreg_t	i_rsvd_1		  :	 4;
-		bdrkreg_t	i_d_avail_sel		  :	 2;
-		bdrkreg_t	i_maxrtry		  :	10;
-		bdrkreg_t	i_rsvd_2		  :	 1;
-		bdrkreg_t	i_remote_power		  :	 1;
-		bdrkreg_t	i_llp_stat		  :	 2;
-		bdrkreg_t	i_bm8			  :	 1;
-		bdrkreg_t	i_llp_en		  :	 1;
-		bdrkreg_t	i_rsvd_3		  :	 1;
-		bdrkreg_t	i_wrmrst		  :	 1;
-		bdrkreg_t	i_rsvd_4		  :	 2;
-		bdrkreg_t	i_nullto		  :	 6;
-	} ii_ilcsr_fld_s;
-} ii_ilcsr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This is simply a status registers that monitors the LLP error       *
- * rate.                                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_illr_u {
-	bdrkreg_t	ii_illr_regval;
-	struct	{
-		bdrkreg_t	i_sn_cnt		  :	16;
-		bdrkreg_t	i_cb_cnt		  :	16;
-		bdrkreg_t	i_rsvd			  :	32;
-	} ii_illr_fld_s;
-} ii_illr_u_t;
-
-#else
-
-typedef union ii_illr_u {
-	bdrkreg_t	ii_illr_regval;
-	struct  {
-		bdrkreg_t	i_rsvd                    :	32;
-		bdrkreg_t	i_cb_cnt                  :	16;
-		bdrkreg_t	i_sn_cnt                  :	16;
-	} ii_illr_fld_s;
-} ii_illr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  All II-detected non-BTE error interrupts are           *
- * specified via this register.                                         *
- * NOTE: The PI interrupt register address is hardcoded in the II. If   *
- * PI_ID==0, then the II sends an interrupt request (Duplonet PWRI      *
- * packet) to address offset 0x0180_0090 within the local register      *
- * address space of PI0 on the node specified by the NODE field. If     *
- * PI_ID==1, then the II sends the interrupt request to address         *
- * offset 0x01A0_0090 within the local register address space of PI1    *
- * on the node specified by the NODE field.                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iidsr_u {
-	bdrkreg_t	ii_iidsr_regval;
-	struct  {
-		bdrkreg_t	i_level                   :	 7;
-		bdrkreg_t	i_rsvd_4		  :	 1;
-		bdrkreg_t       i_pi_id                   :      1;
-		bdrkreg_t	i_node			  :	 8;
-		bdrkreg_t       i_rsvd_3                  :      7;
-		bdrkreg_t	i_enable		  :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 3;
-		bdrkreg_t	i_int_sent		  :	 1;
-		bdrkreg_t       i_rsvd_1                  :      3;
-		bdrkreg_t	i_pi0_forward_int	  :	 1;
-		bdrkreg_t	i_pi1_forward_int	  :	 1;
-		bdrkreg_t	i_rsvd			  :	30;
-	} ii_iidsr_fld_s;
-} ii_iidsr_u_t;
-
-#else
-
-typedef union ii_iidsr_u {
-	bdrkreg_t	ii_iidsr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	30;
-		bdrkreg_t	i_pi1_forward_int	  :	 1;
-		bdrkreg_t	i_pi0_forward_int	  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_int_sent		  :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 3;
-		bdrkreg_t	i_enable		  :	 1;
-		bdrkreg_t	i_rsvd_3		  :	 7;
-		bdrkreg_t	i_node			  :	 8;
-		bdrkreg_t	i_pi_id			  :	 1;
-		bdrkreg_t	i_rsvd_4		  :	 1;
-		bdrkreg_t	i_level			  :	 7;
-	} ii_iidsr_fld_s;
-} ii_iidsr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are two instances of this register. This register is used     *
- * for matching up the incoming responses from the graphics widget to   *
- * the processor that initiated the graphics operation. The             *
- * write-responses are converted to graphics credits and returned to    *
- * the processor so that the processor interface can manage the flow    *
- * control.                                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_igfx0_u {
-	bdrkreg_t	ii_igfx0_regval;
-	struct	{
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t       i_pi_id                   :      1;
-		bdrkreg_t	i_n_num			  :	 8;
-		bdrkreg_t       i_rsvd_1                  :      3;
-		bdrkreg_t       i_p_num                   :      1;
-		bdrkreg_t       i_rsvd                    :     47;
-	} ii_igfx0_fld_s;
-} ii_igfx0_u_t;
-
-#else
-
-typedef union ii_igfx0_u {
-	bdrkreg_t	ii_igfx0_regval;
-	struct  {
-		bdrkreg_t	i_rsvd                    :	47;
-		bdrkreg_t	i_p_num                   :	 1;
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_n_num                   :	 8;
-		bdrkreg_t	i_pi_id                   :	 1;
-		bdrkreg_t	i_w_num                   :	 4;
-	} ii_igfx0_fld_s;
-} ii_igfx0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are two instances of this register. This register is used     *
- * for matching up the incoming responses from the graphics widget to   *
- * the processor that initiated the graphics operation. The             *
- * write-responses are converted to graphics credits and returned to    *
- * the processor so that the processor interface can manage the flow    *
- * control.                                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_igfx1_u {
-	bdrkreg_t	ii_igfx1_regval;
-	struct  {
-		bdrkreg_t	i_w_num                   :	 4;
-		bdrkreg_t	i_pi_id			  :	 1;
-		bdrkreg_t	i_n_num			  :	 8;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_p_num			  :	 1;
-		bdrkreg_t	i_rsvd			  :	47;
-	} ii_igfx1_fld_s;
-} ii_igfx1_u_t;
-
-#else
-
-typedef union ii_igfx1_u {
-	bdrkreg_t	ii_igfx1_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	47;
-		bdrkreg_t	i_p_num			  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_n_num			  :	 8;
-		bdrkreg_t	i_pi_id			  :	 1;
-		bdrkreg_t	i_w_num			  :	 4;
-	} ii_igfx1_fld_s;
-} ii_igfx1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are two instances of this registers. These registers are      *
- * used as scratch registers for software use.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union ii_iscr0_u {
-	bdrkreg_t	ii_iscr0_regval;
-	struct  {
-		bdrkreg_t	i_scratch                 :	64;
-	} ii_iscr0_fld_s;
-} ii_iscr0_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are two instances of this registers. These registers are      *
- * used as scratch registers for software use.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union ii_iscr1_u {
-	bdrkreg_t	ii_iscr1_regval;
-	struct  {
-		bdrkreg_t	i_scratch                 :	64;
-	} ii_iscr1_fld_s;
-} ii_iscr1_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Bedrock Big Window to a 48-bit       *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Bedrock is thus the lower 16 GBytes per widget    *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Bedrock is thus the lower         *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_itte1_u {
-	bdrkreg_t	ii_itte1_regval;
-	struct  {
-		bdrkreg_t	i_offset                  :	 5;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t	i_iosp			  :	 1;
-		bdrkreg_t	i_rsvd			  :	51;
-	} ii_itte1_fld_s;
-} ii_itte1_u_t;
-
-#else
-
-typedef union ii_itte1_u {
-	bdrkreg_t	ii_itte1_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	51;
-		bdrkreg_t	i_iosp			  :	 1;
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_offset		  :	 5;
-	} ii_itte1_fld_s;
-} ii_itte1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Bedrock Big Window to a 48-bit       *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Bedrock is thus the lower 16 GBytes per widget    *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Bedrock is thus the lower         *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_itte2_u {
-	bdrkreg_t	ii_itte2_regval;
-	struct	{
-		bdrkreg_t	i_offset		  :	 5;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t	i_iosp			  :	 1;
-		bdrkreg_t       i_rsvd                    :     51;
-	} ii_itte2_fld_s;
-} ii_itte2_u_t;
-
-#else
-typedef union ii_itte2_u {
-	bdrkreg_t	ii_itte2_regval;
-	struct  {
-		bdrkreg_t	i_rsvd                    :	51;
-		bdrkreg_t	i_iosp                    :	 1;
-		bdrkreg_t	i_w_num                   :	 4;
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_offset                  :	 5;
-	} ii_itte2_fld_s;
-} ii_itte2_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Bedrock Big Window to a 48-bit       *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Bedrock is thus the lower 16 GBytes per widget    *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Bedrock is thus the lower         *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_itte3_u {
-	bdrkreg_t	ii_itte3_regval;
-	struct  {
-		bdrkreg_t	i_offset                  :	 5;
-		bdrkreg_t       i_rsvd_1                  :      3;
-		bdrkreg_t       i_w_num                   :      4;
-		bdrkreg_t       i_iosp                    :      1;
-		bdrkreg_t       i_rsvd                    :     51;
-	} ii_itte3_fld_s;
-} ii_itte3_u_t;
-
-#else
-
-typedef union ii_itte3_u {
-	bdrkreg_t	ii_itte3_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	51;
-		bdrkreg_t	i_iosp			  :	 1;
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_offset		  :	 5;
-	} ii_itte3_fld_s;
-} ii_itte3_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Bedrock Big Window to a 48-bit       *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Bedrock is thus the lower 16 GBytes per widget    *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Bedrock is thus the lower         *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_itte4_u {
-	bdrkreg_t	ii_itte4_regval;
-	struct  {
-		bdrkreg_t	i_offset                  :	 5;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t       i_w_num                   :      4;
-		bdrkreg_t       i_iosp                    :      1;
-		bdrkreg_t       i_rsvd                    :     51;
-	} ii_itte4_fld_s;
-} ii_itte4_u_t;
-
-#else
-
-typedef union ii_itte4_u {
-	bdrkreg_t	ii_itte4_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	51;
-		bdrkreg_t	i_iosp			  :	 1;
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_offset		  :	 5;
-	} ii_itte4_fld_s;
-} ii_itte4_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Bedrock Big Window to a 48-bit       *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Bedrock is thus the lower 16 GBytes per widget    *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Bedrock is thus the lower         *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_itte5_u {
-	bdrkreg_t	ii_itte5_regval;
-	struct  {
-		bdrkreg_t	i_offset                  :	 5;
-		bdrkreg_t       i_rsvd_1                  :      3;
-		bdrkreg_t       i_w_num                   :      4;
-		bdrkreg_t       i_iosp                    :      1;
-		bdrkreg_t       i_rsvd                    :     51;
-	} ii_itte5_fld_s;
-} ii_itte5_u_t;
-
-#else
-
-typedef union ii_itte5_u {
-	bdrkreg_t	ii_itte5_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	51;
-		bdrkreg_t	i_iosp			  :	 1;
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_offset		  :	 5;
-	} ii_itte5_fld_s;
-} ii_itte5_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Bedrock Big Window to a 48-bit       *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Bedrock is thus the lower 16 GBytes per widget    *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Bedrock is thus the lower         *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_itte6_u {
-	bdrkreg_t	ii_itte6_regval;
-	struct  {
-		bdrkreg_t	i_offset                  :	 5;
-		bdrkreg_t       i_rsvd_1                  :      3;
-		bdrkreg_t       i_w_num                   :      4;
-		bdrkreg_t       i_iosp                    :      1;
-		bdrkreg_t       i_rsvd                    :     51;
-	} ii_itte6_fld_s;
-} ii_itte6_u_t;
-
-#else
-
-typedef union ii_itte6_u {
-	bdrkreg_t	ii_itte6_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	51;
-		bdrkreg_t	i_iosp			  :	 1;
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_offset		  :	 5;
-	} ii_itte6_fld_s;
-} ii_itte6_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are seven instances of translation table entry   *
- * registers. Each register maps a Bedrock Big Window to a 48-bit       *
- * address on Crosstalk.                                                *
- * For M-mode (128 nodes, 8 GBytes/node), SysAD[31:29] (Big Window      *
- * number) are used to select one of these 7 registers. The Widget      *
- * number field is then derived from the W_NUM field for synthesizing   *
- * a Crosstalk packet. The 5 bits of OFFSET are concatenated with       *
- * SysAD[28:0] to form Crosstalk[33:0]. The upper Crosstalk[47:34]      *
- * are padded with zeros. Although the maximum Crosstalk space          *
- * addressable by the Bedrock is thus the lower 16 GBytes per widget    *
- * (M-mode), however only <SUP >7</SUP>/<SUB >32nds</SUB> of this       *
- * space can be accessed.                                               *
- * For the N-mode (256 nodes, 4 GBytes/node), SysAD[30:28] (Big         *
- * Window number) are used to select one of these 7 registers. The      *
- * Widget number field is then derived from the W_NUM field for         *
- * synthesizing a Crosstalk packet. The 5 bits of OFFSET are            *
- * concatenated with SysAD[27:0] to form Crosstalk[33:0]. The IOSP      *
- * field is used as Crosstalk[47], and remainder of the Crosstalk       *
- * address bits (Crosstalk[46:34]) are always zero. While the maximum   *
- * Crosstalk space addressable by the Bedrock is thus the lower         *
- * 8-GBytes per widget (N-mode), only <SUP >7</SUP>/<SUB >32nds</SUB>   *
- * of this space can be accessed.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_itte7_u {
-	bdrkreg_t	ii_itte7_regval;
-	struct  {
-		bdrkreg_t	i_offset                  :	 5;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t       i_w_num                   :      4;
-		bdrkreg_t       i_iosp                    :      1;
-		bdrkreg_t       i_rsvd                    :     51;
-	} ii_itte7_fld_s;
-} ii_itte7_u_t;
-
-#else
-
-typedef union ii_itte7_u {
-	bdrkreg_t	ii_itte7_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	51;
-		bdrkreg_t	i_iosp			  :	 1;
-		bdrkreg_t	i_w_num			  :	 4;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_offset		  :	 5;
-	} ii_itte7_fld_s;
-} ii_itte7_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprb0_u {
-	bdrkreg_t	ii_iprb0_regval;
-	struct  {
-		bdrkreg_t	i_c                       :	 8;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t       i_rsvd_2                  :      2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_mult_err		  :	 1;
-	} ii_iprb0_fld_s;
-} ii_iprb0_u_t;
-
-#else
-
-typedef union ii_iprb0_u {
-	bdrkreg_t	ii_iprb0_regval;
-	struct	{
-		bdrkreg_t	i_mult_err		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t	i_c			  :	 8;
-	} ii_iprb0_fld_s;
-} ii_iprb0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprb8_u {
-	bdrkreg_t	ii_iprb8_regval;
-	struct  {
-		bdrkreg_t	i_c                       :	 8;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t       i_rsvd_2                  :      2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t       i_rsvd_1                  :      2;
-		bdrkreg_t       i_m                       :      2;
-		bdrkreg_t       i_f                       :      1;
-		bdrkreg_t       i_of_cnt                  :      5;
-		bdrkreg_t       i_error                   :      1;
-		bdrkreg_t       i_rd_to                   :      1;
-		bdrkreg_t       i_spur_wr                 :      1;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t       i_rsvd                    :     11;
-		bdrkreg_t	i_mult_err		  :	 1;
-	} ii_iprb8_fld_s;
-} ii_iprb8_u_t;
-
-#else
-
-
-typedef union ii_iprb8_u {
-	bdrkreg_t	ii_iprb8_regval;
-	struct	{
-		bdrkreg_t	i_mult_err		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t	i_c			  :	 8;
-	} ii_iprb8_fld_s;
-} ii_iprb8_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprb9_u {
-	bdrkreg_t	ii_iprb9_regval;
-	struct	{
-		bdrkreg_t	i_c			  :	 8;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_mult_err		  :	 1;
-	} ii_iprb9_fld_s;
-} ii_iprb9_u_t;
-
-#else
-
-typedef union ii_iprb9_u {
-	bdrkreg_t	ii_iprb9_regval;
-	struct  {
-		bdrkreg_t	i_mult_err                :	 1;
-		bdrkreg_t	i_rsvd                    :	11;
-		bdrkreg_t	i_spur_rd                 :	 1;
-		bdrkreg_t	i_spur_wr                 :	 1;
-		bdrkreg_t	i_rd_to                   :	 1;
-		bdrkreg_t	i_error                   :	 1;
-		bdrkreg_t	i_of_cnt                  :	 5;
-		bdrkreg_t	i_f                       :	 1;
-		bdrkreg_t	i_m                       :	 2;
-		bdrkreg_t	i_rsvd_1                  :	 2;
-		bdrkreg_t	i_nb                      :	14;
-		bdrkreg_t	i_rsvd_2                  :	 2;
-		bdrkreg_t	i_na                      :	14;
-		bdrkreg_t	i_c                       :	 8;
-	} ii_iprb9_fld_s;
-} ii_iprb9_u_t;
-
-#endif
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprba_u {
-	bdrkreg_t	ii_iprba_regval;
-	struct  {
-		bdrkreg_t	i_c                       :	 8;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t       i_rsvd_2                  :      2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_mult_err		  :	 1;
-	} ii_iprba_fld_s;
-} ii_iprba_u_t;
-
-#else
-
-typedef union ii_iprba_u {
-	bdrkreg_t	ii_iprba_regval;
-	struct	{
-		bdrkreg_t	i_mult_err		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t	i_c			  :	 8;
-	} ii_iprba_fld_s;
-} ii_iprba_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprbb_u {
-	bdrkreg_t	ii_iprbb_regval;
-	struct	{
-		bdrkreg_t	i_c			  :	 8;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_mult_err		  :	 1;
-	} ii_iprbb_fld_s;
-} ii_iprbb_u_t;
-
-#else
-
-typedef union ii_iprbb_u {
-	bdrkreg_t	ii_iprbb_regval;
-	struct  {
-		bdrkreg_t	i_mult_err                :	 1;
-		bdrkreg_t	i_rsvd                    :	11;
-		bdrkreg_t	i_spur_rd                 :	 1;
-		bdrkreg_t	i_spur_wr                 :	 1;
-		bdrkreg_t	i_rd_to                   :	 1;
-		bdrkreg_t	i_error                   :	 1;
-		bdrkreg_t	i_of_cnt                  :	 5;
-		bdrkreg_t	i_f                       :	 1;
-		bdrkreg_t	i_m                       :	 2;
-		bdrkreg_t	i_rsvd_1                  :	 2;
-		bdrkreg_t	i_nb                      :	14;
-		bdrkreg_t	i_rsvd_2                  :	 2;
-		bdrkreg_t	i_na                      :	14;
-		bdrkreg_t	i_c                       :	 8;
-	} ii_iprbb_fld_s;
-} ii_iprbb_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprbc_u {
-	bdrkreg_t	ii_iprbc_regval;
-	struct	{
-		bdrkreg_t	i_c			  :	 8;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_mult_err		  :	 1;
-	} ii_iprbc_fld_s;
-} ii_iprbc_u_t;
-
-#else
-
-typedef union ii_iprbc_u {
-	bdrkreg_t	ii_iprbc_regval;
-	struct  {
-		bdrkreg_t	i_mult_err                :	 1;
-		bdrkreg_t	i_rsvd                    :	11;
-		bdrkreg_t	i_spur_rd                 :	 1;
-		bdrkreg_t	i_spur_wr                 :	 1;
-		bdrkreg_t	i_rd_to                   :	 1;
-		bdrkreg_t	i_error                   :	 1;
-		bdrkreg_t	i_of_cnt                  :	 5;
-		bdrkreg_t	i_f                       :	 1;
-		bdrkreg_t	i_m                       :	 2;
-		bdrkreg_t	i_rsvd_1                  :	 2;
-		bdrkreg_t	i_nb                      :	14;
-		bdrkreg_t	i_rsvd_2                  :	 2;
-		bdrkreg_t	i_na                      :	14;
-		bdrkreg_t	i_c                       :	 8;
-	} ii_iprbc_fld_s;
-} ii_iprbc_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprbd_u {
-	bdrkreg_t	ii_iprbd_regval;
-	struct	{
-		bdrkreg_t	i_c			  :	 8;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_mult_err		  :	 1;
-	} ii_iprbd_fld_s;
-} ii_iprbd_u_t;
-
-#else
-
-typedef union ii_iprbd_u {
-	bdrkreg_t	ii_iprbd_regval;
-	struct  {
-		bdrkreg_t	i_mult_err                :	 1;
-		bdrkreg_t	i_rsvd                    :	11;
-		bdrkreg_t	i_spur_rd                 :	 1;
-		bdrkreg_t	i_spur_wr                 :	 1;
-		bdrkreg_t	i_rd_to                   :	 1;
-		bdrkreg_t	i_error                   :	 1;
-		bdrkreg_t	i_of_cnt                  :	 5;
-		bdrkreg_t	i_f                       :	 1;
-		bdrkreg_t	i_m                       :	 2;
-		bdrkreg_t	i_rsvd_1                  :	 2;
-		bdrkreg_t	i_nb                      :	14;
-		bdrkreg_t	i_rsvd_2                  :	 2;
-		bdrkreg_t	i_na                      :	14;
-		bdrkreg_t	i_c                       :	 8;
-	} ii_iprbd_fld_s;
-} ii_iprbd_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprbe_u {
-	bdrkreg_t	ii_iprbe_regval;
-	struct	{
-		bdrkreg_t	i_c			  :	 8;
-		bdrkreg_t	i_na			  :	14;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_nb			  :	14;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_m			  :	 2;
-		bdrkreg_t	i_f			  :	 1;
-		bdrkreg_t	i_of_cnt		  :	 5;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rd_to			  :	 1;
-		bdrkreg_t	i_spur_wr		  :	 1;
-		bdrkreg_t	i_spur_rd		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_mult_err		  :	 1;
-	} ii_iprbe_fld_s;
-} ii_iprbe_u_t;
-
-#else
-
-typedef union ii_iprbe_u {
-	bdrkreg_t	ii_iprbe_regval;
-	struct  {
-		bdrkreg_t	i_mult_err                :	 1;
-		bdrkreg_t	i_rsvd                    :	11;
-		bdrkreg_t	i_spur_rd                 :	 1;
-		bdrkreg_t	i_spur_wr                 :	 1;
-		bdrkreg_t	i_rd_to                   :	 1;
-		bdrkreg_t	i_error                   :	 1;
-		bdrkreg_t	i_of_cnt                  :	 5;
-		bdrkreg_t	i_f                       :	 1;
-		bdrkreg_t	i_m                       :	 2;
-		bdrkreg_t	i_rsvd_1                  :	 2;
-		bdrkreg_t	i_nb                      :	14;
-		bdrkreg_t	i_rsvd_2                  :	 2;
-		bdrkreg_t	i_na                      :	14;
-		bdrkreg_t	i_c                       :	 8;
-	} ii_iprbe_fld_s;
-} ii_iprbe_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 9 instances of this register, one per        *
- * actual widget in this implementation of Bedrock and Crossbow.        *
- * Note: Crossbow only has ports for Widgets 8 through F, widget 0      *
- * refers to Crossbow's internal space.                                 *
- * This register contains the state elements per widget that are        *
- * necessary to manage the PIO flow control on Crosstalk and on the     *
- * Router Network. See the PIO Flow Control chapter for a complete      *
- * description of this register                                         *
- * The SPUR_WR bit requires some explanation. When this register is     *
- * written, the new value of the C field is captured in an internal     *
- * register so the hardware can remember what the programmer wrote      *
- * into the credit counter. The SPUR_WR bit sets whenever the C field   *
- * increments above this stored value, which indicates that there       *
- * have been more responses received than requests sent. The SPUR_WR    *
- * bit cannot be cleared until a value is written to the IPRBx          *
- * register; the write will correct the C field and capture its new     *
- * value in the internal register. Even if IECLR[E_PRB_x] is set, the   *
- * SPUR_WR bit will persist if IPRBx hasn't yet been written.           *
- * .                                                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprbf_u {
-        bdrkreg_t       ii_iprbf_regval;
-        struct  {
-                bdrkreg_t       i_c                       :      8;
-                bdrkreg_t       i_na                      :     14;
-                bdrkreg_t       i_rsvd_2                  :      2;
-                bdrkreg_t       i_nb                      :     14;
-                bdrkreg_t       i_rsvd_1                  :      2;
-                bdrkreg_t       i_m                       :      2;
-                bdrkreg_t       i_f                       :      1;
-                bdrkreg_t       i_of_cnt                  :      5;
-                bdrkreg_t       i_error                   :      1;
-                bdrkreg_t       i_rd_to                   :      1;
-                bdrkreg_t       i_spur_wr                 :      1;
-                bdrkreg_t       i_spur_rd                 :      1;
-                bdrkreg_t       i_rsvd                    :     11;
-                bdrkreg_t       i_mult_err                :      1;
-        } ii_iprbe_fld_s;
-} ii_iprbf_u_t;
-
-#else
-
-typedef union ii_iprbf_u {
-	bdrkreg_t	ii_iprbf_regval;
-	struct  {
-		bdrkreg_t	i_mult_err                :	 1;
-		bdrkreg_t	i_rsvd                    :	11;
-		bdrkreg_t	i_spur_rd                 :	 1;
-		bdrkreg_t	i_spur_wr                 :	 1;
-		bdrkreg_t	i_rd_to                   :	 1;
-		bdrkreg_t	i_error                   :	 1;
-		bdrkreg_t	i_of_cnt                  :	 5;
-		bdrkreg_t	i_f                       :	 1;
-		bdrkreg_t	i_m                       :	 2;
-		bdrkreg_t	i_rsvd_1                  :	 2;
-		bdrkreg_t	i_nb                      :	14;
-		bdrkreg_t	i_rsvd_2                  :	 2;
-		bdrkreg_t	i_na                      :	14;
-		bdrkreg_t	i_c                       :	 8;
-	} ii_iprbf_fld_s;
-} ii_iprbf_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register specifies the timeout value to use for monitoring     *
- * Crosstalk credits which are used outbound to Crosstalk. An           *
- * internal counter called the Crosstalk Credit Timeout Counter         *
- * increments every 128 II clocks. The counter starts counting          *
- * anytime the credit count drops below a threshold, and resets to      *
- * zero (stops counting) anytime the credit count is at or above the    *
- * threshold. The threshold is 1 credit in direct connect mode and 2    *
- * in Crossbow connect mode. When the internal Crosstalk Credit         *
- * Timeout Counter reaches the value programmed in this register, a     *
- * Crosstalk Credit Timeout has occurred. The internal counter is not   *
- * readable from software, and stops counting at its maximum value,     *
- * so it cannot cause more than one interrupt.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ixcc_u {
-	bdrkreg_t	ii_ixcc_regval;
-	struct  {
-		bdrkreg_t	i_time_out                :	26;
-		bdrkreg_t	i_rsvd			  :	38;
-	} ii_ixcc_fld_s;
-} ii_ixcc_u_t;
-
-#else
-
-typedef union ii_ixcc_u {
-	bdrkreg_t	ii_ixcc_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	38;
-		bdrkreg_t	i_time_out		  :	26;
-	} ii_ixcc_fld_s;
-} ii_ixcc_u_t;
-
-#endif
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register qualifies all the PIO and DMA            *
- * operations launched from widget 0 towards the Bedrock. In            *
- * addition, it also qualifies accesses by the BTE streams.             *
- * The bits in each field of this register are cleared by the Bedrock   *
- * upon detection of an error which requires widget 0 or the BTE        *
- * streams to be terminated. Whether or not widget x has access         *
- * rights to this Bedrock is determined by an AND of the device         *
- * enable bit in the appropriate field of this register and bit 0 in    *
- * the Wx_IAC field. The bits in this field are set by writing a 1 to   *
- * them. Incoming replies from Crosstalk are not subject to this        *
- * access control mechanism.                                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_imem_u {
-	bdrkreg_t	ii_imem_regval;
-	struct  {
-		bdrkreg_t	i_w0_esd                  :	 1;
-		bdrkreg_t	i_rsvd_3		  :	 3;
-		bdrkreg_t	i_b0_esd		  :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 3;
-		bdrkreg_t	i_b1_esd		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_clr_precise		  :	 1;
-		bdrkreg_t       i_rsvd                    :     51;
-	} ii_imem_fld_s;
-} ii_imem_u_t;
-
-#else
-
-typedef union ii_imem_u {
-	bdrkreg_t	ii_imem_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	51;
-		bdrkreg_t	i_clr_precise		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_b1_esd		  :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 3;
-		bdrkreg_t	i_b0_esd		  :	 1;
-		bdrkreg_t	i_rsvd_3		  :	 3;
-		bdrkreg_t	i_w0_esd		  :	 1;
-	} ii_imem_fld_s;
-} ii_imem_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register specifies the timeout value to use for   *
- * monitoring Crosstalk tail flits coming into the Bedrock in the       *
- * TAIL_TO field. An internal counter associated with this register     *
- * is incremented every 128 II internal clocks (7 bits). The counter    *
- * starts counting anytime a header micropacket is received and stops   *
- * counting (and resets to zero) any time a micropacket with a Tail     *
- * bit is received. Once the counter reaches the threshold value        *
- * programmed in this register, it generates an interrupt to the        *
- * processor that is programmed into the IIDSR. The counter saturates   *
- * (does not roll over) at its maximum value, so it cannot cause        *
- * another interrupt until after it is cleared.                         *
- * The register also contains the Read Response Timeout values. The     *
- * Prescalar is 23 bits, and counts II clocks. An internal counter      *
- * increments on every II clock and when it reaches the value in the    *
- * Prescalar field, all IPRTE registers with their valid bits set       *
- * have their Read Response timers bumped. Whenever any of them match   *
- * the value in the RRSP_TO field, a Read Response Timeout has          *
- * occurred, and error handling occurs as described in the Error        *
- * Handling section of this document.                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ixtt_u {
-	bdrkreg_t	ii_ixtt_regval;
-	struct  {
-		bdrkreg_t	i_tail_to                 :	26;
-		bdrkreg_t	i_rsvd_1		  :	 6;
-		bdrkreg_t	i_rrsp_ps		  :	23;
-		bdrkreg_t	i_rrsp_to		  :	 5;
-		bdrkreg_t	i_rsvd			  :	 4;
-	} ii_ixtt_fld_s;
-} ii_ixtt_u_t;
-
-#else
-
-typedef union ii_ixtt_u {
-	bdrkreg_t	ii_ixtt_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	 4;
-		bdrkreg_t	i_rrsp_to		  :	 5;
-		bdrkreg_t	i_rrsp_ps		  :	23;
-		bdrkreg_t	i_rsvd_1		  :	 6;
-		bdrkreg_t	i_tail_to		  :	26;
-	} ii_ixtt_fld_s;
-} ii_ixtt_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Writing a 1 to the fields of this register clears the appropriate   *
- * error bits in other areas of Bedrock_II. Note that when the          *
- * E_PRB_x bits are used to clear error bits in PRB registers,          *
- * SPUR_RD and SPUR_WR may persist, because they require additional     *
- * action to clear them. See the IPRBx and IXSS Register                *
- * specifications.                                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ieclr_u {
-	bdrkreg_t	ii_ieclr_regval;
-	struct  {
-		bdrkreg_t	i_e_prb_0                 :	 1;
-		bdrkreg_t	i_rsvd			  :	 7;
-		bdrkreg_t	i_e_prb_8		  :	 1;
-		bdrkreg_t	i_e_prb_9		  :	 1;
-		bdrkreg_t	i_e_prb_a		  :	 1;
-		bdrkreg_t	i_e_prb_b		  :	 1;
-		bdrkreg_t	i_e_prb_c		  :	 1;
-		bdrkreg_t	i_e_prb_d		  :	 1;
-		bdrkreg_t	i_e_prb_e		  :	 1;
-		bdrkreg_t	i_e_prb_f		  :	 1;
-		bdrkreg_t	i_e_crazy		  :	 1;
-		bdrkreg_t	i_e_bte_0		  :	 1;
-		bdrkreg_t	i_e_bte_1		  :	 1;
-		bdrkreg_t	i_reserved_1		  :	 9;
-		bdrkreg_t	i_ii_internal		  :	 1;
-		bdrkreg_t	i_spur_rd_hdr		  :	 1;
-		bdrkreg_t	i_pi0_forward_int	  :	 1;
-		bdrkreg_t	i_pi1_forward_int	  :	 1;
-		bdrkreg_t       i_reserved                :     32;
-	} ii_ieclr_fld_s;
-} ii_ieclr_u_t;
-
-#else
-
-typedef union ii_ieclr_u {
-	bdrkreg_t	ii_ieclr_regval;
-	struct	{
-		bdrkreg_t	i_reserved		  :	32;
-		bdrkreg_t	i_pi1_forward_int	  :	 1;
-		bdrkreg_t	i_pi0_forward_int	  :	 1;
-		bdrkreg_t	i_spur_rd_hdr		  :	 1;
-		bdrkreg_t	i_ii_internal		  :	 1;
-		bdrkreg_t	i_reserved_1		  :	 9;
-		bdrkreg_t	i_e_bte_1		  :	 1;
-		bdrkreg_t	i_e_bte_0		  :	 1;
-		bdrkreg_t	i_e_crazy		  :	 1;
-		bdrkreg_t	i_e_prb_f		  :	 1;
-		bdrkreg_t	i_e_prb_e		  :	 1;
-		bdrkreg_t	i_e_prb_d		  :	 1;
-		bdrkreg_t	i_e_prb_c		  :	 1;
-		bdrkreg_t	i_e_prb_b		  :	 1;
-		bdrkreg_t	i_e_prb_a		  :	 1;
-		bdrkreg_t	i_e_prb_9		  :	 1;
-		bdrkreg_t	i_e_prb_8		  :	 1;
-		bdrkreg_t	i_rsvd			  :	 7;
-		bdrkreg_t	i_e_prb_0		  :	 1;
-	} ii_ieclr_fld_s;
-} ii_ieclr_u_t;
-
-#endif
-
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register controls both BTEs. SOFT_RESET is intended for        *
- * recovery after an error. COUNT controls the total number of CRBs     *
- * that both BTEs (combined) can use, which affects total BTE           *
- * bandwidth.                                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibcr_u {
-	bdrkreg_t	ii_ibcr_regval;
-	struct  {
-		bdrkreg_t	i_count                   :	 4;
-		bdrkreg_t	i_rsvd_1		  :	 4;
-		bdrkreg_t	i_soft_reset		  :	 1;
-		bdrkreg_t	i_rsvd			  :	55;
-	} ii_ibcr_fld_s;
-} ii_ibcr_u_t;
-
-#else
-
-typedef union ii_ibcr_u {
-	bdrkreg_t	ii_ibcr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	55;
-		bdrkreg_t	i_soft_reset		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 4;
-		bdrkreg_t	i_count			  :	 4;
-	} ii_ibcr_fld_s;
-} ii_ibcr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the header of a spurious read response       *
- * received from Crosstalk. A spurious read response is defined as a    *
- * read response received by II from a widget for which (1) the SIDN    *
- * has a value between 1 and 7, inclusive (II never sends requests to   *
- * these widgets (2) there is no valid IPRTE register which             *
- * corresponds to the TNUM, or (3) the widget indicated in SIDN is      *
- * not the same as the widget recorded in the IPRTE register            *
- * referenced by the TNUM. If this condition is true, and if the        *
- * IXSS[VALID] bit is clear, then the header of the spurious read       *
- * response is capture in IXSM and IXSS, and IXSS[VALID] is set. The    *
- * errant header is thereby captured, and no further spurious read      *
- * respones are captured until IXSS[VALID] is cleared by setting the    *
- * appropriate bit in IECLR.Everytime a spurious read response is       *
- * detected, the SPUR_RD bit of the PRB corresponding to the incoming   *
- * message's SIDN field is set. This always happens, regarless of       *
- * whether a header is captured. The programmer should check            *
- * IXSM[SIDN] to determine which widget sent the spurious response,     *
- * because there may be more than one SPUR_RD bit set in the PRB        *
- * registers. The widget indicated by IXSM[SIDN] was the first          *
- * spurious read response to be received since the last time            *
- * IXSS[VALID] was clear. The SPUR_RD bit of the corresponding PRB      *
- * will be set. Any SPUR_RD bits in any other PRB registers indicate    *
- * spurious messages from other widets which were detected after the    *
- * header was captured..                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ixsm_u {
-	bdrkreg_t	ii_ixsm_regval;
-	struct  {
-		bdrkreg_t	i_byte_en                 :	32;
-		bdrkreg_t	i_reserved		  :	 1;
-		bdrkreg_t	i_tag			  :	 3;
-		bdrkreg_t	i_alt_pactyp		  :	 4;
-		bdrkreg_t	i_bo			  :	 1;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_vbpm			  :	 1;
-		bdrkreg_t	i_gbr			  :	 1;
-		bdrkreg_t	i_ds			  :	 2;
-		bdrkreg_t	i_ct			  :	 1;
-		bdrkreg_t	i_tnum			  :	 5;
-		bdrkreg_t	i_pactyp		  :	 4;
-		bdrkreg_t	i_sidn			  :	 4;
-		bdrkreg_t	i_didn			  :	 4;
-	} ii_ixsm_fld_s;
-} ii_ixsm_u_t;
-
-#else
-
-typedef union ii_ixsm_u {
-	bdrkreg_t	ii_ixsm_regval;
-	struct	{
-		bdrkreg_t	i_didn			  :	 4;
-		bdrkreg_t	i_sidn			  :	 4;
-		bdrkreg_t	i_pactyp		  :	 4;
-		bdrkreg_t	i_tnum			  :	 5;
-		bdrkreg_t	i_ct			  :	 1;
-		bdrkreg_t	i_ds			  :	 2;
-		bdrkreg_t	i_gbr			  :	 1;
-		bdrkreg_t	i_vbpm			  :	 1;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_bo			  :	 1;
-		bdrkreg_t	i_alt_pactyp		  :	 4;
-		bdrkreg_t	i_tag			  :	 3;
-		bdrkreg_t	i_reserved		  :	 1;
-		bdrkreg_t	i_byte_en		  :	32;
-	} ii_ixsm_fld_s;
-} ii_ixsm_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the sideband bits of a spurious read         *
- * response received from Crosstalk.                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ixss_u {
-	bdrkreg_t	ii_ixss_regval;
-	struct  {
-		bdrkreg_t	i_sideband                :	 8;
-		bdrkreg_t	i_rsvd			  :	55;
-		bdrkreg_t	i_valid			  :	 1;
-	} ii_ixss_fld_s;
-} ii_ixss_u_t;
-
-#else
-
-typedef union ii_ixss_u {
-	bdrkreg_t	ii_ixss_regval;
-	struct	{
-		bdrkreg_t	i_valid			  :	 1;
-		bdrkreg_t	i_rsvd			  :	55;
-		bdrkreg_t	i_sideband		  :	 8;
-	} ii_ixss_fld_s;
-} ii_ixss_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register enables software to access the II LLP's test port.    *
- * Refer to the LLP 2.5 documentation for an explanation of the test    *
- * port. Software can write to this register to program the values      *
- * for the control fields (TestErrCapture, TestClear, TestFlit,         *
- * TestMask and TestSeed). Similarly, software can read from this       *
- * register to obtain the values of the test port's status outputs      *
- * (TestCBerr, TestValid and TestData).                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ilct_u {
-	bdrkreg_t	ii_ilct_regval;
-	struct  {
-		bdrkreg_t	i_test_seed		  :	20;
-		bdrkreg_t	i_test_mask		  :	 8;
-		bdrkreg_t	i_test_data		  :	20;
-		bdrkreg_t	i_test_valid		  :	 1;
-		bdrkreg_t	i_test_cberr		  :	 1;
-		bdrkreg_t	i_test_flit		  :	 3;
-		bdrkreg_t	i_test_clear		  :	 1;
-		bdrkreg_t	i_test_err_capture	  :	 1;
-		bdrkreg_t	i_rsvd			  :	 9;
-	} ii_ilct_fld_s;
-} ii_ilct_u_t;
-
-#else
-
-typedef union ii_ilct_u {
-	bdrkreg_t	ii_ilct_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	 9;
-		bdrkreg_t	i_test_err_capture	  :	 1;
-		bdrkreg_t	i_test_clear		  :	 1;
-		bdrkreg_t	i_test_flit		  :	 3;
-		bdrkreg_t	i_test_cberr		  :	 1;
-		bdrkreg_t	i_test_valid		  :	 1;
-		bdrkreg_t	i_test_data		  :	20;
-		bdrkreg_t	i_test_mask		  :	 8;
-		bdrkreg_t	i_test_seed		  :	20;
-	} ii_ilct_fld_s;
-} ii_ilct_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  If the II detects an illegal incoming Duplonet packet (request or   *
- * reply) when VALID==0 in the IIEPH1 register, then it saves the       *
- * contents of the packet's header flit in the IIEPH1 and IIEPH2        *
- * registers, sets the VALID bit in IIEPH1, clears the OVERRUN bit,     *
- * and assigns a value to the ERR_TYPE field which indicates the        *
- * specific nature of the error. The II recognizes four different       *
- * types of errors: short request packets (ERR_TYPE==2), short reply    *
- * packets (ERR_TYPE==3), long request packets (ERR_TYPE==4) and long   *
- * reply packets (ERR_TYPE==5). The encodings for these types of        *
- * errors were chosen to be consistent with the same types of errors    *
- * indicated by the ERR_TYPE field in the LB_ERROR_HDR1 register (in    *
- * the LB unit). If the II detects an illegal incoming Duplonet         *
- * packet when VALID==1 in the IIEPH1 register, then it merely sets     *
- * the OVERRUN bit to indicate that a subsequent error has happened,    *
- * and does nothing further.                                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iieph1_u {
-	bdrkreg_t	ii_iieph1_regval;
-	struct	{
-		bdrkreg_t	i_command		  :	 7;
-		bdrkreg_t	i_rsvd_5		  :	 1;
-		bdrkreg_t	i_suppl			  :	11;
-		bdrkreg_t	i_rsvd_4		  :	 1;
-		bdrkreg_t	i_source		  :	11;
-		bdrkreg_t	i_rsvd_3		  :	 1;
-		bdrkreg_t	i_err_type		  :	 4;
-		bdrkreg_t	i_rsvd_2		  :	 4;
-		bdrkreg_t	i_overrun		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_valid			  :	 1;
-		bdrkreg_t	i_rsvd			  :	19;
-	} ii_iieph1_fld_s;
-} ii_iieph1_u_t;
-
-#else
-
-typedef union ii_iieph1_u {
-	bdrkreg_t	ii_iieph1_regval;
-	struct  {
-		bdrkreg_t	i_rsvd                    :	19;
-		bdrkreg_t	i_valid                   :	 1;
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_overrun                 :	 1;
-		bdrkreg_t	i_rsvd_2                  :	 4;
-		bdrkreg_t	i_err_type                :	 4;
-		bdrkreg_t	i_rsvd_3                  :	 1;
-		bdrkreg_t	i_source                  :	11;
-		bdrkreg_t	i_rsvd_4                  :	 1;
-		bdrkreg_t	i_suppl                   :	11;
-		bdrkreg_t	i_rsvd_5                  :	 1;
-		bdrkreg_t	i_command                 :	 7;
-	} ii_iieph1_fld_s;
-} ii_iieph1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register holds the Address field from the header flit of an    *
- * incoming erroneous Duplonet packet, along with the tail bit which    *
- * accompanied this header flit. This register is essentially an        *
- * extension of IIEPH1. Two registers were necessary because the 64     *
- * bits available in only a single register were insufficient to        *
- * capture the entire header flit of an erroneous packet.               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iieph2_u {
-	bdrkreg_t	ii_iieph2_regval;
-	struct  {
-		bdrkreg_t	i_address                 :	38;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_tail			  :	 1;
-		bdrkreg_t	i_rsvd			  :	23;
-	} ii_iieph2_fld_s;
-} ii_iieph2_u_t;
-
-#else
-
-typedef union ii_iieph2_u {
-	bdrkreg_t	ii_iieph2_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	23;
-		bdrkreg_t	i_tail			  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_address		  :	38;
-	} ii_iieph2_fld_s;
-} ii_iieph2_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  A write to this register causes a particular field in the           *
- * corresponding widget's PRB entry to be adjusted up or down by 1.     *
- * This counter should be used when recovering from error and reset     *
- * conditions. Note that software would be capable of causing           *
- * inadvertent overflow or underflow of these counters.                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ipca_u {
-	bdrkreg_t	ii_ipca_regval;
-	struct  {
-		bdrkreg_t	i_wid                     :	 4;
-		bdrkreg_t	i_adjust		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_field			  :	 2;
-		bdrkreg_t	i_rsvd			  :	54;
-	} ii_ipca_fld_s;
-} ii_ipca_u_t;
-
-#else
-
-typedef union ii_ipca_u {
-	bdrkreg_t	ii_ipca_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	54;
-		bdrkreg_t	i_field			  :	 2;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_adjust		  :	 1;
-		bdrkreg_t	i_wid			  :	 4;
-	} ii_ipca_fld_s;
-} ii_ipca_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprte0_u {
-	bdrkreg_t	ii_iprte0_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t       i_vld                     :      1;
-	} ii_iprte0_fld_s;
-} ii_iprte0_u_t;
-
-#else
-
-typedef union ii_iprte0_u {
-	bdrkreg_t	ii_iprte0_regval;
-	struct	{
-		bdrkreg_t	i_vld			  :	 1;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-	} ii_iprte0_fld_s;
-} ii_iprte0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprte1_u {
-	bdrkreg_t	ii_iprte1_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t       i_vld                     :      1;
-	} ii_iprte1_fld_s;
-} ii_iprte1_u_t;
-
-#else
-
-typedef union ii_iprte1_u {
-	bdrkreg_t	ii_iprte1_regval;
-	struct	{
-		bdrkreg_t	i_vld			  :	 1;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-	} ii_iprte1_fld_s;
-} ii_iprte1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprte2_u {
-	bdrkreg_t	ii_iprte2_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t       i_vld                     :      1;
-	} ii_iprte2_fld_s;
-} ii_iprte2_u_t;
-
-#else
-
-typedef union ii_iprte2_u {
-	bdrkreg_t	ii_iprte2_regval;
-	struct	{
-		bdrkreg_t	i_vld			  :	 1;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-	} ii_iprte2_fld_s;
-} ii_iprte2_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprte3_u {
-	bdrkreg_t	ii_iprte3_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_vld			  :	 1;
-	} ii_iprte3_fld_s;
-} ii_iprte3_u_t;
-
-#else
-
-typedef union ii_iprte3_u {
-	bdrkreg_t	ii_iprte3_regval;
-	struct	{
-		bdrkreg_t	i_vld			  :	 1;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-	} ii_iprte3_fld_s;
-} ii_iprte3_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprte4_u {
-	bdrkreg_t	ii_iprte4_regval;
-	struct	{
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_vld			  :	 1;
-	} ii_iprte4_fld_s;
-} ii_iprte4_u_t;
-
-#else
-
-typedef union ii_iprte4_u {
-	bdrkreg_t	ii_iprte4_regval;
-	struct  {
-		bdrkreg_t	i_vld                     :	 1;
-		bdrkreg_t	i_to_cnt                  :	 5;
-		bdrkreg_t	i_widget                  :	 4;
-		bdrkreg_t	i_rsvd                    :	 2;
-		bdrkreg_t	i_source                  :	 8;
-		bdrkreg_t	i_init                    :	 3;
-		bdrkreg_t	i_addr                    :	38;
-		bdrkreg_t	i_rsvd_1                  :	 3;
-	} ii_iprte4_fld_s;
-} ii_iprte4_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprte5_u {
-	bdrkreg_t	ii_iprte5_regval;
-	struct	{
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_vld			  :	 1;
-	} ii_iprte5_fld_s;
-} ii_iprte5_u_t;
-
-#else
-
-typedef union ii_iprte5_u {
-	bdrkreg_t	ii_iprte5_regval;
-	struct  {
-		bdrkreg_t	i_vld                     :	 1;
-		bdrkreg_t	i_to_cnt                  :	 5;
-		bdrkreg_t	i_widget                  :	 4;
-		bdrkreg_t	i_rsvd                    :	 2;
-		bdrkreg_t	i_source                  :	 8;
-		bdrkreg_t	i_init                    :	 3;
-		bdrkreg_t	i_addr                    :	38;
-		bdrkreg_t	i_rsvd_1                  :	 3;
-	} ii_iprte5_fld_s;
-} ii_iprte5_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprte6_u {
-	bdrkreg_t	ii_iprte6_regval;
-	struct	{
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_vld			  :	 1;
-	} ii_iprte6_fld_s;
-} ii_iprte6_u_t;
-
-#else
-
-typedef union ii_iprte6_u {
-	bdrkreg_t	ii_iprte6_regval;
-	struct  {
-		bdrkreg_t	i_vld                     :	 1;
-		bdrkreg_t	i_to_cnt                  :	 5;
-		bdrkreg_t	i_widget                  :	 4;
-		bdrkreg_t	i_rsvd                    :	 2;
-		bdrkreg_t	i_source                  :	 8;
-		bdrkreg_t	i_init                    :	 3;
-		bdrkreg_t	i_addr                    :	38;
-		bdrkreg_t	i_rsvd_1                  :	 3;
-	} ii_iprte6_fld_s;
-} ii_iprte6_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There are 8 instances of this register. This register contains      *
- * the information that the II has to remember once it has launched a   *
- * PIO Read operation. The contents are used to form the correct        *
- * Router Network packet and direct the Crosstalk reply to the          *
- * appropriate processor.                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iprte7_u {
-        bdrkreg_t       ii_iprte7_regval;
-        struct  {
-                bdrkreg_t       i_rsvd_1                  :      3;
-                bdrkreg_t       i_addr                    :     38;
-                bdrkreg_t       i_init                    :      3;
-                bdrkreg_t       i_source                  :      8;
-                bdrkreg_t       i_rsvd                    :      2;
-                bdrkreg_t       i_widget                  :      4;
-                bdrkreg_t       i_to_cnt                  :      5;
-                bdrkreg_t       i_vld                     :      1;
-        } ii_iprte7_fld_s;
-} ii_iprte7_u_t;
-
-#else
-
-typedef union ii_iprte7_u {
-	bdrkreg_t	ii_iprte7_regval;
-	struct  {
-		bdrkreg_t	i_vld                     :	 1;
-		bdrkreg_t	i_to_cnt                  :	 5;
-		bdrkreg_t	i_widget                  :	 4;
-		bdrkreg_t	i_rsvd                    :	 2;
-		bdrkreg_t	i_source                  :	 8;
-		bdrkreg_t	i_init                    :	 3;
-		bdrkreg_t	i_addr                    :	38;
-		bdrkreg_t	i_rsvd_1                  :	 3;
-	} ii_iprte7_fld_s;
-} ii_iprte7_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  Bedrock_II contains a feature which did not exist in   *
- * the Hub which automatically cleans up after a Read Response          *
- * timeout, including deallocation of the IPRTE and recovery of IBuf    *
- * space. The inclusion of this register in Bedrock is for backward     *
- * compatibility                                                        *
- * A write to this register causes an entry from the table of           *
- * outstanding PIO Read Requests to be freed and returned to the        *
- * stack of free entries. This register is used in handling the         *
- * timeout errors that result in a PIO Reply never returning from       *
- * Crosstalk.                                                           *
- * Note that this register does not affect the contents of the IPRTE    *
- * registers. The Valid bits in those registers have to be              *
- * specifically turned off by software.                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ipdr_u {
-	bdrkreg_t	ii_ipdr_regval;
-	struct  {
-		bdrkreg_t	i_te                      :	 3;
-		bdrkreg_t	i_rsvd_1		  :	 1;
-		bdrkreg_t	i_pnd			  :	 1;
-		bdrkreg_t	i_init_rpcnt		  :	 1;
-		bdrkreg_t	i_rsvd			  :	58;
-	} ii_ipdr_fld_s;
-} ii_ipdr_u_t;
-
-#else
-
-typedef union ii_ipdr_u {
-	bdrkreg_t	ii_ipdr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	58;
-		bdrkreg_t	i_init_rpcnt		  :	 1;
-		bdrkreg_t	i_pnd			  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 1;
-		bdrkreg_t	i_te			  :	 3;
-	} ii_ipdr_fld_s;
-} ii_ipdr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  A write to this register causes a CRB entry to be returned to the   *
- * queue of free CRBs. The entry should have previously been cleared    *
- * (mark bit) via backdoor access to the pertinent CRB entry. This      *
- * register is used in the last step of handling the errors that are    *
- * captured and marked in CRB entries.  Briefly: 1) first error for     *
- * DMA write from a particular device, and first error for a            *
- * particular BTE stream, lead to a marked CRB entry, and processor     *
- * interrupt, 2) software reads the error information captured in the   *
- * CRB entry, and presumably takes some corrective action, 3)           *
- * software clears the mark bit, and finally 4) software writes to      *
- * the ICDR register to return the CRB entry to the list of free CRB    *
- * entries.                                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icdr_u {
-	bdrkreg_t	ii_icdr_regval;
-	struct  {
-		bdrkreg_t	i_crb_num                 :	 4;
-		bdrkreg_t	i_pnd			  :	 1;
-		bdrkreg_t       i_rsvd                    :     59;
-	} ii_icdr_fld_s;
-} ii_icdr_u_t;
-
-#else
-
-typedef union ii_icdr_u {
-	bdrkreg_t	ii_icdr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	59;
-		bdrkreg_t	i_pnd			  :	 1;
-		bdrkreg_t	i_crb_num		  :	 4;
-	} ii_icdr_fld_s;
-} ii_icdr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register provides debug access to two FIFOs inside of II.      *
- * Both IOQ_MAX* fields of this register contain the instantaneous      *
- * depth (in units of the number of available entries) of the           *
- * associated IOQ FIFO.  A read of this register will return the        *
- * number of free entries on each FIFO at the time of the read.  So     *
- * when a FIFO is idle, the associated field contains the maximum       *
- * depth of the FIFO.  This register is writable for debug reasons      *
- * and is intended to be written with the maximum desired FIFO depth    *
- * while the FIFO is idle. Software must assure that II is idle when    *
- * this register is written. If there are any active entries in any     *
- * of these FIFOs when this register is written, the results are        *
- * undefined.                                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ifdr_u {
-	bdrkreg_t	ii_ifdr_regval;
-	struct  {
-		bdrkreg_t	i_ioq_max_rq              :	 7;
-		bdrkreg_t	i_set_ioq_rq		  :	 1;
-		bdrkreg_t	i_ioq_max_rp		  :	 7;
-		bdrkreg_t	i_set_ioq_rp		  :	 1;
-		bdrkreg_t	i_rsvd			  :	48;
-	} ii_ifdr_fld_s;
-} ii_ifdr_u_t;
-
-#else
-
-typedef union ii_ifdr_u {
-	bdrkreg_t	ii_ifdr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	48;
-		bdrkreg_t	i_set_ioq_rp		  :	 1;
-		bdrkreg_t	i_ioq_max_rp		  :	 7;
-		bdrkreg_t	i_set_ioq_rq		  :	 1;
-		bdrkreg_t	i_ioq_max_rq		  :	 7;
-	} ii_ifdr_fld_s;
-} ii_ifdr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register allows the II to become sluggish in removing          *
- * messages from its inbound queue (IIQ). This will cause messages to   *
- * back up in either virtual channel. Disabling the "molasses" mode     *
- * subsequently allows the II to be tested under stress. In the         *
- * sluggish ("Molasses") mode, the localized effects of congestion      *
- * can be observed.                                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iiap_u {
-        bdrkreg_t       ii_iiap_regval;
-        struct  {
-                bdrkreg_t       i_rq_mls                  :      6;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_rp_mls		  :	 6;
-		bdrkreg_t       i_rsvd                    :     50;
-        } ii_iiap_fld_s;
-} ii_iiap_u_t;
-
-#else
-
-typedef union ii_iiap_u {
-	bdrkreg_t	ii_iiap_regval;
-	struct  {
-		bdrkreg_t	i_rsvd                    :	50;
-		bdrkreg_t	i_rp_mls                  :	 6;
-		bdrkreg_t	i_rsvd_1                  :	 2;
-		bdrkreg_t	i_rq_mls                  :	 6;
-	} ii_iiap_fld_s;
-} ii_iiap_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register allows several parameters of CRB operation to be      *
- * set. Note that writing to this register can have catastrophic side   *
- * effects, if the CRB is not quiescent, i.e. if the CRB is             *
- * processing protocol messages when the write occurs.                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icmr_u {
-	bdrkreg_t	ii_icmr_regval;
-	struct  {
-		bdrkreg_t	i_sp_msg                  :	 1;
-		bdrkreg_t	i_rd_hdr		  :	 1;
-		bdrkreg_t	i_rsvd_4		  :	 2;
-		bdrkreg_t	i_c_cnt			  :	 4;
-		bdrkreg_t	i_rsvd_3		  :	 4;
-		bdrkreg_t	i_clr_rqpd		  :	 1;
-		bdrkreg_t	i_clr_rppd		  :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_fc_cnt		  :	 4;
-		bdrkreg_t	i_crb_vld		  :	15;
-		bdrkreg_t	i_crb_mark		  :	15;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_precise		  :	 1;
-		bdrkreg_t	i_rsvd			  :	11;
-	} ii_icmr_fld_s;
-} ii_icmr_u_t;
-
-#else
-
-typedef union ii_icmr_u {
-	bdrkreg_t	ii_icmr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	11;
-		bdrkreg_t	i_precise		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 2;
-		bdrkreg_t	i_crb_mark		  :	15;
-		bdrkreg_t	i_crb_vld		  :	15;
-		bdrkreg_t	i_fc_cnt		  :	 4;
-		bdrkreg_t	i_rsvd_2		  :	 2;
-		bdrkreg_t	i_clr_rppd		  :	 1;
-		bdrkreg_t	i_clr_rqpd		  :	 1;
-		bdrkreg_t	i_rsvd_3		  :	 4;
-		bdrkreg_t	i_c_cnt			  :	 4;
-		bdrkreg_t	i_rsvd_4		  :	 2;
-		bdrkreg_t	i_rd_hdr		  :	 1;
-		bdrkreg_t	i_sp_msg		  :	 1;
-	} ii_icmr_fld_s;
-} ii_icmr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register allows control of the table portion of the CRB        *
- * logic via software. Control operations from this register have       *
- * priority over all incoming Crosstalk or BTE requests.                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_iccr_u {
-	bdrkreg_t	ii_iccr_regval;
-	struct  {
-		bdrkreg_t	i_crb_num                 :	 4;
-		bdrkreg_t	i_rsvd_1		  :	 4;
-		bdrkreg_t	i_cmd			  :	 8;
-		bdrkreg_t	i_pending		  :	 1;
-		bdrkreg_t	i_rsvd			  :	47;
-	} ii_iccr_fld_s;
-} ii_iccr_u_t;
-
-#else
-
-typedef union ii_iccr_u {
-	bdrkreg_t	ii_iccr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	47;
-		bdrkreg_t	i_pending		  :	 1;
-		bdrkreg_t	i_cmd			  :	 8;
-		bdrkreg_t	i_rsvd_1		  :	 4;
-		bdrkreg_t	i_crb_num		  :	 4;
-	} ii_iccr_fld_s;
-} ii_iccr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register allows the maximum timeout value to be programmed.    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icto_u {
-	bdrkreg_t	ii_icto_regval;
-	struct  {
-		bdrkreg_t	i_timeout                 :	 8;
-		bdrkreg_t	i_rsvd			  :	56;
-	} ii_icto_fld_s;
-} ii_icto_u_t;
-
-#else
-
-typedef union ii_icto_u {
-	bdrkreg_t	ii_icto_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	56;
-		bdrkreg_t	i_timeout		  :	 8;
-	} ii_icto_fld_s;
-} ii_icto_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register allows the timeout prescalar to be programmed. An     *
- * internal counter is associated with this register. When the          *
- * internal counter reaches the value of the PRESCALE field, the        *
- * timer registers in all valid CRBs are incremented (CRBx_D[TIMEOUT]   *
- * field). The internal counter resets to zero, and then continues      *
- * counting.                                                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ictp_u {
-	bdrkreg_t	ii_ictp_regval;
-	struct  {
-		bdrkreg_t	i_prescale                :	24;
-		bdrkreg_t	i_rsvd			  :	40;
-	} ii_ictp_fld_s;
-} ii_ictp_u_t;
-
-#else
-
-typedef union ii_ictp_u {
-	bdrkreg_t	ii_ictp_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	40;
-		bdrkreg_t	i_prescale		  :	24;
-	} ii_ictp_fld_s;
-} ii_ictp_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, four   *
- * registers (_A to _D) are required to read and write each entry.      *
- * The CRB Entry registers can be conceptualized as rows and columns    *
- * (illustrated in the table above). Each row contains the 4            *
- * registers required for a single CRB Entry. The first doubleword      *
- * (column) for each entry is labeled A, and the second doubleword      *
- * (higher address) is labeled B, the third doubleword is labeled C,    *
- * and the fourth doubleword is labeled D. All CRB entries have their   *
- * addresses on a quarter cacheline aligned boundary.                   *
- * Upon reset, only the following fields are initialized: valid         *
- * (VLD), priority count, timeout, timeout valid, and context valid.    *
- * All other bits should be cleared by software before use (after       *
- * recovering any potential error state from before the reset).         *
- * The following four tables summarize the format for the four          *
- * registers that are used for each ICRB# Entry.                        *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icrb0_a_u {
-	bdrkreg_t	ii_icrb0_a_regval;
-	struct  {
-		bdrkreg_t	ia_iow                    :	 1;
-		bdrkreg_t	ia_vld			  :	 1;
-		bdrkreg_t	ia_addr			  :	38;
-		bdrkreg_t	ia_tnum			  :	 5;
-		bdrkreg_t	ia_sidn			  :	 4;
-		bdrkreg_t	ia_xt_err		  :	 1;
-		bdrkreg_t	ia_mark			  :	 1;
-		bdrkreg_t	ia_ln_uce		  :	 1;
-		bdrkreg_t	ia_errcode		  :	 3;
-		bdrkreg_t	ia_error		  :	 1;
-		bdrkreg_t	ia_stall__bte_1		  :	 1;
-		bdrkreg_t	ia_stall__bte_0		  :	 1;
-		bdrkreg_t       ia_rsvd                   :      6;
-	} ii_icrb0_a_fld_s;
-} ii_icrb0_a_u_t;
-
-#else
-
-typedef union ii_icrb0_a_u {
-	bdrkreg_t	ii_icrb0_a_regval;
-	struct	{
-		bdrkreg_t	ia_rsvd			  :	 6;
-		bdrkreg_t	ia_stall__bte_0		  :	 1;
-		bdrkreg_t	ia_stall__bte_1		  :	 1;
-		bdrkreg_t	ia_error		  :	 1;
-		bdrkreg_t	ia_errcode		  :	 3;
-		bdrkreg_t	ia_ln_uce		  :	 1;
-		bdrkreg_t	ia_mark			  :	 1;
-		bdrkreg_t	ia_xt_err		  :	 1;
-		bdrkreg_t	ia_sidn			  :	 4;
-		bdrkreg_t	ia_tnum			  :	 5;
-		bdrkreg_t	ia_addr			  :	38;
-		bdrkreg_t	ia_vld			  :	 1;
-		bdrkreg_t	ia_iow			  :	 1;
-	} ii_icrb0_a_fld_s;
-} ii_icrb0_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, four   *
- * registers (_A to _D) are required to read and write each entry.      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icrb0_b_u {
-	bdrkreg_t	ii_icrb0_b_regval;
-	struct	{
-		bdrkreg_t	ib_stall__intr		  :	 1;
-		bdrkreg_t	ib_stall_ib		  :	 1;
-		bdrkreg_t	ib_intvn		  :	 1;
-		bdrkreg_t	ib_wb			  :	 1;
-		bdrkreg_t	ib_hold			  :	 1;
-		bdrkreg_t	ib_ack			  :	 1;
-		bdrkreg_t	ib_resp			  :	 1;
-		bdrkreg_t	ib_ack_cnt		  :	11;
-		bdrkreg_t	ib_rsvd_1		  :	 7;
-		bdrkreg_t	ib_exc			  :	 5;
-		bdrkreg_t	ib_init			  :	 3;
-		bdrkreg_t	ib_imsg			  :	 8;
-		bdrkreg_t	ib_imsgtype		  :	 2;
-		bdrkreg_t	ib_use_old		  :	 1;
-		bdrkreg_t	ib_source		  :	12;
-		bdrkreg_t	ib_size			  :	 2;
-		bdrkreg_t	ib_ct			  :	 1;
-		bdrkreg_t	ib_bte_num		  :	 1;
-		bdrkreg_t	ib_rsvd			  :	 4;
-	} ii_icrb0_b_fld_s;
-} ii_icrb0_b_u_t;
-
-#else
-
-typedef union ii_icrb0_b_u {
-	bdrkreg_t	ii_icrb0_b_regval;
-	struct  {
-		bdrkreg_t	ib_rsvd                   :	 4;
-		bdrkreg_t	ib_bte_num                :	 1;
-		bdrkreg_t	ib_ct                     :	 1;
-		bdrkreg_t	ib_size                   :	 2;
-		bdrkreg_t	ib_source                 :	12;
-		bdrkreg_t	ib_use_old                :	 1;
-		bdrkreg_t	ib_imsgtype               :	 2;
-		bdrkreg_t	ib_imsg                   :	 8;
-		bdrkreg_t	ib_init                   :	 3;
-		bdrkreg_t	ib_exc                    :	 5;
-		bdrkreg_t	ib_rsvd_1                 :	 7;
-		bdrkreg_t	ib_ack_cnt                :	11;
-		bdrkreg_t	ib_resp                   :	 1;
-		bdrkreg_t	ib_ack                    :	 1;
-		bdrkreg_t	ib_hold                   :	 1;
-		bdrkreg_t	ib_wb                     :	 1;
-		bdrkreg_t	ib_intvn                  :	 1;
-		bdrkreg_t	ib_stall_ib               :	 1;
-		bdrkreg_t	ib_stall__intr            :	 1;
-	} ii_icrb0_b_fld_s;
-} ii_icrb0_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, four   *
- * registers (_A to _D) are required to read and write each entry.      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icrb0_c_u {
-	bdrkreg_t	ii_icrb0_c_regval;
-	struct	{
-		bdrkreg_t	ic_gbr			  :	 1;
-		bdrkreg_t	ic_resprqd		  :	 1;
-		bdrkreg_t	ic_bo			  :	 1;
-		bdrkreg_t	ic_suppl		  :	12;
-		bdrkreg_t	ic_pa_be		  :	34;
-		bdrkreg_t	ic_bte_op		  :	 1;
-		bdrkreg_t	ic_pr_psc		  :	 4;
-		bdrkreg_t	ic_pr_cnt		  :	 4;
-		bdrkreg_t	ic_sleep		  :	 1;
-		bdrkreg_t	ic_rsvd			  :	 5;
-	} ii_icrb0_c_fld_s;
-} ii_icrb0_c_u_t;
-
-#else
-
-typedef union ii_icrb0_c_u {
-	bdrkreg_t	ii_icrb0_c_regval;
-	struct  {
-		bdrkreg_t	ic_rsvd                   :	 5;
-		bdrkreg_t	ic_sleep                  :	 1;
-		bdrkreg_t	ic_pr_cnt                 :	 4;
-		bdrkreg_t	ic_pr_psc                 :	 4;
-		bdrkreg_t	ic_bte_op                 :	 1;
-		bdrkreg_t	ic_pa_be                  :	34;
-		bdrkreg_t	ic_suppl                  :	12;
-		bdrkreg_t	ic_bo                     :	 1;
-		bdrkreg_t	ic_resprqd                :	 1;
-		bdrkreg_t	ic_gbr                    :	 1;
-	} ii_icrb0_c_fld_s;
-} ii_icrb0_c_u_t;
-
-#endif
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There are 15 CRB Entries (ICRB0 to ICRBE) that are     *
- * used for Crosstalk operations (both cacheline and partial            *
- * operations) or BTE/IO. Because the CRB entries are very wide, four   *
- * registers (_A to _D) are required to read and write each entry.      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icrb0_d_u {
-	bdrkreg_t	ii_icrb0_d_regval;
-	struct  {
-		bdrkreg_t	id_timeout                :	 8;
-		bdrkreg_t	id_context		  :	15;
-		bdrkreg_t	id_rsvd_1		  :	 1;
-		bdrkreg_t	id_tvld			  :	 1;
-		bdrkreg_t	id_cvld			  :	 1;
-		bdrkreg_t	id_rsvd			  :	38;
-	} ii_icrb0_d_fld_s;
-} ii_icrb0_d_u_t;
-
-#else
-
-typedef union ii_icrb0_d_u {
-	bdrkreg_t	ii_icrb0_d_regval;
-	struct	{
-		bdrkreg_t	id_rsvd			  :	38;
-		bdrkreg_t	id_cvld			  :	 1;
-		bdrkreg_t	id_tvld			  :	 1;
-		bdrkreg_t	id_rsvd_1		  :	 1;
-		bdrkreg_t	id_context		  :	15;
-		bdrkreg_t	id_timeout		  :	 8;
-	} ii_icrb0_d_fld_s;
-} ii_icrb0_d_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the lower 64 bits of the header of the       *
- * spurious message captured by II. Valid when the SP_MSG bit in ICMR   *
- * register is set.                                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icsml_u {
-	bdrkreg_t	ii_icsml_regval;
-	struct  {
-		bdrkreg_t	i_tt_addr                 :	38;
-		bdrkreg_t	i_tt_ack_cnt		  :	11;
-		bdrkreg_t	i_newsuppl_ex		  :	11;
-		bdrkreg_t	i_reserved		  :	 3;
-		bdrkreg_t       i_overflow                :      1;
-	} ii_icsml_fld_s;
-} ii_icsml_u_t;
-
-#else
-
-typedef union ii_icsml_u {
-	bdrkreg_t	ii_icsml_regval;
-	struct	{
-		bdrkreg_t	i_overflow		  :	 1;
-		bdrkreg_t	i_reserved		  :	 3;
-		bdrkreg_t	i_newsuppl_ex		  :	11;
-		bdrkreg_t	i_tt_ack_cnt		  :	11;
-		bdrkreg_t	i_tt_addr		  :	38;
-	} ii_icsml_fld_s;
-} ii_icsml_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the microscopic state, all the inputs to     *
- * the protocol table, captured with the spurious message. Valid when   *
- * the SP_MSG bit in the ICMR register is set.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_icsmh_u {
-	bdrkreg_t	ii_icsmh_regval;
-	struct  {
-		bdrkreg_t	i_tt_vld                  :	 1;
-		bdrkreg_t	i_xerr			  :	 1;
-		bdrkreg_t	i_ft_cwact_o		  :	 1;
-		bdrkreg_t	i_ft_wact_o		  :	 1;
-		bdrkreg_t       i_ft_active_o             :      1;
-		bdrkreg_t	i_sync			  :	 1;
-		bdrkreg_t	i_mnusg			  :	 1;
-		bdrkreg_t	i_mnusz			  :	 1;
-		bdrkreg_t	i_plusz			  :	 1;
-		bdrkreg_t	i_plusg			  :	 1;
-		bdrkreg_t	i_tt_exc		  :	 5;
-		bdrkreg_t	i_tt_wb			  :	 1;
-		bdrkreg_t	i_tt_hold		  :	 1;
-		bdrkreg_t	i_tt_ack		  :	 1;
-		bdrkreg_t	i_tt_resp		  :	 1;
-		bdrkreg_t	i_tt_intvn		  :	 1;
-		bdrkreg_t	i_g_stall_bte1		  :	 1;
-		bdrkreg_t	i_g_stall_bte0		  :	 1;
-		bdrkreg_t	i_g_stall_il		  :	 1;
-		bdrkreg_t	i_g_stall_ib		  :	 1;
-		bdrkreg_t	i_tt_imsg		  :	 8;
-		bdrkreg_t	i_tt_imsgtype		  :	 2;
-		bdrkreg_t	i_tt_use_old		  :	 1;
-		bdrkreg_t	i_tt_respreqd		  :	 1;
-		bdrkreg_t	i_tt_bte_num		  :	 1;
-		bdrkreg_t	i_cbn			  :	 1;
-		bdrkreg_t	i_match			  :	 1;
-		bdrkreg_t	i_rpcnt_lt_34		  :	 1;
-		bdrkreg_t	i_rpcnt_ge_34		  :	 1;
-		bdrkreg_t	i_rpcnt_lt_18		  :	 1;
-		bdrkreg_t	i_rpcnt_ge_18		  :	 1;
-		bdrkreg_t       i_rpcnt_lt_2              :      1;
-		bdrkreg_t	i_rpcnt_ge_2		  :	 1;
-		bdrkreg_t	i_rqcnt_lt_18		  :	 1;
-		bdrkreg_t	i_rqcnt_ge_18		  :	 1;
-		bdrkreg_t	i_rqcnt_lt_2		  :	 1;
-		bdrkreg_t	i_rqcnt_ge_2		  :	 1;
-		bdrkreg_t	i_tt_device		  :	 7;
-		bdrkreg_t	i_tt_init		  :	 3;
-		bdrkreg_t	i_reserved		  :	 5;
-	} ii_icsmh_fld_s;
-} ii_icsmh_u_t;
-
-#else
-
-typedef union ii_icsmh_u {
-	bdrkreg_t	ii_icsmh_regval;
-	struct	{
-		bdrkreg_t	i_reserved		  :	 5;
-		bdrkreg_t	i_tt_init		  :	 3;
-		bdrkreg_t	i_tt_device		  :	 7;
-		bdrkreg_t	i_rqcnt_ge_2		  :	 1;
-		bdrkreg_t	i_rqcnt_lt_2		  :	 1;
-		bdrkreg_t	i_rqcnt_ge_18		  :	 1;
-		bdrkreg_t	i_rqcnt_lt_18		  :	 1;
-		bdrkreg_t	i_rpcnt_ge_2		  :	 1;
-		bdrkreg_t	i_rpcnt_lt_2		  :	 1;
-		bdrkreg_t	i_rpcnt_ge_18		  :	 1;
-		bdrkreg_t	i_rpcnt_lt_18		  :	 1;
-		bdrkreg_t	i_rpcnt_ge_34		  :	 1;
-		bdrkreg_t	i_rpcnt_lt_34		  :	 1;
-		bdrkreg_t	i_match			  :	 1;
-		bdrkreg_t	i_cbn			  :	 1;
-		bdrkreg_t	i_tt_bte_num		  :	 1;
-		bdrkreg_t	i_tt_respreqd		  :	 1;
-		bdrkreg_t	i_tt_use_old		  :	 1;
-		bdrkreg_t	i_tt_imsgtype		  :	 2;
-		bdrkreg_t	i_tt_imsg		  :	 8;
-		bdrkreg_t	i_g_stall_ib		  :	 1;
-		bdrkreg_t	i_g_stall_il		  :	 1;
-		bdrkreg_t	i_g_stall_bte0		  :	 1;
-		bdrkreg_t	i_g_stall_bte1		  :	 1;
-		bdrkreg_t	i_tt_intvn		  :	 1;
-		bdrkreg_t	i_tt_resp		  :	 1;
-		bdrkreg_t	i_tt_ack		  :	 1;
-		bdrkreg_t	i_tt_hold		  :	 1;
-		bdrkreg_t	i_tt_wb			  :	 1;
-		bdrkreg_t	i_tt_exc		  :	 5;
-		bdrkreg_t	i_plusg			  :	 1;
-		bdrkreg_t	i_plusz			  :	 1;
-		bdrkreg_t	i_mnusz			  :	 1;
-		bdrkreg_t	i_mnusg			  :	 1;
-		bdrkreg_t	i_sync			  :	 1;
-		bdrkreg_t	i_ft_active_o		  :	 1;
-		bdrkreg_t	i_ft_wact_o		  :	 1;
-		bdrkreg_t	i_ft_cwact_o		  :	 1;
-		bdrkreg_t	i_xerr			  :	 1;
-		bdrkreg_t	i_tt_vld		  :	 1;
-	} ii_icsmh_fld_s;
-} ii_icsmh_u_t;
-
-#endif
-
-
-/************************************************************************
- *                                                                      *
- *  The Bedrock DEBUG unit provides a 3-bit selection signal to the     *
- * II unit, thus allowing a choice of one set of debug signal outputs   *
- * from a menu of 8 options. Each option is limited to 32 bits in       *
- * size. There are more signals of interest than can be accommodated    *
- * in this 8*32 framework, so the IDBSS register has been defined to    *
- * extend the range of choices available. For each menu option          *
- * available to the DEBUG unit, the II provides a "submenu" of          *
- * several options. The value of the SUBMENU field in the IDBSS         *
- * register selects the desired submenu. Hence, the particular debug    *
- * signals provided by the II are determined by the 3-bit selection     *
- * signal from the DEBUG unit and the value of the SUBMENU field        *
- * within the IDBSS register. For a detailed description of the         *
- * available menus and submenus for II debug signals, refer to the      *
- * documentation in ii_interface.doc..                                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LIITLE_ENDIAN
-
-typedef union ii_idbss_u {
-	bdrkreg_t	ii_idbss_regval;
-	struct  {
-		bdrkreg_t	i_submenu                 :	 3;
-		bdrkreg_t	i_rsvd			  :	61;
-	} ii_idbss_fld_s;
-} ii_idbss_u_t;
-
-#else
-
-typedef union ii_idbss_u {
-	bdrkreg_t	ii_idbss_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	61;
-		bdrkreg_t	i_submenu		  :	 3;
-	} ii_idbss_fld_s;
-} ii_idbss_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register is used to set up the length for a       *
- * transfer and then to monitor the progress of that transfer. This     *
- * register needs to be initialized before a transfer is started. A     *
- * legitimate write to this register will set the Busy bit, clear the   *
- * Error bit, and initialize the length to the value desired.           *
- * While the transfer is in progress, hardware will decrement the       *
- * length field with each successful block that is copied. Once the     *
- * transfer completes, hardware will clear the Busy bit. The length     *
- * field will also contain the number of cache lines left to be         *
- * transferred.                                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LIITLE_ENDIAN
-
-typedef union ii_ibls0_u {
-	bdrkreg_t	ii_ibls0_regval;
-	struct	{
-		bdrkreg_t	i_length		  :	16;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_busy			  :	 1;
-		bdrkreg_t       i_rsvd                    :     43;
-	} ii_ibls0_fld_s;
-} ii_ibls0_u_t;
-
-#else
-
-typedef union ii_ibls0_u {
-	bdrkreg_t	ii_ibls0_regval;
-	struct  {
-		bdrkreg_t	i_rsvd                    :	43;
-		bdrkreg_t	i_busy                    :	 1;
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_error                   :	 1;
-		bdrkreg_t	i_length                  :	16;
-	} ii_ibls0_fld_s;
-} ii_ibls0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register should be loaded before a transfer is started. The    *
- * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
- * address as described in Section 1.3, Figure2 and Figure3. Since      *
- * the bottom 7 bits of the address are always taken to be zero, BTE    *
- * transfers are always cacheline-aligned.                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibsa0_u {
-	bdrkreg_t	ii_ibsa0_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 7;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t       i_rsvd                    :     24;
-	} ii_ibsa0_fld_s;
-} ii_ibsa0_u_t;
-
-#else
-
-typedef union ii_ibsa0_u {
-	bdrkreg_t	ii_ibsa0_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	24;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-	} ii_ibsa0_fld_s;
-} ii_ibsa0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register should be loaded before a transfer is started. The    *
- * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
- * address as described in Section 1.3, Figure2 and Figure3. Since      *
- * the bottom 7 bits of the address are always taken to be zero, BTE    *
- * transfers are always cacheline-aligned.                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibda0_u {
-	bdrkreg_t	ii_ibda0_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 7;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd			  :	24;
-	} ii_ibda0_fld_s;
-} ii_ibda0_u_t;
-
-#else
-
-typedef union ii_ibda0_u {
-	bdrkreg_t	ii_ibda0_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	24;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-	} ii_ibda0_fld_s;
-} ii_ibda0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Writing to this register sets up the attributes of the transfer     *
- * and initiates the transfer operation. Reading this register has      *
- * the side effect of terminating any transfer in progress. Note:       *
- * stopping a transfer midstream could have an adverse impact on the    *
- * other BTE. If a BTE stream has to be stopped (due to error           *
- * handling for example), both BTE streams should be stopped and        *
- * their transfers discarded.                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibct0_u {
-	bdrkreg_t	ii_ibct0_regval;
-	struct  {
-		bdrkreg_t	i_zerofill                :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 3;
-		bdrkreg_t	i_notify		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t       i_poison                  :      1;
-		bdrkreg_t       i_rsvd                    :     55;
-	} ii_ibct0_fld_s;
-} ii_ibct0_u_t;
-
-#else
-
-typedef union ii_ibct0_u {
-	bdrkreg_t	ii_ibct0_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	55;
-		bdrkreg_t	i_poison		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_notify		  :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 3;
-		bdrkreg_t	i_zerofill		  :	 1;
-	} ii_ibct0_fld_s;
-} ii_ibct0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the address to which the WINV is sent.       *
- * This address has to be cache line aligned.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibna0_u {
-	bdrkreg_t	ii_ibna0_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 7;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd			  :	24;
-	} ii_ibna0_fld_s;
-} ii_ibna0_u_t;
-
-#else
-
-typedef union ii_ibna0_u {
-	bdrkreg_t	ii_ibna0_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	24;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-	} ii_ibna0_fld_s;
-} ii_ibna0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the programmable level as well as the node   *
- * ID and PI unit of the processor to which the interrupt will be       *
- * sent.                                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibia0_u {
-	bdrkreg_t	ii_ibia0_regval;
-	struct  {
-		bdrkreg_t	i_pi_id                   :	 1;
-		bdrkreg_t	i_node_id		  :	 8;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-		bdrkreg_t	i_level			  :	 7;
-		bdrkreg_t       i_rsvd                    :     41;
-	} ii_ibia0_fld_s;
-} ii_ibia0_u_t;
-
-#else
-
-typedef union ii_ibia0_u {
-	bdrkreg_t	ii_ibia0_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	41;
-		bdrkreg_t	i_level			  :	 7;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-		bdrkreg_t	i_node_id		  :	 8;
-		bdrkreg_t	i_pi_id			  :	 1;
-	} ii_ibia0_fld_s;
-} ii_ibia0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register is used to set up the length for a       *
- * transfer and then to monitor the progress of that transfer. This     *
- * register needs to be initialized before a transfer is started. A     *
- * legitimate write to this register will set the Busy bit, clear the   *
- * Error bit, and initialize the length to the value desired.           *
- * While the transfer is in progress, hardware will decrement the       *
- * length field with each successful block that is copied. Once the     *
- * transfer completes, hardware will clear the Busy bit. The length     *
- * field will also contain the number of cache lines left to be         *
- * transferred.                                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibls1_u {
-	bdrkreg_t	ii_ibls1_regval;
-	struct  {
-		bdrkreg_t	i_length                  :	16;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_busy			  :	 1;
-		bdrkreg_t       i_rsvd                    :     43;
-	} ii_ibls1_fld_s;
-} ii_ibls1_u_t;
-
-#else
-
-typedef union ii_ibls1_u {
-	bdrkreg_t	ii_ibls1_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	43;
-		bdrkreg_t	i_busy			  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_error			  :	 1;
-		bdrkreg_t	i_length		  :	16;
-	} ii_ibls1_fld_s;
-} ii_ibls1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register should be loaded before a transfer is started. The    *
- * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
- * address as described in Section 1.3, Figure2 and Figure3. Since      *
- * the bottom 7 bits of the address are always taken to be zero, BTE    *
- * transfers are always cacheline-aligned.                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibsa1_u {
-	bdrkreg_t	ii_ibsa1_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 7;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd			  :	24;
-	} ii_ibsa1_fld_s;
-} ii_ibsa1_u_t;
-
-#else
-
-typedef union ii_ibsa1_u {
-	bdrkreg_t	ii_ibsa1_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	24;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-	} ii_ibsa1_fld_s;
-} ii_ibsa1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register should be loaded before a transfer is started. The    *
- * address to be loaded in bits 39:0 is the 40-bit TRex+ physical       *
- * address as described in Section 1.3, Figure2 and Figure3. Since      *
- * the bottom 7 bits of the address are always taken to be zero, BTE    *
- * transfers are always cacheline-aligned.                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibda1_u {
-	bdrkreg_t	ii_ibda1_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 7;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd			  :	24;
-	} ii_ibda1_fld_s;
-} ii_ibda1_u_t;
-
-#else
-
-typedef union ii_ibda1_u {
-	bdrkreg_t	ii_ibda1_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	24;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-	} ii_ibda1_fld_s;
-} ii_ibda1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Writing to this register sets up the attributes of the transfer     *
- * and initiates the transfer operation. Reading this register has      *
- * the side effect of terminating any transfer in progress. Note:       *
- * stopping a transfer midstream could have an adverse impact on the    *
- * other BTE. If a BTE stream has to be stopped (due to error           *
- * handling for example), both BTE streams should be stopped and        *
- * their transfers discarded.                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibct1_u {
-	bdrkreg_t	ii_ibct1_regval;
-	struct  {
-		bdrkreg_t	i_zerofill                :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 3;
-		bdrkreg_t	i_notify		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_poison		  :	 1;
-		bdrkreg_t	i_rsvd			  :	55;
-	} ii_ibct1_fld_s;
-} ii_ibct1_u_t;
-
-#else
-
-typedef union ii_ibct1_u {
-	bdrkreg_t	ii_ibct1_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	55;
-		bdrkreg_t	i_poison		  :	 1;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-		bdrkreg_t	i_notify		  :	 1;
-		bdrkreg_t	i_rsvd_2		  :	 3;
-		bdrkreg_t	i_zerofill		  :	 1;
-	} ii_ibct1_fld_s;
-} ii_ibct1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the address to which the WINV is sent.       *
- * This address has to be cache line aligned.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibna1_u {
-	bdrkreg_t	ii_ibna1_regval;
-	struct  {
-		bdrkreg_t	i_rsvd_1                  :	 7;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t       i_rsvd                    :     24;
-	} ii_ibna1_fld_s;
-} ii_ibna1_u_t;
-
-#else
-
-typedef union ii_ibna1_u {
-	bdrkreg_t	ii_ibna1_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	24;
-		bdrkreg_t	i_addr			  :	33;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-	} ii_ibna1_fld_s;
-} ii_ibna1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the programmable level as well as the node   *
- * ID and PI unit of the processor to which the interrupt will be       *
- * sent.                                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ibia1_u {
-	bdrkreg_t	ii_ibia1_regval;
-	struct  {
-		bdrkreg_t	i_pi_id                   :	 1;
-		bdrkreg_t	i_node_id		  :	 8;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-		bdrkreg_t	i_level			  :	 7;
-		bdrkreg_t	i_rsvd			  :	41;
-	} ii_ibia1_fld_s;
-} ii_ibia1_u_t;
-
-#else
-
-typedef union ii_ibia1_u {
-	bdrkreg_t	ii_ibia1_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	41;
-		bdrkreg_t	i_level			  :	 7;
-		bdrkreg_t	i_rsvd_1		  :	 7;
-		bdrkreg_t	i_node_id		  :	 8;
-		bdrkreg_t	i_pi_id			  :	 1;
-	} ii_ibia1_fld_s;
-} ii_ibia1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register defines the resources that feed information into      *
- * the two performance counters located in the IO Performance           *
- * Profiling Register. There are 17 different quantities that can be    *
- * measured. Given these 17 different options, the two performance      *
- * counters have 15 of them in common; menu selections 0 through 0xE    *
- * are identical for each performance counter. As for the other two     *
- * options, one is available from one performance counter and the       *
- * other is available from the other performance counter. Hence, the    *
- * II supports all 17*16=272 possible combinations of quantities to     *
- * measure.                                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ipcr_u {
-	bdrkreg_t	ii_ipcr_regval;
-	struct  {
-		bdrkreg_t	i_ippr0_c                 :	 4;
-		bdrkreg_t	i_ippr1_c		  :	 4;
-		bdrkreg_t	i_icct			  :	 8;
-		bdrkreg_t       i_rsvd                    :     48;
-	} ii_ipcr_fld_s;
-} ii_ipcr_u_t;
-
-#else
-
-typedef union ii_ipcr_u {
-	bdrkreg_t	ii_ipcr_regval;
-	struct	{
-		bdrkreg_t	i_rsvd			  :	48;
-		bdrkreg_t	i_icct			  :	 8;
-		bdrkreg_t	i_ippr1_c		  :	 4;
-		bdrkreg_t	i_ippr0_c		  :	 4;
-	} ii_ipcr_fld_s;
-} ii_ipcr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *                                                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ii_ippr_u {
-	bdrkreg_t	ii_ippr_regval;
-	struct  {
-		bdrkreg_t	i_ippr0                   :	32;
-		bdrkreg_t	i_ippr1			  :	32;
-	} ii_ippr_fld_s;
-} ii_ippr_u_t;
-
-#else
-
-typedef union ii_ippr_u {
-	bdrkreg_t	ii_ippr_regval;
-	struct	{
-		bdrkreg_t	i_ippr1			  :	32;
-		bdrkreg_t	i_ippr0			  :	32;
-	} ii_ippr_fld_s;
-} ii_ippr_u_t;
-
-#endif
-
-
-
-
-
-
-#endif /* __ASSEMBLY__ */
-
-/************************************************************************
- *                                                                      *
- * The following defines which were not formed into structures are      *
- * probably indentical to another register, and the name of the         *
- * register is provided against each of these registers. This           *
- * information needs to be checked carefully                            *
- *                                                                      *
- *           IIO_ICRB1_A                IIO_ICRB0_A                       *
- *           IIO_ICRB1_B                IIO_ICRB0_B                       *
- *           IIO_ICRB1_C                IIO_ICRB0_C                       *
- *           IIO_ICRB1_D                IIO_ICRB0_D                       *
- *           IIO_ICRB2_A                IIO_ICRB0_A                       *
- *           IIO_ICRB2_B                IIO_ICRB0_B                       *
- *           IIO_ICRB2_C                IIO_ICRB0_C                       *
- *           IIO_ICRB2_D                IIO_ICRB0_D                       *
- *           IIO_ICRB3_A                IIO_ICRB0_A                       *
- *           IIO_ICRB3_B                IIO_ICRB0_B                       *
- *           IIO_ICRB3_C                IIO_ICRB0_C                       *
- *           IIO_ICRB3_D                IIO_ICRB0_D                       *
- *           IIO_ICRB4_A                IIO_ICRB0_A                       *
- *           IIO_ICRB4_B                IIO_ICRB0_B                       *
- *           IIO_ICRB4_C                IIO_ICRB0_C                       *
- *           IIO_ICRB4_D                IIO_ICRB0_D                       *
- *           IIO_ICRB5_A                IIO_ICRB0_A                       *
- *           IIO_ICRB5_B                IIO_ICRB0_B                       *
- *           IIO_ICRB5_C                IIO_ICRB0_C                       *
- *           IIO_ICRB5_D                IIO_ICRB0_D                       *
- *           IIO_ICRB6_A                IIO_ICRB0_A                       *
- *           IIO_ICRB6_B                IIO_ICRB0_B                       *
- *           IIO_ICRB6_C                IIO_ICRB0_C                       *
- *           IIO_ICRB6_D                IIO_ICRB0_D                       *
- *           IIO_ICRB7_A                IIO_ICRB0_A                       *
- *           IIO_ICRB7_B                IIO_ICRB0_B                       *
- *           IIO_ICRB7_C                IIO_ICRB0_C                       *
- *           IIO_ICRB7_D                IIO_ICRB0_D                       *
- *           IIO_ICRB8_A                IIO_ICRB0_A                       *
- *           IIO_ICRB8_B                IIO_ICRB0_B                       *
- *           IIO_ICRB8_C                IIO_ICRB0_C                       *
- *           IIO_ICRB8_D                IIO_ICRB0_D                       *
- *           IIO_ICRB9_A                IIO_ICRB0_A                       *
- *           IIO_ICRB9_B                IIO_ICRB0_B                       *
- *           IIO_ICRB9_C                IIO_ICRB0_C                       *
- *           IIO_ICRB9_D                IIO_ICRB0_D                       *
- *           IIO_ICRBA_A                IIO_ICRB0_A                       *
- *           IIO_ICRBA_B                IIO_ICRB0_B                       *
- *           IIO_ICRBA_C                IIO_ICRB0_C                       *
- *           IIO_ICRBA_D                IIO_ICRB0_D                       *
- *           IIO_ICRBB_A                IIO_ICRB0_A                       *
- *           IIO_ICRBB_B                IIO_ICRB0_B                       *
- *           IIO_ICRBB_C                IIO_ICRB0_C                       *
- *           IIO_ICRBB_D                IIO_ICRB0_D                       *
- *           IIO_ICRBC_A                IIO_ICRB0_A                       *
- *           IIO_ICRBC_B                IIO_ICRB0_B                       *
- *           IIO_ICRBC_C                IIO_ICRB0_C                       *
- *           IIO_ICRBC_D                IIO_ICRB0_D                       *
- *           IIO_ICRBD_A                IIO_ICRB0_A                       *
- *           IIO_ICRBD_B                IIO_ICRB0_B                       *
- *           IIO_ICRBD_C                IIO_ICRB0_C                       *
- *           IIO_ICRBD_D                IIO_ICRB0_D                       *
- *           IIO_ICRBE_A                IIO_ICRB0_A                       *
- *           IIO_ICRBE_B                IIO_ICRB0_B                       *
- *           IIO_ICRBE_C                IIO_ICRB0_C                       *
- *           IIO_ICRBE_D                IIO_ICRB0_D                       *
- *                                                                      *
- ************************************************************************/
-
-
-/************************************************************************
- *                                                                      *
- *               MAKE ALL ADDITIONS AFTER THIS LINE                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-
-#endif /* _ASM_IA64_SN_SN1_HUBIO_H */
diff -Nru a/include/asm-ia64/sn/sn1/hubio_next.h b/include/asm-ia64/sn/sn1/hubio_next.h
--- a/include/asm-ia64/sn/sn1/hubio_next.h	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,762 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBIO_NEXT_H
-#define _ASM_IA64_SN_SN1_HUBIO_NEXT_H
-
-/*
- * Slightly friendlier names for some common registers.
- */
-#define IIO_WIDGET              IIO_WID      /* Widget identification */
-#define IIO_WIDGET_STAT         IIO_WSTAT    /* Widget status register */
-#define IIO_WIDGET_CTRL         IIO_WCR      /* Widget control register */
-#define IIO_PROTECT             IIO_ILAPR    /* IO interface protection */
-#define IIO_PROTECT_OVRRD       IIO_ILAPO    /* IO protect override */
-#define IIO_OUTWIDGET_ACCESS    IIO_IOWA     /* Outbound widget access */
-#define IIO_INWIDGET_ACCESS     IIO_IIWA     /* Inbound widget access */
-#define IIO_INDEV_ERR_MASK      IIO_IIDEM    /* Inbound device error mask */
-#define IIO_LLP_CSR             IIO_ILCSR    /* LLP control and status */
-#define IIO_LLP_LOG             IIO_ILLR     /* LLP log */
-#define IIO_XTALKCC_TOUT        IIO_IXCC     /* Xtalk credit count timeout*/
-#define IIO_XTALKTT_TOUT        IIO_IXTT     /* Xtalk tail timeout */
-#define IIO_IO_ERR_CLR          IIO_IECLR    /* IO error clear */
-#define IIO_IGFX_0 		IIO_IGFX0
-#define IIO_IGFX_1 		IIO_IGFX1
-#define IIO_IBCT_0		IIO_IBCT0
-#define IIO_IBCT_1		IIO_IBCT1
-#define IIO_IBLS_0		IIO_IBLS0
-#define IIO_IBLS_1		IIO_IBLS1
-#define IIO_IBSA_0		IIO_IBSA0
-#define IIO_IBSA_1		IIO_IBSA1
-#define IIO_IBDA_0		IIO_IBDA0
-#define IIO_IBDA_1		IIO_IBDA1
-#define IIO_IBNA_0		IIO_IBNA0
-#define IIO_IBNA_1		IIO_IBNA1
-#define IIO_IBIA_0		IIO_IBIA0
-#define IIO_IBIA_1		IIO_IBIA1
-#define IIO_IOPRB_0		IIO_IPRB0
-#define IIO_PRTE_0      	IIO_IPRTE0        /* PIO Read address table entry 0 */
-#define IIO_PRTE(_x)    	(IIO_PRTE_0 + (8 * (_x)))
-#define IIO_NUM_IPRBS 		(9) 
-#define IIO_WIDPRTE(x)  IIO_PRTE(((x) - 8)) /* widget ID to its PRTE num */
-
-#define IIO_LLP_CSR_IS_UP               0x00002000
-#define IIO_LLP_CSR_LLP_STAT_MASK       0x00003000
-#define IIO_LLP_CSR_LLP_STAT_SHFT       12
-
-#define IIO_LLP_CB_MAX  0xffff	/* in ILLR CB_CNT, Max Check Bit errors */
-#define IIO_LLP_SN_MAX  0xffff	/* in ILLR SN_CNT, Max Sequence Number errors */
-
-/* key to IIO_PROTECT_OVRRD */
-#define IIO_PROTECT_OVRRD_KEY   0x53474972756c6573ull   /* "SGIrules" */
-
-/* BTE register names */
-#define IIO_BTE_STAT_0          IIO_IBLS_0   /* Also BTE length/status 0 */
-#define IIO_BTE_SRC_0           IIO_IBSA_0   /* Also BTE source address  0 */
-#define IIO_BTE_DEST_0          IIO_IBDA_0   /* Also BTE dest. address 0 */
-#define IIO_BTE_CTRL_0          IIO_IBCT_0   /* Also BTE control/terminate 0 */
-#define IIO_BTE_NOTIFY_0        IIO_IBNA_0   /* Also BTE notification 0 */
-#define IIO_BTE_INT_0           IIO_IBIA_0   /* Also BTE interrupt 0 */
-#define IIO_BTE_OFF_0           0            /* Base offset from BTE 0 regs. */
-#define IIO_BTE_OFF_1  (IIO_IBLS_1 - IIO_IBLS_0) /* Offset from base to BTE 1 */
-
-/* BTE register offsets from base */
-#define BTEOFF_STAT             0
-#define BTEOFF_SRC              (IIO_BTE_SRC_0 - IIO_BTE_STAT_0)
-#define BTEOFF_DEST             (IIO_BTE_DEST_0 - IIO_BTE_STAT_0)
-#define BTEOFF_CTRL             (IIO_BTE_CTRL_0 - IIO_BTE_STAT_0)
-#define BTEOFF_NOTIFY           (IIO_BTE_NOTIFY_0 - IIO_BTE_STAT_0)
-#define BTEOFF_INT              (IIO_BTE_INT_0 - IIO_BTE_STAT_0)
-
-
-/* names used in hub_diags.c; carried over from SN0 */
-#define IIO_BASE_BTE0   IIO_IBLS_0		
-#define IIO_BASE_BTE1   IIO_IBLS_1		
-
-/*
- * Macro which takes the widget number, and returns the 
- * IO PRB address of that widget.
- * value _x is expected to be a widget number in the range 
- * 0, 8 - 0xF
- */
-#define	IIO_IOPRB(_x)	(IIO_IOPRB_0 + ( ( (_x) < HUB_WIDGET_ID_MIN ? \
-			(_x) : \
-			(_x) - (HUB_WIDGET_ID_MIN-1)) << 3) )
-
-
-/* GFX Flow Control Node/Widget Register */
-#define IIO_IGFX_W_NUM_BITS	4	/* size of widget num field */
-#define IIO_IGFX_W_NUM_MASK	((1<<IIO_IGFX_W_NUM_BITS)-1)
-#define IIO_IGFX_W_NUM_SHIFT	0
-#define IIO_IGFX_PI_NUM_BITS	1	/* size of PI num field */
-#define IIO_IGFX_PI_NUM_MASK	((1<<IIO_IGFX_PI_NUM_BITS)-1)
-#define IIO_IGFX_PI_NUM_SHIFT	4
-#define IIO_IGFX_N_NUM_BITS	8	/* size of node num field */
-#define IIO_IGFX_N_NUM_MASK	((1<<IIO_IGFX_N_NUM_BITS)-1)
-#define IIO_IGFX_N_NUM_SHIFT	5
-#define IIO_IGFX_P_NUM_BITS	1	/* size of processor num field */
-#define IIO_IGFX_P_NUM_MASK	((1<<IIO_IGFX_P_NUM_BITS)-1)
-#define IIO_IGFX_P_NUM_SHIFT	16
-#define IIO_IGFX_INIT(widget, pi, node, cpu)				(\
-	(((widget) & IIO_IGFX_W_NUM_MASK) << IIO_IGFX_W_NUM_SHIFT) |	 \
-	(((pi)     & IIO_IGFX_PI_NUM_MASK)<< IIO_IGFX_PI_NUM_SHIFT)|	 \
-	(((node)   & IIO_IGFX_N_NUM_MASK) << IIO_IGFX_N_NUM_SHIFT) |	 \
-	(((cpu)    & IIO_IGFX_P_NUM_MASK) << IIO_IGFX_P_NUM_SHIFT))
-
-
-/* Scratch registers (all bits available) */
-#define IIO_SCRATCH_REG0        IIO_ISCR0
-#define IIO_SCRATCH_REG1        IIO_ISCR1
-#define IIO_SCRATCH_MASK        0xffffffffffffffff
-
-#define IIO_SCRATCH_BIT0_0      0x0000000000000001
-#define IIO_SCRATCH_BIT0_1      0x0000000000000002
-#define IIO_SCRATCH_BIT0_2      0x0000000000000004
-#define IIO_SCRATCH_BIT0_3      0x0000000000000008
-#define IIO_SCRATCH_BIT0_4      0x0000000000000010
-#define IIO_SCRATCH_BIT0_5      0x0000000000000020
-#define IIO_SCRATCH_BIT0_6      0x0000000000000040
-#define IIO_SCRATCH_BIT0_7      0x0000000000000080
-#define IIO_SCRATCH_BIT0_8      0x0000000000000100
-#define IIO_SCRATCH_BIT0_9      0x0000000000000200
-#define IIO_SCRATCH_BIT0_A      0x0000000000000400
-
-#define IIO_SCRATCH_BIT1_0      0x0000000000000001
-#define IIO_SCRATCH_BIT1_1      0x0000000000000002
-/* IO Translation Table Entries */
-#define IIO_NUM_ITTES   7               /* ITTEs numbered 0..6 */
-                                        /* Hw manuals number them 1..7! */
-/*
- * IIO_IMEM Register fields.
- */
-#define IIO_IMEM_W0ESD  0x1             /* Widget 0 shut down due to error */
-#define IIO_IMEM_B0ESD  (1 << 4)        /* BTE 0 shut down due to error */
-#define IIO_IMEM_B1ESD  (1 << 8)        /* BTE 1 Shut down due to error */
-
-/*
- * As a permanent workaround for a bug in the PI side of the hub, we've
- * redefined big window 7 as small window 0.
- XXX does this still apply for SN1??
- */
-#define HUB_NUM_BIG_WINDOW      (IIO_NUM_ITTES - 1)
-
-/*
- * Use the top big window as a surrogate for the first small window
- */
-#define SWIN0_BIGWIN            HUB_NUM_BIG_WINDOW
-
-#define IIO_NUM_PRTES   8               /* Total number of PRB table entries */
-
-#define ILCSR_WARM_RESET        0x100
-
-/*
- * CRB manipulation macros
- *      The CRB macros are slightly complicated, since there are up to
- *      four registers associated with each CRB entry.
- */
-#define IIO_NUM_CRBS            15      /* Number of CRBs */
-#define IIO_NUM_NORMAL_CRBS     12      /* Number of regular CRB entries */
-#define IIO_NUM_PC_CRBS         4       /* Number of partial cache CRBs */
-#define IIO_ICRB_OFFSET         8
-#define IIO_ICRB_0              IIO_ICRB0_A
-#define IIO_ICRB_ADDR_SHFT	2	/* Shift to get proper address */
-/* XXX - This is now tuneable:
-        #define IIO_FIRST_PC_ENTRY 12
- */
-
-#define IIO_ICRB_A(_x)  (IIO_ICRB_0 + (4 * IIO_ICRB_OFFSET * (_x)))
-#define IIO_ICRB_B(_x)  (IIO_ICRB_A(_x) + 1*IIO_ICRB_OFFSET)
-#define IIO_ICRB_C(_x)  (IIO_ICRB_A(_x) + 2*IIO_ICRB_OFFSET)
-#define IIO_ICRB_D(_x)  (IIO_ICRB_A(_x) + 3*IIO_ICRB_OFFSET)
-
-#define TNUM_TO_WIDGET_DEV(_tnum)	(_tnum & 0x7)
-
-/*
- * values for "ecode" field
- */
-#define IIO_ICRB_ECODE_DERR     0       /* Directory error due to IIO access */
-#define IIO_ICRB_ECODE_PERR     1       /* Poison error on IO access */
-#define IIO_ICRB_ECODE_WERR     2       /* Write error by IIO access
-                                         * e.g. WINV to a Read only line. */
-#define IIO_ICRB_ECODE_AERR     3       /* Access error caused by IIO access */
-#define IIO_ICRB_ECODE_PWERR    4       /* Error on partial write       */
-#define IIO_ICRB_ECODE_PRERR    5       /* Error on partial read        */
-#define IIO_ICRB_ECODE_TOUT     6       /* CRB timeout before deallocating */
-#define IIO_ICRB_ECODE_XTERR    7       /* Incoming xtalk pkt had error bit */
-
-/*
- * Number of credits Hub widget has while sending req/response to
- * xbow.
- * Value of 3 is required by Xbow 1.1
- * We may be able to increase this to 4 with Xbow 1.2.
- */
-#define       HUBII_XBOW_CREDIT       3
-#define       HUBII_XBOW_REV2_CREDIT  4
-
-/*
- * Number of credits that xtalk devices should use when communicating
- * with a Bedrock (depth of Bedrock's queue).
- */
-#define HUB_CREDIT 4
-
-/*
- * Some IIO_PRB fields
- */
-#define IIO_PRB_MULTI_ERR	(1LL << 63)
-#define IIO_PRB_SPUR_RD		(1LL << 51)
-#define IIO_PRB_SPUR_WR		(1LL << 50)
-#define IIO_PRB_RD_TO		(1LL << 49)
-#define IIO_PRB_ERROR		(1LL << 48)
-
-/*************************************************************************
-
- Some of the IIO field masks and shifts are defined here.
- This is in order to maintain compatibility in SN0 and SN1 code
- 
-**************************************************************************/
-
-/*
- * ICMR register fields
- * (Note: the IIO_ICMR_P_CNT and IIO_ICMR_PC_VLD from Hub are not
- * present in Bedrock)
- */
-
-#define IIO_ICMR_CRB_VLD_SHFT   20
-#define IIO_ICMR_CRB_VLD_MASK   (0x7fffUL << IIO_ICMR_CRB_VLD_SHFT)
-
-#define IIO_ICMR_FC_CNT_SHFT    16
-#define IIO_ICMR_FC_CNT_MASK    (0xf << IIO_ICMR_FC_CNT_SHFT)
-
-#define IIO_ICMR_C_CNT_SHFT     4
-#define IIO_ICMR_C_CNT_MASK     (0xf << IIO_ICMR_C_CNT_SHFT)
-
-#define IIO_ICMR_PRECISE        (1UL << 52)
-#define IIO_ICMR_CLR_RPPD       (1UL << 13)
-#define IIO_ICMR_CLR_RQPD       (1UL << 12)
-
-/*
- * IIO PIO Deallocation register field masks : (IIO_IPDR)
- XXX present but not needed in bedrock?  See the manual.
- */
-#define IIO_IPDR_PND    (1 << 4)
-
-/*
- * IIO CRB deallocation register field masks: (IIO_ICDR)
- */
-#define IIO_ICDR_PND    (1 << 4)
-
-/* 
- * IO BTE Length/Status (IIO_IBLS) register bit field definitions
- */
-#define IBLS_BUSY		(0x1 << 20)
-#define IBLS_ERROR_SHFT		16
-#define IBLS_ERROR		(0x1 << IBLS_ERROR_SHFT)
-#define IBLS_LENGTH_MASK	0xffff
-
-/*
- * IO BTE Control/Terminate register (IBCT) register bit field definitions
- */
-#define IBCT_POISON		(0x1 << 8)
-#define IBCT_NOTIFY		(0x1 << 4)
-#define IBCT_ZFIL_MODE		(0x1 << 0)
-
-/*
- * IIO Incoming Error Packet Header (IIO_IIEPH1/IIO_IIEPH2)
- */
-#define IIEPH1_VALID		(1 << 44)
-#define IIEPH1_OVERRUN		(1 << 40)
-#define IIEPH1_ERR_TYPE_SHFT	32
-#define IIEPH1_ERR_TYPE_MASK	0xf
-#define IIEPH1_SOURCE_SHFT	20
-#define IIEPH1_SOURCE_MASK	11
-#define IIEPH1_SUPPL_SHFT	8
-#define IIEPH1_SUPPL_MASK	11
-#define IIEPH1_CMD_SHFT		0
-#define IIEPH1_CMD_MASK		7
-
-#define IIEPH2_TAIL		(1 << 40)
-#define IIEPH2_ADDRESS_SHFT	0
-#define IIEPH2_ADDRESS_MASK	38
-
-#define IIEPH1_ERR_SHORT_REQ	2
-#define IIEPH1_ERR_SHORT_REPLY	3
-#define IIEPH1_ERR_LONG_REQ	4
-#define IIEPH1_ERR_LONG_REPLY	5
-
-/*
- * IO Error Clear register bit field definitions
- */
-#define IECLR_PI1_FWD_INT	(1 << 31)  /* clear PI1_FORWARD_INT in iidsr */
-#define IECLR_PI0_FWD_INT	(1 << 30)  /* clear PI0_FORWARD_INT in iidsr */
-#define IECLR_SPUR_RD_HDR	(1 << 29)  /* clear valid bit in ixss reg */
-#define IECLR_BTE1		(1 << 18)  /* clear bte error 1 */
-#define IECLR_BTE0		(1 << 17)  /* clear bte error 0 */
-#define IECLR_CRAZY		(1 << 16)  /* clear crazy bit in wstat reg */
-#define IECLR_PRB_F		(1 << 15)  /* clear err bit in PRB_F reg */
-#define IECLR_PRB_E		(1 << 14)  /* clear err bit in PRB_E reg */
-#define IECLR_PRB_D		(1 << 13)  /* clear err bit in PRB_D reg */
-#define IECLR_PRB_C		(1 << 12)  /* clear err bit in PRB_C reg */
-#define IECLR_PRB_B		(1 << 11)  /* clear err bit in PRB_B reg */
-#define IECLR_PRB_A		(1 << 10)  /* clear err bit in PRB_A reg */
-#define IECLR_PRB_9		(1 << 9)   /* clear err bit in PRB_9 reg */
-#define IECLR_PRB_8		(1 << 8)   /* clear err bit in PRB_8 reg */
-#define IECLR_PRB_0		(1 << 0)   /* clear err bit in PRB_0 reg */
-
-/*
- * IIO CRB control register Fields: IIO_ICCR 
- */
-#define	IIO_ICCR_PENDING	(0x10000)
-#define	IIO_ICCR_CMD_MASK	(0xFF)
-#define	IIO_ICCR_CMD_SHFT	(7)
-#define	IIO_ICCR_CMD_NOP	(0x0)	/* No Op */
-#define	IIO_ICCR_CMD_WAKE	(0x100) /* Reactivate CRB entry and process */
-#define	IIO_ICCR_CMD_TIMEOUT	(0x200)	/* Make CRB timeout & mark invalid */
-#define	IIO_ICCR_CMD_EJECT	(0x400)	/* Contents of entry written to memory 
-					 * via a WB
-					 */
-#define	IIO_ICCR_CMD_FLUSH	(0x800)
-
-/*
- *
- * CRB Register description.
- *
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING * WARNING
- *
- * Many of the fields in CRB are status bits used by hardware
- * for implementation of the protocol. It's very dangerous to
- * mess around with the CRB registers.
- *
- * It's OK to read the CRB registers and try to make sense out of the
- * fields in CRB.
- *
- * Updating CRB requires all activities in Hub IIO to be quiesced.
- * otherwise, a write to CRB could corrupt other CRB entries.
- * CRBs are here only as a back door peek to hub IIO's status.
- * Quiescing implies  no dmas no PIOs
- * either directly from the cpu or from sn0net.
- * this is not something that can be done easily. So, AVOID updating
- * CRBs.
- */
-
-#ifndef __ASSEMBLY__
-
-/*
- * Easy access macros for CRBs, all 4 registers (A-D)
- */
-typedef ii_icrb0_a_u_t icrba_t;	/* what it was called on SN0/hub */
-#define a_error         ii_icrb0_a_fld_s.ia_error
-#define a_ecode         ii_icrb0_a_fld_s.ia_errcode
-#define a_lnetuce       ii_icrb0_a_fld_s.ia_ln_uce
-#define a_mark          ii_icrb0_a_fld_s.ia_mark
-#define a_xerr          ii_icrb0_a_fld_s.ia_xt_err
-#define a_sidn          ii_icrb0_a_fld_s.ia_sidn
-#define a_tnum          ii_icrb0_a_fld_s.ia_tnum
-#define a_addr          ii_icrb0_a_fld_s.ia_addr
-#define a_valid         ii_icrb0_a_fld_s.ia_vld
-#define a_iow           ii_icrb0_a_fld_s.ia_iow
-#define a_regvalue	ii_icrb0_a_regval
-
-typedef ii_icrb0_b_u_t icrbb_t;
-#define b_btenum        ii_icrb0_b_fld_s.ib_bte_num
-#define b_cohtrans      ii_icrb0_b_fld_s.ib_ct
-#define b_xtsize        ii_icrb0_b_fld_s.ib_size
-#define b_source        ii_icrb0_b_fld_s.ib_source
-#define b_imsgtype      ii_icrb0_b_fld_s.ib_imsgtype
-#define b_imsg          ii_icrb0_b_fld_s.ib_imsg
-#define b_initiator     ii_icrb0_b_fld_s.ib_init
-#define b_regvalue	ii_icrb0_b_regval
-
-typedef ii_icrb0_c_u_t icrbc_t;
-#define c_pricnt        ii_icrb0_c_fld_s.ic_pr_cnt
-#define c_pripsc        ii_icrb0_c_fld_s.ic_pr_psc
-#define c_bteop         ii_icrb0_c_fld_s.ic_bte_op
-#define c_bteaddr       ii_icrb0_c_fld_s.ic_pa_be /* ic_pa_be fld has 2 names*/
-#define c_benable       ii_icrb0_c_fld_s.ic_pa_be /* ic_pa_be fld has 2 names*/
-#define c_suppl         ii_icrb0_c_fld_s.ic_suppl
-#define c_barrop        ii_icrb0_c_fld_s.ic_bo
-#define c_doresp        ii_icrb0_c_fld_s.ic_resprqd
-#define c_gbr           ii_icrb0_c_fld_s.ic_gbr
-#define c_regvalue	ii_icrb0_c_regval
-
-typedef ii_icrb0_d_u_t icrbd_t;
-#define icrbd_ctxtvld   ii_icrb0_d_fld_s.id_cvld
-#define icrbd_toutvld   ii_icrb0_d_fld_s.id_tvld
-#define icrbd_context   ii_icrb0_d_fld_s.id_context
-#define d_regvalue	ii_icrb0_d_regval
-
-#endif /* __ASSEMBLY__ */
-
-/* Number of widgets supported by hub */
-#define HUB_NUM_WIDGET          9
-#define HUB_WIDGET_ID_MIN       0x8
-#define HUB_WIDGET_ID_MAX       0xf
-
-#define HUB_WIDGET_PART_NUM     0xc110
-#define MAX_HUBS_PER_XBOW       2
-
-#ifndef __ASSEMBLY__
-/* A few more #defines for backwards compatibility */
-#define iprb_t          ii_iprb0_u_t
-#define iprb_regval     ii_iprb0_regval
-#define iprb_mult_err	ii_iprb0_fld_s.i_mult_err
-#define iprb_spur_rd	ii_iprb0_fld_s.i_spur_rd
-#define iprb_spur_wr	ii_iprb0_fld_s.i_spur_wr
-#define iprb_rd_to	ii_iprb0_fld_s.i_rd_to
-#define iprb_ovflow     ii_iprb0_fld_s.i_of_cnt
-#define iprb_error      ii_iprb0_fld_s.i_error
-#define iprb_ff         ii_iprb0_fld_s.i_f
-#define iprb_mode       ii_iprb0_fld_s.i_m
-#define iprb_bnakctr    ii_iprb0_fld_s.i_nb
-#define iprb_anakctr    ii_iprb0_fld_s.i_na
-#define iprb_xtalkctr   ii_iprb0_fld_s.i_c
-#endif
-
-#define LNK_STAT_WORKING        0x2
-
-#define IIO_WSTAT_ECRAZY        (1ULL << 32)    /* Hub gone crazy */
-#define IIO_WSTAT_TXRETRY       (1ULL << 9)     /* Hub Tx Retry timeout */
-#define IIO_WSTAT_TXRETRY_MASK  (0x7F)   /* should be 0xFF?? */
-#define IIO_WSTAT_TXRETRY_SHFT  (16)
-#define IIO_WSTAT_TXRETRY_CNT(w)        (((w) >> IIO_WSTAT_TXRETRY_SHFT) & \
-                                          IIO_WSTAT_TXRETRY_MASK)
-
-/* Number of II perf. counters we can multiplex at once */
-
-#define IO_PERF_SETS	32
-
-#if __KERNEL__
-#ifndef __ASSEMBLY__
-/* XXX moved over from SN/SN0/hubio.h -- each should be checked for SN1 */
-#include <asm/sn/alenlist.h>
-#include <asm/sn/dmamap.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/xtalk/xtalk.h>
-
-/* Bit for the widget in inbound access register */
-#define IIO_IIWA_WIDGET(_w)     ((uint64_t)(1ULL << _w))
-/* Bit for the widget in outbound access register */
-#define IIO_IOWA_WIDGET(_w)     ((uint64_t)(1ULL << _w))
-
-/* NOTE: The following define assumes that we are going to get
- * widget numbers from 8 thru F and the device numbers within
- * widget from 0 thru 7.
- */
-#define IIO_IIDEM_WIDGETDEV_MASK(w, d)  ((uint64_t)(1ULL << (8 * ((w) - 8) + (d))))
-
-/* IO Interrupt Destination Register */
-#define IIO_IIDSR_SENT_SHIFT    28
-#define IIO_IIDSR_SENT_MASK     0x10000000
-#define IIO_IIDSR_ENB_SHIFT     24
-#define IIO_IIDSR_ENB_MASK      0x01000000
-#define IIO_IIDSR_NODE_SHIFT    8
-#define IIO_IIDSR_NODE_MASK     0x0000ff00
-#define IIO_IIDSR_PI_ID_SHIFT   8
-#define IIO_IIDSR_PI_ID_MASK    0x00000010
-#define IIO_IIDSR_LVL_SHIFT     0
-#define IIO_IIDSR_LVL_MASK      0x0000007f
-
-/* Xtalk timeout threshhold register (IIO_IXTT) */
-#define IXTT_RRSP_TO_SHFT	55	   /* read response timeout */
-#define IXTT_RRSP_TO_MASK	(0x1FULL << IXTT_RRSP_TO_SHFT)
-#define IXTT_RRSP_PS_SHFT	32	   /* read responsed TO prescalar */
-#define IXTT_RRSP_PS_MASK	(0x7FFFFFULL << IXTT_RRSP_PS_SHFT)
-#define IXTT_TAIL_TO_SHFT	0	   /* tail timeout counter threshold */
-#define IXTT_TAIL_TO_MASK	(0x3FFFFFFULL << IXTT_TAIL_TO_SHFT)
-
-/*
- * The IO LLP control status register and widget control register
- */
-
-#ifdef LITTLE_ENDIAN
-
-typedef union hubii_wcr_u {
-        uint64_t      wcr_reg_value;
-        struct {
-	  uint64_t	wcr_widget_id:   4,     /* LLP crossbar credit */
-			wcr_tag_mode:	 1,	/* Tag mode */
-			wcr_rsvd1:	 8,	/* Reserved */
-			wcr_xbar_crd:	 3,	/* LLP crossbar credit */
-			wcr_f_bad_pkt:	 1,	/* Force bad llp pkt enable */
-			wcr_dir_con:	 1,	/* widget direct connect */
-			wcr_e_thresh:	 5,	/* elasticity threshold */
-			wcr_rsvd:	41;	/* unused */
-        } wcr_fields_s;
-} hubii_wcr_t;
-
-#else
-
-typedef union hubii_wcr_u {
-	uint64_t	wcr_reg_value;
-	struct {
-	    uint64_t	wcr_rsvd:	41,	/* unused */
-			wcr_e_thresh:	 5,	/* elasticity threshold */
-			wcr_dir_con:	 1,	/* widget direct connect */
-			wcr_f_bad_pkt:	 1,	/* Force bad llp pkt enable */
-			wcr_xbar_crd:	 3,	/* LLP crossbar credit */
-			wcr_rsvd1:	 8,	/* Reserved */
-			wcr_tag_mode:	 1,	/* Tag mode */
-			wcr_widget_id:	 4;	/* LLP crossbar credit */
-	} wcr_fields_s;
-} hubii_wcr_t;
-
-#endif
-
-#define iwcr_dir_con    wcr_fields_s.wcr_dir_con
-
-/* The structures below are defined to extract and modify the ii
-performance registers */
-
-/* io_perf_sel allows the caller to specify what tests will be
-   performed */
-#ifdef LITTLE_ENDIAN
-
-typedef union io_perf_sel {
-        uint64_t perf_sel_reg;
-        struct {
-               uint64_t	perf_ippr0 :  4,
-				perf_ippr1 :  4,
-				perf_icct  :  8,
-				perf_rsvd  : 48;
-        } perf_sel_bits;
-} io_perf_sel_t;
-
-#else
-
-typedef union io_perf_sel {
-	uint64_t perf_sel_reg;
-	struct {
-		uint64_t	perf_rsvd  : 48,
-				perf_icct  :  8,
-				perf_ippr1 :  4,
-				perf_ippr0 :  4;
-	} perf_sel_bits;
-} io_perf_sel_t;
-
-#endif
-
-/* io_perf_cnt is to extract the count from the hub registers. Due to
-   hardware problems there is only one counter, not two. */
-
-#ifdef LITTLE_ENDIAN
-
-typedef union io_perf_cnt {
-        uint64_t      perf_cnt;
-        struct {
-               uint64_t	perf_cnt   : 20,
-				perf_rsvd2 : 12,
-				perf_rsvd1 : 32;
-        } perf_cnt_bits;
-
-} io_perf_cnt_t;
-
-#else
-
-typedef union io_perf_cnt {
-	uint64_t	perf_cnt;
-	struct {
-		uint64_t	perf_rsvd1 : 32,
-				perf_rsvd2 : 12,
-				perf_cnt   : 20;
-	} perf_cnt_bits;
-
-} io_perf_cnt_t;
-
-#endif
-
-#ifdef LITTLE_ENDIAN
-
-typedef union iprte_a {
-	bdrkreg_t	entry;
-	struct {
-		bdrkreg_t	i_rsvd_1                  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t       i_vld                     :      1;
-	} iprte_fields;
-} iprte_a_t;
-
-#else
-
-typedef union iprte_a {
-	bdrkreg_t	entry;
-	struct {
-		bdrkreg_t	i_vld			  :	 1;
-		bdrkreg_t	i_to_cnt		  :	 5;
-		bdrkreg_t	i_widget		  :	 4;
-		bdrkreg_t	i_rsvd			  :	 2;
-		bdrkreg_t	i_source		  :	 8;
-		bdrkreg_t	i_init			  :	 3;
-		bdrkreg_t	i_addr			  :	38;
-		bdrkreg_t	i_rsvd_1		  :	 3;
-	} iprte_fields;
-} iprte_a_t;
-
-#endif
-
-/* PIO MANAGEMENT */
-typedef struct hub_piomap_s *hub_piomap_t;
-
-extern hub_piomap_t
-hub_piomap_alloc(devfs_handle_t dev,      /* set up mapping for this device */
-                device_desc_t dev_desc, /* device descriptor */
-                iopaddr_t xtalk_addr,   /* map for this xtalk_addr range */
-                size_t byte_count,
-                size_t byte_count_max,  /* maximum size of a mapping */
-                unsigned flags);                /* defined in sys/pio.h */
-
-extern void hub_piomap_free(hub_piomap_t hub_piomap);
-
-extern caddr_t
-hub_piomap_addr(hub_piomap_t hub_piomap,        /* mapping resources */
-                iopaddr_t xtalk_addr,           /* map for this xtalk addr */
-                size_t byte_count);             /* map this many bytes */
-
-extern void
-hub_piomap_done(hub_piomap_t hub_piomap);
-
-extern caddr_t
-hub_piotrans_addr(      devfs_handle_t dev,       /* translate to this device */
-                        device_desc_t dev_desc, /* device descriptor */
-                        iopaddr_t xtalk_addr,   /* Crosstalk address */
-                        size_t byte_count,      /* map this many bytes */
-                        unsigned flags);        /* (currently unused) */
-
-/* DMA MANAGEMENT */
-typedef struct hub_dmamap_s *hub_dmamap_t;
-
-extern hub_dmamap_t
-hub_dmamap_alloc(       devfs_handle_t dev,       /* set up mappings for dev */
-                        device_desc_t dev_desc, /* device descriptor */
-                        size_t byte_count_max,  /* max size of a mapping */
-                        unsigned flags);        /* defined in dma.h */
-
-extern void
-hub_dmamap_free(hub_dmamap_t dmamap);
-
-extern iopaddr_t
-hub_dmamap_addr(        hub_dmamap_t dmamap,    /* use mapping resources */
-                        paddr_t paddr,          /* map for this address */
-                        size_t byte_count);     /* map this many bytes */
-
-extern alenlist_t
-hub_dmamap_list(        hub_dmamap_t dmamap,    /* use mapping resources */
-                        alenlist_t alenlist,    /* map this Addr/Length List */
-                        unsigned flags);
-
-extern void
-hub_dmamap_done(        hub_dmamap_t dmamap);   /* done w/ mapping resources */
-
-extern iopaddr_t
-hub_dmatrans_addr(      devfs_handle_t dev,       /* translate for this device */
-                        device_desc_t dev_desc, /* device descriptor */
-                        paddr_t paddr,          /* system physical address */
-                        size_t byte_count,      /* length */
-                        unsigned flags);                /* defined in dma.h */
-
-extern alenlist_t
-hub_dmatrans_list(      devfs_handle_t dev,       /* translate for this device */
-                        device_desc_t dev_desc, /* device descriptor */
-                        alenlist_t palenlist,   /* system addr/length list */
-                        unsigned flags);                /* defined in dma.h */
-
-extern void
-hub_dmamap_drain(       hub_dmamap_t map);
-
-extern void
-hub_dmaaddr_drain(      devfs_handle_t vhdl,
-                        paddr_t addr,
-                        size_t bytes);
-
-extern void
-hub_dmalist_drain(      devfs_handle_t vhdl,
-                        alenlist_t list);
-
-
-/* INTERRUPT MANAGEMENT */
-typedef struct hub_intr_s *hub_intr_t;
-
-extern hub_intr_t
-hub_intr_alloc( devfs_handle_t dev,               /* which device */
-                device_desc_t dev_desc,         /* device descriptor */
-                devfs_handle_t owner_dev);        /* owner of this interrupt */
-
-extern hub_intr_t
-hub_intr_alloc_nothd(devfs_handle_t dev,          /* which device */
-                device_desc_t dev_desc,         /* device descriptor */
-                devfs_handle_t owner_dev);        /* owner of this interrupt */
-
-extern void
-hub_intr_free(hub_intr_t intr_hdl);
-
-extern int
-hub_intr_connect(       hub_intr_t intr_hdl,    /* xtalk intr resource hndl */
-                        xtalk_intr_setfunc_t setfunc,
-                                                /* func to set intr hw */
-                        void *setfunc_arg);     /* arg to setfunc */
-
-extern void
-hub_intr_disconnect(hub_intr_t intr_hdl);
-
-extern devfs_handle_t
-hub_intr_cpu_get(hub_intr_t intr_hdl);
-
-/* CONFIGURATION MANAGEMENT */
-
-extern void
-hub_provider_startup(devfs_handle_t hub);
-
-extern void
-hub_provider_shutdown(devfs_handle_t hub);
-
-#define HUB_PIO_CONVEYOR        0x1     /* PIO in conveyor belt mode */
-#define HUB_PIO_FIRE_N_FORGET   0x2     /* PIO in fire-and-forget mode */
-
-/* Flags that make sense to hub_widget_flags_set */
-#define HUB_WIDGET_FLAGS        (                               \
-				 HUB_PIO_CONVEYOR       |       \
-				 HUB_PIO_FIRE_N_FORGET          \
-				)
-
-
-typedef int     hub_widget_flags_t;
-
-/* Set the PIO mode for a widget.  These two functions perform the
- * same operation, but hub_device_flags_set() takes a hardware graph
- * vertex while hub_widget_flags_set() takes a nasid and widget
- * number.  In most cases, hub_device_flags_set() should be used.
- */
-extern int      hub_widget_flags_set(nasid_t            nasid,
-                                     xwidgetnum_t       widget_num,
-                                     hub_widget_flags_t flags);
-
-/* Depending on the flags set take the appropriate actions */
-extern int      hub_device_flags_set(devfs_handle_t       widget_dev,
-                                     hub_widget_flags_t flags);
-                                                    
-
-/* Error Handling. */
-extern int hub_ioerror_handler(devfs_handle_t, int, int, struct io_error_s *);
-extern int kl_ioerror_handler(cnodeid_t, cnodeid_t, cpuid_t,
-                              int, paddr_t, caddr_t, ioerror_mode_t);
-extern void hub_widget_reset(devfs_handle_t, xwidgetnum_t);
-extern int hub_error_devenable(devfs_handle_t, int, int);
-extern void hub_widgetdev_enable(devfs_handle_t, int);
-extern void hub_widgetdev_shutdown(devfs_handle_t, int);
-extern int  hub_dma_enabled(devfs_handle_t);
-
-#endif /* __ASSEMBLY__ */
-#endif /* _KERNEL */
-#endif  /* _ASM_IA64_SN_SN1_HUBIO_NEXT_H */
diff -Nru a/include/asm-ia64/sn/sn1/hublb.h b/include/asm-ia64/sn/sn1/hublb.h
--- a/include/asm-ia64/sn/sn1/hublb.h	Wed Jun 18 23:42:09 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1607 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-
-/************************************************************************
- *                                                                      *
- *      WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!      *
- *                                                                      *
- * This file is created by an automated script. Any (minimal) changes   *
- * made manually to this  file should be made with care.                *
- *                                                                      *
- *               MAKE ALL ADDITIONS TO THE END OF THIS FILE             *
- *                                                                      *
- ************************************************************************/
-
-
-#ifndef _ASM_IA64_SN_SN1_HUBLB_H
-#define _ASM_IA64_SN_SN1_HUBLB_H
-
-
-#define    LB_REV_ID                 0x00600000    /*
-                                                    * Bedrock Revision
-                                                    * and ID
-                                                    */
-
-
-
-#define    LB_CPU_PERMISSION         0x00604000    /*
-                                                    * CPU PIO access
-                                                    * permission bits
-                                                    */
-
-
-
-#define    LB_CPU_PERM_OVRRD         0x00604008    /*
-                                                    * CPU PIO access
-                                                    * permission bit
-                                                    * override
-                                                    */
-
-
-
-#define    LB_IO_PERMISSION          0x00604010    /*
-                                                    * IO PIO access
-                                                    * permission bits
-                                                    */
-
-
-
-#define    LB_SOFT_RESET             0x00604018    /*
-                                                    * Soft reset the
-                                                    * Bedrock chip
-                                                    */
-
-
-
-#define    LB_REGION_PRESENT         0x00604020    /*
-                                                    * Regions Present for
-                                                    * Invalidates
-                                                    */
-
-
-
-#define    LB_NODES_ABSENT           0x00604028    /*
-                                                    * Nodes Absent for
-                                                    * Invalidates
-                                                    */
-
-
-
-#define    LB_MICROLAN_CTL           0x00604030    /*
-                                                    * Microlan Control
-                                                    * (NIC)
-                                                    */
-
-
-
-#define    LB_ERROR_BITS             0x00604040    /*
-                                                    * Local Block error
-                                                    * bits
-                                                    */
-
-
-
-#define    LB_ERROR_MASK_CLR         0x00604048    /*
-                                                    * Bit mask write to
-                                                    * clear error bits
-                                                    */
-
-
-
-#define    LB_ERROR_HDR1             0x00604050    /*
-                                                    * Source, Suppl and
-                                                    * Cmd fields
-                                                    */
-
-
-
-#define    LB_ERROR_HDR2             0x00604058    /*
-                                                    * Address field from
-                                                    * first error
-                                                    */
-
-
-
-#define    LB_ERROR_DATA             0x00604060    /*
-                                                    * Data flit (if any)
-                                                    * from first error
-                                                    */
-
-
-
-#define    LB_DEBUG_SELECT           0x00604100    /*
-                                                    * Choice of debug
-                                                    * signals from chip
-                                                    */
-
-
-
-#define    LB_DEBUG_PINS             0x00604108    /*
-                                                    * Value on the chip's
-                                                    * debug pins
-                                                    */
-
-
-
-#define    LB_RT_LOCAL_CTRL          0x00604200    /*
-                                                    * Local generation of
-                                                    * real-time clock
-                                                    */
-
-
-
-#define    LB_RT_FILTER_CTRL         0x00604208    /*
-                                                    * Control of
-                                                    * filtering of global
-                                                    * clock
-                                                    */
-
-
-
-#define    LB_SCRATCH_REG0           0x00608000    /* Scratch Register 0     */
-
-
-
-#define    LB_SCRATCH_REG1           0x00608008    /* Scratch Register 1     */
-
-
-
-#define    LB_SCRATCH_REG2           0x00608010    /* Scratch Register 2     */
-
-
-
-#define    LB_SCRATCH_REG3           0x00608018    /* Scratch Register 3     */
-
-
-
-#define    LB_SCRATCH_REG4           0x00608020    /* Scratch Register 4     */
-
-
-
-#define    LB_SCRATCH_REG0_WZ        0x00608040    /*
-                                                    * Scratch Register 0
-                                                    * (WZ alias)
-                                                    */
-
-
-
-#define    LB_SCRATCH_REG1_WZ        0x00608048    /*
-                                                    * Scratch Register 1
-                                                    * (WZ alias)
-                                                    */
-
-
-
-#define    LB_SCRATCH_REG2_WZ        0x00608050    /*
-                                                    * Scratch Register 2
-                                                    * (WZ alias)
-                                                    */
-
-
-
-#define    LB_SCRATCH_REG3_RZ        0x00608058    /*
-                                                    * Scratch Register 3
-                                                    * (RZ alias)
-                                                    */
-
-
-
-#define    LB_SCRATCH_REG4_RZ        0x00608060    /*
-                                                    * Scratch Register 4
-                                                    * (RZ alias)
-                                                    */
-
-
-
-#define    LB_VECTOR_PARMS           0x0060C000    /*
-                                                    * Vector PIO
-                                                    * parameters
-                                                    */
-
-
-
-#define    LB_VECTOR_ROUTE           0x0060C008    /*
-                                                    * Vector PIO Vector
-                                                    * Route
-                                                    */
-
-
-
-#define    LB_VECTOR_DATA            0x0060C010    /*
-                                                    * Vector PIO Write
-                                                    * Data
-                                                    */
-
-
-
-#define    LB_VECTOR_STATUS          0x0060C020    /*
-                                                    * Vector PIO Return
-                                                    * Status
-                                                    */
-
-
-
-#define    LB_VECTOR_RETURN          0x0060C028    /*
-                                                    * Vector PIO Return
-                                                    * Route
-                                                    */
-
-
-
-#define    LB_VECTOR_READ_DATA       0x0060C030    /*
-                                                    * Vector PIO Read
-                                                    * Data
-                                                    */
-
-
-
-#define    LB_VECTOR_STATUS_CLEAR    0x0060C038    /*
-                                                    * Clear Vector PIO
-                                                    * Return Status
-                                                    */
-
-
-
-
-
-#ifndef __ASSEMBLY__
-
-/************************************************************************
- *                                                                      *
- * Description:  This register contains information that allows         *
- * exploratory software to probe for chip type. This is also the        *
- * register that sets this node's ID and the size of each region        *
- * (which affects the maximum possible system size). IBM assigns the    *
- * values for the REVISION, PART_NUMBER and MANUFACTURER fields, in     *
- * accordance with the IEEE 1149.1 standard; SGI is not at liberty to   *
- * unilaterally change the values of these fields.                      *
- *  .                                                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_rev_id_u {
-	bdrkreg_t	lb_rev_id_regval;
-	struct  {
-		bdrkreg_t	ri_reserved_2             :	 1;
-		bdrkreg_t       ri_manufacturer           :     11;
-		bdrkreg_t       ri_part_number            :     16;
-		bdrkreg_t       ri_revision               :      4;
-		bdrkreg_t       ri_node_id                :      8;
-		bdrkreg_t       ri_reserved_1             :      6;
-		bdrkreg_t       ri_region_size            :      2;
-		bdrkreg_t       ri_reserved               :     16;
-	} lb_rev_id_fld_s;
-} lb_rev_id_u_t;
-
-#else
-
-typedef union lb_rev_id_u {
-        bdrkreg_t       lb_rev_id_regval;
-	struct	{
-		bdrkreg_t	ri_reserved		  :	16;
-		bdrkreg_t	ri_region_size		  :	 2;
-		bdrkreg_t	ri_reserved_1		  :	 6;
-		bdrkreg_t	ri_node_id		  :	 8;
-		bdrkreg_t	ri_revision		  :	 4;
-		bdrkreg_t	ri_part_number		  :	16;
-		bdrkreg_t	ri_manufacturer		  :	11;
-		bdrkreg_t	ri_reserved_2		  :	 1;
-	} lb_rev_id_fld_s;
-} lb_rev_id_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the PI-access-rights bit-vector for the      *
- * LB, NI, XB and MD portions of the Bedrock local register space. If   *
- * a bit in the bit-vector is set, the region corresponding to that     *
- * bit has read/write permission on the LB, NI, XB and MD local         *
- * registers. If the bit is clear, that region has no write access to   *
- * the local registers and no read access if the read will cause any    *
- * state change. If a write or a read with side effects is attempted    *
- * by a PI in a region for which access is restricted, the LB will      *
- * not perform the operation and will send back a reply which           *
- * indicates an error.                                                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_cpu_permission_u {
-	bdrkreg_t	lb_cpu_permission_regval;
-	struct  {
-		bdrkreg_t	cp_cpu_access             :	64;
-	} lb_cpu_permission_fld_s;
-} lb_cpu_permission_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  A write to this register of the 64-bit value "SGIrules" will        *
- * cause the bit in the LB_CPU_PROTECT register corresponding to the    *
- * region of the requester to be set.                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_cpu_perm_ovrrd_u {
-	bdrkreg_t	lb_cpu_perm_ovrrd_regval;
-	struct  {
-		bdrkreg_t	cpo_cpu_perm_ovr          :	64;
-	} lb_cpu_perm_ovrrd_fld_s;
-} lb_cpu_perm_ovrrd_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the II-access-rights bit-vector for the      *
- * LB, NI, XB and MD portions of the Bedrock local register space. If   *
- * a bit in the bit-vector is set, the region corresponding to that     *
- * bit has read/write permission on the LB, NI, XB and MD local         *
- * registers. If the bit is clear, then that region has no write        *
- * access to the local registers and no read access if the read         *
- * results in any state change. If a write or a read with side          *
- * effects is attempted by an II in a region for which access is        *
- * restricted, the LB will not perform the operation and will send      *
- * back a reply which indicates an error.                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_io_permission_u {
-	bdrkreg_t	lb_io_permission_regval;
-	struct  {
-		bdrkreg_t	ip_io_permission          :	64;
-	} lb_io_permission_fld_s;
-} lb_io_permission_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  A write to this bit resets the Bedrock chip with a soft reset.      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_soft_reset_u {
-	bdrkreg_t	lb_soft_reset_regval;
-	struct  {
-		bdrkreg_t	sr_soft_reset             :	 1;
-		bdrkreg_t	sr_reserved		  :	63;
-	} lb_soft_reset_fld_s;
-} lb_soft_reset_u_t;
-
-#else
-
-typedef union lb_soft_reset_u {
-	bdrkreg_t	lb_soft_reset_regval;
-	struct	{
-		bdrkreg_t	sr_reserved		  :	63;
-		bdrkreg_t	sr_soft_reset		  :	 1;
-	} lb_soft_reset_fld_s;
-} lb_soft_reset_u_t;
-
-#endif
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register indicates which regions are present and capable of    *
- * receiving an invalidate (INVAL) request. The LB samples this         *
- * register at the start of processing each LINVAL. When an LINVAL      *
- * indicates that a particular PI unit might hold a shared copy of a    *
- * cache block but this PI is in a region which is not present (i.e.,   *
- * its bit in LB_REGION_PRESENT is clear), then the LB sends an IVACK   *
- * reply packet on behalf of this PI. The REGION_SIZE field in the      *
- * LB_REV_ID register determines the number of nodes per region (and    *
- * hence, the number of PI units which share a common bit in the        *
- * LB_REGION_PRESENT register).                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_region_present_u {
-	bdrkreg_t	lb_region_present_regval;
-	struct  {
-		bdrkreg_t	rp_present_bits           :	64;
-	} lb_region_present_fld_s;
-} lb_region_present_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register indicates which nodes are absent and     *
- * not capable of receiving an invalidate (INVAL) request. The LB       *
- * samples this register at the start of processing each LINVAL. When   *
- * an LINVAL indicates that a particular PI unit might hold a shared    *
- * copy of a cache block but this PI unit's node is not present         *
- * (i.e., its node ID is listed in the LB_NODES_ABSENT register),       *
- * then the LB sends an IVACK reply packet on behalf of this PI.        *
- *                                                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_nodes_absent_u {
-	bdrkreg_t	lb_nodes_absent_regval;
-	struct  {
-		bdrkreg_t	na_node_0                 :	 8;
-		bdrkreg_t       na_reserved_3             :      7;
-		bdrkreg_t       na_node_0_valid           :      1;
-		bdrkreg_t       na_node_1                 :      8;
-		bdrkreg_t       na_reserved_2             :      7;
-		bdrkreg_t       na_node_1_valid           :      1;
-		bdrkreg_t       na_node_2                 :      8;
-		bdrkreg_t       na_reserved_1             :      7;
-		bdrkreg_t       na_node_2_valid           :      1;
-		bdrkreg_t       na_node_3                 :      8;
-		bdrkreg_t       na_reserved               :      7;
-		bdrkreg_t       na_node_3_valid           :      1;
-	} lb_nodes_absent_fld_s;
-} lb_nodes_absent_u_t;
-
-#else
-
-typedef union lb_nodes_absent_u {
-	bdrkreg_t	lb_nodes_absent_regval;
-	struct	{
-		bdrkreg_t	na_node_3_valid		  :	 1;
-		bdrkreg_t	na_reserved		  :	 7;
-		bdrkreg_t	na_node_3		  :	 8;
-		bdrkreg_t	na_node_2_valid		  :	 1;
-		bdrkreg_t	na_reserved_1		  :	 7;
-		bdrkreg_t	na_node_2		  :	 8;
-		bdrkreg_t	na_node_1_valid		  :	 1;
-		bdrkreg_t	na_reserved_2		  :	 7;
-		bdrkreg_t	na_node_1		  :	 8;
-		bdrkreg_t	na_node_0_valid		  :	 1;
-		bdrkreg_t	na_reserved_3		  :	 7;
-		bdrkreg_t	na_node_0		  :	 8;
-	} lb_nodes_absent_fld_s;
-} lb_nodes_absent_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register provides access to the Number-In-a-Can add-only       *
- * serial PROM that is used to store node board serial number and       *
- * configuration information. (Refer to NIC datasheet Dallas 1990A      *
- * that is viewable at                                                  *
- * URL::http://www.dalsemi.com/DocControl/PDFs/pdfindex.html). Data     *
- * comes from this interface LSB first.                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_microlan_ctl_u {
-	bdrkreg_t	lb_microlan_ctl_regval;
-	struct  {
-		bdrkreg_t	mc_rd_data                :	 1;
-		bdrkreg_t       mc_done                   :      1;
-		bdrkreg_t       mc_sample                 :      8;
-		bdrkreg_t       mc_pulse                  :     10;
-		bdrkreg_t       mc_clkdiv_phi0            :      7;
-		bdrkreg_t       mc_clkdiv_phi1            :      7;
-		bdrkreg_t       mc_reserved               :     30;
-	} lb_microlan_ctl_fld_s;
-} lb_microlan_ctl_u_t;
-
-#else
-
-typedef union lb_microlan_ctl_u {
-        bdrkreg_t       lb_microlan_ctl_regval;
-        struct  {
-                bdrkreg_t       mc_reserved               :     30;
-                bdrkreg_t       mc_clkdiv_phi1            :      7;
-                bdrkreg_t       mc_clkdiv_phi0            :      7;
-                bdrkreg_t       mc_pulse                  :     10;
-                bdrkreg_t       mc_sample                 :      8;
-                bdrkreg_t       mc_done                   :      1;
-                bdrkreg_t       mc_rd_data                :      1;
-        } lb_microlan_ctl_fld_s;
-} lb_microlan_ctl_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register contains the LB error status bits.       *
- * Whenever a particular type of error occurs, the LB sets its bit in   *
- * this register so that software will be aware that such an event      *
- * has happened. Reads from this register are non-destructive and the   *
- * contents of this register remain intact across reset operations.     *
- * Whenever any of these bits is set, the LB will assert its            *
- * interrupt request output signals that go to the PI units.            *
- *  Software can simulate the occurrence of an error by first writing   *
- * appropriate values into the LB_ERROR_HDR1, LB_ERROR_HDR2 and         *
- * LB_ERROR_DATA registers, and then writing to the LB_ERROR_BITS       *
- * register to set the error bits in a particular way. Setting one or   *
- * more error bits will cause the LB to interrupt a processor and       *
- * invoke error-handling software.                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_error_bits_u {
-	bdrkreg_t	lb_error_bits_regval;
-	struct  {
-		bdrkreg_t	eb_rq_bad_cmd             :	 1;
-		bdrkreg_t       eb_rp_bad_cmd             :      1;
-		bdrkreg_t       eb_rq_short               :      1;
-		bdrkreg_t       eb_rp_short               :      1;
-		bdrkreg_t       eb_rq_long                :      1;
-		bdrkreg_t       eb_rp_long                :      1;
-		bdrkreg_t       eb_rq_bad_data            :      1;
-		bdrkreg_t       eb_rp_bad_data            :      1;
-		bdrkreg_t       eb_rq_bad_addr            :      1;
-		bdrkreg_t       eb_rq_bad_linval          :      1;
-		bdrkreg_t       eb_gclk_drop              :      1;
-		bdrkreg_t       eb_reserved               :     53;
-	} lb_error_bits_fld_s;
-} lb_error_bits_u_t;
-
-#else
-
-typedef union lb_error_bits_u {
-	bdrkreg_t	lb_error_bits_regval;
-	struct	{
-		bdrkreg_t	eb_reserved		  :	53;
-		bdrkreg_t	eb_gclk_drop		  :	 1;
-		bdrkreg_t	eb_rq_bad_linval	  :	 1;
-		bdrkreg_t	eb_rq_bad_addr		  :	 1;
-		bdrkreg_t	eb_rp_bad_data		  :	 1;
-		bdrkreg_t	eb_rq_bad_data		  :	 1;
-		bdrkreg_t	eb_rp_long		  :	 1;
-		bdrkreg_t	eb_rq_long		  :	 1;
-		bdrkreg_t	eb_rp_short		  :	 1;
-		bdrkreg_t	eb_rq_short		  :	 1;
-		bdrkreg_t	eb_rp_bad_cmd		  :	 1;
-		bdrkreg_t	eb_rq_bad_cmd		  :	 1;
-	} lb_error_bits_fld_s;
-} lb_error_bits_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register lets software clear some of the bits in the           *
- * LB_ERROR_BITS register without affecting other bits.  Essentially,   *
- * it provides bit mask functionality. When software writes to the      *
- * LB_ERROR_MASK_CLR register, the bits which are set in the data       *
- * value indicate which bits are to be cleared in LB_ERROR_BITS. If a   *
- * bit is clear in the data value written to the LB_ERROR_MASK_CLR      *
- * register, then its corresponding bit in the LB_ERROR_BITS register   *
- * is not affected. Hence, software can atomically clear any subset     *
- * of the error bits in the LB_ERROR_BITS register.                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_error_mask_clr_u {
-	bdrkreg_t	lb_error_mask_clr_regval;
-	struct  {
-		bdrkreg_t	emc_clr_rq_bad_cmd        :	 1;
-		bdrkreg_t       emc_clr_rp_bad_cmd        :      1;
-		bdrkreg_t       emc_clr_rq_short          :      1;
-		bdrkreg_t       emc_clr_rp_short          :      1;
-		bdrkreg_t       emc_clr_rq_long           :      1;
-		bdrkreg_t       emc_clr_rp_long           :      1;
-		bdrkreg_t       emc_clr_rq_bad_data       :      1;
-		bdrkreg_t       emc_clr_rp_bad_data       :      1;
-		bdrkreg_t       emc_clr_rq_bad_addr       :      1;
-		bdrkreg_t       emc_clr_rq_bad_linval     :      1;
-		bdrkreg_t       emc_clr_gclk_drop         :      1;
-		bdrkreg_t       emc_reserved              :     53;
-	} lb_error_mask_clr_fld_s;
-} lb_error_mask_clr_u_t;
-
-#else
-
-typedef union lb_error_mask_clr_u {
-	bdrkreg_t	lb_error_mask_clr_regval;
-	struct	{
-		bdrkreg_t	emc_reserved		  :	53;
-		bdrkreg_t	emc_clr_gclk_drop	  :	 1;
-		bdrkreg_t	emc_clr_rq_bad_linval	  :	 1;
-		bdrkreg_t	emc_clr_rq_bad_addr	  :	 1;
-		bdrkreg_t	emc_clr_rp_bad_data	  :	 1;
-		bdrkreg_t	emc_clr_rq_bad_data	  :	 1;
-		bdrkreg_t	emc_clr_rp_long		  :	 1;
-		bdrkreg_t	emc_clr_rq_long		  :	 1;
-		bdrkreg_t	emc_clr_rp_short	  :	 1;
-		bdrkreg_t	emc_clr_rq_short	  :	 1;
-		bdrkreg_t	emc_clr_rp_bad_cmd	  :	 1;
-		bdrkreg_t	emc_clr_rq_bad_cmd	  :	 1;
-	} lb_error_mask_clr_fld_s;
-} lb_error_mask_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  If the LB detects an error when VALID==0 in the LB_ERROR_HDR1       *
- * register, then it saves the contents of the offending packet's       *
- * header flit in the LB_ERROR_HDR1 and LB_ERROR_HDR2 registers, sets   *
- * the VALID bit in LB_ERROR_HDR1 and clears the OVERRUN bit in         *
- * LB_ERROR_HDR1 (and it will also set the corresponding bit in the     *
- * LB_ERROR_BITS register). The ERR_TYPE field indicates specifically   *
- * what kind of error occurred.  Its encoding corresponds to the bit    *
- * positions in the LB_ERROR_BITS register (e.g., ERR_TYPE==5           *
- * indicates a RP_LONG error).  If an error (of any type except         *
- * GCLK_DROP) subsequently happens while VALID==1, then the LB sets     *
- * the OVERRUN bit in LB_ERROR_HDR1. This register is not relevant      *
- * when a GCLK_DROP error occurs; the LB does not even attempt to       *
- * change the ERR_TYPE, VALID or OVERRUN field when a GCLK_DROP error   *
- * happens.                                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_error_hdr1_u {
-	bdrkreg_t	lb_error_hdr1_regval;
-	struct  {
-		bdrkreg_t	eh_command                :	 7;
-		bdrkreg_t       eh_reserved_5             :      1;
-		bdrkreg_t       eh_suppl                  :     11;
-		bdrkreg_t       eh_reserved_4             :      1;
-		bdrkreg_t       eh_source                 :     11;
-		bdrkreg_t       eh_reserved_3             :      1;
-		bdrkreg_t       eh_err_type               :      4;
-		bdrkreg_t       eh_reserved_2             :      4;
-		bdrkreg_t       eh_overrun                :      1;
-		bdrkreg_t       eh_reserved_1             :      3;
-		bdrkreg_t       eh_valid                  :      1;
-		bdrkreg_t       eh_reserved               :     19;
-	} lb_error_hdr1_fld_s;
-} lb_error_hdr1_u_t;
-
-#else
-
-typedef union lb_error_hdr1_u {
-	bdrkreg_t	lb_error_hdr1_regval;
-	struct	{
-		bdrkreg_t	eh_reserved		  :	19;
-		bdrkreg_t	eh_valid		  :	 1;
-		bdrkreg_t	eh_reserved_1		  :	 3;
-		bdrkreg_t	eh_overrun		  :	 1;
-		bdrkreg_t	eh_reserved_2		  :	 4;
-		bdrkreg_t	eh_err_type		  :	 4;
-		bdrkreg_t	eh_reserved_3		  :	 1;
-		bdrkreg_t	eh_source		  :	11;
-		bdrkreg_t	eh_reserved_4		  :	 1;
-		bdrkreg_t	eh_suppl		  :	11;
-		bdrkreg_t	eh_reserved_5		  :	 1;
-		bdrkreg_t	eh_command		  :	 7;
-	} lb_error_hdr1_fld_s;
-} lb_error_hdr1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contents of the Address field from header flit of first packet      *
- * that causes an error. This register is not relevant when a           *
- * GCLK_DROP error occurs.                                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_error_hdr2_u {
-	bdrkreg_t	lb_error_hdr2_regval;
-	struct  {
-		bdrkreg_t	eh_address                :	38;
-		bdrkreg_t       eh_reserved               :     26;
-	} lb_error_hdr2_fld_s;
-} lb_error_hdr2_u_t;
-
-#else
-
-typedef union lb_error_hdr2_u {
-	bdrkreg_t	lb_error_hdr2_regval;
-	struct	{
-		bdrkreg_t	eh_reserved		  :	26;
-		bdrkreg_t	eh_address		  :	38;
-	} lb_error_hdr2_fld_s;
-} lb_error_hdr2_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register accompanies the LB_ERROR_HDR1 and        *
- * LB_ERROR_HDR2 registers.  The LB updates the value in this           *
- * register when an incoming packet with a data flit causes an error    *
- * while VALID==0 in the LB_ERROR_HDR1 register.  This register         *
- * retains the contents of the data flit from the incoming packet       *
- * that caused the error. This register is relevant for the following   *
- * types of errors:                                                     *
- * <UL >                                                                *
- * <UL >                                                                *
- * <UL >                                                                *
- * <UL >                                                                *
- * <UL >                                                                *
- * <LI >RQ_BAD_LINVAL for a LINVAL request.                             *
- * <LI >RQ_BAD_ADDR for a normal or vector PIO request.                 *
- * <LI >RP_BAD_DATA for a vector PIO reply.                             *
- * <LI >RQ_BAD DATA for an incoming request with data.                  *
- * <LI >RP_LONG for a vector PIO reply.                                 *
- * <LI >RQ_LONG for an incoming request with expected data.             *
- * <BLOCKQUOTE >                                                        *
- * In the case of RQ_BAD_LINVAL, the register retains the 64-bit data   *
- * value that followed the header flit.  In the case of RQ_BAD_ADDR     *
- * or RQ_BAD_DATA, the register retains the incoming packet's 64-bit    *
- * data value (i.e., 2nd flit in the packet for a normal PIO write or   *
- * an LINVAL, 3rd flit for a vector PIO read or write). In the case     *
- * of RP_BAD_DATA, the register retains the 64-bit data value in the    *
- * 3rd flit of the packet. When a RP_LONG or RQ_LONG error occurs,      *
- * the LB loads the LB_ERROR_DATA register with the contents of the     *
- * expected data flit (i.e., the 3rd flit in the packet for a vector    *
- * PIO request or reply, the 2nd flit for other packets), if any. The   *
- * contents of the LB_ERROR_DATA register are undefined after a         *
- * RP_SHORT, RQ_SHORT, RP_BAD_CMD or RQ_BAD_CMD error. The contents     *
- * of the LB_ERROR_DATA register are also undefined after an incoming   *
- * normal PIO read request which encounters a RQ_LONG error.            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_error_data_u {
-	bdrkreg_t	lb_error_data_regval;
-	struct  {
-		bdrkreg_t	ed_data                   :	64;
-	} lb_error_data_fld_s;
-} lb_error_data_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register enables software to control what internal Bedrock     *
- * signals are visible on the chip's debug pins. The LB provides the    *
- * 6-bit value in this register to Bedrock's DEBUG unit. The JTAG       *
- * unit provides a similar 6-bit selection input to the DEBUG unit,     *
- * along with another signal that tells the DEBUG unit whether to use   *
- * the selection signal from the LB or the JTAG unit. For a             *
- * description of the menu of choices for debug signals, refer to the   *
- * documentation for the DEBUG unit.                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_debug_select_u {
-	bdrkreg_t	lb_debug_select_regval;
-	struct  {
-		bdrkreg_t	ds_debug_sel              :	 6;
-		bdrkreg_t       ds_reserved               :     58;
-	} lb_debug_select_fld_s;
-} lb_debug_select_u_t;
-
-#else
-
-typedef union lb_debug_select_u {
-	bdrkreg_t	lb_debug_select_regval;
-	struct	{
-		bdrkreg_t	ds_reserved		  :	58;
-		bdrkreg_t	ds_debug_sel		  :	 6;
-	} lb_debug_select_fld_s;
-} lb_debug_select_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  A PIO read from this register returns the 32-bit value that is      *
- * currently on the Bedrock chip's debug pins. This register allows     *
- * software to observe debug pin output values which do not change      *
- * frequently (i.e., they remain constant over a period of many         *
- * cycles).                                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_debug_pins_u {
-	bdrkreg_t	lb_debug_pins_regval;
-	struct  {
-		bdrkreg_t	dp_debug_pins             :	32;
-		bdrkreg_t       dp_reserved               :     32;
-	} lb_debug_pins_fld_s;
-} lb_debug_pins_u_t;
-
-#else
-
-typedef union lb_debug_pins_u {
-	bdrkreg_t	lb_debug_pins_regval;
-	struct	{
-		bdrkreg_t	dp_reserved		  :	32;
-		bdrkreg_t	dp_debug_pins		  :	32;
-	} lb_debug_pins_fld_s;
-} lb_debug_pins_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  The LB unit provides the PI0 and PI1 units with a real-time clock   *
- * signal. The LB can generate this signal itself, based on the         *
- * Bedrock chip's system clock which the LB receives as an input.       *
- * Alternatively, the LB can filter a global clock signal which it      *
- * receives as an input and provide the filtered version to PI0 and     *
- * PI1. The user can program the LB_RT_LOCAL_CTRL register to choose    *
- * the source of the real-time clock. If the user chooses to generate   *
- * the real-time clock internally within the LB, then the user can      *
- * specify the period for the real-time clock signal.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_rt_local_ctrl_u {
-	bdrkreg_t	lb_rt_local_ctrl_regval;
-	struct  {
-		bdrkreg_t	rlc_gclk_enable           :	 1;
-		bdrkreg_t       rlc_reserved_4            :      3;
-		bdrkreg_t       rlc_max_count             :     10;
-		bdrkreg_t       rlc_reserved_3            :      2;
-		bdrkreg_t       rlc_gclk_counter          :     10;
-		bdrkreg_t       rlc_reserved_2            :      2;
-		bdrkreg_t       rlc_gclk                  :      1;
-		bdrkreg_t       rlc_reserved_1            :      3;
-		bdrkreg_t       rlc_use_internal          :      1;
-		bdrkreg_t       rlc_reserved              :     31;
-	} lb_rt_local_ctrl_fld_s;
-} lb_rt_local_ctrl_u_t;
-
-#else
-
-typedef union lb_rt_local_ctrl_u {
-        bdrkreg_t       lb_rt_local_ctrl_regval;
-        struct  {
-                bdrkreg_t       rlc_reserved              :     31;
-                bdrkreg_t       rlc_use_internal          :      1;
-                bdrkreg_t       rlc_reserved_1            :      3;
-                bdrkreg_t       rlc_gclk                  :      1;
-                bdrkreg_t       rlc_reserved_2            :      2;
-                bdrkreg_t       rlc_gclk_counter          :     10;
-                bdrkreg_t       rlc_reserved_3            :      2;
-                bdrkreg_t       rlc_max_count             :     10;
-                bdrkreg_t       rlc_reserved_4            :      3;
-                bdrkreg_t       rlc_gclk_enable           :      1;
-        } lb_rt_local_ctrl_fld_s;
-} lb_rt_local_ctrl_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  When the value of the USE_INTERNAL field in the LB_RT_LOCAL_CTRL    *
- * register is 0, the LB filters an incoming global clock signal and    *
- * provides the result to PI0 and PI1 for their real-time clock         *
- * inputs. The LB can perform either simple filtering or complex        *
- * filtering, depending on the value of the MASK_ENABLE bit. For the    *
- * simple filtering option, the LB merely removes glitches from the     *
- * incoming global clock; if the global clock goes high (or low) for    *
- * only a single cycle, the LB considers it to be a glitch and does     *
- * not pass it through to PI0 and PI1. For the complex filtering        *
- * option, the LB expects positive edges on the incoming global clock   *
- * to be spaced at fairly regular intervals and it looks for them at    *
- * these times; the LB keeps track of unexpected or missing positive    *
- * edges, and it generates an edge itself whenever the incoming         *
- * global clock apparently misses an edge. For each filtering option,   *
- * the real-time clock which the LB provides to PI0 and PI1 is not      *
- * necessarily a square wave; when a positive edge happens, the         *
- * real-time clock stays high for (2*MAX_COUNT+1-OFFSET)/2 cycles of    *
- * the LB's system clock, and then is low until the next positive       *
- * edge.                                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_rt_filter_ctrl_u {
-	bdrkreg_t	lb_rt_filter_ctrl_regval;
-	struct  {
-		bdrkreg_t       rfc_offset                :      5;
-		bdrkreg_t       rfc_reserved_4            :      3;
-		bdrkreg_t       rfc_mask_counter          :     12;
-		bdrkreg_t       rfc_mask_enable           :      1;
-		bdrkreg_t       rfc_reserved_3            :      3;
-		bdrkreg_t       rfc_dropout_counter       :     10;
-		bdrkreg_t       rfc_reserved_2            :      2;
-		bdrkreg_t       rfc_dropout_thresh        :     10;
-		bdrkreg_t       rfc_reserved_1            :      2;
-		bdrkreg_t       rfc_error_counter         :     10;
-		bdrkreg_t       rfc_reserved              :      6;
-	} lb_rt_filter_ctrl_fld_s;
-} lb_rt_filter_ctrl_u_t;
-
-#else
-
-typedef union lb_rt_filter_ctrl_u {
-        bdrkreg_t       lb_rt_filter_ctrl_regval;
-        struct  {
-                bdrkreg_t       rfc_reserved              :      6;
-                bdrkreg_t       rfc_error_counter         :     10;
-                bdrkreg_t       rfc_reserved_1            :      2;
-                bdrkreg_t       rfc_dropout_thresh        :     10;
-                bdrkreg_t       rfc_reserved_2            :      2;
-                bdrkreg_t       rfc_dropout_counter       :     10;
-                bdrkreg_t       rfc_reserved_3            :      3;
-                bdrkreg_t       rfc_mask_enable           :      1;
-                bdrkreg_t       rfc_mask_counter          :     12;
-                bdrkreg_t       rfc_reserved_4            :      3;
-                bdrkreg_t       rfc_offset                :      5;
-        } lb_rt_filter_ctrl_fld_s;
-} lb_rt_filter_ctrl_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is a scratch register that is reset to 0x0. At the    *
- * normal address, the register is a simple storage location. At the    *
- * Write-If-Zero address, the register accepts a new value from a       *
- * write operation only if the current value is zero.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_scratch_reg0_u {
-	bdrkreg_t	lb_scratch_reg0_regval;
-	struct  {
-		bdrkreg_t	sr_scratch_bits           :	64;
-	} lb_scratch_reg0_fld_s;
-} lb_scratch_reg0_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  These registers are scratch registers that are not reset. At a      *
- * register's normal address, it is a simple storage location. At a     *
- * register's Write-If-Zero address, it accepts a new value from a      *
- * write operation only if the current value is zero.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_scratch_reg1_u {
-	bdrkreg_t	lb_scratch_reg1_regval;
-	struct  {
-		bdrkreg_t	sr_scratch_bits           :	64;
-	} lb_scratch_reg1_fld_s;
-} lb_scratch_reg1_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  These registers are scratch registers that are not reset. At a      *
- * register's normal address, it is a simple storage location. At a     *
- * register's Write-If-Zero address, it accepts a new value from a      *
- * write operation only if the current value is zero.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_scratch_reg2_u {
-	bdrkreg_t	lb_scratch_reg2_regval;
-	struct  {
-		bdrkreg_t	sr_scratch_bits           :	64;
-	} lb_scratch_reg2_fld_s;
-} lb_scratch_reg2_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  These one-bit registers are scratch registers. At a register's      *
- * normal address, it is a simple storage location. At a register's     *
- * Read-Set-If-Zero address, it returns the original contents and       *
- * sets the bit if the original value is zero.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_scratch_reg3_u {
-	bdrkreg_t	lb_scratch_reg3_regval;
-	struct  {
-		bdrkreg_t	sr_scratch_bit            :	 1;
-		bdrkreg_t	sr_reserved		  :	63;
-	} lb_scratch_reg3_fld_s;
-} lb_scratch_reg3_u_t;
-
-#else
-
-typedef union lb_scratch_reg3_u {
-	bdrkreg_t	lb_scratch_reg3_regval;
-	struct	{
-		bdrkreg_t	sr_reserved		  :	63;
-		bdrkreg_t	sr_scratch_bit		  :	 1;
-	} lb_scratch_reg3_fld_s;
-} lb_scratch_reg3_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  These one-bit registers are scratch registers. At a register's      *
- * normal address, it is a simple storage location. At a register's     *
- * Read-Set-If-Zero address, it returns the original contents and       *
- * sets the bit if the original value is zero.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_scratch_reg4_u {
-	bdrkreg_t	lb_scratch_reg4_regval;
-	struct  {
-		bdrkreg_t	sr_scratch_bit            :	 1;
-		bdrkreg_t       sr_reserved               :     63;
-	} lb_scratch_reg4_fld_s;
-} lb_scratch_reg4_u_t;
-
-#else
-
-typedef union lb_scratch_reg4_u {
-	bdrkreg_t	lb_scratch_reg4_regval;
-	struct	{
-		bdrkreg_t	sr_reserved		  :	63;
-		bdrkreg_t	sr_scratch_bit		  :	 1;
-	} lb_scratch_reg4_fld_s;
-} lb_scratch_reg4_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is a scratch register that is reset to 0x0. At the    *
- * normal address, the register is a simple storage location. At the    *
- * Write-If-Zero address, the register accepts a new value from a       *
- * write operation only if the current value is zero.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_scratch_reg0_wz_u {
-	bdrkreg_t	lb_scratch_reg0_wz_regval;
-	struct  {
-		bdrkreg_t	srw_scratch_bits          :	64;
-	} lb_scratch_reg0_wz_fld_s;
-} lb_scratch_reg0_wz_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  These registers are scratch registers that are not reset. At a      *
- * register's normal address, it is a simple storage location. At a     *
- * register's Write-If-Zero address, it accepts a new value from a      *
- * write operation only if the current value is zero.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_scratch_reg1_wz_u {
-	bdrkreg_t	lb_scratch_reg1_wz_regval;
-	struct  {
-		bdrkreg_t	srw_scratch_bits          :	64;
-	} lb_scratch_reg1_wz_fld_s;
-} lb_scratch_reg1_wz_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  These registers are scratch registers that are not reset. At a      *
- * register's normal address, it is a simple storage location. At a     *
- * register's Write-If-Zero address, it accepts a new value from a      *
- * write operation only if the current value is zero.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_scratch_reg2_wz_u {
-	bdrkreg_t	lb_scratch_reg2_wz_regval;
-	struct  {
-		bdrkreg_t	srw_scratch_bits          :	64;
-	} lb_scratch_reg2_wz_fld_s;
-} lb_scratch_reg2_wz_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  These one-bit registers are scratch registers. At a register's      *
- * normal address, it is a simple storage location. At a register's     *
- * Read-Set-If-Zero address, it returns the original contents and       *
- * sets the bit if the original value is zero.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_scratch_reg3_rz_u {
-	bdrkreg_t	lb_scratch_reg3_rz_regval;
-	struct  {
-		bdrkreg_t	srr_scratch_bit           :	 1;
-		bdrkreg_t       srr_reserved              :     63;
-	} lb_scratch_reg3_rz_fld_s;
-} lb_scratch_reg3_rz_u_t;
-
-#else
-
-typedef union lb_scratch_reg3_rz_u {
-	bdrkreg_t	lb_scratch_reg3_rz_regval;
-	struct	{
-		bdrkreg_t	srr_reserved		  :	63;
-		bdrkreg_t	srr_scratch_bit		  :	 1;
-	} lb_scratch_reg3_rz_fld_s;
-} lb_scratch_reg3_rz_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  These one-bit registers are scratch registers. At a register's      *
- * normal address, it is a simple storage location. At a register's     *
- * Read-Set-If-Zero address, it returns the original contents and       *
- * sets the bit if the original value is zero.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_scratch_reg4_rz_u {
-	bdrkreg_t	lb_scratch_reg4_rz_regval;
-	struct  {
-		bdrkreg_t	srr_scratch_bit           :	 1;
-		bdrkreg_t       srr_reserved              :     63;
-	} lb_scratch_reg4_rz_fld_s;
-} lb_scratch_reg4_rz_u_t;
-
-#else
-
-typedef union lb_scratch_reg4_rz_u {
-	bdrkreg_t	lb_scratch_reg4_rz_regval;
-	struct	{
-		bdrkreg_t	srr_reserved		  :	63;
-		bdrkreg_t	srr_scratch_bit		  :	 1;
-	} lb_scratch_reg4_rz_fld_s;
-} lb_scratch_reg4_rz_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register contains vector PIO parameters. A        *
- * write to this register triggers the LB to send out a vector PIO      *
- * request packet. Immediately after servicing a write request to the   *
- * LB_VECTOR_PARMS register, the LB sends back a reply (i.e., the LB    *
- * doesn't wait for the vector PIO operation to finish first). Three    *
- * LB registers provide the contents for an outgoing vector PIO         *
- * request packet. Software should wait until the BUSY bit in           *
- * LB_VECTOR_PARMS is clear and then initialize all three of these      *
- * registers before initiating a vector PIO operation. The three        *
- * vector PIO registers are:                                            *
- * LB_VECTOR_ROUTE                                                      *
- * LB_VECTOR_DATA                                                       *
- * LB_VECTOR_PARMS (should be written last)                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_vector_parms_u {
-	bdrkreg_t	lb_vector_parms_regval;
-	struct  {
-		bdrkreg_t	vp_type                   :	 1;
-		bdrkreg_t       vp_reserved_2             :      2;
-		bdrkreg_t       vp_address                :     21;
-		bdrkreg_t       vp_reserved_1             :      8;
-		bdrkreg_t       vp_write_id               :      8;
-		bdrkreg_t       vp_pio_id                 :     11;
-		bdrkreg_t       vp_reserved               :     12;
-		bdrkreg_t       vp_busy                   :      1;
-	} lb_vector_parms_fld_s;
-} lb_vector_parms_u_t;
-
-#else
-
-typedef union lb_vector_parms_u {
-	bdrkreg_t	lb_vector_parms_regval;
-	struct	{
-		bdrkreg_t	vp_busy			  :	 1;
-		bdrkreg_t	vp_reserved		  :	12;
-		bdrkreg_t	vp_pio_id		  :	11;
-		bdrkreg_t	vp_write_id		  :	 8;
-		bdrkreg_t	vp_reserved_1		  :	 8;
-		bdrkreg_t	vp_address		  :	21;
-		bdrkreg_t	vp_reserved_2		  :	 2;
-		bdrkreg_t	vp_type			  :	 1;
-	} lb_vector_parms_fld_s;
-} lb_vector_parms_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the vector PIO route. This is one of the 3   *
- * vector PIO control registers.                                        *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_vector_route_u {
-	bdrkreg_t	lb_vector_route_regval;
-	struct  {
-		bdrkreg_t	vr_vector                 :	64;
-	} lb_vector_route_fld_s;
-} lb_vector_route_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the vector PIO write data. This is one of    *
- * the 3 vector PIO control registers. The contents of this register    *
- * also provide the data value to be sent in outgoing vector PIO read   *
- * requests and vector PIO write replies.                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_vector_data_u {
-	bdrkreg_t	lb_vector_data_regval;
-	struct  {
-		bdrkreg_t	vd_write_data             :	64;
-	} lb_vector_data_fld_s;
-} lb_vector_data_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register contains the vector PIO return status.   *
- * Software should clear this register before launching a vector PIO    *
- * request from the LB. The LB will not modify this register's value    *
- * if an incoming reply packet encounters any kind of error. If an      *
- * incoming reply packet does not encounter an error but the            *
- * STATUS_VALID bit is already set, then the LB sets the OVERRUN bit    *
- * and leaves the other fields unchanged. The LB updates the values     *
- * of the SOURCE, PIO_ID, WRITE_ID, ADDRESS and TYPE fields only if     *
- * an incoming vector PIO reply packet does not encounter an error      *
- * and the STATUS_VALID bit is clear; at the same time, the LB sets     *
- * the STATUS_VALID bit and will also update the LB_VECTOR_RETURN and   *
- * LB_VECTOR_READ_DATA registers.                                       *
- *                                                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_vector_status_u {
-	bdrkreg_t	lb_vector_status_regval;
-	struct  {
-		bdrkreg_t	vs_type                   :	 3;
-		bdrkreg_t       vs_address                :     21;
-		bdrkreg_t       vs_reserved               :      8;
-		bdrkreg_t       vs_write_id               :      8;
-		bdrkreg_t       vs_pio_id                 :     11;
-		bdrkreg_t       vs_source                 :     11;
-		bdrkreg_t       vs_overrun                :      1;
-		bdrkreg_t       vs_status_valid           :      1;
-	} lb_vector_status_fld_s;
-} lb_vector_status_u_t;
-
-#else
-
-typedef union lb_vector_status_u {
-	bdrkreg_t	lb_vector_status_regval;
-	struct	{
-		bdrkreg_t	vs_status_valid		  :	 1;
-		bdrkreg_t	vs_overrun		  :	 1;
-		bdrkreg_t	vs_source		  :	11;
-		bdrkreg_t	vs_pio_id		  :	11;
-		bdrkreg_t	vs_write_id		  :	 8;
-		bdrkreg_t	vs_reserved		  :	 8;
-		bdrkreg_t	vs_address		  :	21;
-		bdrkreg_t	vs_type			  :	 3;
-	} lb_vector_status_fld_s;
-} lb_vector_status_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the return vector PIO route. The LB will     *
- * not modify this register's value if an incoming reply packet         *
- * encounters any kind of error. The LB also will not modify this       *
- * register's value if the STATUS_VALID bit in the LB_VECTOR_STATUS     *
- * register is set when it receives an incoming vector PIO reply. The   *
- * LB stores an incoming vector PIO reply packet's vector route flit    *
- * in this register only if the packet does not encounter an error      *
- * and the STATUS_VALID bit is clear.                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_vector_return_u {
-	bdrkreg_t	lb_vector_return_regval;
-	struct  {
-		bdrkreg_t	vr_return_vector          :	64;
-	} lb_vector_return_fld_s;
-} lb_vector_return_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the vector PIO read data, if any. The LB     *
- * will not modify this register's value if an incoming reply packet    *
- * encounters any kind of error. The LB also will not modify this       *
- * register's value if the STATUS_VALID bit in the LB_VECTOR_STATUS     *
- * register is set when it receives an incoming vector PIO reply. The   *
- * LB stores an incoming vector PIO reply packet's data flit in this    *
- * register only if the packet does not encounter an error and the      *
- * STATUS_VALID bit is clear.                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union lb_vector_read_data_u {
-	bdrkreg_t	lb_vector_read_data_regval;
-	struct  {
-		bdrkreg_t	vrd_read_data             :	64;
-	} lb_vector_read_data_fld_s;
-} lb_vector_read_data_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register contains the vector PIO return status.   *
- * Software should clear this register before launching a vector PIO    *
- * request from the LB. The LB will not modify this register's value    *
- * if an incoming reply packet encounters any kind of error. If an      *
- * incoming reply packet does not encounter an error but the            *
- * STATUS_VALID bit is already set, then the LB sets the OVERRUN bit    *
- * and leaves the other fields unchanged. The LB updates the values     *
- * of the SOURCE, PIO_ID, WRITE_ID, ADDRESS and TYPE fields only if     *
- * an incoming vector PIO reply packet does not encounter an error      *
- * and the STATUS_VALID bit is clear; at the same time, the LB sets     *
- * the STATUS_VALID bit and will also update the LB_VECTOR_RETURN and   *
- * LB_VECTOR_READ_DATA registers.                                       *
- *                                                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union lb_vector_status_clear_u {
-	bdrkreg_t	lb_vector_status_clear_regval;
-	struct  {
-		bdrkreg_t	vsc_type                  :	 3;
-		bdrkreg_t       vsc_address               :     21;
-		bdrkreg_t       vsc_reserved              :      8;
-		bdrkreg_t       vsc_write_id              :      8;
-		bdrkreg_t       vsc_pio_id                :     11;
-		bdrkreg_t       vsc_source                :     11;
-		bdrkreg_t       vsc_overrun               :      1;
-		bdrkreg_t       vsc_status_valid          :      1;
-	} lb_vector_status_clear_fld_s;
-} lb_vector_status_clear_u_t;
-
-#else
-
-typedef union lb_vector_status_clear_u {
-	bdrkreg_t	lb_vector_status_clear_regval;
-	struct	{
-		bdrkreg_t	vsc_status_valid	  :	 1;
-		bdrkreg_t	vsc_overrun		  :	 1;
-		bdrkreg_t	vsc_source		  :	11;
-		bdrkreg_t	vsc_pio_id		  :	11;
-		bdrkreg_t	vsc_write_id		  :	 8;
-		bdrkreg_t	vsc_reserved		  :	 8;
-		bdrkreg_t	vsc_address		  :	21;
-		bdrkreg_t	vsc_type		  :	 3;
-	} lb_vector_status_clear_fld_s;
-} lb_vector_status_clear_u_t;
-
-#endif
-
-
-
-
-
-
-#endif /* __ASSEMBLY__ */
-
-/************************************************************************
- *                                                                      *
- *               MAKE ALL ADDITIONS AFTER THIS LINE                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-
-#endif /* _ASM_IA64_SN_SN1_HUBLB_H */
diff -Nru a/include/asm-ia64/sn/sn1/hublb_next.h b/include/asm-ia64/sn/sn1/hublb_next.h
--- a/include/asm-ia64/sn/sn1/hublb_next.h	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,109 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBLB_NEXT_H
-#define _ASM_IA64_SN_SN1_HUBLB_NEXT_H
-
-/**********************************************************************
-
- This contains some mask and shift values for LB defined as required
- for compatibility.
-
- **********************************************************************/
-
-#define LRI_SYSTEM_SIZE_SHFT        46
-#define LRI_SYSTEM_SIZE_MASK        (UINT64_CAST 0x3 << LRI_SYSTEM_SIZE_SHFT)
-#define LRI_NODEID_SHFT        32
-#define LRI_NODEID_MASK        (UINT64_CAST 0xff << LRI_NODEID_SHFT)/* Node ID    */
-#define LRI_CHIPID_SHFT		12
-#define LRI_CHIPID_MASK		(UINT64_CAST 0xffff << LRI_CHIPID_SHFT) /* should be 0x3012 */
-#define LRI_REV_SHFT        28
-#define LRI_REV_MASK        (UINT64_CAST 0xf << LRI_REV_SHFT)/* Chip revision    */
-
-/* Values for LRI_SYSTEM_SIZE */
-#define SYSTEM_SIZE_INVALID	0x3
-#define SYSTEM_SIZE_NMODE	0x2
-#define SYSTEM_SIZE_COARSE 	0x1
-#define SYSTEM_SIZE_SMALL	0x0
-
-/* In fine mode, each node is a region.  In coarse mode, there are
- * 2 nodes per region.  In N-mode, there are 4 nodes per region. */
-#define NASID_TO_FINEREG_SHFT   0
-#define NASID_TO_COARSEREG_SHFT 1
-#define NASID_TO_NMODEREG_SHFT  2
-
-#define LR_LOCALRESET               (UINT64_CAST 1)
-/*
- * LB_VECTOR_PARMS mask and shift definitions.
- * TYPE may be any of the first four PIOTYPEs defined under NI_VECTOR_STATUS.
- */
-
-#define LVP_BUSY		(UINT64_CAST 1 << 63)
-#define LVP_PIOID_SHFT          40
-#define LVP_PIOID_MASK          (UINT64_CAST 0x7ff << 40)
-#define LVP_WRITEID_SHFT        32
-#define LVP_WRITEID_MASK        (UINT64_CAST 0xff << 32)
-#define LVP_ADDRESS_MASK        (UINT64_CAST 0xfffff8)   /* Bits 23:3        */
-#define LVP_TYPE_SHFT           0
-#define LVP_TYPE_MASK           (UINT64_CAST 0x3)
-
-/* LB_VECTOR_STATUS mask and shift definitions */
-
-#define LVS_VALID               (UINT64_CAST 1 << 63)
-#define LVS_OVERRUN             (UINT64_CAST 1 << 62)
-#define LVS_TARGET_SHFT         51
-#define LVS_TARGET_MASK         (UINT64_CAST 0x7ff << 51)
-#define LVS_PIOID_SHFT          40
-#define LVS_PIOID_MASK          (UINT64_CAST 0x7ff << 40)
-#define LVS_WRITEID_SHFT        32
-#define LVS_WRITEID_MASK        (UINT64_CAST 0xff << 32)
-#define LVS_ADDRESS_MASK        (UINT64_CAST 0xfffff8)   /* Bits 23:3     */
-#define LVS_TYPE_SHFT           0
-#define LVS_TYPE_MASK           (UINT64_CAST 0x7)
-#define LVS_ERROR_MASK          (UINT64_CAST 0x4)  /* bit set means error */
-
-/* LB_RT_LOCAL_CTRL mask and shift definitions */
-
-#define LRLC_USE_INT_SHFT       32
-#define LRLC_USE_INT_MASK       (UINT64_CAST 1 << 32)
-#define LRLC_USE_INT            (UINT64_CAST 1 << 32)
-#define LRLC_GCLK_SHFT          28
-#define LRLC_GCLK_MASK          (UINT64_CAST 1 << 28)
-#define LRLC_GCLK               (UINT64_CAST 1 << 28)
-#define LRLC_GCLK_COUNT_SHFT    16
-#define LRLC_GCLK_COUNT_MASK    (UINT64_CAST 0x3ff << 16)
-#define LRLC_MAX_COUNT_SHFT     4
-#define LRLC_MAX_COUNT_MASK     (UINT64_CAST 0x3ff << 4)
-#define LRLC_GCLK_EN_SHFT       0
-#define LRLC_GCLK_EN_MASK       (UINT64_CAST 1)
-#define LRLC_GCLK_EN            (UINT64_CAST 1)
-
-/* LB_NODES_ABSENT mask and shift definitions */
-#define LNA_VALID_SHFT		15
-#define LNA_VALID_MASK		(UINT64_CAST 1 << LNA_VALID_SHFT)
-#define LNA_VALID		(UINT64_CAST 1 << LNA_VALID_SHFT)
-#define LNA_NODE_SHFT		0
-#define LNA_NODE_MASK		(UINT64_CAST 0xff << LNA_NODE_SHFT)
-
-/* LB_NODES_ABSENT has 4 identical sub-registers, on 16-bit boundaries */
-#define LNA_ENTRY_SHFT		16
-#define LNA_MAX_ENTRIES		4
-#define LNA_ADD(_reg, _n)	((_reg) = (_reg) << LNA_ENTRY_SHFT | \
-				 	LNA_VALID | (_n) << LNA_NODE_SHFT)
-
-#define  PIOTYPE_READ           0       /* VECTOR_PARMS and VECTOR_STATUS   */
-#define  PIOTYPE_WRITE          1       /* VECTOR_PARMS and VECTOR_STATUS   */
-#define  PIOTYPE_UNDEFINED      2       /* VECTOR_PARMS and VECTOR_STATUS   */
-/* XXX IP35 doesn't support vector exchange:  scr. regs. do locks directly */
-#define  PIOTYPE_EXCHANGE       3       /* VECTOR_PARMS and VECTOR_STATUS   */
-#define  PIOTYPE_ADDR_ERR       4       /* VECTOR_STATUS only               */
-#define  PIOTYPE_CMD_ERR        5       /* VECTOR_STATUS only               */
-#define  PIOTYPE_PROT_ERR       6       /* VECTOR_STATUS only               */
-#define  PIOTYPE_UNKNOWN        7       /* VECTOR_STATUS only               */
-
-#endif /* _ASM_IA64_SN_SN1_HUBLB_NEXT_H */
diff -Nru a/include/asm-ia64/sn/sn1/hubmd.h b/include/asm-ia64/sn/sn1/hubmd.h
--- a/include/asm-ia64/sn/sn1/hubmd.h	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,2476 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBMD_H
-#define _ASM_IA64_SN_SN1_HUBMD_H
-
-
-/************************************************************************
- *                                                                      *
- *      WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!      *
- *                                                                      *
- * This file is created by an automated script. Any (minimal) changes   *
- * made manually to this  file should be made with care.                *
- *                                                                      *
- *               MAKE ALL ADDITIONS TO THE END OF THIS FILE             *
- *                                                                      *
- ************************************************************************/
-
-
-#define    MD_CURRENT_CELL           0x00780000    /*
-                                                    * BDDIR, LREG, LBOOT,
-                                                    * RREG, RBOOT
-                                                    * protection and mask
-                                                    * for using Local
-                                                    * Access protection.
-                                                    */
-
-
-
-#define    MD_MEMORY_CONFIG          0x00780008    /*
-                                                    * Memory/Directory
-                                                    * DIMM control
-                                                    */
-
-
-
-#define    MD_ARBITRATION_CONTROL    0x00780010    /*
-                                                    * Arbitration
-                                                    * Parameters
-                                                    */
-
-
-
-#define    MD_MIG_CONFIG             0x00780018    /*
-                                                    * Page Migration
-                                                    * control
-                                                    */
-
-
-
-#define    MD_FANDOP_CAC_STAT0       0x00780020    /*
-                                                    * Fetch-and-op cache
-                                                    * 0 status
-                                                    */
-
-
-
-#define    MD_FANDOP_CAC_STAT1       0x00780028    /*
-                                                    * Fetch-and-op cache
-                                                    * 1 status
-                                                    */
-
-
-
-#define    MD_MISC0_ERROR            0x00780040    /*
-                                                    * Miscellaneous MD
-                                                    * error
-                                                    */
-
-
-
-#define    MD_MISC1_ERROR            0x00780048    /*
-                                                    * Miscellaneous MD
-                                                    * error
-                                                    */
-
-
-
-#define    MD_MISC1_ERROR_CLR        0x00780058    /*
-                                                    * Miscellaneous MD
-                                                    * error clear
-                                                    */
-
-
-
-#define    MD_OUTGOING_RP_QUEUE_SIZE 0x00780060    /*
-                                                    * MD outgoing reply
-                                                    * queues sizing
-                                                    */
-
-
-
-#define    MD_PERF_SEL0              0x00790000    /*
-                                                    * Selects events
-                                                    * monitored by
-                                                    * MD_PERF_CNT0
-                                                    */
-
-
-
-#define    MD_PERF_SEL1              0x00790008    /*
-                                                    * Selects events
-                                                    * monitored by
-                                                    * MD_PERF_CNT1
-                                                    */
-
-
-
-#define    MD_PERF_CNT0              0x00790010    /*
-                                                    * Performance counter
-                                                    * 0
-                                                    */
-
-
-
-#define    MD_PERF_CNT1              0x00790018    /*
-                                                    * Performance counter
-                                                    * 1
-                                                    */
-
-
-
-#define    MD_REFRESH_CONTROL        0x007A0000    /*
-                                                    * Memory/Directory
-                                                    * refresh control
-                                                    */
-
-
-
-#define    MD_JUNK_BUS_TIMING        0x007A0008    /* Junk Bus Timing        */
-
-
-
-#define    MD_LED0                   0x007A0010    /* Reads of 8-bit LED0    */
-
-
-
-#define    MD_LED1                   0x007A0018    /* Reads of 8-bit LED1    */
-
-
-
-#define    MD_LED2                   0x007A0020    /* Reads of 8-bit LED2    */
-
-
-
-#define    MD_LED3                   0x007A0028    /* Reads of 8-bit LED3    */
-
-
-
-#define    MD_BIST_CTL               0x007A0030    /*
-                                                    * BIST general
-                                                    * control
-                                                    */
-
-
-
-#define    MD_BIST_DATA              0x007A0038    /*
-                                                    * BIST initial data
-                                                    * pattern and
-                                                    * variation control
-                                                    */
-
-
-
-#define    MD_BIST_AB_ERR_ADDR       0x007A0040    /* BIST error address     */
-
-
-
-#define    MD_BIST_STATUS            0x007A0048    /* BIST status            */
-
-
-
-#define    MD_IB_DEBUG               0x007A0060    /* IB debug select        */
-
-
-
-#define    MD_DIR_CONFIG             0x007C0000    /*
-                                                    * Directory mode
-                                                    * control
-                                                    */
-
-
-
-#define    MD_DIR_ERROR              0x007C0010    /*
-                                                    * Directory DIMM
-                                                    * error
-                                                    */
-
-
-
-#define    MD_DIR_ERROR_CLR          0x007C0018    /*
-                                                    * Directory DIMM
-                                                    * error clear
-                                                    */
-
-
-
-#define    MD_PROTOCOL_ERROR         0x007C0020    /*
-                                                    * Directory protocol
-                                                    * error
-                                                    */
-
-
-
-#define    MD_PROTOCOL_ERR_CLR       0x007C0028    /*
-                                                    * Directory protocol
-                                                    * error clear
-                                                    */
-
-
-
-#define    MD_MIG_CANDIDATE          0x007C0030    /*
-                                                    * Page migration
-                                                    * candidate
-                                                    */
-
-
-
-#define    MD_MIG_CANDIDATE_CLR      0x007C0038    /*
-                                                    * Page migration
-                                                    * candidate clear
-                                                    */
-
-
-
-#define    MD_MIG_DIFF_THRESH        0x007C0040    /*
-                                                    * Page migration
-                                                    * count difference
-                                                    * threshold
-                                                    */
-
-
-
-#define    MD_MIG_VALUE_THRESH       0x007C0048    /*
-                                                    * Page migration
-                                                    * count absolute
-                                                    * threshold
-                                                    */
-
-
-
-#define    MD_OUTGOING_RQ_QUEUE_SIZE 0x007C0050    /*
-                                                    * MD outgoing request
-                                                    * queues sizing
-                                                    */
-
-
-
-#define    MD_BIST_DB_ERR_DATA       0x007C0058    /*
-                                                    * BIST directory
-                                                    * error data
-                                                    */
-
-
-
-#define    MD_DB_DEBUG               0x007C0060    /* DB debug select        */
-
-
-
-#define    MD_MB_ECC_CONFIG          0x007E0000    /*
-                                                    * Data ECC
-                                                    * Configuration
-                                                    */
-
-
-
-#define    MD_MEM_ERROR              0x007E0010    /* Memory DIMM error      */
-
-
-
-#define    MD_MEM_ERROR_CLR          0x007E0018    /*
-                                                    * Memory DIMM error
-                                                    * clear
-                                                    */
-
-
-
-#define    MD_BIST_MB_ERR_DATA_0     0x007E0020    /*
-                                                    * BIST memory error
-                                                    * data
-                                                    */
-
-
-
-#define    MD_BIST_MB_ERR_DATA_1     0x007E0028    /*
-                                                    * BIST memory error
-                                                    * data
-                                                    */
-
-
-
-#define    MD_BIST_MB_ERR_DATA_2     0x007E0030    /*
-                                                    * BIST memory error
-                                                    * data
-                                                    */
-
-
-
-#define    MD_BIST_MB_ERR_DATA_3     0x007E0038    /*
-                                                    * BIST memory error
-                                                    * data
-                                                    */
-
-
-
-#define    MD_MB_DEBUG               0x007E0040    /* MB debug select        */
-
-
-
-
-
-#ifndef __ASSEMBLY__
-
-/************************************************************************
- *                                                                      *
- * Description:  This register shows which regions are in the current   *
- * cell. If a region has its bit set in this register, then it uses     *
- * the Local Access protection in the directory instead of the          *
- * separate per-region protection (which would cause a small            *
- * performance penalty). In addition, writeback and write reply         *
- * commands from outside the current cell will always check the         *
- * directory protection before writing data to memory. Writeback and    *
- * write reply commands from inside the current cell will write         *
- * memory regardless of the protection value.                           *
- * This register is also used as the access-rights bit-vector for       *
- * most of the ASIC-special (HSpec) portion of the address space. It    *
- * covers the BDDIR, LREG, LBOOT, RREG, and RBOOT spaces. It does not   *
- * cover the UALIAS and BDECC spaces, as they are covered by the        *
- * protection in the directory. If a bit in the bit-vector is set,      *
- * the region corresponding to that bit has read/write permission on    *
- * these spaces. If the bit is clear, then that region has read-only    *
- * access to these spaces (except for LREG/RREG which have no access    *
- * when the bit is clear).                                              *
- * The granularity of a region is set by the REGION_SIZE register in    *
- * the NI local register space.                                         *
- * NOTE: This means that no processor outside the current cell can      *
- * write into the BDDIR, LREG, LBOOT, RREG, or RBOOT spaces.            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union md_current_cell_u {
-	bdrkreg_t	md_current_cell_regval;
-	struct  {
-		bdrkreg_t	cc_hspec_prot             :	64;
-	} md_current_cell_fld_s;
-} md_current_cell_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register contains three sets of information.      *
- * The first set describes the size and configuration of DIMMs that     *
- * are plugged into a system, the second set controls which set of      *
- * protection checks are performed on each access and the third set     *
- * controls various DDR SDRAM timing parameters.                        *
- * In order to config a DIMM bank, three fields must be initialized:    *
- * BANK_SIZE, DRAM_WIDTH, and BANK_ENABLE. The BANK_SIZE field sets     *
- * the address range that the MD unit will accept for that DIMM bank.   *
- * All addresses larger than the specified size will return errors on   *
- * access. In order to read from a DIMM bank, Bedrock must know         *
- * whether or not the bank contains x4 or x8/x16 DRAM. The operating    *
- * system must query the System Controller for this information and     *
- * then set the DRAM_WIDTH field accordingly. The BANK_ENABLE field     *
- * can be used to individually enable the two physical banks located    *
- * on each DIMM bank.                                                   *
- * The contents of this register are preserved through soft-resets.     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_memory_config_u {
-	bdrkreg_t	md_memory_config_regval;
-	struct  {
-		bdrkreg_t	mc_dimm0_bank_enable      :	 2;
-		bdrkreg_t       mc_reserved_7             :      1;
-		bdrkreg_t       mc_dimm0_dram_width       :      1;
-		bdrkreg_t       mc_dimm0_bank_size        :      4;
-		bdrkreg_t       mc_dimm1_bank_enable      :      2;
-		bdrkreg_t       mc_reserved_6             :      1;
-		bdrkreg_t       mc_dimm1_dram_width       :      1;
-		bdrkreg_t       mc_dimm1_bank_size        :      4;
-                bdrkreg_t       mc_dimm2_bank_enable      :      2;
-                bdrkreg_t       mc_reserved_5             :      1;
-                bdrkreg_t       mc_dimm2_dram_width       :      1;
-                bdrkreg_t       mc_dimm2_bank_size        :      4;
-                bdrkreg_t       mc_dimm3_bank_enable      :      2;
-                bdrkreg_t       mc_reserved_4             :      1;
-                bdrkreg_t       mc_dimm3_dram_width       :      1;
-                bdrkreg_t       mc_dimm3_bank_size        :      4;
-                bdrkreg_t       mc_dimm0_sel              :      2;
-                bdrkreg_t       mc_reserved_3             :     10;
-                bdrkreg_t       mc_cc_enable              :      1;
-                bdrkreg_t       mc_io_prot_en             :      1;
-                bdrkreg_t       mc_io_prot_ignore         :      1;
-                bdrkreg_t       mc_cpu_prot_ignore        :      1;
-                bdrkreg_t       mc_db_neg_edge            :      1;
-                bdrkreg_t       mc_phase_delay            :      1;
-                bdrkreg_t       mc_delay_mux_sel          :      2;
-                bdrkreg_t       mc_sample_time            :      2;
-                bdrkreg_t       mc_reserved_2             :      2;
-                bdrkreg_t       mc_mb_neg_edge            :      3;
-                bdrkreg_t       mc_reserved_1             :      1;
-                bdrkreg_t       mc_rcd_config             :      1;
-                bdrkreg_t       mc_rp_config              :      1;
-                bdrkreg_t       mc_reserved               :      2;
-	} md_memory_config_fld_s;
-} md_memory_config_u_t;
-
-#else
-
-typedef union md_memory_config_u {
-	bdrkreg_t	md_memory_config_regval;
-	struct	{
-		bdrkreg_t	mc_reserved		  :	 2;
-		bdrkreg_t	mc_rp_config		  :	 1;
-		bdrkreg_t	mc_rcd_config		  :	 1;
-		bdrkreg_t	mc_reserved_1		  :	 1;
-		bdrkreg_t	mc_mb_neg_edge		  :	 3;
-		bdrkreg_t	mc_reserved_2		  :	 2;
-		bdrkreg_t	mc_sample_time		  :	 2;
-		bdrkreg_t	mc_delay_mux_sel	  :	 2;
-		bdrkreg_t	mc_phase_delay		  :	 1;
-		bdrkreg_t	mc_db_neg_edge		  :	 1;
-		bdrkreg_t	mc_cpu_prot_ignore	  :	 1;
-		bdrkreg_t	mc_io_prot_ignore	  :	 1;
-		bdrkreg_t	mc_io_prot_en		  :	 1;
-		bdrkreg_t	mc_cc_enable		  :	 1;
-		bdrkreg_t	mc_reserved_3		  :	10;
-		bdrkreg_t	mc_dimm0_sel		  :	 2;
-		bdrkreg_t	mc_dimm3_bank_size	  :	 4;
-		bdrkreg_t	mc_dimm3_dram_width	  :	 1;
-		bdrkreg_t	mc_reserved_4		  :	 1;
-		bdrkreg_t	mc_dimm3_bank_enable	  :	 2;
-		bdrkreg_t	mc_dimm2_bank_size	  :	 4;
-		bdrkreg_t	mc_dimm2_dram_width	  :	 1;
-		bdrkreg_t	mc_reserved_5		  :	 1;
-		bdrkreg_t	mc_dimm2_bank_enable	  :	 2;
-		bdrkreg_t	mc_dimm1_bank_size	  :	 4;
-		bdrkreg_t	mc_dimm1_dram_width	  :	 1;
-		bdrkreg_t	mc_reserved_6		  :	 1;
-		bdrkreg_t	mc_dimm1_bank_enable	  :	 2;
-		bdrkreg_t	mc_dimm0_bank_size	  :	 4;
-		bdrkreg_t	mc_dimm0_dram_width	  :	 1;
-		bdrkreg_t	mc_reserved_7		  :	 1;
-		bdrkreg_t	mc_dimm0_bank_enable	  :	 2;
-	} md_memory_config_fld_s;
-} md_memory_config_u_t;
-
-#endif
-
-
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_arbitration_control_u {
-	bdrkreg_t	md_arbitration_control_regval;
-	struct  {
-		bdrkreg_t	ac_reply_guar             :	 4;
-		bdrkreg_t       ac_write_guar             :      4;
-		bdrkreg_t       ac_reserved               :     56;
-	} md_arbitration_control_fld_s;
-} md_arbitration_control_u_t;
-
-#else
-
-typedef union md_arbitration_control_u {
-	bdrkreg_t	md_arbitration_control_regval;
-	struct	{
-		bdrkreg_t	ac_reserved		  :	56;
-		bdrkreg_t	ac_write_guar		  :	 4;
-		bdrkreg_t	ac_reply_guar		  :	 4;
-	} md_arbitration_control_fld_s;
-} md_arbitration_control_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains page migration control fields.                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mig_config_u {
-	bdrkreg_t	md_mig_config_regval;
-	struct  {
-		bdrkreg_t	mc_mig_interval           :	10;
-		bdrkreg_t       mc_reserved_2             :      6;
-		bdrkreg_t       mc_mig_node_mask          :      8;
-		bdrkreg_t       mc_reserved_1             :      8;
-		bdrkreg_t       mc_mig_enable             :      1;
-		bdrkreg_t       mc_reserved               :     31;
-	} md_mig_config_fld_s;
-} md_mig_config_u_t;
-
-#else
-
-typedef union md_mig_config_u {
-	bdrkreg_t	md_mig_config_regval;
-	struct	{
-		bdrkreg_t	mc_reserved		  :	31;
-		bdrkreg_t	mc_mig_enable		  :	 1;
-		bdrkreg_t	mc_reserved_1		  :	 8;
-		bdrkreg_t	mc_mig_node_mask	  :	 8;
-		bdrkreg_t	mc_reserved_2		  :	 6;
-		bdrkreg_t	mc_mig_interval		  :	10;
-	} md_mig_config_fld_s;
-} md_mig_config_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Each register contains the valid bit and address of the entry in    *
- * the fetch-and-op for cache 0 (or 1).                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_fandop_cac_stat0_u {
-	bdrkreg_t	md_fandop_cac_stat0_regval;
-	struct  {
-		bdrkreg_t	fcs_reserved_1            :	 6;
-		bdrkreg_t       fcs_addr                  :     27;
-		bdrkreg_t       fcs_reserved              :     30;
-		bdrkreg_t       fcs_valid                 :      1;
-	} md_fandop_cac_stat0_fld_s;
-} md_fandop_cac_stat0_u_t;
-
-#else
-
-typedef union md_fandop_cac_stat0_u {
-	bdrkreg_t	md_fandop_cac_stat0_regval;
-	struct	{
-		bdrkreg_t	fcs_valid		  :	 1;
-		bdrkreg_t	fcs_reserved		  :	30;
-		bdrkreg_t	fcs_addr		  :	27;
-		bdrkreg_t	fcs_reserved_1		  :	 6;
-	} md_fandop_cac_stat0_fld_s;
-} md_fandop_cac_stat0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Each register contains the valid bit and address of the entry in    *
- * the fetch-and-op for cache 0 (or 1).                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_fandop_cac_stat1_u {
-	bdrkreg_t	md_fandop_cac_stat1_regval;
-	struct  {
-		bdrkreg_t	fcs_reserved_1            :	 6;
-		bdrkreg_t       fcs_addr                  :     27;
-		bdrkreg_t       fcs_reserved              :     30;
-		bdrkreg_t       fcs_valid                 :      1;
-	} md_fandop_cac_stat1_fld_s;
-} md_fandop_cac_stat1_u_t;
-
-#else
-
-typedef union md_fandop_cac_stat1_u {
-	bdrkreg_t	md_fandop_cac_stat1_regval;
-	struct	{
-		bdrkreg_t	fcs_valid		  :	 1;
-		bdrkreg_t	fcs_reserved		  :	30;
-		bdrkreg_t	fcs_addr		  :	27;
-		bdrkreg_t	fcs_reserved_1		  :	 6;
-	} md_fandop_cac_stat1_fld_s;
-} md_fandop_cac_stat1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  Contains a number of fields to capture various         *
- * random memory/directory errors. For each 2-bit field, the LSB        *
- * indicates that additional information has been captured for the      *
- * error and the MSB indicates overrun, thus:                           *
- *  x1: bits 51...0 of this register contain additional information     *
- * for the message that caused this error                               *
- *  1x: overrun occurred                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_misc0_error_u {
-	bdrkreg_t	md_misc0_error_regval;
-	struct	{
-		bdrkreg_t	me_command		  :	 7;
-                bdrkreg_t       me_reserved_4             :      1;
-                bdrkreg_t       me_source                 :     11;
-                bdrkreg_t       me_reserved_3             :      1;
-                bdrkreg_t       me_suppl                  :     11;
-                bdrkreg_t       me_reserved_2             :      1;
-                bdrkreg_t       me_virtual_channel        :      2;
-                bdrkreg_t       me_reserved_1             :      2;
-                bdrkreg_t       me_tail                   :      1;
-                bdrkreg_t       me_reserved               :     11;
-                bdrkreg_t       me_xb_error               :      4;
-                bdrkreg_t       me_bad_partial_data       :      2;
-                bdrkreg_t       me_missing_dv             :      2;
-                bdrkreg_t       me_short_pack             :      2;
-                bdrkreg_t       me_long_pack              :      2;
-                bdrkreg_t       me_ill_msg                :      2;
-                bdrkreg_t       me_ill_revision           :      2;
-	} md_misc0_error_fld_s;
-} md_misc0_error_u_t;
-
-#else
-
-typedef union md_misc0_error_u {
-	bdrkreg_t	md_misc0_error_regval;
-	struct  {
-		bdrkreg_t	me_ill_revision           :	 2;
-		bdrkreg_t	me_ill_msg                :	 2;
-		bdrkreg_t	me_long_pack              :	 2;
-		bdrkreg_t	me_short_pack             :	 2;
-		bdrkreg_t	me_missing_dv             :	 2;
-		bdrkreg_t	me_bad_partial_data       :	 2;
-		bdrkreg_t	me_xb_error               :	 4;
-		bdrkreg_t	me_reserved               :	11;
-		bdrkreg_t	me_tail                   :	 1;
-		bdrkreg_t	me_reserved_1             :	 2;
-		bdrkreg_t	me_virtual_channel        :	 2;
-		bdrkreg_t	me_reserved_2             :	 1;
-		bdrkreg_t	me_suppl                  :	11;
-		bdrkreg_t	me_reserved_3             :	 1;
-		bdrkreg_t	me_source                 :	11;
-		bdrkreg_t	me_reserved_4             :	 1;
-		bdrkreg_t	me_command                :	 7;
-	} md_misc0_error_fld_s;
-} md_misc0_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Address for error captured in MISC0_ERROR. Error valid bits are     *
- * repeated in both MISC0_ERROR and MISC1_ERROR (allowing them to be    *
- * read sequentially without missing any errors).                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_misc1_error_u {
-	bdrkreg_t	md_misc1_error_regval;
-	struct  {
-		bdrkreg_t	me_reserved_1             :	 3;
-		bdrkreg_t       me_address                :     38;
-		bdrkreg_t       me_reserved               :      7;
-		bdrkreg_t       me_xb_error               :      4;
-		bdrkreg_t       me_bad_partial_data       :      2;
-		bdrkreg_t       me_missing_dv             :      2;
-		bdrkreg_t       me_short_pack             :      2;
-		bdrkreg_t       me_long_pack              :      2;
-		bdrkreg_t       me_ill_msg                :      2;
-		bdrkreg_t       me_ill_revision           :      2;
-	} md_misc1_error_fld_s;
-} md_misc1_error_u_t;
-
-#else
-
-typedef union md_misc1_error_u {
-	bdrkreg_t	md_misc1_error_regval;
-	struct	{
-		bdrkreg_t	me_ill_revision		  :	 2;
-		bdrkreg_t	me_ill_msg		  :	 2;
-		bdrkreg_t	me_long_pack		  :	 2;
-		bdrkreg_t	me_short_pack		  :	 2;
-		bdrkreg_t	me_missing_dv		  :	 2;
-		bdrkreg_t	me_bad_partial_data	  :	 2;
-		bdrkreg_t	me_xb_error		  :	 4;
-		bdrkreg_t	me_reserved		  :	 7;
-		bdrkreg_t	me_address		  :	38;
-		bdrkreg_t	me_reserved_1		  :	 3;
-	} md_misc1_error_fld_s;
-} md_misc1_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Address for error captured in MISC0_ERROR. Error valid bits are     *
- * repeated in both MISC0_ERROR and MISC1_ERROR (allowing them to be    *
- * read sequentially without missing any errors).                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_misc1_error_clr_u {
-	bdrkreg_t	md_misc1_error_clr_regval;
-	struct  {
-		bdrkreg_t	mec_reserved_1            :	 3;
-		bdrkreg_t       mec_address               :     38;
-		bdrkreg_t       mec_reserved              :      7;
-		bdrkreg_t       mec_xb_error              :      4;
-		bdrkreg_t       mec_bad_partial_data      :      2;
-		bdrkreg_t       mec_missing_dv            :      2;
-		bdrkreg_t       mec_short_pack            :      2;
-		bdrkreg_t       mec_long_pack             :      2;
-		bdrkreg_t       mec_ill_msg               :      2;
-		bdrkreg_t       mec_ill_revision          :      2;
-	} md_misc1_error_clr_fld_s;
-} md_misc1_error_clr_u_t;
-
-#else
-
-typedef union md_misc1_error_clr_u {
-	bdrkreg_t	md_misc1_error_clr_regval;
-	struct	{
-		bdrkreg_t	mec_ill_revision	  :	 2;
-		bdrkreg_t	mec_ill_msg		  :	 2;
-		bdrkreg_t	mec_long_pack		  :	 2;
-		bdrkreg_t	mec_short_pack		  :	 2;
-		bdrkreg_t	mec_missing_dv		  :	 2;
-		bdrkreg_t	mec_bad_partial_data	  :	 2;
-		bdrkreg_t	mec_xb_error		  :	 4;
-		bdrkreg_t	mec_reserved		  :	 7;
-		bdrkreg_t	mec_address		  :	38;
-		bdrkreg_t	mec_reserved_1		  :	 3;
-	} md_misc1_error_clr_fld_s;
-} md_misc1_error_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  The MD no longer allows for arbitrarily sizing the     *
- * reply queues, so all of the fields in this register are read-only    *
- * and contain the reset default value of 12 for the MOQHs (for         *
- * headers) and 24 for the MOQDs (for data).                            *
- * Reading from this register returns the values currently held in      *
- * the MD's credit counters. Writing to the register resets the         *
- * counters to the default reset values specified in the table below.   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_outgoing_rp_queue_size_u {
-	bdrkreg_t	md_outgoing_rp_queue_size_regval;
-	struct  {
-		bdrkreg_t	orqs_reserved_6           :	 8;
-		bdrkreg_t       orqs_moqh_p0_rp_size      :      4;
-		bdrkreg_t       orqs_reserved_5           :      4;
-		bdrkreg_t       orqs_moqh_p1_rp_size      :      4;
-		bdrkreg_t       orqs_reserved_4           :      4;
-		bdrkreg_t       orqs_moqh_np_rp_size      :      4;
-		bdrkreg_t       orqs_reserved_3           :      4;
-		bdrkreg_t       orqs_moqd_pi0_rp_size     :      5;
-		bdrkreg_t       orqs_reserved_2           :      3;
-		bdrkreg_t       orqs_moqd_pi1_rp_size     :      5;
-		bdrkreg_t       orqs_reserved_1           :      3;
-		bdrkreg_t       orqs_moqd_np_rp_size      :      5;
-		bdrkreg_t       orqs_reserved             :     11;
-	} md_outgoing_rp_queue_size_fld_s;
-} md_outgoing_rp_queue_size_u_t;
-
-#else
-
-typedef union md_outgoing_rp_queue_size_u {
-	bdrkreg_t	md_outgoing_rp_queue_size_regval;
-	struct	{
-		bdrkreg_t	orqs_reserved		  :	11;
-		bdrkreg_t	orqs_moqd_np_rp_size	  :	 5;
-		bdrkreg_t	orqs_reserved_1		  :	 3;
-		bdrkreg_t	orqs_moqd_pi1_rp_size	  :	 5;
-		bdrkreg_t	orqs_reserved_2		  :	 3;
-		bdrkreg_t	orqs_moqd_pi0_rp_size	  :	 5;
-		bdrkreg_t	orqs_reserved_3		  :	 4;
-		bdrkreg_t	orqs_moqh_np_rp_size	  :	 4;
-		bdrkreg_t	orqs_reserved_4		  :	 4;
-		bdrkreg_t	orqs_moqh_p1_rp_size	  :	 4;
-		bdrkreg_t	orqs_reserved_5		  :	 4;
-		bdrkreg_t	orqs_moqh_p0_rp_size	  :	 4;
-		bdrkreg_t	orqs_reserved_6		  :	 8;
-	} md_outgoing_rp_queue_size_fld_s;
-} md_outgoing_rp_queue_size_u_t;
-
-#endif
-
-
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_perf_sel0_u {
-	bdrkreg_t	md_perf_sel0_regval;
-	struct  {
-		bdrkreg_t	ps_cnt_mode               :	 2;
-		bdrkreg_t       ps_reserved_2             :      2;
-		bdrkreg_t       ps_activity               :      4;
-		bdrkreg_t       ps_source                 :      7;
-		bdrkreg_t       ps_reserved_1             :      1;
-		bdrkreg_t       ps_channel                :      4;
-		bdrkreg_t       ps_command                :     40;
-		bdrkreg_t       ps_reserved               :      3;
-		bdrkreg_t       ps_interrupt              :      1;
-	} md_perf_sel0_fld_s;
-} md_perf_sel0_u_t;
-
-#else
-
-typedef union md_perf_sel0_u {
-	bdrkreg_t	md_perf_sel0_regval;
-	struct	{
-		bdrkreg_t	ps_interrupt		  :	 1;
-		bdrkreg_t	ps_reserved		  :	 3;
-		bdrkreg_t	ps_command		  :	40;
-		bdrkreg_t	ps_channel		  :	 4;
-		bdrkreg_t	ps_reserved_1		  :	 1;
-		bdrkreg_t	ps_source		  :	 7;
-		bdrkreg_t	ps_activity		  :	 4;
-		bdrkreg_t	ps_reserved_2		  :	 2;
-		bdrkreg_t	ps_cnt_mode		  :	 2;
-	} md_perf_sel0_fld_s;
-} md_perf_sel0_u_t;
-
-#endif
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_perf_sel1_u {
-	bdrkreg_t	md_perf_sel1_regval;
-	struct  {
-		bdrkreg_t	ps_cnt_mode               :	 2;
-		bdrkreg_t       ps_reserved_2             :      2;
-		bdrkreg_t       ps_activity               :      4;
-		bdrkreg_t       ps_source                 :      7;
-		bdrkreg_t       ps_reserved_1             :      1;
-		bdrkreg_t       ps_channel                :      4;
-		bdrkreg_t       ps_command                :     40;
-		bdrkreg_t       ps_reserved               :      3;
-		bdrkreg_t       ps_interrupt              :      1;
-	} md_perf_sel1_fld_s;
-} md_perf_sel1_u_t;
-
-#else
-
-typedef union md_perf_sel1_u {
-	bdrkreg_t	md_perf_sel1_regval;
-	struct	{
-		bdrkreg_t	ps_interrupt		  :	 1;
-		bdrkreg_t	ps_reserved		  :	 3;
-		bdrkreg_t	ps_command		  :	40;
-		bdrkreg_t	ps_channel		  :	 4;
-		bdrkreg_t	ps_reserved_1		  :	 1;
-		bdrkreg_t	ps_source		  :	 7;
-		bdrkreg_t	ps_activity		  :	 4;
-		bdrkreg_t	ps_reserved_2		  :	 2;
-		bdrkreg_t	ps_cnt_mode		  :	 2;
-	} md_perf_sel1_fld_s;
-} md_perf_sel1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Performance counter.                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_perf_cnt0_u {
-	bdrkreg_t	md_perf_cnt0_regval;
-	struct  {
-		bdrkreg_t	pc_perf_cnt               :	41;
-		bdrkreg_t	pc_reserved		  :	23;
-	} md_perf_cnt0_fld_s;
-} md_perf_cnt0_u_t;
-
-#else
-
-typedef union md_perf_cnt0_u {
-	bdrkreg_t	md_perf_cnt0_regval;
-	struct	{
-		bdrkreg_t	pc_reserved		  :	23;
-		bdrkreg_t	pc_perf_cnt		  :	41;
-	} md_perf_cnt0_fld_s;
-} md_perf_cnt0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Performance counter.                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_perf_cnt1_u {
-	bdrkreg_t	md_perf_cnt1_regval;
-	struct  {
-		bdrkreg_t	pc_perf_cnt               :	41;
-		bdrkreg_t	pc_reserved		  :	23;
-	} md_perf_cnt1_fld_s;
-} md_perf_cnt1_u_t;
-
-#else
-
-typedef union md_perf_cnt1_u {
-	bdrkreg_t	md_perf_cnt1_regval;
-	struct	{
-		bdrkreg_t	pc_reserved		  :	23;
-		bdrkreg_t	pc_perf_cnt		  :	41;
-	} md_perf_cnt1_fld_s;
-} md_perf_cnt1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register contains the control for                 *
- * memory/directory refresh. Once the MEMORY_CONFIG register contains   *
- * the correct DIMM information, the hardware takes care of             *
- * refreshing all the banks in the system. Therefore, the value in      *
- * the counter threshold is corresponds exactly to the refresh value    *
- * required by the SDRAM parts (expressed in Bedrock clock cycles).     *
- * The refresh will execute whenever there is a free cycle and there    *
- * are still banks that have not been refreshed in the current          *
- * window. If the window expires with banks still waiting to be         *
- * refreshed, all other transactions are halted until the banks are     *
- * refreshed.                                                           *
- * The upper order bit contains an enable, which may be needed for      *
- * correct initialization of the DIMMs (according to the specs, the     *
- * first operation to the DIMMs should be a mode register write, not    *
- * a refresh, so this bit is cleared on reset) and is also useful for   *
- * diagnostic purposes.                                                 *
- * For the SDRAM parts used by Bedrock, 4096 refreshes need to be       *
- * issued during every 64 ms window, resulting in a refresh threshold   *
- * of 3125 Bedrock cycles.                                              *
- * The ENABLE and CNT_THRESH fields of this register are preserved      *
- * through soft-resets.                                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_refresh_control_u {
-	bdrkreg_t	md_refresh_control_regval;
-	struct  {
-		bdrkreg_t	rc_cnt_thresh             :	12;
-		bdrkreg_t       rc_counter                :     12;
-		bdrkreg_t       rc_reserved               :     39;
-		bdrkreg_t       rc_enable                 :      1;
-	} md_refresh_control_fld_s;
-} md_refresh_control_u_t;
-
-#else
-
-typedef union md_refresh_control_u {
-	bdrkreg_t	md_refresh_control_regval;
-	struct	{
-		bdrkreg_t	rc_enable		  :	 1;
-		bdrkreg_t	rc_reserved		  :	39;
-		bdrkreg_t	rc_counter		  :	12;
-		bdrkreg_t	rc_cnt_thresh		  :	12;
-	} md_refresh_control_fld_s;
-} md_refresh_control_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register controls the read and write timing for Flash PROM,    *
- * UART and Synergy junk bus devices.                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_junk_bus_timing_u {
-	bdrkreg_t	md_junk_bus_timing_regval;
-	struct  {
-		bdrkreg_t	jbt_fprom_setup_hold      :	 8;
-		bdrkreg_t       jbt_fprom_enable          :      8;
-		bdrkreg_t       jbt_uart_setup_hold       :      8;
-		bdrkreg_t       jbt_uart_enable           :      8;
-		bdrkreg_t       jbt_synergy_setup_hold    :      8;
-		bdrkreg_t       jbt_synergy_enable        :      8;
-		bdrkreg_t       jbt_reserved              :     16;
-	} md_junk_bus_timing_fld_s;
-} md_junk_bus_timing_u_t;
-
-#else
-
-typedef union md_junk_bus_timing_u {
-	bdrkreg_t	md_junk_bus_timing_regval;
-	struct	{
-		bdrkreg_t	jbt_reserved		  :	16;
-		bdrkreg_t	jbt_synergy_enable	  :	 8;
-		bdrkreg_t	jbt_synergy_setup_hold	  :	 8;
-		bdrkreg_t	jbt_uart_enable		  :	 8;
-		bdrkreg_t	jbt_uart_setup_hold	  :	 8;
-		bdrkreg_t	jbt_fprom_enable	  :	 8;
-		bdrkreg_t	jbt_fprom_setup_hold	  :	 8;
-	} md_junk_bus_timing_fld_s;
-} md_junk_bus_timing_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Each of these addresses allows the value on one 8-bit bank of       *
- * LEDs to be read.                                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_led0_u {
-	bdrkreg_t	md_led0_regval;
-	struct  {
-		bdrkreg_t	l_data                    :	 8;
-		bdrkreg_t       l_reserved                :     56;
-	} md_led0_fld_s;
-} md_led0_u_t;
-
-#else
-
-typedef union md_led0_u {
-	bdrkreg_t	md_led0_regval;
-	struct	{
-		bdrkreg_t	l_reserved		  :	56;
-		bdrkreg_t	l_data			  :	 8;
-	} md_led0_fld_s;
-} md_led0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Each of these addresses allows the value on one 8-bit bank of       *
- * LEDs to be read.                                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_led1_u {
-	bdrkreg_t	md_led1_regval;
-	struct  {
-		bdrkreg_t	l_data                    :	 8;
-		bdrkreg_t       l_reserved                :     56;
-	} md_led1_fld_s;
-} md_led1_u_t;
-
-#else
-
-typedef union md_led1_u {
-	bdrkreg_t	md_led1_regval;
-	struct	{
-		bdrkreg_t	l_reserved		  :	56;
-		bdrkreg_t	l_data			  :	 8;
-	} md_led1_fld_s;
-} md_led1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Each of these addresses allows the value on one 8-bit bank of       *
- * LEDs to be read.                                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_led2_u {
-	bdrkreg_t	md_led2_regval;
-	struct  {
-		bdrkreg_t	l_data                    :	 8;
-		bdrkreg_t       l_reserved                :     56;
-	} md_led2_fld_s;
-} md_led2_u_t;
-
-#else
-
-typedef union md_led2_u {
-	bdrkreg_t	md_led2_regval;
-	struct	{
-		bdrkreg_t	l_reserved		  :	56;
-		bdrkreg_t	l_data			  :	 8;
-	} md_led2_fld_s;
-} md_led2_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Each of these addresses allows the value on one 8-bit bank of       *
- * LEDs to be read.                                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_led3_u {
-	bdrkreg_t	md_led3_regval;
-	struct  {
-		bdrkreg_t	l_data                    :	 8;
-		bdrkreg_t       l_reserved                :     56;
-	} md_led3_fld_s;
-} md_led3_u_t;
-
-#else
-
-typedef union md_led3_u {
-	bdrkreg_t	md_led3_regval;
-	struct	{
-		bdrkreg_t	l_reserved		  :	56;
-		bdrkreg_t	l_data			  :	 8;
-	} md_led3_fld_s;
-} md_led3_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Core control for the BIST function. Start and stop BIST at any      *
- * time.                                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_ctl_u {
-	bdrkreg_t	md_bist_ctl_regval;
-	struct  {
-		bdrkreg_t	bc_bist_start             :	 1;
-		bdrkreg_t       bc_bist_stop              :      1;
-		bdrkreg_t       bc_bist_reset             :      1;
-		bdrkreg_t       bc_reserved_1             :      1;
-		bdrkreg_t       bc_bank_num               :      1;
-		bdrkreg_t       bc_dimm_num               :      2;
-		bdrkreg_t       bc_reserved               :     57;
-	} md_bist_ctl_fld_s;
-} md_bist_ctl_u_t;
-
-#else
-
-typedef union md_bist_ctl_u {
-	bdrkreg_t	md_bist_ctl_regval;
-	struct	{
-		bdrkreg_t	bc_reserved		  :	57;
-		bdrkreg_t	bc_dimm_num		  :	 2;
-		bdrkreg_t	bc_bank_num		  :	 1;
-		bdrkreg_t	bc_reserved_1		  :	 1;
-		bdrkreg_t	bc_bist_reset		  :	 1;
-		bdrkreg_t	bc_bist_stop		  :	 1;
-		bdrkreg_t	bc_bist_start		  :	 1;
-	} md_bist_ctl_fld_s;
-} md_bist_ctl_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contain the initial BIST data nibble and the 4-bit data control     *
- * field..                                                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_data_u {
-	bdrkreg_t	md_bist_data_regval;
-	struct  {
-		bdrkreg_t	bd_bist_data              :	 4;
-		bdrkreg_t	bd_bist_nibble		  :	 1;
-		bdrkreg_t       bd_bist_byte              :      1;
-		bdrkreg_t       bd_bist_cycle             :      1;
-		bdrkreg_t       bd_bist_write             :      1;
-		bdrkreg_t       bd_reserved               :     56;
-	} md_bist_data_fld_s;
-} md_bist_data_u_t;
-
-#else
-
-typedef union md_bist_data_u {
-	bdrkreg_t	md_bist_data_regval;
-	struct	{
-		bdrkreg_t	bd_reserved		  :	56;
-		bdrkreg_t	bd_bist_write		  :	 1;
-		bdrkreg_t	bd_bist_cycle		  :	 1;
-		bdrkreg_t	bd_bist_byte		  :	 1;
-		bdrkreg_t	bd_bist_nibble		  :	 1;
-		bdrkreg_t	bd_bist_data		  :	 4;
-	} md_bist_data_fld_s;
-} md_bist_data_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Captures the BIST error address and indicates whether it is an MB   *
- * error or DB error.                                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_ab_err_addr_u {
-	bdrkreg_t	md_bist_ab_err_addr_regval;
-	struct  {
-		bdrkreg_t	baea_be_db_cas_addr       :	15;
-		bdrkreg_t       baea_reserved_3           :      1;
-		bdrkreg_t       baea_be_mb_cas_addr       :     15;
-		bdrkreg_t       baea_reserved_2           :      1;
-		bdrkreg_t       baea_be_ras_addr          :     15;
-		bdrkreg_t       baea_reserved_1           :      1;
-		bdrkreg_t       baea_bist_mb_error        :      1;
-		bdrkreg_t       baea_bist_db_error        :      1;
-		bdrkreg_t       baea_reserved             :     14;
-	} md_bist_ab_err_addr_fld_s;
-} md_bist_ab_err_addr_u_t;
-
-#else
-
-typedef union md_bist_ab_err_addr_u {
-	bdrkreg_t	md_bist_ab_err_addr_regval;
-	struct	{
-		bdrkreg_t	baea_reserved		  :	14;
-		bdrkreg_t	baea_bist_db_error	  :	 1;
-		bdrkreg_t	baea_bist_mb_error	  :	 1;
-		bdrkreg_t	baea_reserved_1		  :	 1;
-		bdrkreg_t	baea_be_ras_addr	  :	15;
-		bdrkreg_t	baea_reserved_2		  :	 1;
-		bdrkreg_t	baea_be_mb_cas_addr	  :	15;
-		bdrkreg_t	baea_reserved_3		  :	 1;
-		bdrkreg_t	baea_be_db_cas_addr	  :	15;
-	} md_bist_ab_err_addr_fld_s;
-} md_bist_ab_err_addr_u_t;
-
-#endif
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains information on BIST progress and memory bank currently     *
- * under BIST.                                                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_status_u {
-	bdrkreg_t	md_bist_status_regval;
-	struct  {
-		bdrkreg_t	bs_bist_passed            :	 1;
-		bdrkreg_t       bs_bist_done              :      1;
-		bdrkreg_t       bs_reserved               :     62;
-	} md_bist_status_fld_s;
-} md_bist_status_u_t;
-
-#else
-
-typedef union md_bist_status_u {
-	bdrkreg_t	md_bist_status_regval;
-	struct	{
-		bdrkreg_t	bs_reserved		  :	62;
-		bdrkreg_t	bs_bist_done		  :	 1;
-		bdrkreg_t	bs_bist_passed		  :	 1;
-	} md_bist_status_fld_s;
-} md_bist_status_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains 3 bits that allow the selection of IB debug information    *
- * at the debug port (see design specification for available debug      *
- * information).                                                        *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_ib_debug_u {
-	bdrkreg_t	md_ib_debug_regval;
-	struct  {
-		bdrkreg_t	id_ib_debug_sel           :	 2;
-		bdrkreg_t       id_reserved               :     62;
-	} md_ib_debug_fld_s;
-} md_ib_debug_u_t;
-
-#else
-
-typedef union md_ib_debug_u {
-	bdrkreg_t	md_ib_debug_regval;
-	struct	{
-		bdrkreg_t	id_reserved		  :	62;
-		bdrkreg_t	id_ib_debug_sel		  :	 2;
-	} md_ib_debug_fld_s;
-} md_ib_debug_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains the directory specific mode bits. The contents of this     *
- * register are preserved through soft-resets.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_dir_config_u {
-	bdrkreg_t	md_dir_config_regval;
-	struct  {
-		bdrkreg_t	dc_dir_flavor             :	 1;
-		bdrkreg_t       dc_ignore_dir_ecc         :      1;
-		bdrkreg_t       dc_reserved               :     62;
-	} md_dir_config_fld_s;
-} md_dir_config_u_t;
-
-#else
-
-typedef union md_dir_config_u {
-	bdrkreg_t	md_dir_config_regval;
-	struct	{
-		bdrkreg_t	dc_reserved		  :	62;
-		bdrkreg_t	dc_ignore_dir_ecc	  :	 1;
-		bdrkreg_t	dc_dir_flavor		  :	 1;
-	} md_dir_config_fld_s;
-} md_dir_config_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  Contains information on uncorrectable and              *
- * correctable directory ECC errors, along with protection ECC          *
- * errors. The priority of ECC errors latched is: uncorrectable         *
- * directory, protection error, correctable directory. Thus the valid   *
- * bits signal:                                                         *
- * 1xxx: uncorrectable directory ECC error (UCE)                        *
- * 01xx: access protection double bit error (AE)                        *
- * 001x: correctable directory ECC error (CE)                           *
- * 0001: access protection correctable error (ACE)                      *
- * If the UCE valid bit is set, the address field contains a pointer    *
- * to the Hspec address of the offending directory entry, the           *
- * syndrome field contains the bad syndrome, and the UCE overrun bit    *
- * indicates whether multiple double-bit errors were received.          *
- * If the UCE valid bit is clear but the AE valid bit is set, the       *
- * address field contains a pointer to the Hspec address of the         *
- * offending protection entry, the Bad Protection field contains the    *
- * 4-bit bad protection value, the PROT_INDEX field shows which of      *
- * the 8 protection values in the word was bad and the AE overrun bit   *
- * indicates whether multiple AE errors were received.                  *
- * If the UCE and AE valid bits are clear, but the CE valid bit is      *
- * set, the address field contains a pointer to the Hspec address of    *
- * the offending directory entry, the syndrome field contains the bad   *
- * syndrome, and the CE overrun bit indicates whether multiple          *
- * single-bit errors were received.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_dir_error_u {
-	bdrkreg_t	md_dir_error_regval;
-	struct  {
-		bdrkreg_t	de_reserved_3             :	 3;
-		bdrkreg_t       de_hspec_addr             :     30;
-		bdrkreg_t       de_reserved_2             :      7;
-		bdrkreg_t       de_bad_syn                :      7;
-		bdrkreg_t       de_reserved_1             :      1;
-                bdrkreg_t       de_bad_protect            :      4;
-                bdrkreg_t       de_prot_index             :      3;
-                bdrkreg_t       de_reserved               :      1;
-                bdrkreg_t       de_ace_overrun            :      1;
-                bdrkreg_t       de_ce_overrun             :      1;
-                bdrkreg_t       de_ae_overrun             :      1;
-                bdrkreg_t       de_uce_overrun            :      1;
-                bdrkreg_t       de_ace_valid              :      1;
-                bdrkreg_t       de_ce_valid               :      1;
-                bdrkreg_t       de_ae_valid               :      1;
-                bdrkreg_t       de_uce_valid              :      1;
-	} md_dir_error_fld_s;
-} md_dir_error_u_t;
-
-#else
-
-typedef union md_dir_error_u {
-	bdrkreg_t	md_dir_error_regval;
-	struct	{
-		bdrkreg_t	de_uce_valid		  :	 1;
-		bdrkreg_t	de_ae_valid		  :	 1;
-		bdrkreg_t	de_ce_valid		  :	 1;
-		bdrkreg_t	de_ace_valid		  :	 1;
-		bdrkreg_t	de_uce_overrun		  :	 1;
-		bdrkreg_t	de_ae_overrun		  :	 1;
-		bdrkreg_t	de_ce_overrun		  :	 1;
-		bdrkreg_t	de_ace_overrun		  :	 1;
-		bdrkreg_t	de_reserved		  :	 1;
-		bdrkreg_t	de_prot_index		  :	 3;
-		bdrkreg_t	de_bad_protect		  :	 4;
-		bdrkreg_t	de_reserved_1		  :	 1;
-		bdrkreg_t	de_bad_syn		  :	 7;
-		bdrkreg_t	de_reserved_2		  :	 7;
-		bdrkreg_t	de_hspec_addr		  :	30;
-		bdrkreg_t	de_reserved_3		  :	 3;
-	} md_dir_error_fld_s;
-} md_dir_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  Contains information on uncorrectable and              *
- * correctable directory ECC errors, along with protection ECC          *
- * errors. The priority of ECC errors latched is: uncorrectable         *
- * directory, protection error, correctable directory. Thus the valid   *
- * bits signal:                                                         *
- * 1xxx: uncorrectable directory ECC error (UCE)                        *
- * 01xx: access protection double bit error (AE)                        *
- * 001x: correctable directory ECC error (CE)                           *
- * 0001: access protection correctable error (ACE)                      *
- * If the UCE valid bit is set, the address field contains a pointer    *
- * to the Hspec address of the offending directory entry, the           *
- * syndrome field contains the bad syndrome, and the UCE overrun bit    *
- * indicates whether multiple double-bit errors were received.          *
- * If the UCE valid bit is clear but the AE valid bit is set, the       *
- * address field contains a pointer to the Hspec address of the         *
- * offending protection entry, the Bad Protection field contains the    *
- * 4-bit bad protection value, the PROT_INDEX field shows which of      *
- * the 8 protection values in the word was bad and the AE overrun bit   *
- * indicates whether multiple AE errors were received.                  *
- * If the UCE and AE valid bits are clear, but the CE valid bit is      *
- * set, the address field contains a pointer to the Hspec address of    *
- * the offending directory entry, the syndrome field contains the bad   *
- * syndrome, and the CE overrun bit indicates whether multiple          *
- * single-bit errors were received.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_dir_error_clr_u {
-	bdrkreg_t	md_dir_error_clr_regval;
-	struct  {
-		bdrkreg_t	dec_reserved_3            :	 3;
-                bdrkreg_t       dec_hspec_addr            :     30;
-                bdrkreg_t       dec_reserved_2            :      7;
-                bdrkreg_t       dec_bad_syn               :      7;
-                bdrkreg_t       dec_reserved_1            :      1;
-                bdrkreg_t       dec_bad_protect           :      4;
-                bdrkreg_t       dec_prot_index            :      3;
-                bdrkreg_t       dec_reserved              :      1;
-                bdrkreg_t       dec_ace_overrun           :      1;
-                bdrkreg_t       dec_ce_overrun            :      1;
-                bdrkreg_t       dec_ae_overrun            :      1;
-                bdrkreg_t       dec_uce_overrun           :      1;
-                bdrkreg_t       dec_ace_valid             :      1;
-                bdrkreg_t       dec_ce_valid              :      1;
-                bdrkreg_t       dec_ae_valid              :      1;
-                bdrkreg_t       dec_uce_valid             :      1;
-	} md_dir_error_clr_fld_s;
-} md_dir_error_clr_u_t;
-
-#else
-
-typedef union md_dir_error_clr_u {
-	bdrkreg_t	md_dir_error_clr_regval;
-	struct	{
-		bdrkreg_t	dec_uce_valid		  :	 1;
-		bdrkreg_t	dec_ae_valid		  :	 1;
-		bdrkreg_t	dec_ce_valid		  :	 1;
-		bdrkreg_t	dec_ace_valid		  :	 1;
-		bdrkreg_t	dec_uce_overrun		  :	 1;
-		bdrkreg_t	dec_ae_overrun		  :	 1;
-		bdrkreg_t	dec_ce_overrun		  :	 1;
-		bdrkreg_t	dec_ace_overrun		  :	 1;
-		bdrkreg_t	dec_reserved		  :	 1;
-		bdrkreg_t	dec_prot_index		  :	 3;
-		bdrkreg_t	dec_bad_protect		  :	 4;
-		bdrkreg_t	dec_reserved_1		  :	 1;
-		bdrkreg_t	dec_bad_syn		  :	 7;
-		bdrkreg_t	dec_reserved_2		  :	 7;
-		bdrkreg_t	dec_hspec_addr		  :	30;
-		bdrkreg_t	dec_reserved_3		  :	 3;
-	} md_dir_error_clr_fld_s;
-} md_dir_error_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains information on requests that encounter no valid protocol   *
- * table entry.                                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_protocol_error_u {
-	bdrkreg_t	md_protocol_error_regval;
-	struct  {
-		bdrkreg_t	pe_overrun                :	 1;
-                bdrkreg_t       pe_pointer_me             :      1;
-                bdrkreg_t       pe_reserved_1             :      1;
-                bdrkreg_t       pe_address                :     30;
-                bdrkreg_t       pe_reserved               :      1;
-                bdrkreg_t       pe_ptr1_btmbits           :      3;
-                bdrkreg_t       pe_dir_format             :      2;
-                bdrkreg_t       pe_dir_state              :      3;
-                bdrkreg_t       pe_priority               :      1;
-                bdrkreg_t       pe_access                 :      1;
-                bdrkreg_t       pe_msg_type               :      8;
-                bdrkreg_t       pe_initiator              :     11;
-                bdrkreg_t       pe_valid                  :      1;
-	} md_protocol_error_fld_s;
-} md_protocol_error_u_t;
-
-#else
-
-typedef union md_protocol_error_u {
-	bdrkreg_t	md_protocol_error_regval;
-	struct	{
-		bdrkreg_t	pe_valid		  :	 1;
-		bdrkreg_t	pe_initiator		  :	11;
-		bdrkreg_t	pe_msg_type		  :	 8;
-		bdrkreg_t	pe_access		  :	 1;
-		bdrkreg_t	pe_priority		  :	 1;
-		bdrkreg_t	pe_dir_state		  :	 3;
-		bdrkreg_t	pe_dir_format		  :	 2;
-		bdrkreg_t	pe_ptr1_btmbits		  :	 3;
-		bdrkreg_t	pe_reserved		  :	 1;
-		bdrkreg_t	pe_address		  :	30;
-		bdrkreg_t	pe_reserved_1		  :	 1;
-		bdrkreg_t	pe_pointer_me		  :	 1;
-		bdrkreg_t	pe_overrun		  :	 1;
-	} md_protocol_error_fld_s;
-} md_protocol_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains information on requests that encounter no valid protocol   *
- * table entry.                                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_protocol_err_clr_u {
-	bdrkreg_t	md_protocol_err_clr_regval;
-	struct  {
-		bdrkreg_t	pec_overrun               :	 1;
-                bdrkreg_t       pec_pointer_me            :      1;
-                bdrkreg_t       pec_reserved_1            :      1;
-                bdrkreg_t       pec_address               :     30;
-                bdrkreg_t       pec_reserved              :      1;
-                bdrkreg_t       pec_ptr1_btmbits          :      3;
-                bdrkreg_t       pec_dir_format            :      2;
-                bdrkreg_t       pec_dir_state             :      3;
-                bdrkreg_t       pec_priority              :      1;
-                bdrkreg_t       pec_access                :      1;
-                bdrkreg_t       pec_msg_type              :      8;
-                bdrkreg_t       pec_initiator             :     11;
-                bdrkreg_t       pec_valid                 :      1;
-	} md_protocol_err_clr_fld_s;
-} md_protocol_err_clr_u_t;
-
-#else
-
-typedef union md_protocol_err_clr_u {
-	bdrkreg_t	md_protocol_err_clr_regval;
-	struct	{
-		bdrkreg_t	pec_valid		  :	 1;
-		bdrkreg_t	pec_initiator		  :	11;
-		bdrkreg_t	pec_msg_type		  :	 8;
-		bdrkreg_t	pec_access		  :	 1;
-		bdrkreg_t	pec_priority		  :	 1;
-		bdrkreg_t	pec_dir_state		  :	 3;
-		bdrkreg_t	pec_dir_format		  :	 2;
-		bdrkreg_t	pec_ptr1_btmbits	  :	 3;
-		bdrkreg_t	pec_reserved		  :	 1;
-		bdrkreg_t	pec_address		  :	30;
-		bdrkreg_t	pec_reserved_1		  :	 1;
-		bdrkreg_t	pec_pointer_me		  :	 1;
-		bdrkreg_t	pec_overrun		  :	 1;
-	} md_protocol_err_clr_fld_s;
-} md_protocol_err_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains the address of the page and the requestor which caused a   *
- * migration threshold to be exceeded. Also contains the type of        *
- * threshold exceeded and an overrun bit. For Value mode type           *
- * interrupts, it indicates whether the local or the remote counter     *
- * triggered the interrupt. Unlike most registers, when the overrun     *
- * bit is set the register contains information on the most recent      *
- * (the last) migration candidate.                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mig_candidate_u {
-	bdrkreg_t	md_mig_candidate_regval;
-	struct  {
-		bdrkreg_t	mc_address                :	21;
-                bdrkreg_t       mc_initiator              :     11;
-                bdrkreg_t       mc_overrun                :      1;
-                bdrkreg_t       mc_type                   :      1;
-                bdrkreg_t       mc_local                  :      1;
-                bdrkreg_t       mc_reserved               :     28;
-                bdrkreg_t       mc_valid                  :      1;
-	} md_mig_candidate_fld_s;
-} md_mig_candidate_u_t;
-
-#else
-
-typedef union md_mig_candidate_u {
-	bdrkreg_t	md_mig_candidate_regval;
-	struct	{
-		bdrkreg_t	mc_valid		  :	 1;
-		bdrkreg_t	mc_reserved		  :	28;
-		bdrkreg_t	mc_local		  :	 1;
-		bdrkreg_t	mc_type			  :	 1;
-		bdrkreg_t	mc_overrun		  :	 1;
-		bdrkreg_t	mc_initiator		  :	11;
-		bdrkreg_t	mc_address		  :	21;
-	} md_mig_candidate_fld_s;
-} md_mig_candidate_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains the address of the page and the requestor which caused a   *
- * migration threshold to be exceeded. Also contains the type of        *
- * threshold exceeded and an overrun bit. For Value mode type           *
- * interrupts, it indicates whether the local or the remote counter     *
- * triggered the interrupt. Unlike most registers, when the overrun     *
- * bit is set the register contains information on the most recent      *
- * (the last) migration candidate.                                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mig_candidate_clr_u {
-	bdrkreg_t	md_mig_candidate_clr_regval;
-	struct  {
-		bdrkreg_t	mcc_address               :	21;
-                bdrkreg_t       mcc_initiator             :     11;
-                bdrkreg_t       mcc_overrun               :      1;
-                bdrkreg_t       mcc_type                  :      1;
-                bdrkreg_t       mcc_local                 :      1;
-                bdrkreg_t       mcc_reserved              :     28;
-                bdrkreg_t       mcc_valid                 :      1;
-	} md_mig_candidate_clr_fld_s;
-} md_mig_candidate_clr_u_t;
-
-#else
-
-typedef union md_mig_candidate_clr_u {
-	bdrkreg_t	md_mig_candidate_clr_regval;
-	struct	{
-		bdrkreg_t	mcc_valid		  :	 1;
-		bdrkreg_t	mcc_reserved		  :	28;
-		bdrkreg_t	mcc_local		  :	 1;
-		bdrkreg_t	mcc_type		  :	 1;
-		bdrkreg_t	mcc_overrun		  :	 1;
-		bdrkreg_t	mcc_initiator		  :	11;
-		bdrkreg_t	mcc_address		  :	21;
-	} md_mig_candidate_clr_fld_s;
-} md_mig_candidate_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Controls the generation of page-migration interrupts and loading    *
- * of the MIGRATION_CANDIDATE register for pages which are using the    *
- * difference between the requestor and home counts. If the             *
- * difference is greater-than or equal to than the threshold            *
- * contained in the register, and the valid bit is set, the migration   *
- * candidate is loaded (and an interrupt generated if enabled by the    *
- * page migration mode).                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mig_diff_thresh_u {
-	bdrkreg_t	md_mig_diff_thresh_regval;
-	struct  {
-		bdrkreg_t	mdt_threshold             :	15;
-                bdrkreg_t       mdt_reserved_1            :     17;
-                bdrkreg_t       mdt_th_action             :      3;
-                bdrkreg_t       mdt_sat_action            :      3;
-                bdrkreg_t       mdt_reserved              :     25;
-                bdrkreg_t       mdt_valid                 :      1;
-	} md_mig_diff_thresh_fld_s;
-} md_mig_diff_thresh_u_t;
-
-#else
-
-typedef union md_mig_diff_thresh_u {
-	bdrkreg_t	md_mig_diff_thresh_regval;
-	struct	{
-		bdrkreg_t	mdt_valid		  :	 1;
-		bdrkreg_t	mdt_reserved		  :	25;
-		bdrkreg_t	mdt_sat_action		  :	 3;
-		bdrkreg_t	mdt_th_action		  :	 3;
-		bdrkreg_t	mdt_reserved_1		  :	17;
-		bdrkreg_t	mdt_threshold		  :	15;
-	} md_mig_diff_thresh_fld_s;
-} md_mig_diff_thresh_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Controls the generation of page-migration interrupts and loading    *
- * of the MIGRATION_CANDIDATE register for pages that are using the     *
- * absolute value of the requestor count. If the value is               *
- * greater-than or equal to the threshold contained in the register,    *
- * and the register valid bit is set, the migration candidate is        *
- * loaded and an interrupt generated. For the value mode of page        *
- * migration, there are two variations. In the first variation,         *
- * interrupts are only generated when the remote counter reaches the    *
- * threshold, not when the local counter reaches the threshold. In      *
- * the second mode, both the local counter and the remote counter       *
- * generate interrupts if they reach the threshold. This second mode    *
- * is useful for performance monitoring, to track the number of local   *
- * and remote references to a page. LOCAL_INT determines whether we     *
- * will generate interrupts when the local counter reaches the          *
- * threshold.                                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mig_value_thresh_u {
-	bdrkreg_t	md_mig_value_thresh_regval;
-	struct  {
-		bdrkreg_t	mvt_threshold             :	15;
-                bdrkreg_t       mvt_reserved_1            :     17;
-                bdrkreg_t       mvt_th_action             :      3;
-                bdrkreg_t       mvt_sat_action            :      3;
-                bdrkreg_t       mvt_reserved              :     24;
-                bdrkreg_t       mvt_local_int             :      1;
-                bdrkreg_t       mvt_valid                 :      1;
-	} md_mig_value_thresh_fld_s;
-} md_mig_value_thresh_u_t;
-
-#else
-
-typedef union md_mig_value_thresh_u {
-        bdrkreg_t       md_mig_value_thresh_regval;
-        struct  {
-                bdrkreg_t       mvt_valid                 :      1;
-                bdrkreg_t       mvt_local_int             :      1;
-                bdrkreg_t       mvt_reserved              :     24;
-                bdrkreg_t       mvt_sat_action            :      3;
-                bdrkreg_t       mvt_th_action             :      3;
-                bdrkreg_t       mvt_reserved_1            :     17;
-                bdrkreg_t       mvt_threshold             :     15;
-        } md_mig_value_thresh_fld_s;
-} md_mig_value_thresh_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains the controls for the sizing of the three MOQH request      *
- * queues. The maximum (and default) value is 4. Queue sizes are in     *
- * flits. One header equals one flit.                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_outgoing_rq_queue_size_u {
-	bdrkreg_t	md_outgoing_rq_queue_size_regval;
-	struct  {
-		bdrkreg_t	orqs_reserved_3           :	 8;
-                bdrkreg_t       orqs_moqh_p0_rq_size      :      3;
-                bdrkreg_t       orqs_reserved_2           :      5;
-                bdrkreg_t       orqs_moqh_p1_rq_size      :      3;
-                bdrkreg_t       orqs_reserved_1           :      5;
-                bdrkreg_t       orqs_moqh_np_rq_size      :      3;
-                bdrkreg_t       orqs_reserved             :     37;
-	} md_outgoing_rq_queue_size_fld_s;
-} md_outgoing_rq_queue_size_u_t;
-
-#else
-
-typedef union md_outgoing_rq_queue_size_u {
-	bdrkreg_t	md_outgoing_rq_queue_size_regval;
-	struct	{
-		bdrkreg_t	orqs_reserved		  :	37;
-		bdrkreg_t	orqs_moqh_np_rq_size	  :	 3;
-		bdrkreg_t	orqs_reserved_1		  :	 5;
-		bdrkreg_t	orqs_moqh_p1_rq_size	  :	 3;
-		bdrkreg_t	orqs_reserved_2		  :	 5;
-		bdrkreg_t	orqs_moqh_p0_rq_size	  :	 3;
-		bdrkreg_t	orqs_reserved_3		  :	 8;
-	} md_outgoing_rq_queue_size_fld_s;
-} md_outgoing_rq_queue_size_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains the 32-bit directory word failing BIST.                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_db_err_data_u {
-	bdrkreg_t	md_bist_db_err_data_regval;
-	struct  {
-		bdrkreg_t	bded_db_er_d              :	32;
-		bdrkreg_t       bded_reserved             :     32;
-	} md_bist_db_err_data_fld_s;
-} md_bist_db_err_data_u_t;
-
-#else
-
-typedef union md_bist_db_err_data_u {
-	bdrkreg_t	md_bist_db_err_data_regval;
-	struct	{
-		bdrkreg_t	bded_reserved		  :	32;
-		bdrkreg_t	bded_db_er_d		  :	32;
-	} md_bist_db_err_data_fld_s;
-} md_bist_db_err_data_u_t;
-
-#endif
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains 2 bits that allow the selection of DB debug information    *
- * at the debug port (see the design specification for descrition of    *
- * the available debug information).                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_db_debug_u {
-	bdrkreg_t	md_db_debug_regval;
-	struct  {
-		bdrkreg_t	dd_db_debug_sel           :	 2;
-		bdrkreg_t       dd_reserved               :     62;
-	} md_db_debug_fld_s;
-} md_db_debug_u_t;
-
-#else
-
-typedef union md_db_debug_u {
-	bdrkreg_t	md_db_debug_regval;
-	struct	{
-		bdrkreg_t	dd_reserved		  :	62;
-		bdrkreg_t	dd_db_debug_sel		  :	 2;
-	} md_db_debug_fld_s;
-} md_db_debug_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains the IgnoreECC bit. When this bit is set, all ECC errors    *
- * are ignored. ECC bits will still be generated on writebacks.         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mb_ecc_config_u {
-	bdrkreg_t	md_mb_ecc_config_regval;
-	struct  {
-		bdrkreg_t	mec_ignore_dataecc        :	 1;
-		bdrkreg_t       mec_reserved              :     63;
-	} md_mb_ecc_config_fld_s;
-} md_mb_ecc_config_u_t;
-
-#else
-
-typedef union md_mb_ecc_config_u {
-	bdrkreg_t	md_mb_ecc_config_regval;
-	struct	{
-		bdrkreg_t	mec_reserved		  :	63;
-		bdrkreg_t	mec_ignore_dataecc	  :	 1;
-	} md_mb_ecc_config_fld_s;
-} md_mb_ecc_config_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  Contains information on read memory errors (both       *
- * correctable and uncorrectable) and write memory errors (always       *
- * uncorrectable). The errors are prioritized as follows:               *
- *  highest: uncorrectable read error (READ_UCE)                        *
- *  middle: write error (WRITE_UCE)                                     *
- *  lowest: correctable read error (READ_CE)                            *
- * Each type of error maintains a two-bit valid/overrun field           *
- * (READ_UCE, WRITE_UCE, or READ_CE). Bit 0 of each two-bit field       *
- * corresponds to the valid bit, and bit 1 of each two-bit field        *
- * corresponds to the overrun bit.                                      *
- * The rule for the valid bit is that it gets set whenever that error   *
- * occurs, regardless of whether a higher priority error has occurred.  *
- * The rule for the overrun bit is that it gets set whenever we are     *
- * unable to record the address information for this particular         *
- * error, due to a previous error of the same or higher priority.       *
- * Note that the syndrome and address information always corresponds    *
- * to the earliest, highest priority error.                             *
- *  Finally, the UCE_DIFF_ADDR bit is set whenever there have been      *
- * several uncorrectable errors, to different cache line addresses.     *
- * If all the UCEs were to the same cache line address, then            *
- * UCE_DIFF_ADDR will be 0. This allows the operating system to         *
- * detect the case where a UCE error is read exclusively, and then      *
- * written back by the processor. If the bit is 0, it indicates that    *
- * no information has been lost about UCEs on other cache lines. In     *
- * particular, partial writes do a read modify write of the cache       *
- * line. A UCE read error will be set when the cache line is read,      *
- * and a UCE write error will occur when the cache line is written      *
- * back, but the UCE_DIFF_ADDR will not be set.                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mem_error_u {
-	bdrkreg_t	md_mem_error_regval;
-	struct  {
-		bdrkreg_t	me_reserved_5             :	 3;
-                bdrkreg_t       me_address                :     30;
-                bdrkreg_t       me_reserved_4             :      7;
-                bdrkreg_t       me_bad_syn                :      8;
-                bdrkreg_t       me_reserved_3             :      4;
-                bdrkreg_t       me_read_ce                :      2;
-                bdrkreg_t       me_reserved_2             :      2;
-                bdrkreg_t       me_write_uce              :      2;
-                bdrkreg_t       me_reserved_1             :      2;
-                bdrkreg_t       me_read_uce               :      2;
-                bdrkreg_t       me_reserved               :      1;
-                bdrkreg_t       me_uce_diff_addr          :      1;
-	} md_mem_error_fld_s;
-} md_mem_error_u_t;
-
-#else
-
-typedef union md_mem_error_u {
-	bdrkreg_t	md_mem_error_regval;
-	struct	{
-		bdrkreg_t	me_uce_diff_addr	  :	 1;
-		bdrkreg_t	me_reserved		  :	 1;
-		bdrkreg_t	me_read_uce		  :	 2;
-		bdrkreg_t	me_reserved_1		  :	 2;
-		bdrkreg_t	me_write_uce		  :	 2;
-		bdrkreg_t	me_reserved_2		  :	 2;
-		bdrkreg_t	me_read_ce		  :	 2;
-		bdrkreg_t	me_reserved_3		  :	 4;
-		bdrkreg_t	me_bad_syn		  :	 8;
-		bdrkreg_t	me_reserved_4		  :	 7;
-		bdrkreg_t	me_address		  :	30;
-		bdrkreg_t	me_reserved_5		  :	 3;
-	} md_mem_error_fld_s;
-} md_mem_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  Contains information on read memory errors (both       *
- * correctable and uncorrectable) and write memory errors (always       *
- * uncorrectable). The errors are prioritized as follows:               *
- *  highest: uncorrectable read error (READ_UCE)                        *
- *  middle: write error (WRITE_UCE)                                     *
- *  lowest: correctable read error (READ_CE)                            *
- * Each type of error maintains a two-bit valid/overrun field           *
- * (READ_UCE, WRITE_UCE, or READ_CE). Bit 0 of each two-bit field       *
- * corresponds to the valid bit, and bit 1 of each two-bit field        *
- * corresponds to the overrun bit.                                      *
- * The rule for the valid bit is that it gets set whenever that error   *
- * occurs, regardless of whether a higher priority error has occurred.  *
- * The rule for the overrun bit is that it gets set whenever we are     *
- * unable to record the address information for this particular         *
- * error, due to a previous error of the same or higher priority.       *
- * Note that the syndrome and address information always corresponds    *
- * to the earliest, highest priority error.                             *
- *  Finally, the UCE_DIFF_ADDR bit is set whenever there have been      *
- * several uncorrectable errors, to different cache line addresses.     *
- * If all the UCEs were to the same cache line address, then            *
- * UCE_DIFF_ADDR will be 0. This allows the operating system to         *
- * detect the case where a UCE error is read exclusively, and then      *
- * written back by the processor. If the bit is 0, it indicates that    *
- * no information has been lost about UCEs on other cache lines. In     *
- * particular, partial writes do a read modify write of the cache       *
- * line. A UCE read error will be set when the cache line is read,      *
- * and a UCE write error will occur when the cache line is written      *
- * back, but the UCE_DIFF_ADDR will not be set.                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mem_error_clr_u {
-	bdrkreg_t	md_mem_error_clr_regval;
-	struct  {
-		bdrkreg_t	mec_reserved_5            :	 3;
-                bdrkreg_t       mec_address               :     30;
-                bdrkreg_t       mec_reserved_4            :      7;
-                bdrkreg_t       mec_bad_syn               :      8;
-                bdrkreg_t       mec_reserved_3            :      4;
-                bdrkreg_t       mec_read_ce               :      2;
-                bdrkreg_t       mec_reserved_2            :      2;
-                bdrkreg_t       mec_write_uce             :      2;
-                bdrkreg_t       mec_reserved_1            :      2;
-                bdrkreg_t       mec_read_uce              :      2;
-                bdrkreg_t       mec_reserved              :      1;
-                bdrkreg_t       mec_uce_diff_addr         :      1;
-	} md_mem_error_clr_fld_s;
-} md_mem_error_clr_u_t;
-
-#else
-
-typedef union md_mem_error_clr_u {
-	bdrkreg_t	md_mem_error_clr_regval;
-	struct	{
-		bdrkreg_t	mec_uce_diff_addr	  :	 1;
-		bdrkreg_t	mec_reserved		  :	 1;
-		bdrkreg_t	mec_read_uce		  :	 2;
-		bdrkreg_t	mec_reserved_1		  :	 2;
-		bdrkreg_t	mec_write_uce		  :	 2;
-		bdrkreg_t	mec_reserved_2		  :	 2;
-		bdrkreg_t	mec_read_ce		  :	 2;
-		bdrkreg_t	mec_reserved_3		  :	 4;
-		bdrkreg_t	mec_bad_syn		  :	 8;
-		bdrkreg_t	mec_reserved_4		  :	 7;
-		bdrkreg_t	mec_address		  :	30;
-		bdrkreg_t	mec_reserved_5		  :	 3;
-	} md_mem_error_clr_fld_s;
-} md_mem_error_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains one-quarter of the error memory line failing BIST.         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_mb_err_data_0_u {
-	bdrkreg_t	md_bist_mb_err_data_0_regval;
-	struct  {
-		bdrkreg_t	bmed0_mb_er_d             :	36;
-		bdrkreg_t       bmed0_reserved            :     28;
-	} md_bist_mb_err_data_0_fld_s;
-} md_bist_mb_err_data_0_u_t;
-
-#else
-
-typedef union md_bist_mb_err_data_0_u {
-	bdrkreg_t	md_bist_mb_err_data_0_regval;
-	struct	{
-		bdrkreg_t	bmed0_reserved		  :	28;
-		bdrkreg_t	bmed0_mb_er_d		  :	36;
-	} md_bist_mb_err_data_0_fld_s;
-} md_bist_mb_err_data_0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains one-quarter of the error memory line failing BIST.         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_mb_err_data_1_u {
-	bdrkreg_t	md_bist_mb_err_data_1_regval;
-	struct  {
-		bdrkreg_t	bmed1_mb_er_d             :	36;
-		bdrkreg_t       bmed1_reserved            :     28;
-	} md_bist_mb_err_data_1_fld_s;
-} md_bist_mb_err_data_1_u_t;
-
-#else
-
-typedef union md_bist_mb_err_data_1_u {
-	bdrkreg_t	md_bist_mb_err_data_1_regval;
-	struct	{
-		bdrkreg_t	bmed1_reserved		  :	28;
-		bdrkreg_t	bmed1_mb_er_d		  :	36;
-	} md_bist_mb_err_data_1_fld_s;
-} md_bist_mb_err_data_1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains one-quarter of the error memory line failing BIST.         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_mb_err_data_2_u {
-	bdrkreg_t	md_bist_mb_err_data_2_regval;
-	struct  {
-		bdrkreg_t	bmed2_mb_er_d             :	36;
-		bdrkreg_t       bmed2_reserved            :     28;
-	} md_bist_mb_err_data_2_fld_s;
-} md_bist_mb_err_data_2_u_t;
-
-#else
-
-typedef union md_bist_mb_err_data_2_u {
-	bdrkreg_t	md_bist_mb_err_data_2_regval;
-	struct	{
-		bdrkreg_t	bmed2_reserved		  :	28;
-		bdrkreg_t	bmed2_mb_er_d		  :	36;
-	} md_bist_mb_err_data_2_fld_s;
-} md_bist_mb_err_data_2_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains one-quarter of the error memory line failing BIST.         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_bist_mb_err_data_3_u {
-	bdrkreg_t	md_bist_mb_err_data_3_regval;
-	struct  {
-		bdrkreg_t	bmed3_mb_er_d             :	36;
-		bdrkreg_t       bmed3_reserved            :     28;
-	} md_bist_mb_err_data_3_fld_s;
-} md_bist_mb_err_data_3_u_t;
-
-#else
-
-typedef union md_bist_mb_err_data_3_u {
-	bdrkreg_t	md_bist_mb_err_data_3_regval;
-	struct	{
-		bdrkreg_t	bmed3_reserved		  :	28;
-		bdrkreg_t	bmed3_mb_er_d		  :	36;
-	} md_bist_mb_err_data_3_fld_s;
-} md_bist_mb_err_data_3_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Contains 1 bit that allow the selection of MB debug information     *
- * at the debug port (see the design specification for the available    *
- * debug information).                                                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union md_mb_debug_u {
-	bdrkreg_t	md_mb_debug_regval;
-	struct  {
-		bdrkreg_t	md_mb_debug_sel           :	 1;
-		bdrkreg_t       md_reserved               :     63;
-	} md_mb_debug_fld_s;
-} md_mb_debug_u_t;
-
-#else
-
-typedef union md_mb_debug_u {
-	bdrkreg_t	md_mb_debug_regval;
-	struct	{
-		bdrkreg_t	md_reserved		  :	63;
-		bdrkreg_t	md_mb_debug_sel		  :	 1;
-	} md_mb_debug_fld_s;
-} md_mb_debug_u_t;
-
-#endif
-
-
-
-
-
-
-#endif /* __ASSEMBLY__ */
-
-/************************************************************************
- *                                                                      *
- *               MAKE ALL ADDITIONS AFTER THIS LINE                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#endif /* _ASM_IA64_SN_SN1_HUBMD_H */
diff -Nru a/include/asm-ia64/sn/sn1/hubmd_next.h b/include/asm-ia64/sn/sn1/hubmd_next.h
--- a/include/asm-ia64/sn/sn1/hubmd_next.h	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,812 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBMD_NEXT_H
-#define _ASM_IA64_SN_SN1_HUBMD_NEXT_H
-
-/* XXX moved over from SN/SN0/hubmd.h -- each should be checked for SN1 */
-/* In fact, most of this stuff is wrong. Some is correct, such as
- * MD_PAGE_SIZE and MD_PAGE_NUM_SHFT.
- */
-
-#define MD_PERF_COUNTERS        6
-#define MD_PERF_SETS            6
-
-#define MD_SIZE_EMPTY           0       
-#define MD_SIZE_64MB            1       
-#define MD_SIZE_128MB           2       
-#define MD_SIZE_256MB           3
-#define MD_SIZE_512MB           4      
-#define MD_SIZE_1GB             5      
-
-#define MD_SIZE_BYTES(size)     ((size) == 0 ? 0 : 0x2000000L << (size))
-#define MD_SIZE_MBYTES(size)    ((size) == 0 ? 0 :   0x20       << (size))
-#define MD_NUM_ENABLED(_x)	((_x & 0x1) + ((_x >> 1) & 0x1) + \
-				((_x >> 2) & 0x1) + ((_x >> 3) & 0x1))
-
-
-/* Hardware page size and shift */
-
-#define MD_PAGE_SIZE            16384    /* Page size in bytes              */
-#define MD_PAGE_NUM_SHFT        14       /* Address to page number shift    */
-
-#define MMC_IO_PROT 		(UINT64_CAST 1 << 45)
-
-/* Register offsets from LOCAL_HUB or REMOTE_HUB */
-#define MD_PERF_SEL             0x210000 /* Select perf monitor events      */
-
-/* MD_MIG_VALUE_THRESH bit definitions */
-
-#define MD_MIG_VALUE_THRES_VALID_MASK (UINT64_CAST 0x1 << 63)
-#define MD_MIG_VALUE_THRES_VALUE_MASK (UINT64_CAST 0xfffff)
-
-/* MD_MIG_CANDIDATE bit definitions */
-
-#define MD_MIG_CANDIDATE_VALID_MASK (UINT64_CAST 0x1 << 63)
-#define MD_MIG_CANDIDATE_VALID_SHFT 63
-#define MD_MIG_CANDIDATE_TYPE_MASK (UINT64_CAST 0x1 << 30)
-#define MD_MIG_CANDIDATE_TYPE_SHFT 30
-#define MD_MIG_CANDIDATE_OVERRUN_MASK (UINT64_CAST 0x1 << 29)
-#define MD_MIG_CANDIDATE_OVERRUN_SHFT 29
-#define MD_MIG_CANDIDATE_NODEID_MASK (UINT64_CAST 0x1ff << 20)
-#define MD_MIG_CANDIDATE_NODEID_SHFT 20
-#define MD_MIG_CANDIDATE_ADDR_MASK (UINT64_CAST 0x3ffff)
-
-
-/* XXX protection and migration are completely revised on SN1.  On
-   SN0, the reference count and protection fields were accessed in the
-   same word, but on SN1 they reside at different addresses.  The
-   users of these macros will need to be rewritten.  Also, the MD page
-   size is 16K on SN1 but 4K on SN0.  */
-
-/* Premium SIMM protection entry shifts and masks. */
-
-#define MD_PPROT_SHFT           0                       /* Prot. field      */
-#define MD_PPROT_MASK           0xf
-#define MD_PPROT_REFCNT_SHFT    5                       /* Reference count  */
-#define MD_PPROT_REFCNT_WIDTH   0x7ffff
-#define MD_PPROT_REFCNT_MASK    (MD_PPROT_REFCNT_WIDTH << 5)
-
-#define MD_PPROT_IO_SHFT        8                       /* I/O Prot field   */
-
-/* Standard SIMM protection entry shifts and masks. */
-
-#define MD_SPROT_SHFT           0                       /* Prot. field      */
-#define MD_SPROT_MASK           0xf
-#define MD_SPROT_IO_SHFT	8
-#define MD_SPROT_REFCNT_SHFT    5                       /* Reference count  */
-#define MD_SPROT_REFCNT_WIDTH   0x7ff
-#define MD_SPROT_REFCNT_MASK    (MD_SPROT_REFCNT_WIDTH << 5)
-
-/* Migration modes used in protection entries */
-
-#define MD_PROT_MIGMD_IREL      (UINT64_CAST 0x3 << 3)
-#define MD_PROT_MIGMD_IABS      (UINT64_CAST 0x2 << 3)
-#define MD_PROT_MIGMD_PREL      (UINT64_CAST 0x1 << 3)
-#define MD_PROT_MIGMD_OFF       (UINT64_CAST 0x0 << 3)
-
-/*
- * Operations on Memory/Directory DIMM control register
- */
-
-#define DIRTYPE_PREMIUM 1
-#define DIRTYPE_STANDARD 0
-
-/*
- * Operations on page migration count difference and absolute threshold
- * registers
- */
-
-#define MD_MIG_VALUE_THRESH_GET(region) (                               \
-        REMOTE_HUB_L((region), MD_MIG_VALUE_THRESH) &  \
-        MD_MIG_VALUE_THRES_VALUE_MASK)
-
-#define MD_MIG_VALUE_THRESH_SET(region, value) (                        \
-        REMOTE_HUB_S((region), MD_MIG_VALUE_THRESH,                     \
-                MD_MIG_VALUE_THRES_VALID_MASK | (value)))
-
-#define MD_MIG_VALUE_THRESH_ENABLE(region) (                    \
-        REMOTE_HUB_S((region), MD_MIG_VALUE_THRESH,                     \
-                REMOTE_HUB_L((region), MD_MIG_VALUE_THRESH)             \
-                             | MD_MIG_VALUE_THRES_VALID_MASK))
-
-/*
- * Operations on page migration candidate register
- */
-
-#define MD_MIG_CANDIDATE_GET(my_region_id) ( \
-        REMOTE_HUB_L((my_region_id), MD_MIG_CANDIDATE_CLR))
-
-#define MD_MIG_CANDIDATE_HWPFN(value) ((value) & MD_MIG_CANDIDATE_ADDR_MASK)
-
-#define MD_MIG_CANDIDATE_NODEID(value) ( \
-        ((value) & MD_MIG_CANDIDATE_NODEID_MASK) >> MD_MIG_CANDIDATE_NODEID_SHFT)
-
-#define MD_MIG_CANDIDATE_TYPE(value) ( \
-        ((value) & MD_MIG_CANDIDATE_TYPE_MASK) >> MD_MIG_CANDIDATE_TYPE_SHFT)
-
-#define MD_MIG_CANDIDATE_VALID(value) ( \
-        ((value) & MD_MIG_CANDIDATE_VALID_MASK) >> MD_MIG_CANDIDATE_VALID_SHFT)
-
-/*
- * Macros to retrieve fields in the protection entry
- */
-
-/* for Premium SIMM */
-#define MD_PPROT_REFCNT_GET(value) ( \
-        ((value) & MD_PPROT_REFCNT_MASK) >> MD_PPROT_REFCNT_SHFT)
-
-/* for Standard SIMM */
-#define MD_SPROT_REFCNT_GET(value) ( \
-        ((value) & MD_SPROT_REFCNT_MASK) >> MD_SPROT_REFCNT_SHFT)
-
-#ifndef __ASSEMBLY__
-#ifdef LITTLE_ENDIAN
-
-typedef union md_perf_sel {
-        uint64_t      perf_sel_reg;
-        struct  {
-                uint64_t      perf_sel  :  3,
-				perf_en   :  1,
-				perf_rsvd : 60;
-        } perf_sel_bits;
-} md_perf_sel_t;
-
-#else
-
-typedef union md_perf_sel {
-	uint64_t	perf_sel_reg;
-	struct	{
-		uint64_t	perf_rsvd : 60,
-				perf_en	  :  1,
-				perf_sel  :  3;
-	} perf_sel_bits;
-} md_perf_sel_t;
-
-#endif
-#endif /* __ASSEMBLY__ */
-
-
-/* Like SN0, SN1 supports a mostly-flat address space with 8
-   CPU-visible, evenly spaced, contiguous regions, or "software
-   banks".  On SN1, software bank n begins at addresses n * 1GB, 
-   0 <= n < 8.
-
-   Physically (and very unlike SN0), each SN1 node board contains 8
-   dimm sockets, arranged as 4 "DIMM banks" of 2 dimms each.  DIMM
-   size and width (x4/x8) is assigned per dimm bank.  Each DIMM bank
-   consists of 2 "physical banks", one on the front sides of the 2
-   DIMMs and the other on the back sides.  Therefore a node has a
-   total of 8 ( = 4 * 2) physical banks.  They are collectively
-   referred to as "locational banks", since the locational bank number
-   depends on the physical location of the DIMMs on the board.
-
-	      Dimm bank 0, Phys bank 0a (locational bank 0a)
-     Slot D0  ----------------------------------------------
-	      Dimm bank 0, Phys bank 1a (locational bank 1a)
-
-	      Dimm bank 1, Phys bank 0a (locational bank 2a)
-     Slot D1  ----------------------------------------------
-	      Dimm bank 1, Phys bank 1a (locational bank 3a)
-
-	      Dimm bank 2, Phys bank 0a (locational bank 4a)
-     Slot D2  ----------------------------------------------
-	      Dimm bank 2, Phys bank 1a (locational bank 5a)
-
-	      Dimm bank 3, Phys bank 0a (locational bank 6a)
-     Slot D3  ----------------------------------------------
-	      Dimm bank 3, Phys bank 1a (locational bank 7a)
-
-	      Dimm bank 0, Phys bank 0b (locational bank 0b)
-     Slot D4  ----------------------------------------------
-	      Dimm bank 0, Phys bank 1b (locational bank 1b)
-
-	      Dimm bank 1, Phys bank 0b (locational bank 2b)
-     Slot D5  ----------------------------------------------
-	      Dimm bank 1, Phys bank 1b (locational bank 3b)
-
-	      Dimm bank 2, Phys bank 0b (locational bank 4b)
-     Slot D6  ----------------------------------------------
-	      Dimm bank 2, Phys bank 1b (locational bank 5b)
-
-	      Dimm bank 3, Phys bank 0b (locational bank 6b)
-     Slot D7  ----------------------------------------------
-	      Dimm bank 3, Phys bank 1b (locational bank 7b)
-
-   Since bank size is assigned per DIMM bank, each pair of locational
-   banks must have the same size.  However, they may be
-   enabled/disabled individually.
-
-   The locational banks map to the software banks via the dimm0_sel
-   field in MD_MEMORY_CONFIG.  When the field is 0 (the usual case),
-   the mapping is direct:  eg. locational bank 1 (dimm bank 0,
-   physical bank 1, which is the back side of the first DIMM pair)
-   corresponds to software bank 1, at node offset 1GB.  More
-   generally, locational bank = software bank XOR dimm0_sel.
-
-   All the PROM's data structures (promlog variables, klconfig, etc.)
-   track memory by the locational bank number.  The kernel usually
-   tracks memory by the software bank number.
-   memsupport.c:slot_psize_compute() performs the mapping.
-
-   (Note:  the terms "locational bank" and "software bank" are not
-   offical in any way, but I've tried to make the PROM use them
-   consistently -- bjj.)
- */
-
-#define MD_MEM_BANKS 		8
-#define MD_MEM_DIMM_BANKS 	4
-#define MD_BANK_SHFT            30                     /* log2(1 GB)     */
-#define MD_BANK_MASK            (UINT64_CAST 0x7 << 30)
-#define MD_BANK_SIZE            (UINT64_CAST 1 << MD_BANK_SHFT)   /*  1 GB */
-#define MD_BANK_OFFSET(_b)      (UINT64_CAST (_b) << MD_BANK_SHFT)
-#define MD_BANK_GET(addr)	(((addr) & MD_BANK_MASK) >> MD_BANK_SHFT)
-#define MD_BANK_TO_DIMM_BANK(_b) (( (_b) >> 1) & 0x3)
-#define MD_BANK_TO_PHYS_BANK(_b) (( (_b) >> 0) & 0x1)
-#define MD_DIMM_BANK_GET(addr)   MD_BANK_TO_DIMM_BANK(MD_BANK_GET(addr))
-#define MD_PHYS_BANK_GET(addr)   MD_BANK_TO_PHYS_BANK(MD_BANK_GET(addr))
-
-
-/* Split an MD pointer (or message source & suppl. fields) into node, device */
-
-#define MD_PTR_NODE_SHFT	3
-#define MD_PTR_DEVICE_MASK	0x7
-#define MD_PTR_SUBNODE0_MASK	0x1
-#define MD_PTR_SUBNODE1_MASK	0x4
-
-
-/**********************************************************************
-
- Backdoor protection and page counter structures
-
-**********************************************************************/
-
-/* Protection entries and page counters are interleaved at 4 separate
-   addresses, 0x10 apart.  Software must read/write all four. */
-
-#define BD_ITLV_COUNT		4
-#define BD_ITLV_STRIDE		0x10
-
-/* Protection entries */
-
-/* (these macros work for standard (_rgn < 32) or premium DIMMs) */
-#define MD_PROT_SHFT(_rgn, _io)	((((_rgn) & 0x20) >> 2 | \
-				  ((_rgn) & 0x01) << 2 | \
-				  ((_io)  &  0x1) << 1) * 8)
-#define MD_PROT_MASK(_rgn, _io)	(0xff << MD_PROT_SHFT(_rgn, _io))
-#define MD_PROT_GET(_val, _rgn, _io) \
-	(((_val) & MD_PROT_MASK(_rgn, _io)) >> MD_PROT_SHFT(_rgn, _io))
-
-/* Protection field values */
-
-#define MD_PROT_RW              (UINT64_CAST 0xff)
-#define MD_PROT_RO              (UINT64_CAST 0x0f)
-#define MD_PROT_NO              (UINT64_CAST 0x00)
-
-
-
-
-/**********************************************************************
-
- Directory format structures
-
-***********************************************************************/
-
-#ifndef __ASSEMBLY__
-
-/* Standard Directory Entries */
-
-#ifdef LITTLE_ENDIAN
-
-struct	md_sdir_pointer_fmt { /* exclusive, busy shared/excl, wait, poisoned */
-	bdrkreg_t	sdp_format                :	 2;
-        bdrkreg_t       sdp_state                 :      3;
-        bdrkreg_t       sdp_priority              :      3;
-        bdrkreg_t       sdp_pointer1              :      8;
-        bdrkreg_t       sdp_ecc                   :      6;
-        bdrkreg_t       sdp_locprot               :      1;
-        bdrkreg_t       sdp_reserved              :      1;
-        bdrkreg_t       sdp_crit_word_off         :      3;
-        bdrkreg_t       sdp_pointer2              :      5;
-        bdrkreg_t       sdp_fill                  :     32;
-};
-
-#else
-
-struct	md_sdir_pointer_fmt { /* exclusive, busy shared/excl, wait, poisoned */
-	bdrkreg_t	sdp_fill		  :	32;
-	bdrkreg_t	sdp_pointer2		  :	 5;
-	bdrkreg_t	sdp_crit_word_off	  :	 3;
-	bdrkreg_t	sdp_reserved		  :	 1;
-	bdrkreg_t	sdp_locprot		  :	 1;
-	bdrkreg_t	sdp_ecc			  :	 6;
-	bdrkreg_t	sdp_pointer1		  :	 8;
-	bdrkreg_t	sdp_priority		  :	 3;
-	bdrkreg_t	sdp_state		  :	 3;
-	bdrkreg_t	sdp_format		  :	 2;
-};
-
-#endif
-
-#ifdef LITTLE_ENDIAN
-
-struct	md_sdir_fine_fmt { /* shared (fine) */
-	bdrkreg_t	sdf_format                :	 2;
-        bdrkreg_t       sdf_tag1                  :      3;
-        bdrkreg_t       sdf_tag2                  :      3;
-        bdrkreg_t       sdf_vector1               :      8;
-        bdrkreg_t       sdf_ecc                   :      6;
-        bdrkreg_t       sdf_locprot               :      1;
-        bdrkreg_t       sdf_tag2valid             :      1;
-        bdrkreg_t       sdf_vector2               :      8;
-        bdrkreg_t       sdf_fill                  :     32;
-};
-
-#else
-
-struct	md_sdir_fine_fmt { /* shared (fine) */
-	bdrkreg_t	sdf_fill		  :	32;
-	bdrkreg_t	sdf_vector2		  :	 8;
-	bdrkreg_t	sdf_tag2valid		  :	 1;
-	bdrkreg_t	sdf_locprot		  :	 1;
-	bdrkreg_t	sdf_ecc			  :	 6;
-	bdrkreg_t	sdf_vector1		  :	 8;
-	bdrkreg_t	sdf_tag2		  :	 3;
-	bdrkreg_t	sdf_tag1		  :	 3;
-	bdrkreg_t	sdf_format		  :	 2;
-};
-
-#endif
-
-#ifdef LITTLE_ENDIAN
-
-struct	md_sdir_coarse_fmt { /* shared (coarse) */
-	bdrkreg_t	sdc_format                :	 2;
-        bdrkreg_t       sdc_reserved_1            :      6;
-        bdrkreg_t       sdc_vector_a              :      8;
-        bdrkreg_t       sdc_ecc                   :      6;
-        bdrkreg_t       sdc_locprot               :      1;
-        bdrkreg_t       sdc_reserved              :      1;
-        bdrkreg_t       sdc_vector_b              :      8;
-        bdrkreg_t       sdc_fill                  :     32;
-};
-
-#else
-
-struct	md_sdir_coarse_fmt { /* shared (coarse) */
-	bdrkreg_t	sdc_fill		  :	32;
-	bdrkreg_t	sdc_vector_b		  :	 8;
-	bdrkreg_t	sdc_reserved		  :	 1;
-	bdrkreg_t	sdc_locprot		  :	 1;
-	bdrkreg_t	sdc_ecc			  :	 6;
-	bdrkreg_t	sdc_vector_a		  :	 8;
-	bdrkreg_t	sdc_reserved_1		  :	 6;
-	bdrkreg_t	sdc_format		  :	 2;
-};
-
-#endif
-
-typedef union md_sdir {
-	/* The 32 bits of standard directory, in bits 31:0 */
-	uint64_t	sd_val;
-	struct	md_sdir_pointer_fmt	sdp_fmt;
-	struct	md_sdir_fine_fmt	sdf_fmt;
-	struct	md_sdir_coarse_fmt	sdc_fmt;
-} md_sdir_t;
-
-
-/* Premium Directory Entries */
-
-#ifdef LITTLE_ENDIAN
-
-struct	md_pdir_pointer_fmt { /* exclusive, busy shared/excl, wait, poisoned */
-	bdrkreg_t	pdp_format                :	 2;
-        bdrkreg_t       pdp_state                 :      3;
-        bdrkreg_t       pdp_priority              :      3;
-        bdrkreg_t       pdp_pointer1_a            :      8;
-        bdrkreg_t       pdp_reserved_4            :      6;
-        bdrkreg_t       pdp_pointer1_b            :      3;
-        bdrkreg_t       pdp_reserved_3            :      7;
-        bdrkreg_t       pdp_ecc_a                 :      6;
-        bdrkreg_t       pdp_locprot               :      1;
-        bdrkreg_t       pdp_reserved_2            :      1;
-        bdrkreg_t       pdp_crit_word_off         :      3;
-        bdrkreg_t       pdp_pointer2_a            :      5;
-        bdrkreg_t       pdp_ecc_b                 :      1;
-        bdrkreg_t       pdp_reserved_1            :      5;
-        bdrkreg_t       pdp_pointer2_b            :      3;
-        bdrkreg_t       pdp_reserved              :      7;
-};
-
-#else
-
-struct	md_pdir_pointer_fmt { /* exclusive, busy shared/excl, wait, poisoned */
-	bdrkreg_t	pdp_reserved		  :	 7;
-	bdrkreg_t	pdp_pointer2_b		  :	 3;
-	bdrkreg_t	pdp_reserved_1		  :	 5;
-	bdrkreg_t	pdp_ecc_b		  :	 1;
-	bdrkreg_t	pdp_pointer2_a		  :	 5;
-	bdrkreg_t	pdp_crit_word_off	  :	 3;
-	bdrkreg_t	pdp_reserved_2		  :	 1;
-	bdrkreg_t	pdp_locprot		  :	 1;
-	bdrkreg_t	pdp_ecc_a		  :	 6;
-	bdrkreg_t	pdp_reserved_3		  :	 7;
-	bdrkreg_t	pdp_pointer1_b		  :	 3;
-	bdrkreg_t	pdp_reserved_4		  :	 6;
-	bdrkreg_t	pdp_pointer1_a		  :	 8;
-	bdrkreg_t	pdp_priority		  :	 3;
-	bdrkreg_t	pdp_state		  :	 3;
-	bdrkreg_t	pdp_format		  :	 2;
-};
-
-#endif
-
-#ifdef LITTLE_ENDIAN
-
-struct	md_pdir_fine_fmt { /* shared (fine) */
-	bdrkreg_t	pdf_format                :	 2;
-        bdrkreg_t       pdf_tag1_a                :      3;
-        bdrkreg_t       pdf_tag2_a                :      3;
-        bdrkreg_t       pdf_vector1_a             :      8;
-        bdrkreg_t       pdf_reserved_1            :      6;
-        bdrkreg_t       pdf_tag1_b                :      2;
-        bdrkreg_t       pdf_vector1_b             :      8;
-        bdrkreg_t       pdf_ecc_a                 :      6;
-        bdrkreg_t       pdf_locprot               :      1;
-        bdrkreg_t       pdf_tag2valid             :      1;
-        bdrkreg_t       pdf_vector2_a             :      8;
-        bdrkreg_t       pdf_ecc_b                 :      1;
-        bdrkreg_t       pdf_reserved              :      5;
-        bdrkreg_t       pdf_tag2_b                :      2;
-        bdrkreg_t       pdf_vector2_b             :      8;
-};
-
-#else
-
-struct	md_pdir_fine_fmt { /* shared (fine) */
-	bdrkreg_t	pdf_vector2_b		  :	 8;
-	bdrkreg_t	pdf_tag2_b		  :	 2;
-	bdrkreg_t	pdf_reserved		  :	 5;
-	bdrkreg_t	pdf_ecc_b		  :	 1;
-	bdrkreg_t	pdf_vector2_a		  :	 8;
-	bdrkreg_t	pdf_tag2valid		  :	 1;
-	bdrkreg_t	pdf_locprot		  :	 1;
-	bdrkreg_t	pdf_ecc_a		  :	 6;
-	bdrkreg_t	pdf_vector1_b		  :	 8;
-	bdrkreg_t	pdf_tag1_b		  :	 2;
-	bdrkreg_t	pdf_reserved_1		  :	 6;
-	bdrkreg_t	pdf_vector1_a		  :	 8;
-	bdrkreg_t	pdf_tag2_a		  :	 3;
-	bdrkreg_t	pdf_tag1_a		  :	 3;
-	bdrkreg_t	pdf_format		  :	 2;
-};
-
-#endif
-
-#ifdef LITTLE_ENDIAN
-
-struct	md_pdir_sparse_fmt { /* shared (sparse) */
-	bdrkreg_t	pds_format                :	 2;
-        bdrkreg_t       pds_column_a              :      6;
-        bdrkreg_t       pds_row_a                 :      8;
-        bdrkreg_t       pds_column_b              :     16;
-        bdrkreg_t       pds_ecc_a                 :      6;
-        bdrkreg_t       pds_locprot               :      1;
-        bdrkreg_t       pds_reserved_1            :      1;
-        bdrkreg_t       pds_row_b                 :      8;
-        bdrkreg_t       pds_ecc_b                 :      1;
-        bdrkreg_t       pds_column_c              :     10;
-        bdrkreg_t       pds_reserved              :      5;
-};
-
-#else
-
-struct	md_pdir_sparse_fmt { /* shared (sparse) */
-	bdrkreg_t	pds_reserved		  :	 5;
-	bdrkreg_t	pds_column_c		  :	10;
-	bdrkreg_t	pds_ecc_b		  :	 1;
-	bdrkreg_t	pds_row_b		  :	 8;
-	bdrkreg_t	pds_reserved_1		  :	 1;
-	bdrkreg_t	pds_locprot		  :	 1;
-	bdrkreg_t	pds_ecc_a		  :	 6;
-	bdrkreg_t	pds_column_b		  :	16;
-	bdrkreg_t	pds_row_a		  :	 8;
-	bdrkreg_t	pds_column_a		  :	 6;
-	bdrkreg_t	pds_format		  :	 2;
-};
-
-#endif
-
-typedef union md_pdir {
-	/* The 64 bits of premium directory */
-	uint64_t	pd_val;
-	struct	md_pdir_pointer_fmt	pdp_fmt;
-	struct	md_pdir_fine_fmt	pdf_fmt;
-	struct	md_pdir_sparse_fmt	pds_fmt;
-} md_pdir_t;
-
-#endif /* __ASSEMBLY__ */
-
-
-/**********************************************************************
-
- The defines for backdoor directory and backdoor ECC.
-
-***********************************************************************/
-
-/* Directory formats, for each format's "format" field */
-
-#define MD_FORMAT_UNOWNED	(UINT64_CAST 0x0)	/* 00 */
-#define MD_FORMAT_POINTER	(UINT64_CAST 0x1)	/* 01 */
-#define MD_FORMAT_SHFINE	(UINT64_CAST 0x2)	/* 10 */
-#define MD_FORMAT_SHCOARSE	(UINT64_CAST 0x3)	/* 11 */
-  /* Shared coarse (standard) and shared sparse (premium) both use fmt 0x3 */
-
-
-/*
- * Cacheline state values.
- *
- * These are really *software* notions of the "state" of a cacheline; but the
- * actual values have been carefully chosen to align with some hardware values!
- * The MD_FMT_ST_TO_STATE macro is used to convert from hardware format/state
- * pairs in the directory entried into one of these cacheline state values.
- */
-
-#define MD_DIR_EXCLUSIVE	(UINT64_CAST 0x0)	/* ptr format, hw-defined */
-#define MD_DIR_UNOWNED		(UINT64_CAST 0x1)	/* format=0 */
-#define MD_DIR_SHARED		(UINT64_CAST 0x2)	/* format=2,3 */
-#define MD_DIR_BUSY_SHARED	(UINT64_CAST 0x4)	/* ptr format, hw-defined */
-#define MD_DIR_BUSY_EXCL	(UINT64_CAST 0x5)	/* ptr format, hw-defined */
-#define MD_DIR_WAIT		(UINT64_CAST 0x6)	/* ptr format, hw-defined */
-#define MD_DIR_POISONED		(UINT64_CAST 0x7)	/* ptr format, hw-defined */
-
-#ifndef __ASSEMBLY__
-
-/* Convert format and state fields into a single "cacheline state" value, defined above */
-
-#define MD_FMT_ST_TO_STATE(fmt, state) \
-  ((fmt) == MD_FORMAT_POINTER ? (state) : \
-   (fmt) == MD_FORMAT_UNOWNED ? MD_DIR_UNOWNED : \
-   MD_DIR_SHARED)
-#define MD_DIR_STATE(x) MD_FMT_ST_TO_STATE(MD_DIR_FORMAT(x), MD_DIR_STVAL(x))
-
-#endif /* __ASSEMBLY__ */
-
-
-
-/* Directory field shifts and masks */
-
-/* Standard */
-
-#define MD_SDIR_FORMAT_SHFT	0			/* All formats */
-#define MD_SDIR_FORMAT_MASK	(0x3 << 0)
-#define MD_SDIR_STATE_SHFT	2			/* Pointer fmt. only */
-#define MD_SDIR_STATE_MASK	(0x7 << 2)
-
-/* Premium */
-
-#define MD_PDIR_FORMAT_SHFT	0			/* All formats */
-#define MD_PDIR_FORMAT_MASK	(0x3 << 0)
-#define MD_PDIR_STATE_SHFT	2			/* Pointer fmt. only */
-#define MD_PDIR_STATE_MASK	(0x7 << 2)
-
-/* Generic */
-
-#define MD_FORMAT_SHFT	0				/* All formats */
-#define MD_FORMAT_MASK	(0x3 << 0)
-#define MD_STATE_SHFT	2				/* Pointer fmt. only */
-#define MD_STATE_MASK	(0x7 << 2)
-
-
-/* Special shifts to reconstruct fields from the _a and _b parts */
-
-/* Standard:  only shared coarse has split fields */
-
-#define MD_SDC_VECTORB_SHFT	8	/* eg: sdc_vector_a is 8 bits */
-
-/* Premium:  pointer, shared fine, shared sparse */
-
-#define MD_PDP_POINTER1A_MASK	0xFF
-#define MD_PDP_POINTER1B_SHFT	8
-#define MD_PDP_POINTER2B_SHFT	5
-#define MD_PDP_ECCB_SHFT	6
-
-#define MD_PDF_VECTOR1B_SHFT	8
-#define MD_PDF_VECTOR2B_SHFT	8
-#define MD_PDF_TAG1B_SHFT	3
-#define MD_PDF_TAG2B_SHFT	3
-#define MD_PDF_ECC_SHFT		6
-
-#define MD_PDS_ROWB_SHFT	8
-#define MD_PDS_COLUMNB_SHFT	6
-#define MD_PDS_COLUMNC_SHFT	(MD_PDS_COLUMNB_SHFT + 16)
-#define MD_PDS_ECC_SHFT		6
-
-
-
-/*
- * Directory/protection/counter initialization values, premium and standard
- */
-
-#define MD_PDIR_INIT		0
-#define MD_PDIR_INIT_CNT	0
-#define MD_PDIR_INIT_PROT	0
-
-#define MD_SDIR_INIT		0
-#define MD_SDIR_INIT_CNT	0
-#define MD_SDIR_INIT_PROT	0
-
-#define MD_PDIR_MASK            0xffffffffffffffff
-#define MD_SDIR_MASK            0xffffffff
-
-/* When premium mode is on for probing but standard directory memory
-   is installed, the valid directory bits depend on the phys. bank */
-#define MD_PDIR_PROBE_MASK(pb)  0xffffffffffffffff
-#define MD_SDIR_PROBE_MASK(pb)  (0xffff0000ffff << ((pb) ? 16 : 0))
-
-
-/*
- * Misc. field extractions and conversions
- */
-
-/* Convert an MD pointer (or message source, supplemental fields) */
-
-#define MD_PTR_NODE(x)		((x) >> MD_PTR_NODE_SHFT)
-#define MD_PTR_DEVICE(x)	((x) & MD_PTR_DEVICE_MASK)
-#define MD_PTR_SLICE(x)		(((x) & MD_PTR_SUBNODE0_MASK) | \
-				 ((x) & MD_PTR_SUBNODE1_MASK) >> 1)
-#define MD_PTR_OWNER_CPU(x)	(! ((x) & 2))
-#define MD_PTR_OWNER_IO(x)	((x) & 2)
-
-/* Extract format and raw state from a directory entry */
-
-#define MD_DIR_FORMAT(x)	((x) >> MD_SDIR_FORMAT_SHFT & \
-				 MD_SDIR_FORMAT_MASK >> MD_SDIR_FORMAT_SHFT)
-#define MD_DIR_STVAL(x)		((x) >> MD_SDIR_STATE_SHFT & \
-				 MD_SDIR_STATE_MASK >> MD_SDIR_STATE_SHFT)
-
-/* Mask & Shift to get HSPEC_ADDR from MD DIR_ERROR register */
-#define ERROR_ADDR_SHFT         3
-#define ERROR_HSPEC_SHFT        3
-#define DIR_ERR_HSPEC_MASK      0x1fffffff8
-
-/*
- *  DIR_ERR* and MEM_ERR* defines are used to avoid ugly
- *  #ifdefs for SN0 and SN1 in memerror.c code.  See SN0/hubmd.h
- *  for corresponding SN0 definitions.
- */
-#define md_dir_error_t  md_dir_error_u_t
-#define md_mem_error_t  md_mem_error_u_t
-#define derr_reg        md_dir_error_regval
-#define merr_reg        md_mem_error_regval
-
-#define DIR_ERR_UCE_VALID       dir_err.md_dir_error_fld_s.de_uce_valid
-#define DIR_ERR_AE_VALID        dir_err.md_dir_error_fld_s.de_ae_valid
-#define DIR_ERR_BAD_SYN         dir_err.md_dir_error_fld_s.de_bad_syn
-#define DIR_ERR_CE_OVERRUN      dir_err.md_dir_error_fld_s.de_ce_overrun
-#define MEM_ERR_ADDRESS         mem_err.md_mem_error_fld_s.me_address
-        /* BRINGUP Can the overrun bit be set without the valid bit? */
-#define MEM_ERR_CE_OVERRUN      (mem_err.md_mem_error_fld_s.me_read_ce >> 1)
-#define MEM_ERR_BAD_SYN         mem_err.md_mem_error_fld_s.me_bad_syn
-#define MEM_ERR_UCE_VALID       (mem_err.md_mem_error_fld_s.me_read_uce & 1)
-
-
-
-/*********************************************************************
-
- We have the shift and masks of various fields defined below.
-
- *********************************************************************/
-
-/* MD_REFRESH_CONTROL fields */
-
-#define MRC_ENABLE_SHFT         63
-#define MRC_ENABLE_MASK         (UINT64_CAST 1 << 63)
-#define MRC_ENABLE              (UINT64_CAST 1 << 63)
-#define MRC_COUNTER_SHFT        12
-#define MRC_COUNTER_MASK        (UINT64_CAST 0xfff << 12)
-#define MRC_CNT_THRESH_MASK     0xfff
-#define MRC_RESET_DEFAULTS      (UINT64_CAST 0x800)
-
-/* MD_DIR_CONFIG fields */
-
-#define MDC_DIR_PREMIUM		(UINT64_CAST 1 << 0)
-#define MDC_IGNORE_ECC_SHFT      1
-#define MDC_IGNORE_ECC_MASK     (UINT64_CAST 1 << 1)
-
-/* MD_MEMORY_CONFIG fields */
-
-#define MMC_RP_CONFIG_SHFT	61
-#define MMC_RP_CONFIG_MASK	(UINT64_CAST 1 << 61)
-#define MMC_RCD_CONFIG_SHFT	60
-#define MMC_RCD_CONFIG_MASK	(UINT64_CAST 1 << 60)
-#define MMC_MB_NEG_EDGE_SHFT	56
-#define MMC_MB_NEG_EDGE_MASK	(UINT64_CAST 0x7 << 56)
-#define MMC_SAMPLE_TIME_SHFT	52
-#define MMC_SAMPLE_TIME_MASK	(UINT64_CAST 0x3 << 52)
-#define MMC_DELAY_MUX_SEL_SHFT	50
-#define MMC_DELAY_MUX_SEL_MASK	(UINT64_CAST 0x3 << 50)
-#define MMC_PHASE_DELAY_SHFT	49
-#define MMC_PHASE_DELAY_MASK	(UINT64_CAST 1 << 49)
-#define MMC_DB_NEG_EDGE_SHFT	48
-#define MMC_DB_NEG_EDGE_MASK	(UINT64_CAST 1 << 48)
-#define MMC_CPU_PROT_IGNORE_SHFT	 47
-#define MMC_CPU_PROT_IGNORE_MASK	(UINT64_CAST 1 << 47)
-#define MMC_IO_PROT_IGNORE_SHFT 46
-#define MMC_IO_PROT_IGNORE_MASK	(UINT64_CAST 1 << 46)
-#define MMC_IO_PROT_EN_SHFT	45
-#define MMC_IO_PROT_EN_MASK	(UINT64_CAST 1 << 45)
-#define MMC_CC_ENABLE_SHFT	44
-#define MMC_CC_ENABLE_MASK	(UINT64_CAST 1 << 44)
-#define MMC_DIMM0_SEL_SHFT	32
-#define MMC_DIMM0_SEL_MASK     (UINT64_CAST 0x3 << 32)
-#define MMC_DIMM_SIZE_SHFT(_dimm)    ((_dimm << 3) + 4)
-#define MMC_DIMM_SIZE_MASK(_dimm)    (UINT64_CAST 0xf << MMC_DIMM_SIZE_SHFT(_dimm))
-#define MMC_DIMM_WIDTH_SHFT(_dimm)    ((_dimm << 3) + 3)
-#define MMC_DIMM_WIDTH_MASK(_dimm)    (UINT64_CAST 0x1 << MMC_DIMM_WIDTH_SHFT(_dimm))
-#define MMC_DIMM_BANKS_SHFT(_dimm)    (_dimm << 3)
-#define MMC_DIMM_BANKS_MASK(_dimm)    (UINT64_CAST 0x3 << MMC_DIMM_BANKS_SHFT(_dimm))
-#define MMC_BANK_ALL_MASK	0xffffffffLL
-/* Default values for write-only bits in MD_MEMORY_CONFIG */
-#define MMC_DEFAULT_BITS	(UINT64_CAST 0x7 << MMC_MB_NEG_EDGE_SHFT)
-
-/* MD_MB_ECC_CONFIG fields */
-
-#define MEC_IGNORE_ECC		(UINT64_CAST 0x1 << 0)
-
-/* MD_BIST_DATA fields */
-
-#define MBD_BIST_WRITE		(UINT64_CAST 1 << 7)
-#define MBD_BIST_CYCLE		(UINT64_CAST 1 << 6)
-#define MBD_BIST_BYTE		(UINT64_CAST 1 << 5)
-#define MBD_BIST_NIBBLE		(UINT64_CAST 1 << 4)
-#define MBD_BIST_DATA_MASK	0xf
-
-/* MD_BIST_CTL fields */
-
-#define MBC_DIMM_SHFT		5
-#define MBC_DIMM_MASK		(UINT64_CAST 0x3 << 5)
-#define MBC_BANK_SHFT		4
-#define MBC_BANK_MASK		(UINT64_CAST 0x1 << 4)
-#define MBC_BIST_RESET		(UINT64_CAST 0x1 << 2)
-#define MBC_BIST_STOP		(UINT64_CAST 0x1 << 1)
-#define MBC_BIST_START		(UINT64_CAST 0x1 << 0)
-
-#define MBC_GO(dimm, bank) \
-    (((dimm) << MBC_DIMM_SHFT) & MBC_DIMM_MASK | \
-     ((bank) << MBC_BANK_SHFT) & MBC_BANK_MASK | \
-     MBC_BIST_START)
-
-/* MD_BIST_STATUS fields */
-
-#define MBS_BIST_DONE		(UINT64_CAST 0X1 << 1)
-#define MBS_BIST_PASSED		(UINT64_CAST 0X1 << 0)
-
-/* MD_JUNK_BUS_TIMING fields */
-
-#define MJT_SYNERGY_ENABLE_SHFT	40
-#define MJT_SYNERGY_ENABLE_MASK	(UINT64_CAST 0Xff << MJT_SYNERGY_ENABLE_SHFT)
-#define MJT_SYNERGY_SETUP_SHFT	32
-#define MJT_SYNERGY_SETUP_MASK	(UINT64_CAST 0Xff << MJT_SYNERGY_SETUP_SHFT)
-#define MJT_UART_ENABLE_SHFT	24
-#define MJT_UART_ENABLE_MASK	(UINT64_CAST 0Xff << MJT_UART_ENABLE_SHFT)
-#define MJT_UART_SETUP_SHFT	16
-#define MJT_UART_SETUP_MASK	(UINT64_CAST 0Xff << MJT_UART_SETUP_SHFT)
-#define MJT_FPROM_ENABLE_SHFT	8
-#define MJT_FPROM_ENABLE_MASK	(UINT64_CAST 0Xff << MJT_FPROM_ENABLE_SHFT)
-#define MJT_FPROM_SETUP_SHFT	0
-#define MJT_FPROM_SETUP_MASK	(UINT64_CAST 0Xff << MJT_FPROM_SETUP_SHFT)
-
-#define MEM_ERROR_VALID_CE      1
-
-
-/* MD_FANDOP_CAC_STAT0, MD_FANDOP_CAC_STAT1 addr field shift */
-
-#define MFC_ADDR_SHFT		6
-
-#endif  /* _ASM_IA64_SN_SN1_HUBMD_NEXT_H */
diff -Nru a/include/asm-ia64/sn/sn1/hubni.h b/include/asm-ia64/sn/sn1/hubni.h
--- a/include/asm-ia64/sn/sn1/hubni.h	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1781 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBNI_H
-#define _ASM_IA64_SN_SN1_HUBNI_H
-
-
-/************************************************************************
- *                                                                      *
- *      WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!      *
- *                                                                      *
- * This file is created by an automated script. Any (minimal) changes   *
- * made manually to this  file should be made with care.                *
- *                                                                      *
- *               MAKE ALL ADDITIONS TO THE END OF THIS FILE             *
- *                                                                      *
- ************************************************************************/
-
-#define    NI_PORT_STATUS            0x00680000    /* LLP Status             */
-
-
-
-#define    NI_PORT_RESET             0x00680008    /*
-                                                    * Reset the Network
-                                                    * Interface
-                                                    */
-
-
-
-#define    NI_RESET_ENABLE           0x00680010    /* Warm Reset Enable      */
-
-
-
-#define    NI_DIAG_PARMS             0x00680018    /*
-                                                    * Diagnostic
-                                                    * Parameters
-                                                    */
-
-
-
-#define    NI_CHANNEL_CONTROL        0x00680020    /*
-                                                    * Virtual channel
-                                                    * control
-                                                    */
-
-
-
-#define    NI_CHANNEL_TEST           0x00680028    /* LLP Test Control.      */
-
-
-
-#define    NI_PORT_PARMS             0x00680030    /* LLP Parameters         */
-
-
-
-#define    NI_CHANNEL_AGE            0x00680038    /*
-                                                    * Network age
-                                                    * injection control
-                                                    */
-
-
-
-#define    NI_PORT_ERRORS            0x00680100    /* Errors                 */
-
-
-
-#define    NI_PORT_HEADER_A          0x00680108    /*
-                                                    * Error Header first
-                                                    * half
-                                                    */
-
-
-
-#define    NI_PORT_HEADER_B          0x00680110    /*
-                                                    * Error Header second
-                                                    * half
-                                                    */
-
-
-
-#define    NI_PORT_SIDEBAND          0x00680118    /* Error Sideband         */
-
-
-
-#define    NI_PORT_ERROR_CLEAR       0x00680120    /*
-                                                    * Clear the Error
-                                                    * bits
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_0          0x00681000    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_1          0x00681008    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_2          0x00681010    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_3          0x00681018    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_4          0x00681020    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_5          0x00681028    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_6          0x00681030    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_7          0x00681038    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_8          0x00681040    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_9          0x00681048    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_10         0x00681050    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_11         0x00681058    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_12         0x00681060    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_13         0x00681068    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_14         0x00681070    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_15         0x00681078    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_16         0x00681080    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_17         0x00681088    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_18         0x00681090    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_19         0x00681098    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_20         0x006810A0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_21         0x006810A8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_22         0x006810B0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_23         0x006810B8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_24         0x006810C0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_25         0x006810C8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_26         0x006810D0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_27         0x006810D8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_28         0x006810E0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_29         0x006810E8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_30         0x006810F0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_31         0x006810F8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_32         0x00681100    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_33         0x00681108    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_34         0x00681110    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_35         0x00681118    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_36         0x00681120    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_37         0x00681128    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_38         0x00681130    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_39         0x00681138    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_40         0x00681140    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_41         0x00681148    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_42         0x00681150    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_43         0x00681158    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_44         0x00681160    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_45         0x00681168    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_46         0x00681170    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_47         0x00681178    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_48         0x00681180    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_49         0x00681188    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_50         0x00681190    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_51         0x00681198    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_52         0x006811A0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_53         0x006811A8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_54         0x006811B0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_55         0x006811B8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_56         0x006811C0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_57         0x006811C8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_58         0x006811D0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_59         0x006811D8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_60         0x006811E0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_61         0x006811E8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_62         0x006811F0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_63         0x006811F8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_64         0x00681200    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_65         0x00681208    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_66         0x00681210    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_67         0x00681218    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_68         0x00681220    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_69         0x00681228    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_70         0x00681230    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_71         0x00681238    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_72         0x00681240    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_73         0x00681248    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_74         0x00681250    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_75         0x00681258    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_76         0x00681260    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_77         0x00681268    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_78         0x00681270    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_79         0x00681278    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_80         0x00681280    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_81         0x00681288    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_82         0x00681290    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_83         0x00681298    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_84         0x006812A0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_85         0x006812A8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_86         0x006812B0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_87         0x006812B8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_88         0x006812C0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_89         0x006812C8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_90         0x006812D0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_91         0x006812D8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_92         0x006812E0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_93         0x006812E8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_94         0x006812F0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_95         0x006812F8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_96         0x00681300    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_97         0x00681308    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_98         0x00681310    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_99         0x00681318    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_100        0x00681320    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_101        0x00681328    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_102        0x00681330    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_103        0x00681338    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_104        0x00681340    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_105        0x00681348    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_106        0x00681350    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_107        0x00681358    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_108        0x00681360    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_109        0x00681368    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_110        0x00681370    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_111        0x00681378    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_112        0x00681380    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_113        0x00681388    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_114        0x00681390    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_115        0x00681398    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_116        0x006813A0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_117        0x006813A8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_118        0x006813B0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_119        0x006813B8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_120        0x006813C0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_121        0x006813C8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_122        0x006813D0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_123        0x006813D8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_124        0x006813E0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_125        0x006813E8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_126        0x006813F0    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_LOCAL_TABLE_127        0x006813F8    /*
-                                                    * Base of Local
-                                                    * Mapping Table 0-127
-                                                    */
-
-
-
-#define    NI_GLOBAL_TABLE           0x00682000    /*
-                                                    * Base of Global
-                                                    * Mapping Table
-                                                    */
-
-
-
-
-
-#ifndef __ASSEMBLY__
-
-/************************************************************************
- *                                                                      *
- *  This register describes the LLP status.                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_port_status_u {
-	bdrkreg_t	ni_port_status_regval;
-	struct  {
-		bdrkreg_t	ps_port_status            :	 2;
-                bdrkreg_t       ps_remote_power           :      1;
-                bdrkreg_t       ps_rsvd                   :     61;
-	} ni_port_status_fld_s;
-} ni_port_status_u_t;
-
-#else
-
-typedef union ni_port_status_u {
-	bdrkreg_t	ni_port_status_regval;
-	struct	{
-		bdrkreg_t	ps_rsvd			  :	61;
-		bdrkreg_t	ps_remote_power		  :	 1;
-		bdrkreg_t	ps_port_status		  :	 2;
-	} ni_port_status_fld_s;
-} ni_port_status_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Writing this register issues a reset to the network interface.      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_port_reset_u {
-	bdrkreg_t	ni_port_reset_regval;
-	struct  {
-		bdrkreg_t	pr_link_reset_out         :	 1;
-                bdrkreg_t       pr_port_reset             :      1;
-                bdrkreg_t       pr_local_reset            :      1;
-                bdrkreg_t       pr_rsvd                   :     61;
-	} ni_port_reset_fld_s;
-} ni_port_reset_u_t;
-
-#else
-
-typedef union ni_port_reset_u {
-	bdrkreg_t	ni_port_reset_regval;
-	struct	{
-		bdrkreg_t	pr_rsvd			  :	61;
-		bdrkreg_t	pr_local_reset		  :	 1;
-		bdrkreg_t	pr_port_reset		  :	 1;
-		bdrkreg_t	pr_link_reset_out	  :	 1;
-	} ni_port_reset_fld_s;
-} ni_port_reset_u_t;
-
-#endif
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the warm reset enable bit.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_reset_enable_u {
-	bdrkreg_t	ni_reset_enable_regval;
-	struct  {
-		bdrkreg_t	re_reset_ok               :	 1;
-                bdrkreg_t       re_rsvd                   :     63;
-	} ni_reset_enable_fld_s;
-} ni_reset_enable_u_t;
-
-#else
-
-typedef union ni_reset_enable_u {
-	bdrkreg_t	ni_reset_enable_regval;
-	struct	{
-		bdrkreg_t	re_rsvd			  :	63;
-		bdrkreg_t	re_reset_ok		  :	 1;
-	} ni_reset_enable_fld_s;
-} ni_reset_enable_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains parameters for diagnostics.                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_diag_parms_u {
-	bdrkreg_t	ni_diag_parms_regval;
-	struct  {
-		bdrkreg_t	dp_send_data_error        :	 1;
-                bdrkreg_t       dp_port_disable           :      1;
-                bdrkreg_t       dp_send_err_off           :      1;
-                bdrkreg_t       dp_rsvd                   :     61;
-	} ni_diag_parms_fld_s;
-} ni_diag_parms_u_t;
-
-#else
-
-typedef union ni_diag_parms_u {
-	bdrkreg_t	ni_diag_parms_regval;
-	struct	{
-		bdrkreg_t	dp_rsvd			  :	61;
-		bdrkreg_t	dp_send_err_off		  :	 1;
-		bdrkreg_t	dp_port_disable		  :	 1;
-		bdrkreg_t	dp_send_data_error	  :	 1;
-	} ni_diag_parms_fld_s;
-} ni_diag_parms_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the virtual channel selection control for    *
- * outgoing messages from the Bedrock.                                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_channel_control_u {
-	bdrkreg_t	ni_channel_control_regval;
-	struct  {
-		bdrkreg_t	cc_vch_one_request        :	 1;
-                bdrkreg_t       cc_vch_two_request        :      1;
-                bdrkreg_t       cc_vch_nine_request       :      1;
-                bdrkreg_t       cc_vch_vector_request     :      1;
-                bdrkreg_t       cc_vch_one_reply          :      1;
-                bdrkreg_t       cc_vch_two_reply          :      1;
-                bdrkreg_t       cc_vch_nine_reply         :      1;
-                bdrkreg_t       cc_vch_vector_reply       :      1;
-                bdrkreg_t       cc_send_vch_sel           :      1;
-                bdrkreg_t       cc_rsvd                   :     55;
-	} ni_channel_control_fld_s;
-} ni_channel_control_u_t;
-
-#else
-
-typedef union ni_channel_control_u {
-	bdrkreg_t	ni_channel_control_regval;
-	struct	{
-		bdrkreg_t	cc_rsvd			  :	55;
-		bdrkreg_t	cc_send_vch_sel		  :	 1;
-		bdrkreg_t	cc_vch_vector_reply	  :	 1;
-		bdrkreg_t	cc_vch_nine_reply	  :	 1;
-		bdrkreg_t	cc_vch_two_reply	  :	 1;
-		bdrkreg_t	cc_vch_one_reply	  :	 1;
-		bdrkreg_t	cc_vch_vector_request	  :	 1;
-		bdrkreg_t	cc_vch_nine_request	  :	 1;
-		bdrkreg_t	cc_vch_two_request	  :	 1;
-		bdrkreg_t	cc_vch_one_request	  :	 1;
-	} ni_channel_control_fld_s;
-} ni_channel_control_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register allows access to the LLP test logic.                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_channel_test_u {
-	bdrkreg_t	ni_channel_test_regval;
-	struct  {
-		bdrkreg_t	ct_testseed               :	20;
-                bdrkreg_t       ct_testmask               :      8;
-                bdrkreg_t       ct_testdata               :     20;
-                bdrkreg_t       ct_testvalid              :      1;
-                bdrkreg_t       ct_testcberr              :      1;
-                bdrkreg_t       ct_testflit               :      3;
-                bdrkreg_t       ct_testclear              :      1;
-                bdrkreg_t       ct_testerrcapture         :      1;
-                bdrkreg_t       ct_rsvd                   :      9;
-	} ni_channel_test_fld_s;
-} ni_channel_test_u_t;
-
-#else
-
-typedef union ni_channel_test_u {
-	bdrkreg_t	ni_channel_test_regval;
-	struct	{
-		bdrkreg_t	ct_rsvd			  :	 9;
-		bdrkreg_t	ct_testerrcapture	  :	 1;
-		bdrkreg_t	ct_testclear		  :	 1;
-		bdrkreg_t	ct_testflit		  :	 3;
-		bdrkreg_t	ct_testcberr		  :	 1;
-		bdrkreg_t	ct_testvalid		  :	 1;
-		bdrkreg_t	ct_testdata		  :	20;
-		bdrkreg_t	ct_testmask		  :	 8;
-		bdrkreg_t	ct_testseed		  :	20;
-	} ni_channel_test_fld_s;
-} ni_channel_test_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains LLP port parameters and enables for the      *
- * capture of header data.                                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_port_parms_u {
-	bdrkreg_t	ni_port_parms_regval;
-	struct  {
-		bdrkreg_t	pp_max_burst              :	10;
-                bdrkreg_t       pp_null_timeout           :      6;
-                bdrkreg_t       pp_max_retry              :     10;
-                bdrkreg_t       pp_d_avail_sel            :      2;
-                bdrkreg_t       pp_rsvd_1                 :      1;
-                bdrkreg_t       pp_first_err_enable       :      1;
-                bdrkreg_t       pp_squash_err_enable      :      1;
-                bdrkreg_t       pp_vch_err_enable         :      4;
-                bdrkreg_t       pp_rsvd                   :     29;
-	} ni_port_parms_fld_s;
-} ni_port_parms_u_t;
-
-#else
-
-typedef union ni_port_parms_u {
-	bdrkreg_t	ni_port_parms_regval;
-	struct	{
-		bdrkreg_t	pp_rsvd			  :	29;
-		bdrkreg_t	pp_vch_err_enable	  :	 4;
-		bdrkreg_t	pp_squash_err_enable	  :	 1;
-		bdrkreg_t	pp_first_err_enable	  :	 1;
-		bdrkreg_t	pp_rsvd_1		  :	 1;
-		bdrkreg_t	pp_d_avail_sel		  :	 2;
-		bdrkreg_t	pp_max_retry		  :	10;
-		bdrkreg_t	pp_null_timeout		  :	 6;
-		bdrkreg_t	pp_max_burst		  :	10;
-	} ni_port_parms_fld_s;
-} ni_port_parms_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains the age at which request and reply packets   *
- * are injected into the network. This feature allows replies to be     *
- * given a higher fixed priority than requests, which can be            *
- * important in some network saturation situations.                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_channel_age_u {
-	bdrkreg_t	ni_channel_age_regval;
-	struct  {
-		bdrkreg_t	ca_request_inject_age     :	 8;
-                bdrkreg_t       ca_reply_inject_age       :      8;
-                bdrkreg_t       ca_rsvd                   :     48;
-	} ni_channel_age_fld_s;
-} ni_channel_age_u_t;
-
-#else
-
-typedef union ni_channel_age_u {
-	bdrkreg_t	ni_channel_age_regval;
-	struct	{
-		bdrkreg_t	ca_rsvd			  :	48;
-		bdrkreg_t	ca_reply_inject_age	  :	 8;
-		bdrkreg_t	ca_request_inject_age	  :	 8;
-	} ni_channel_age_fld_s;
-} ni_channel_age_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains latched LLP port and problematic message     *
- * errors. The contents are the same information as the                 *
- * NI_PORT_ERROR_CLEAR register, but, in this register read accesses    *
- * are non-destructive. Bits [52:24] assert the NI interrupt.           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_port_errors_u {
-	bdrkreg_t	ni_port_errors_regval;
-	struct  {
-		bdrkreg_t	pe_sn_error_count         :	 8;
-                bdrkreg_t       pe_cb_error_count         :      8;
-                bdrkreg_t       pe_retry_count            :      8;
-                bdrkreg_t       pe_tail_timeout           :      4;
-                bdrkreg_t       pe_fifo_overflow          :      4;
-                bdrkreg_t       pe_external_short         :      4;
-                bdrkreg_t       pe_external_long          :      4;
-                bdrkreg_t       pe_external_bad_header    :      4;
-                bdrkreg_t       pe_internal_short         :      4;
-                bdrkreg_t       pe_internal_long          :      4;
-                bdrkreg_t       pe_link_reset_in          :      1;
-                bdrkreg_t       pe_rsvd                   :     11;
-	} ni_port_errors_fld_s;
-} ni_port_errors_u_t;
-
-#else
-
-typedef union ni_port_errors_u {
-	bdrkreg_t	ni_port_errors_regval;
-	struct	{
-		bdrkreg_t	pe_rsvd			  :	11;
-		bdrkreg_t	pe_link_reset_in	  :	 1;
-		bdrkreg_t	pe_internal_long	  :	 4;
-		bdrkreg_t	pe_internal_short	  :	 4;
-		bdrkreg_t	pe_external_bad_header	  :	 4;
-		bdrkreg_t	pe_external_long	  :	 4;
-		bdrkreg_t	pe_external_short	  :	 4;
-		bdrkreg_t	pe_fifo_overflow	  :	 4;
-		bdrkreg_t	pe_tail_timeout		  :	 4;
-		bdrkreg_t	pe_retry_count		  :	 8;
-		bdrkreg_t	pe_cb_error_count	  :	 8;
-		bdrkreg_t	pe_sn_error_count	  :	 8;
-	} ni_port_errors_fld_s;
-} ni_port_errors_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register provides the sideband data associated with the        *
- * NI_PORT_HEADER registers and also additional data for error          *
- * processing. This register is not cleared on reset.                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_port_sideband_u {
-	bdrkreg_t	ni_port_sideband_regval;
-	struct  {
-		bdrkreg_t	ps_sideband               :	 8;
-                bdrkreg_t       ps_bad_dest               :      1;
-                bdrkreg_t       ps_bad_prexsel            :      1;
-                bdrkreg_t       ps_rcv_error              :      1;
-                bdrkreg_t       ps_bad_message            :      1;
-                bdrkreg_t       ps_squash                 :      1;
-                bdrkreg_t       ps_sn_status              :      1;
-                bdrkreg_t       ps_cb_status              :      1;
-                bdrkreg_t       ps_send_error             :      1;
-                bdrkreg_t       ps_vch_active             :      4;
-                bdrkreg_t       ps_rsvd                   :     44;
-	} ni_port_sideband_fld_s;
-} ni_port_sideband_u_t;
-
-#else
-
-typedef union ni_port_sideband_u {
-	bdrkreg_t	ni_port_sideband_regval;
-	struct	{
-		bdrkreg_t	ps_rsvd			  :	44;
-		bdrkreg_t	ps_vch_active		  :	 4;
-		bdrkreg_t	ps_send_error		  :	 1;
-		bdrkreg_t	ps_cb_status		  :	 1;
-		bdrkreg_t	ps_sn_status		  :	 1;
-		bdrkreg_t	ps_squash		  :	 1;
-		bdrkreg_t	ps_bad_message		  :	 1;
-		bdrkreg_t	ps_rcv_error		  :	 1;
-		bdrkreg_t	ps_bad_prexsel		  :	 1;
-		bdrkreg_t	ps_bad_dest		  :	 1;
-		bdrkreg_t	ps_sideband		  :	 8;
-	} ni_port_sideband_fld_s;
-} ni_port_sideband_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register contains latched LLP port and problematic message     *
- * errors. The contents are the same information as the                 *
- * NI_PORT_ERROR_CLEAR register, but, in this register read accesses    *
- * are non-destructive. Bits [52:24] assert the NI interrupt.           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_port_error_clear_u {
-	bdrkreg_t	ni_port_error_clear_regval;
-	struct  {
-		bdrkreg_t	pec_sn_error_count        :	 8;
-                bdrkreg_t       pec_cb_error_count        :      8;
-                bdrkreg_t       pec_retry_count           :      8;
-                bdrkreg_t       pec_tail_timeout          :      4;
-                bdrkreg_t       pec_fifo_overflow         :      4;
-                bdrkreg_t       pec_external_short        :      4;
-                bdrkreg_t       pec_external_long         :      4;
-                bdrkreg_t       pec_external_bad_header   :      4;
-                bdrkreg_t       pec_internal_short        :      4;
-                bdrkreg_t       pec_internal_long         :      4;
-                bdrkreg_t       pec_link_reset_in         :      1;
-                bdrkreg_t       pec_rsvd                  :     11;
-	} ni_port_error_clear_fld_s;
-} ni_port_error_clear_u_t;
-
-#else
-
-typedef union ni_port_error_clear_u {
-	bdrkreg_t	ni_port_error_clear_regval;
-	struct	{
-		bdrkreg_t	pec_rsvd		  :	11;
-		bdrkreg_t	pec_link_reset_in	  :	 1;
-		bdrkreg_t	pec_internal_long	  :	 4;
-		bdrkreg_t	pec_internal_short	  :	 4;
-		bdrkreg_t	pec_external_bad_header	  :	 4;
-		bdrkreg_t	pec_external_long	  :	 4;
-		bdrkreg_t	pec_external_short	  :	 4;
-		bdrkreg_t	pec_fifo_overflow	  :	 4;
-		bdrkreg_t	pec_tail_timeout	  :	 4;
-		bdrkreg_t	pec_retry_count		  :	 8;
-		bdrkreg_t	pec_cb_error_count	  :	 8;
-		bdrkreg_t	pec_sn_error_count	  :	 8;
-	} ni_port_error_clear_fld_s;
-} ni_port_error_clear_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Lookup table for the next hop's exit port. The table entry          *
- * selection is based on the 7-bit LocalCube routing destination.       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_local_table_0_u {
-	bdrkreg_t	ni_local_table_0_regval;
-	struct  {
-		bdrkreg_t	lt0_next_exit_port        :	 4;
-                bdrkreg_t       lt0_next_vch_lsb          :      1;
-                bdrkreg_t       lt0_rsvd                  :     59;
-	} ni_local_table_0_fld_s;
-} ni_local_table_0_u_t;
-
-#else
-
-typedef union ni_local_table_0_u {
-	bdrkreg_t	ni_local_table_0_regval;
-	struct	{
-		bdrkreg_t	lt0_rsvd		  :	59;
-		bdrkreg_t	lt0_next_vch_lsb	  :	 1;
-		bdrkreg_t	lt0_next_exit_port	  :	 4;
-	} ni_local_table_0_fld_s;
-} ni_local_table_0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Lookup table for the next hop's exit port. The table entry          *
- * selection is based on the 7-bit LocalCube routing destination.       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_local_table_127_u {
-	bdrkreg_t	ni_local_table_127_regval;
-	struct  {
-		bdrkreg_t	lt1_next_exit_port        :	 4;
-                bdrkreg_t       lt1_next_vch_lsb          :      1;
-                bdrkreg_t       lt1_rsvd                  :     59;
-	} ni_local_table_127_fld_s;
-} ni_local_table_127_u_t;
-
-#else
-
-typedef union ni_local_table_127_u {
-	bdrkreg_t	ni_local_table_127_regval;
-	struct	{
-		bdrkreg_t	lt1_rsvd		  :	59;
-		bdrkreg_t	lt1_next_vch_lsb	  :	 1;
-		bdrkreg_t	lt1_next_exit_port	  :	 4;
-	} ni_local_table_127_fld_s;
-} ni_local_table_127_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Lookup table for the next hop's exit port. The table entry          *
- * selection is based on the 1-bit MetaCube routing destination.        *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_global_table_u {
-	bdrkreg_t	ni_global_table_regval;
-	struct  {
-		bdrkreg_t	gt_next_exit_port         :	 4;
-                bdrkreg_t       gt_next_vch_lsb           :      1;
-                bdrkreg_t       gt_rsvd                   :     59;
-	} ni_global_table_fld_s;
-} ni_global_table_u_t;
-
-#else
-
-typedef union ni_global_table_u {
-	bdrkreg_t	ni_global_table_regval;
-	struct	{
-		bdrkreg_t	gt_rsvd			  :	59;
-		bdrkreg_t	gt_next_vch_lsb		  :	 1;
-		bdrkreg_t	gt_next_exit_port	  :	 4;
-	} ni_global_table_fld_s;
-} ni_global_table_u_t;
-
-#endif
-
-
-
-
-
-
-#endif /* __ASSEMBLY__ */
-
-/************************************************************************
- *                                                                      *
- * The following defines which were not formed into structures are      *
- * probably indentical to another register, and the name of the         *
- * register is provided against each of these registers. This           *
- * information needs to be checked carefully                            *
- *                                                                      *
- *           NI_LOCAL_TABLE_1          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_2          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_3          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_4          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_5          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_6          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_7          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_8          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_9          NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_10         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_11         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_12         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_13         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_14         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_15         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_16         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_17         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_18         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_19         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_20         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_21         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_22         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_23         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_24         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_25         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_26         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_27         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_28         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_29         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_30         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_31         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_32         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_33         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_34         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_35         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_36         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_37         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_38         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_39         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_40         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_41         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_42         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_43         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_44         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_45         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_46         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_47         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_48         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_49         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_50         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_51         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_52         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_53         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_54         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_55         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_56         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_57         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_58         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_59         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_60         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_61         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_62         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_63         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_64         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_65         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_66         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_67         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_68         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_69         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_70         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_71         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_72         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_73         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_74         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_75         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_76         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_77         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_78         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_79         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_80         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_81         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_82         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_83         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_84         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_85         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_86         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_87         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_88         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_89         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_90         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_91         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_92         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_93         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_94         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_95         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_96         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_97         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_98         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_99         NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_100        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_101        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_102        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_103        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_104        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_105        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_106        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_107        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_108        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_109        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_110        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_111        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_112        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_113        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_114        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_115        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_116        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_117        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_118        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_119        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_120        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_121        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_122        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_123        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_124        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_125        NI_LOCAL_TABLE_0                 *
- *           NI_LOCAL_TABLE_126        NI_LOCAL_TABLE_0                 *
- *                                                                      *
- ************************************************************************/
-
-
-/************************************************************************
- *                                                                      *
- * The following defines were not formed into structures                *
- *                                                                      *
- * This could be because the document did not contain details of the    *
- * register, or because the automated script did not recognize the      *
- * register details in the documentation. If these register need        *
- * structure definition, please create them manually                    *
- *                                                                      *
- *           NI_PORT_HEADER_A         0x680108                          *
- *           NI_PORT_HEADER_B         0x680110                          *
- *                                                                      *
- ************************************************************************/
-
-
-/************************************************************************
- *                                                                      *
- *               MAKE ALL ADDITIONS AFTER THIS LINE                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-
-#endif /* _ASM_IA64_SN_SN1_HUBNI_H */
diff -Nru a/include/asm-ia64/sn/sn1/hubni_next.h b/include/asm-ia64/sn/sn1/hubni_next.h
--- a/include/asm-ia64/sn/sn1/hubni_next.h	Wed Jun 18 23:42:09 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,174 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBNI_NEXT_H
-#define _ASM_IA64_SN_SN1_HUBNI_NEXT_H
-
-#define NI_LOCAL_ENTRIES        128
-#define NI_META_ENTRIES        1
-
-#define NI_LOCAL_TABLE(_x)      (NI_LOCAL_TABLE_0 + (8 * (_x)))
-#define NI_META_TABLE(_x)       (NI_GLOBAL_TABLE + (8 * (_x)))
-
-/**************************************************************
-
-  Masks and shifts for NI registers are defined below. 
-
-**************************************************************/
-
-#define NPS_LINKUP_SHFT        1
-#define NPS_LINKUP_MASK        (UINT64_CAST 0x1 << 1)
-
-
-#define NPR_LOCALRESET          (UINT64_CAST 1 << 2)    /* Reset loc. bdrck */
-#define NPR_PORTRESET           (UINT64_CAST 1 << 1)    /* Send warm reset  */
-#define NPR_LINKRESET           (UINT64_CAST 1 << 0)    /* Send link reset  */
-
-/* NI_DIAG_PARMS bit definitions */
-#define NDP_SENDERROR           (UINT64_CAST 1 <<  0)   /* Send data error  */
-#define NDP_PORTDISABLE         (UINT64_CAST 1 <<  1)   /* Port disable     */
-#define NDP_SENDERROFF          (UINT64_CAST 1 <<  2)   /* Disable send error recovery */
-
-
-/* NI_PORT_ERROR mask and shift definitions (some are not present in SN0) */
-
-#define NPE_LINKRESET		(UINT64_CAST 1 << 52)
-#define NPE_INTLONG_SHFT	48
-#define NPE_INTLONG_MASK	(UINT64_CAST 0xf << NPE_INTLONG_SHFT)
-#define NPE_INTSHORT_SHFT	44
-#define NPE_INTSHORT_MASK	(UINT64_CAST 0xf << NPE_INTSHORT_SHFT)
-#define NPE_EXTBADHEADER_SHFT	40
-#define NPE_EXTBADHEADER_MASK	(UINT64_CAST 0xf << NPE_EXTBADHEADER_SHFT)
-#define NPE_EXTLONG_SHFT	36
-#define NPE_EXTLONG_MASK	(UINT64_CAST 0xf << NPE_EXTLONG_SHFT)
-#define NPE_EXTSHORT_SHFT	32
-#define NPE_EXTSHORT_MASK	(UINT64_CAST 0xf << NPE_EXTSHORT_SHFT)
-#define NPE_FIFOOVFLOW_SHFT	28
-#define NPE_FIFOOVFLOW_MASK	(UINT64_CAST 0xf << NPE_FIFOOVFLOW_SHFT)
-#define NPE_TAILTO_SHFT		24
-#define NPE_TAILTO_MASK		(UINT64_CAST 0xf << NPE_TAILTO_SHFT)
-#define NPE_RETRYCOUNT_SHFT	16
-#define NPE_RETRYCOUNT_MASK	(UINT64_CAST 0xff << NPE_RETRYCOUNT_SHFT)
-#define NPE_CBERRCOUNT_SHFT	8
-#define NPE_CBERRCOUNT_MASK	(UINT64_CAST 0xff << NPE_CBERRCOUNT_SHFT)
-#define NPE_SNERRCOUNT_SHFT	0
-#define NPE_SNERRCOUNT_MASK	(UINT64_CAST 0xff << NPE_SNERRCOUNT_SHFT)
-
-#define NPE_COUNT_MAX		0xff
-
-#define NPE_FATAL_ERRORS	(NPE_LINKRESET | NPE_INTLONG_MASK |\
-				 NPE_INTSHORT_MASK | NPE_EXTBADHEADER_MASK |\
-				 NPE_EXTLONG_MASK | NPE_EXTSHORT_MASK |\
-				 NPE_FIFOOVFLOW_MASK | NPE_TAILTO_MASK)
-
-#ifndef __ASSEMBLY__
-/* NI_PORT_HEADER[AB] registers (not automatically generated) */
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_port_header_a_u {
-	bdrkreg_t	ni_port_header_a_regval;
-	struct  {
-		bdrkreg_t	pha_v                     :	 1;
-                bdrkreg_t       pha_age                   :      8;
-                bdrkreg_t       pha_direction             :      4;
-                bdrkreg_t       pha_destination           :      8;
-                bdrkreg_t       pha_reserved_1            :      3;
-                bdrkreg_t       pha_command               :      8;
-                bdrkreg_t       pha_prexsel               :      3;
-                bdrkreg_t       pha_address_b             :     27;
-                bdrkreg_t       pha_reserved              :      2;
-	} ni_port_header_a_fld_s;
-} ni_port_header_a_u_t;
-
-#else
-
-typedef union ni_port_header_a_u {
-	bdrkreg_t	ni_port_header_a_regval;
-	struct	{
-		bdrkreg_t	pha_reserved		  :	 2;
-		bdrkreg_t	pha_address_b		  :	27;
-		bdrkreg_t	pha_prexsel		  :	 3;
-		bdrkreg_t	pha_command		  :	 8;
-		bdrkreg_t	pha_reserved_1		  :	 3;
-		bdrkreg_t	pha_destination		  :	 8;
-		bdrkreg_t	pha_direction		  :	 4;
-		bdrkreg_t	pha_age			  :	 8;
-		bdrkreg_t	pha_v			  :	 1;
-	} ni_port_header_a_fld_s;
-} ni_port_header_a_u_t;
-
-#endif
-
-#ifdef LITTLE_ENDIAN
-
-typedef union ni_port_header_b_u {
-	bdrkreg_t	ni_port_header_b_regval;
-	struct  {
-		bdrkreg_t	phb_supplemental           :	11;
-                bdrkreg_t       phb_reserved_2            :      5;
-                bdrkreg_t       phb_source                :     11;
-                bdrkreg_t       phb_reserved_1            :      8;
-                bdrkreg_t       phb_address_a             :      3;
-                bdrkreg_t       phb_address_c             :      8;
-                bdrkreg_t       phb_reserved              :     18;
-	} ni_port_header_b_fld_s;
-} ni_port_header_b_u_t;
-
-#else
-
-typedef union ni_port_header_b_u {
-	bdrkreg_t	ni_port_header_b_regval;
-	struct	{
-		bdrkreg_t	phb_reserved		  :	18;
-		bdrkreg_t	phb_address_c		  :	 8;
-		bdrkreg_t	phb_address_a		  :	 3;
-		bdrkreg_t	phb_reserved_1		  :	 8;
-		bdrkreg_t	phb_source		  :	11;
-		bdrkreg_t	phb_reserved_2		  :	 5;
-		bdrkreg_t	phb_supplemental	   :	11;
-	} ni_port_header_b_fld_s;
-} ni_port_header_b_u_t;
-
-#endif
-#endif
-
-/* NI_RESET_ENABLE mask definitions */
-
-#define NRE_RESETOK		(UINT64_CAST 1)	/* Let LLP reset bedrock */
-
-/* NI PORT_ERRORS, Max number of RETRY_COUNT, Check Bit, and Sequence   */
-/* Number errors (8 bit counters that do not wrap).                     */
-#define NI_LLP_RETRY_MAX        0xff
-#define NI_LLP_CB_MAX           0xff
-#define NI_LLP_SN_MAX           0xff
-
-/* NI_PORT_PARMS shift and mask definitions */
-
-#define NPP_VCH_ERR_EN_SHFT	31
-#define NPP_VCH_ERR_EN_MASK	(0xf << NPP_VCH_ERR_EN_SHFT)
-#define NPP_SQUASH_ERR_EN_SHFT	30
-#define NPP_SQUASH_ERR_EN_MASK	(0x1 << NPP_SQUASH_ERR_EN_SHFT)
-#define NPP_FIRST_ERR_EN_SHFT	29
-#define NPP_FIRST_ERR_EN_MASK	(0x1 << NPP_FIRST_ERR_EN_SHFT)
-#define NPP_D_AVAIL_SEL_SHFT	26
-#define NPP_D_AVAIL_SEL_MASK	(0x3 << NPP_D_AVAIL_SEL_SHFT)
-#define NPP_MAX_RETRY_SHFT	16
-#define NPP_MAX_RETRY_MASK	(0x3ff << NPP_MAX_RETRY_SHFT)
-#define NPP_NULL_TIMEOUT_SHFT	10
-#define NPP_NULL_TIMEOUT_MASK	(0x3f << NPP_NULL_TIMEOUT_SHFT)
-#define NPP_MAX_BURST_SHFT	0
-#define NPP_MAX_BURST_MASK	(0x3ff << NPP_MAX_BURST_SHFT)
-
-#define NPP_RESET_DEFAULTS	(0xf << NPP_VCH_ERR_EN_SHFT |   \
-				 0x1 << NPP_FIRST_ERR_EN_SHFT | \
-				 0x3ff << NPP_MAX_RETRY_SHFT |  \
-				 0x6 << NPP_NULL_TIMEOUT_SHFT | \
-				 0x3f0 << NPP_MAX_BURST_SHFT)
-
-#endif /* _ASM_IA64_SN_SN1_HUBNI_NEXT_H */
diff -Nru a/include/asm-ia64/sn/sn1/hubpi.h b/include/asm-ia64/sn/sn1/hubpi.h
--- a/include/asm-ia64/sn/sn1/hubpi.h	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,4263 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBPI_H
-#define _ASM_IA64_SN_SN1_HUBPI_H
-
-/************************************************************************
- *                                                                      *
- *      WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!      *
- *                                                                      *
- * This file is created by an automated script. Any (minimal) changes   *
- * made manually to this  file should be made with care.                *
- *                                                                      *
- *               MAKE ALL ADDITIONS TO THE END OF THIS FILE             *
- *                                                                      *
- ************************************************************************/
-
-
-#define    PI_CPU_PROTECT            0x00000000    /* CPU Protection         */
-
-
-
-#define    PI_PROT_OVRRD             0x00000008    /*
-                                                    * Clear CPU
-                                                    * Protection bit in 
-                                                    * CPU_PROTECT
-                                                    */
-
-
-
-#define    PI_IO_PROTECT             0x00000010    /*
-                                                    * Interrupt Pending
-                                                    * Protection for IO
-                                                    * access
-                                                    */
-
-
-
-#define    PI_REGION_PRESENT         0x00000018    /* Region present         */
-
-
-
-#define    PI_CPU_NUM                0x00000020    /* CPU Number ID          */
-
-
-
-#define    PI_CALIAS_SIZE            0x00000028    /* Cached Alias Size      */
-
-
-
-#define    PI_MAX_CRB_TIMEOUT        0x00000030    /*
-                                                    * Maximum Timeout for
-                                                    * CRB
-                                                    */
-
-
-
-#define    PI_CRB_SFACTOR            0x00000038    /*
-                                                    * Scale Factor for
-                                                    * CRB Timeout
-                                                    */
-
-
-
-#define    PI_CPU_PRESENT_A          0x00000040    /*
-                                                    * CPU Present for
-                                                    * CPU_A
-                                                    */
-
-
-
-#define    PI_CPU_PRESENT_B          0x00000048    /*
-                                                    * CPU Present for
-                                                    * CPU_B
-                                                    */
-
-
-
-#define    PI_CPU_ENABLE_A           0x00000050    /*
-                                                    * CPU Enable for
-                                                    * CPU_A
-                                                    */
-
-
-
-#define    PI_CPU_ENABLE_B           0x00000058    /*
-                                                    * CPU Enable for
-                                                    * CPU_B
-                                                    */
-
-
-
-#define    PI_REPLY_LEVEL            0x00010060    /*
-                                                    * Reply FIFO Priority
-                                                    * Control
-                                                    */
-
-
-
-#define    PI_GFX_CREDIT_MODE        0x00020068    /*
-                                                    * Graphics Credit
-                                                    * Mode
-                                                    */
-
-
-
-#define    PI_NMI_A                  0x00000070    /*
-                                                    * Non-maskable
-                                                    * Interrupt to CPU A
-                                                    */
-
-
-
-#define    PI_NMI_B                  0x00000078    /*
-                                                    * Non-maskable
-                                                    * Interrupt to CPU B
-                                                    */
-
-
-
-#define    PI_INT_PEND_MOD           0x00000090    /*
-                                                    * Interrupt Pending
-                                                    * Modify
-                                                    */
-
-
-
-#define    PI_INT_PEND0              0x00000098    /* Interrupt Pending 0    */
-
-
-
-#define    PI_INT_PEND1              0x000000A0    /* Interrupt Pending 1    */
-
-
-
-#define    PI_INT_MASK0_A            0x000000A8    /*
-                                                    * Interrupt Mask 0
-                                                    * for CPU A
-                                                    */
-
-
-
-#define    PI_INT_MASK1_A            0x000000B0    /*
-                                                    * Interrupt Mask 1
-                                                    * for CPU A
-                                                    */
-
-
-
-#define    PI_INT_MASK0_B            0x000000B8    /*
-                                                    * Interrupt Mask 0
-                                                    * for CPU B
-                                                    */
-
-
-
-#define    PI_INT_MASK1_B            0x000000C0    /*
-                                                    * Interrupt Mask 1
-                                                    * for CPU B
-                                                    */
-
-
-
-#define    PI_CC_PEND_SET_A          0x000000C8    /*
-                                                    * CC Interrupt
-                                                    * Pending for CPU A
-                                                    */
-
-
-
-#define    PI_CC_PEND_SET_B          0x000000D0    /*
-                                                    * CC Interrupt
-                                                    * Pending for CPU B
-                                                    */
-
-
-
-#define    PI_CC_PEND_CLR_A          0x000000D8    /*
-                                                    * CPU to CPU
-                                                    * Interrupt Pending
-                                                    * Clear for CPU A
-                                                    */
-
-
-
-#define    PI_CC_PEND_CLR_B          0x000000E0    /*
-                                                    * CPU to CPU
-                                                    * Interrupt Pending
-                                                    * Clear for CPU B
-                                                    */
-
-
-
-#define    PI_CC_MASK                0x000000E8    /*
-                                                    * Mask of both
-                                                    * CC_PENDs
-                                                    */
-
-
-
-#define    PI_INT_PEND1_REMAP        0x000000F0    /*
-                                                    * Remap Interrupt
-                                                    * Pending
-                                                    */
-
-
-
-#define    PI_RT_COUNTER             0x00030100    /* Real Time Counter      */
-
-
-
-#define    PI_RT_COMPARE_A           0x00000108    /* Real Time Compare A    */
-
-
-
-#define    PI_RT_COMPARE_B           0x00000110    /* Real Time Compare B    */
-
-
-
-#define    PI_PROFILE_COMPARE        0x00000118    /* Profiling Compare      */
-
-
-
-#define    PI_RT_INT_PEND_A          0x00000120    /*
-                                                    * RT interrupt
-                                                    * pending
-                                                    */
-
-
-
-#define    PI_RT_INT_PEND_B          0x00000128    /*
-                                                    * RT interrupt
-                                                    * pending
-                                                    */
-
-
-
-#define    PI_PROF_INT_PEND_A        0x00000130    /*
-                                                    * Profiling interrupt
-                                                    * pending
-                                                    */
-
-
-
-#define    PI_PROF_INT_PEND_B        0x00000138    /*
-                                                    * Profiling interrupt
-                                                    * pending
-                                                    */
-
-
-
-#define    PI_RT_INT_EN_A            0x00000140    /* RT Interrupt Enable    */
-
-
-
-#define    PI_RT_INT_EN_B            0x00000148    /* RT Interrupt Enable    */
-
-
-
-#define    PI_PROF_INT_EN_A          0x00000150    /*
-                                                    * Profiling Interrupt
-                                                    * Enable
-                                                    */
-
-
-
-#define    PI_PROF_INT_EN_B          0x00000158    /*
-                                                    * Profiling Interrupt
-                                                    * Enable
-                                                    */
-
-
-
-#define    PI_DEBUG_SEL              0x00000160    /* PI Debug Select        */
-
-
-
-#define    PI_INT_PEND_MOD_ALIAS     0x00000180    /*
-                                                    * Interrupt Pending
-                                                    * Modify
-                                                    */
-
-
-
-#define    PI_PERF_CNTL_A            0x00040200    /*
-                                                    * Performance Counter
-                                                    * Control A
-                                                    */
-
-
-
-#define    PI_PERF_CNTR0_A           0x00040208    /*
-                                                    * Performance Counter
-                                                    * 0 A
-                                                    */
-
-
-
-#define    PI_PERF_CNTR1_A           0x00040210    /*
-                                                    * Performance Counter
-                                                    * 1 A
-                                                    */
-
-
-
-#define    PI_PERF_CNTL_B            0x00050200    /*
-                                                    * Performance Counter
-                                                    * Control B
-                                                    */
-
-
-
-#define    PI_PERF_CNTR0_B           0x00050208    /*
-                                                    * Performance Counter
-                                                    * 0 B
-                                                    */
-
-
-
-#define    PI_PERF_CNTR1_B           0x00050210    /*
-                                                    * Performance Counter
-                                                    * 1 B
-                                                    */
-
-
-
-#define    PI_GFX_PAGE_A             0x00000300    /* Graphics Page          */
-
-
-
-#define    PI_GFX_CREDIT_CNTR_A      0x00000308    /*
-                                                    * Graphics Credit
-                                                    * Counter
-                                                    */
-
-
-
-#define    PI_GFX_BIAS_A             0x00000310    /* TRex+ BIAS             */
-
-
-
-#define    PI_GFX_INT_CNTR_A         0x00000318    /*
-                                                    * Graphics Interrupt
-                                                    * Counter
-                                                    */
-
-
-
-#define    PI_GFX_INT_CMP_A          0x00000320    /*
-                                                    * Graphics Interrupt
-                                                    * Compare
-                                                    */
-
-
-
-#define    PI_GFX_PAGE_B             0x00000328    /* Graphics Page          */
-
-
-
-#define    PI_GFX_CREDIT_CNTR_B      0x00000330    /*
-                                                    * Graphics Credit
-                                                    * Counter
-                                                    */
-
-
-
-#define    PI_GFX_BIAS_B             0x00000338    /* TRex+ BIAS             */
-
-
-
-#define    PI_GFX_INT_CNTR_B         0x00000340    /*
-                                                    * Graphics Interrupt
-                                                    * Counter
-                                                    */
-
-
-
-#define    PI_GFX_INT_CMP_B          0x00000348    /*
-                                                    * Graphics Interrupt
-                                                    * Compare
-                                                    */
-
-
-
-#define    PI_ERR_INT_PEND_WR        0x000003F8    /*
-                                                    * Error Interrupt
-                                                    * Pending (Writable)
-                                                    */
-
-
-
-#define    PI_ERR_INT_PEND           0x00000400    /*
-                                                    * Error Interrupt
-                                                    * Pending
-                                                    */
-
-
-
-#define    PI_ERR_INT_MASK_A         0x00000408    /*
-                                                    * Error Interrupt
-                                                    * Mask CPU_A
-                                                    */
-
-
-
-#define    PI_ERR_INT_MASK_B         0x00000410    /*
-                                                    * Error Interrupt
-                                                    * Mask CPU_B
-                                                    */
-
-
-
-#define    PI_ERR_STACK_ADDR_A       0x00000418    /*
-                                                    * Error Stack Address
-                                                    * Pointer
-                                                    */
-
-
-
-#define    PI_ERR_STACK_ADDR_B       0x00000420    /*
-                                                    * Error Stack Address
-                                                    * Pointer
-                                                    */
-
-
-
-#define    PI_ERR_STACK_SIZE         0x00000428    /* Error Stack Size       */
-
-
-
-#define    PI_ERR_STATUS0_A          0x00000430    /* Error Status 0         */
-
-
-
-#define    PI_ERR_STATUS0_A_CLR      0x00000438    /* Error Status 0         */
-
-
-
-#define    PI_ERR_STATUS1_A          0x00000440    /* Error Status 1         */
-
-
-
-#define    PI_ERR_STATUS1_A_CLR      0x00000448    /* Error Status 1         */
-
-
-
-#define    PI_ERR_STATUS0_B          0x00000450    /* Error Status 0         */
-
-
-
-#define    PI_ERR_STATUS0_B_CLR      0x00000458    /* Error Status 0         */
-
-
-
-#define    PI_ERR_STATUS1_B          0x00000460    /* Error Status 1         */
-
-
-
-#define    PI_ERR_STATUS1_B_CLR      0x00000468    /* Error Status 1         */
-
-
-
-#define    PI_SPOOL_CMP_A            0x00000470    /* Spool Compare          */
-
-
-
-#define    PI_SPOOL_CMP_B            0x00000478    /* Spool Compare          */
-
-
-
-#define    PI_CRB_TIMEOUT_A          0x00000480    /*
-                                                    * CRB entries which
-                                                    * have timed out but
-                                                    * are still valid
-                                                    */
-
-
-
-#define    PI_CRB_TIMEOUT_B          0x00000488    /*
-                                                    * CRB entries which
-                                                    * have timed out but
-                                                    * are still valid
-                                                    */
-
-
-
-#define    PI_SYSAD_ERRCHK_EN        0x00000490    /*
-                                                    * enables
-                                                    * sysad/cmd/state
-                                                    * error checking
-                                                    */
-
-
-
-#define    PI_FORCE_BAD_CHECK_BIT_A  0x00000498    /*
-                                                    * force SysAD Check
-                                                    * Bit error
-                                                    */
-
-
-
-#define    PI_FORCE_BAD_CHECK_BIT_B  0x000004A0    /*
-                                                    * force SysAD Check
-                                                    * Bit error
-                                                    */
-
-
-
-#define    PI_NACK_CNT_A             0x000004A8    /*
-                                                    * consecutive NACK
-                                                    * counter
-                                                    */
-
-
-
-#define    PI_NACK_CNT_B             0x000004B0    /*
-                                                    * consecutive NACK
-                                                    * counter
-                                                    */
-
-
-
-#define    PI_NACK_CMP               0x000004B8    /* NACK count compare     */
-
-
-
-#define    PI_SPOOL_MASK             0x000004C0    /* Spool error mask       */
-
-
-
-#define    PI_SPURIOUS_HDR_0         0x000004C8    /* Spurious Error 0       */
-
-
-
-#define    PI_SPURIOUS_HDR_1         0x000004D0    /* Spurious Error 1       */
-
-
-
-#define    PI_ERR_INJECT             0x000004D8    /*
-                                                    * SysAD bus error
-                                                    * injection
-                                                    */
-
-
-
-
-
-#ifndef __ASSEMBLY__
-
-/************************************************************************
- *                                                                      *
- * Description:  This read/write register determines on a               *
- * bit-per-region basis whether incoming CPU-initiated PIO Read and     *
- * Write to local PI registers are allowed. If access is allowed, the   *
- * PI's response to a partial read is a PRPLY message, and the          *
- * response to a partial write is a PACK message. If access is not      *
- * allowed, the PI's response to a partial read is a PRERR message,     *
- * and the response to a partial write is a PWERR message.              *
- * This register is not reset by a soft reset.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_cpu_protect_u {
-	bdrkreg_t	pi_cpu_protect_regval;
-	struct  {
-		bdrkreg_t	cp_cpu_protect            :	64;
-	} pi_cpu_protect_fld_s;
-} pi_cpu_protect_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  A write with a special data pattern allows any CPU to set its       *
- * region's bit in CPU_PROTECT. This register has data pattern          *
- * protection.                                                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_prot_ovrrd_u {
-	bdrkreg_t	pi_prot_ovrrd_regval;
-	struct  {
-		bdrkreg_t	po_prot_ovrrd             :	64;
-	} pi_prot_ovrrd_fld_s;
-} pi_prot_ovrrd_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This read/write register determines on a               *
- * bit-per-region basis whether incoming IO-initiated interrupts are    *
- * allowed to set bits in INT_PEND0 and INT_PEND1. If access is         *
- * allowed, the PI's response to a partial read is a PRPLY message,     *
- * and the response to a partial write is a PACK message. If access     *
- * is not allowed, the PI's response to a partial read is a PRERR       *
- * message, and the response to a partial write is a PWERR message.     *
- * This register is not reset by a soft reset.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_io_protect_u {
-	bdrkreg_t	pi_io_protect_regval;
-	struct  {
-		bdrkreg_t	ip_io_protect             :	64;
-	} pi_io_protect_fld_s;
-} pi_io_protect_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This read/write register determines on a               *
- * bit-per-region basis whether read access from a local processor to   *
- * the region is permissible. For example, setting a bit to 0           *
- * prevents speculative reads to that non-existent node. If a read      *
- * request to a non-present region occurs, an ERR response is issued    *
- * to the TRex+ (no PI error registers are modified). It is up to       *
- * software to load this register with the proper contents.             *
- * Region-present checking is only done for coherent read requests -    *
- * partial reads/writes will be issued to a non-present region. The     *
- * setting of these bits does not affect a node's access to its         *
- * CALIAS space.                                                        *
- * This register is not reset by a soft reset.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_region_present_u {
-	bdrkreg_t	pi_region_present_regval;
-	struct  {
-		bdrkreg_t	rp_region_present         :	64;
-	} pi_region_present_fld_s;
-} pi_region_present_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  A read to the location will allow a CPU to identify itself as       *
- * either CPU_A or CPU_B, and will indicate whether the CPU is          *
- * connected to PI 0 or PI 1.                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_cpu_num_u {
-	bdrkreg_t	pi_cpu_num_regval;
-	struct  {
-		bdrkreg_t	cn_cpu_num                :	 1;
-                bdrkreg_t       cn_pi_id                  :      1;
-                bdrkreg_t       cn_rsvd                   :     62;
-	} pi_cpu_num_fld_s;
-} pi_cpu_num_u_t;
-
-#else
-
-typedef union pi_cpu_num_u {
-	bdrkreg_t	pi_cpu_num_regval;
-	struct	{
-		bdrkreg_t	cn_rsvd			  :	62;
-		bdrkreg_t	cn_pi_id		  :	 1;
-		bdrkreg_t	cn_cpu_num		  :	 1;
-	} pi_cpu_num_fld_s;
-} pi_cpu_num_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This read/write location determines the size of the    *
- * Calias Space.                                                        *
- * This register is not reset by a soft reset.                          *
- * NOTE: For predictable behavior, all Calias spaces in a system must   *
- * be set to the same size.                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_calias_size_u {
-	bdrkreg_t	pi_calias_size_regval;
-	struct  {
-		bdrkreg_t	cs_calias_size            :	 4;
-		bdrkreg_t       cs_rsvd                   :     60;
-	} pi_calias_size_fld_s;
-} pi_calias_size_u_t;
-
-#else
-
-typedef union pi_calias_size_u {
-	bdrkreg_t	pi_calias_size_regval;
-	struct	{
-		bdrkreg_t	cs_rsvd			  :	60;
-		bdrkreg_t	cs_calias_size		  :	 4;
-	} pi_calias_size_fld_s;
-} pi_calias_size_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This Read/Write location determines at which value (increment)      *
- * the CRB Timeout Counters cause a timeout error to occur. See         *
- * Section 3.4.2.2, &quot;Time-outs in RRB and WRB&quot; in the         *
- * Processor Interface chapter, volume 1 of this document for more      *
- * details.                                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_max_crb_timeout_u {
-	bdrkreg_t	pi_max_crb_timeout_regval;
-	struct  {
-		bdrkreg_t	mct_max_timeout           :	 8;
-		bdrkreg_t       mct_rsvd                  :     56;
-	} pi_max_crb_timeout_fld_s;
-} pi_max_crb_timeout_u_t;
-
-#else
-
-typedef union pi_max_crb_timeout_u {
-	bdrkreg_t	pi_max_crb_timeout_regval;
-	struct	{
-		bdrkreg_t	mct_rsvd		  :	56;
-		bdrkreg_t	mct_max_timeout		  :	 8;
-	} pi_max_crb_timeout_fld_s;
-} pi_max_crb_timeout_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This Read/Write location determines how often a valid CRB's         *
- * Timeout Counter is incremented. See Section 3.4.2.2,                 *
- * &quot;Time-outs in RRB and WRB&quot; in the Processor Interface      *
- * chapter, volume 1 of this document for more details.                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_crb_sfactor_u {
-	bdrkreg_t	pi_crb_sfactor_regval;
-	struct  {
-		bdrkreg_t	cs_sfactor                :	24;
-		bdrkreg_t       cs_rsvd                   :     40;
-	} pi_crb_sfactor_fld_s;
-} pi_crb_sfactor_u_t;
-
-#else
-
-typedef union pi_crb_sfactor_u {
-	bdrkreg_t	pi_crb_sfactor_regval;
-	struct	{
-		bdrkreg_t	cs_rsvd			  :	40;
-		bdrkreg_t	cs_sfactor		  :	24;
-	} pi_crb_sfactor_fld_s;
-} pi_crb_sfactor_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. The PI sets this      *
- * bit when it sees the first transaction initiated by the associated   *
- * CPU.                                                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_cpu_present_a_u {
-	bdrkreg_t	pi_cpu_present_a_regval;
-	struct  {
-		bdrkreg_t	cpa_cpu_present           :	 1;
-		bdrkreg_t       cpa_rsvd                  :     63;
-	} pi_cpu_present_a_fld_s;
-} pi_cpu_present_a_u_t;
-
-#else
-
-typedef union pi_cpu_present_a_u {
-	bdrkreg_t	pi_cpu_present_a_regval;
-	struct	{
-		bdrkreg_t	cpa_rsvd		  :	63;
-		bdrkreg_t	cpa_cpu_present		  :	 1;
-	} pi_cpu_present_a_fld_s;
-} pi_cpu_present_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. The PI sets this      *
- * bit when it sees the first transaction initiated by the associated   *
- * CPU.                                                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_cpu_present_b_u {
-	bdrkreg_t	pi_cpu_present_b_regval;
-	struct  {
-		bdrkreg_t	cpb_cpu_present           :	 1;
-		bdrkreg_t       cpb_rsvd                  :     63;
-	} pi_cpu_present_b_fld_s;
-} pi_cpu_present_b_u_t;
-
-#else
-
-typedef union pi_cpu_present_b_u {
-	bdrkreg_t	pi_cpu_present_b_regval;
-	struct	{
-		bdrkreg_t	cpb_rsvd		  :	63;
-		bdrkreg_t	cpb_cpu_present		  :	 1;
-	} pi_cpu_present_b_fld_s;
-} pi_cpu_present_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There is one of these registers for each CPU. This     *
- * Read/Write location determines whether the associated CPU is         *
- * enabled to issue external requests. When this bit is zero for a      *
- * processor, the PI ignores SysReq_L from that processor, and so       *
- * never grants it the bus.                                             *
- * This register is not reset by a soft reset.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_cpu_enable_a_u {
-	bdrkreg_t	pi_cpu_enable_a_regval;
-	struct  {
-		bdrkreg_t	cea_cpu_enable            :	 1;
-		bdrkreg_t       cea_rsvd                  :     63;
-	} pi_cpu_enable_a_fld_s;
-} pi_cpu_enable_a_u_t;
-
-#else
-
-typedef union pi_cpu_enable_a_u {
-	bdrkreg_t	pi_cpu_enable_a_regval;
-	struct	{
-		bdrkreg_t	cea_rsvd		  :	63;
-		bdrkreg_t	cea_cpu_enable		  :	 1;
-	} pi_cpu_enable_a_fld_s;
-} pi_cpu_enable_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There is one of these registers for each CPU. This     *
- * Read/Write location determines whether the associated CPU is         *
- * enabled to issue external requests. When this bit is zero for a      *
- * processor, the PI ignores SysReq_L from that processor, and so       *
- * never grants it the bus.                                             *
- * This register is not reset by a soft reset.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_cpu_enable_b_u {
-	bdrkreg_t	pi_cpu_enable_b_regval;
-	struct  {
-		bdrkreg_t	ceb_cpu_enable            :	 1;
-		bdrkreg_t       ceb_rsvd                  :     63;
-	} pi_cpu_enable_b_fld_s;
-} pi_cpu_enable_b_u_t;
-
-#else
-
-typedef union pi_cpu_enable_b_u {
-	bdrkreg_t	pi_cpu_enable_b_regval;
-	struct	{
-		bdrkreg_t	ceb_rsvd		  :	63;
-		bdrkreg_t	ceb_cpu_enable		  :	 1;
-	} pi_cpu_enable_b_fld_s;
-} pi_cpu_enable_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. A write to this       *
- * location will cause an NMI to be issued to the CPU.                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_nmi_a_u {
-	bdrkreg_t	pi_nmi_a_regval;
-	struct  {
-		bdrkreg_t	na_nmi_cpu                :	64;
-	} pi_nmi_a_fld_s;
-} pi_nmi_a_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. A write to this       *
- * location will cause an NMI to be issued to the CPU.                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_nmi_b_u {
-	bdrkreg_t	pi_nmi_b_regval;
-	struct  {
-		bdrkreg_t	nb_nmi_cpu                :	64;
-	} pi_nmi_b_fld_s;
-} pi_nmi_b_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  A write to this register allows a single bit in the INT_PEND0 or    *
- * INT_PEND1 registers to be set or cleared. If 6 is clear, a bit is    *
- * modified in INT_PEND0, while if 6 is set, a bit is modified in       *
- * INT_PEND1. The value in 5:0 (ranging from 63 to 0) will determine    *
- * which bit in the register is effected. The value of 8 will           *
- * determine whether the desired bit is set (8=1) or cleared (8=0).     *
- * This is the only register which is accessible by IO issued PWRI      *
- * command and is protected through the IO_PROTECT register. If the     *
- * region bit in the IO_PROTECT is not set then a WERR reply is         *
- * issued. CPU access is controlled through CPU_PROTECT. The contents   *
- * of this register are masked with the contents of INT_MASK_A          *
- * (INT_MASK_B) to determine whether an L2 interrupt is issued to       *
- * CPU_A (CPU_B).                                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_int_pend_mod_u {
-	bdrkreg_t	pi_int_pend_mod_regval;
-	struct  {
-		bdrkreg_t	ipm_bit_select            :	 6;
-                bdrkreg_t       ipm_reg_select            :      1;
-                bdrkreg_t       ipm_rsvd_1                :      1;
-                bdrkreg_t       ipm_value                 :      1;
-                bdrkreg_t       ipm_rsvd                  :     55;
-	} pi_int_pend_mod_fld_s;
-} pi_int_pend_mod_u_t;
-
-#else
-
-typedef union pi_int_pend_mod_u {
-	bdrkreg_t	pi_int_pend_mod_regval;
-	struct	{
-		bdrkreg_t	ipm_rsvd		  :	55;
-		bdrkreg_t	ipm_value		  :	 1;
-		bdrkreg_t	ipm_rsvd_1		  :	 1;
-		bdrkreg_t	ipm_reg_select		  :	 1;
-		bdrkreg_t	ipm_bit_select		  :	 6;
-	} pi_int_pend_mod_fld_s;
-} pi_int_pend_mod_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This read-only register provides information about interrupts       *
- * that are currently pending. The interrupts in this register map to   *
- * interrupt level 2 (L2). The GFX_INT_A/B bits are set by hardware     *
- * but must be cleared by software.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_int_pend0_u {
-	bdrkreg_t	pi_int_pend0_regval;
-	struct  {
-		bdrkreg_t	ip_int_pend0_lo           :	 1;
-                bdrkreg_t       ip_gfx_int_a              :      1;
-                bdrkreg_t       ip_gfx_int_b              :      1;
-                bdrkreg_t       ip_page_migration         :      1;
-                bdrkreg_t       ip_uart_ucntrl            :      1;
-                bdrkreg_t       ip_or_cc_pend_a           :      1;
-                bdrkreg_t       ip_or_cc_pend_b           :      1;
-                bdrkreg_t       ip_int_pend0_hi           :     57;
-	} pi_int_pend0_fld_s;
-} pi_int_pend0_u_t;
-
-#else
-
-typedef union pi_int_pend0_u {
-	bdrkreg_t	pi_int_pend0_regval;
-	struct	{
-		bdrkreg_t	ip_int_pend0_hi		  :	57;
-		bdrkreg_t	ip_or_cc_pend_b		  :	 1;
-		bdrkreg_t	ip_or_cc_pend_a		  :	 1;
-		bdrkreg_t	ip_uart_ucntrl		  :	 1;
-		bdrkreg_t	ip_page_migration	  :	 1;
-		bdrkreg_t	ip_gfx_int_b		  :	 1;
-		bdrkreg_t	ip_gfx_int_a		  :	 1;
-		bdrkreg_t	ip_int_pend0_lo		  :	 1;
-	} pi_int_pend0_fld_s;
-} pi_int_pend0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This read-only register provides information about interrupts       *
- * that are currently pending. The interrupts in this register map to   *
- * interrupt level 3 (L3), unless remapped by the INT_PEND1_REMAP       *
- * register. The SYS_COR_ERR_A/B, RTC_DROP_OUT, and NACK_INT_A/B bits   *
- * are set by hardware but must be cleared by software. The             *
- * SYSTEM_SHUTDOWN, NI_ERROR, LB_ERROR and XB_ERROR bits just reflect   *
- * the value of other logic, and cannot be changed by PI register       *
- * writes.                                                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_int_pend1_u {
-	bdrkreg_t	pi_int_pend1_regval;
-	struct  {
-		bdrkreg_t	ip_int_pend1              :	54;
-                bdrkreg_t       ip_xb_error               :      1;
-                bdrkreg_t       ip_lb_error               :      1;
-                bdrkreg_t       ip_nack_int_a             :      1;
-                bdrkreg_t       ip_nack_int_b             :      1;
-                bdrkreg_t       ip_perf_cntr_oflow        :      1;
-                bdrkreg_t       ip_sys_cor_err_b          :      1;
-                bdrkreg_t       ip_sys_cor_err_a          :      1;
-                bdrkreg_t       ip_md_corr_error          :      1;
-                bdrkreg_t       ip_ni_error               :      1;
-                bdrkreg_t       ip_system_shutdown        :      1;
-	} pi_int_pend1_fld_s;
-} pi_int_pend1_u_t;
-
-#else
-
-typedef union pi_int_pend1_u {
-	bdrkreg_t	pi_int_pend1_regval;
-	struct	{
-		bdrkreg_t	ip_system_shutdown	  :	 1;
-		bdrkreg_t	ip_ni_error		  :	 1;
-		bdrkreg_t	ip_md_corr_error	  :	 1;
-		bdrkreg_t	ip_sys_cor_err_a	  :	 1;
-		bdrkreg_t	ip_sys_cor_err_b	  :	 1;
-		bdrkreg_t	ip_perf_cntr_oflow	  :	 1;
-		bdrkreg_t	ip_nack_int_b		  :	 1;
-		bdrkreg_t	ip_nack_int_a		  :	 1;
-		bdrkreg_t	ip_lb_error		  :	 1;
-		bdrkreg_t	ip_xb_error		  :	 1;
-		bdrkreg_t	ip_int_pend1		  :	54;
-	} pi_int_pend1_fld_s;
-} pi_int_pend1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This read/write register masks the contents of INT_PEND0 to         *
- * determine whether an L2 interrupt (bit 10 of the processor's Cause   *
- * register) is sent to CPU_A if the same bit in the INT_PEND0          *
- * register is also set. Only one processor in a Bedrock should         *
- * enable the PAGE_MIGRATION bit/interrupt.                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_int_mask0_a_u {
-	bdrkreg_t	pi_int_mask0_a_regval;
-	struct  {
-		bdrkreg_t	ima_int_mask0_lo          :	 1;
-                bdrkreg_t       ima_gfx_int_a             :      1;
-                bdrkreg_t       ima_gfx_int_b             :      1;
-                bdrkreg_t       ima_page_migration        :      1;
-                bdrkreg_t       ima_uart_ucntrl           :      1;
-                bdrkreg_t       ima_or_ccp_mask_a         :      1;
-                bdrkreg_t       ima_or_ccp_mask_b         :      1;
-                bdrkreg_t       ima_int_mask0_hi          :     57;
-	} pi_int_mask0_a_fld_s;
-} pi_int_mask0_a_u_t;
-
-#else
-
-typedef union pi_int_mask0_a_u {
-	bdrkreg_t	pi_int_mask0_a_regval;
-	struct	{
-		bdrkreg_t	ima_int_mask0_hi	  :	57;
-		bdrkreg_t	ima_or_ccp_mask_b	  :	 1;
-		bdrkreg_t	ima_or_ccp_mask_a	  :	 1;
-		bdrkreg_t	ima_uart_ucntrl		  :	 1;
-		bdrkreg_t	ima_page_migration	  :	 1;
-		bdrkreg_t	ima_gfx_int_b		  :	 1;
-		bdrkreg_t	ima_gfx_int_a		  :	 1;
-		bdrkreg_t	ima_int_mask0_lo	  :	 1;
-	} pi_int_mask0_a_fld_s;
-} pi_int_mask0_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This read/write register masks the contents of INT_PEND1 to         *
- * determine whether an interrupt should be sent. Bits 63:32 always     *
- * generate an L3 interrupt (bit 11 of the processor's Cause            *
- * register) is sent to CPU_A if the same bit in the INT_PEND1          *
- * register is set. Bits 31:0 can generate either an L3 or L2           *
- * interrupt, depending on the value of INT_PEND1_REMAP[3:0]. Only      *
- * one processor in a Bedrock should enable the NI_ERROR, LB_ERROR,     *
- * XB_ERROR and MD_CORR_ERROR bits.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_int_mask1_a_u {
-	bdrkreg_t	pi_int_mask1_a_regval;
-	struct  {
-		bdrkreg_t	ima_int_mask1             :	64;
-	} pi_int_mask1_a_fld_s;
-} pi_int_mask1_a_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This read/write register masks the contents of INT_PEND0 to         *
- * determine whether an L2 interrupt (bit 10 of the processor's Cause   *
- * register) is sent to CPU_B if the same bit in the INT_PEND0          *
- * register is also set. Only one processor in a Bedrock should         *
- * enable the PAGE_MIGRATION bit/interrupt.                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_int_mask0_b_u {
-	bdrkreg_t	pi_int_mask0_b_regval;
-	struct  {
-		bdrkreg_t	imb_int_mask0_lo          :	 1;
-                bdrkreg_t       imb_gfx_int_a             :      1;
-                bdrkreg_t       imb_gfx_int_b             :      1;
-                bdrkreg_t       imb_page_migration        :      1;
-                bdrkreg_t       imb_uart_ucntrl           :      1;
-                bdrkreg_t       imb_or_ccp_mask_a         :      1;
-                bdrkreg_t       imb_or_ccp_mask_b         :      1;
-                bdrkreg_t       imb_int_mask0_hi          :     57;
-	} pi_int_mask0_b_fld_s;
-} pi_int_mask0_b_u_t;
-
-#else
-
-typedef union pi_int_mask0_b_u {
-	bdrkreg_t	pi_int_mask0_b_regval;
-	struct	{
-		bdrkreg_t	imb_int_mask0_hi	  :	57;
-		bdrkreg_t	imb_or_ccp_mask_b	  :	 1;
-		bdrkreg_t	imb_or_ccp_mask_a	  :	 1;
-		bdrkreg_t	imb_uart_ucntrl		  :	 1;
-		bdrkreg_t	imb_page_migration	  :	 1;
-		bdrkreg_t	imb_gfx_int_b		  :	 1;
-		bdrkreg_t	imb_gfx_int_a		  :	 1;
-		bdrkreg_t	imb_int_mask0_lo	  :	 1;
-	} pi_int_mask0_b_fld_s;
-} pi_int_mask0_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This read/write register masks the contents of INT_PEND1 to         *
- * determine whether an interrupt should be sent. Bits 63:32 always     *
- * generate an L3 interrupt (bit 11 of the processor's Cause            *
- * register) is sent to CPU_B if the same bit in the INT_PEND1          *
- * register is set. Bits 31:0 can generate either an L3 or L2           *
- * interrupt, depending on the value of INT_PEND1_REMAP[3:0]. Only      *
- * one processor in a Bedrock should enable the NI_ERROR, LB_ERROR,     *
- * XB_ERROR and MD_CORR_ERROR bits.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_int_mask1_b_u {
-	bdrkreg_t	pi_int_mask1_b_regval;
-	struct  {
-		bdrkreg_t	imb_int_mask1             :	64;
-	} pi_int_mask1_b_fld_s;
-} pi_int_mask1_b_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. These registers do    *
- * not have access protection. A store to this location by a CPU will   *
- * cause the bit corresponding to the source's region to be set in      *
- * CC_PEND_A (or CC_PEND_B). The contents of CC_PEND_A (or CC_PEND_B)   *
- * determines on a bit-per-region basis whether a CPU-to-CPU            *
- * interrupt is pending CPU_A (or CPU_B).                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_cc_pend_set_a_u {
-	bdrkreg_t	pi_cc_pend_set_a_regval;
-	struct  {
-		bdrkreg_t	cpsa_cc_pend              :	64;
-	} pi_cc_pend_set_a_fld_s;
-} pi_cc_pend_set_a_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. These registers do    *
- * not have access protection. A store to this location by a CPU will   *
- * cause the bit corresponding to the source's region to be set in      *
- * CC_PEND_A (or CC_PEND_B). The contents of CC_PEND_A (or CC_PEND_B)   *
- * determines on a bit-per-region basis whether a CPU-to-CPU            *
- * interrupt is pending CPU_A (or CPU_B).                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_cc_pend_set_b_u {
-	bdrkreg_t	pi_cc_pend_set_b_regval;
-	struct  {
-		bdrkreg_t	cpsb_cc_pend              :	64;
-	} pi_cc_pend_set_b_fld_s;
-} pi_cc_pend_set_b_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. Reading this          *
- * location will return the contents of CC_PEND_A (or CC_PEND_B).       *
- * Writing this location will clear the bits corresponding to which     *
- * data bits are driven high during the store; therefore, storing all   *
- * ones would clear all bits.                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_cc_pend_clr_a_u {
-	bdrkreg_t	pi_cc_pend_clr_a_regval;
-	struct  {
-		bdrkreg_t	cpca_cc_pend              :	64;
-	} pi_cc_pend_clr_a_fld_s;
-} pi_cc_pend_clr_a_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. Reading this          *
- * location will return the contents of CC_PEND_A (or CC_PEND_B).       *
- * Writing this location will clear the bits corresponding to which     *
- * data bits are driven high during the store; therefore, storing all   *
- * ones would clear all bits.                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_cc_pend_clr_b_u {
-	bdrkreg_t	pi_cc_pend_clr_b_regval;
-	struct  {
-		bdrkreg_t	cpcb_cc_pend              :	64;
-	} pi_cc_pend_clr_b_fld_s;
-} pi_cc_pend_clr_b_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This read/write register masks the contents of both CC_PEND_A and   *
- * CC_PEND_B.                                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-typedef union pi_cc_mask_u {
-	bdrkreg_t	pi_cc_mask_regval;
-	struct  {
-		bdrkreg_t	cm_cc_mask                :	64;
-	} pi_cc_mask_fld_s;
-} pi_cc_mask_u_t;
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This read/write register redirects INT_PEND1[31:0] from L3 to L2    *
- * interrupt level.Bit 4 in this register is used to enable error       *
- * interrupt forwarding to the II. When this bit is set, if any of      *
- * the three memory interrupts (correctable error, uncorrectable        *
- * error, or page migration), or the NI, LB or XB error interrupts      *
- * are set, the PI_II_ERROR_INT wire will be asserted. When this wire   *
- * is asserted, the II will send an interrupt to the node specified     *
- * in its IIDSR (Interrupt Destination Register). This allows these     *
- * interrupts to be forwarded to another node.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_int_pend1_remap_u {
-	bdrkreg_t	pi_int_pend1_remap_regval;
-	struct  {
-		bdrkreg_t	ipr_remap_0               :	 1;
-                bdrkreg_t       ipr_remap_1               :      1;
-                bdrkreg_t       ipr_remap_2               :      1;
-                bdrkreg_t       ipr_remap_3               :      1;
-                bdrkreg_t       ipr_error_forward         :      1;
-                bdrkreg_t       ipr_reserved              :     59;
-	} pi_int_pend1_remap_fld_s;
-} pi_int_pend1_remap_u_t;
-
-#else
-
-typedef union pi_int_pend1_remap_u {
-	bdrkreg_t	pi_int_pend1_remap_regval;
-	struct	{
-		bdrkreg_t	ipr_reserved		  :	59;
-		bdrkreg_t	ipr_error_forward	  :	 1;
-		bdrkreg_t	ipr_remap_3		  :	 1;
-		bdrkreg_t	ipr_remap_2		  :	 1;
-		bdrkreg_t	ipr_remap_1		  :	 1;
-		bdrkreg_t	ipr_remap_0		  :	 1;
-	} pi_int_pend1_remap_fld_s;
-} pi_int_pend1_remap_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. When the real time    *
- * counter (RT_Counter) is equal to the value in this register, the     *
- * RT_INT_PEND register is set, which causes a Level-4 interrupt to     *
- * be sent to the processor.                                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_rt_compare_a_u {
-	bdrkreg_t	pi_rt_compare_a_regval;
-	struct  {
-		bdrkreg_t	rca_rt_compare            :	55;
-		bdrkreg_t       rca_rsvd                  :      9;
-	} pi_rt_compare_a_fld_s;
-} pi_rt_compare_a_u_t;
-
-#else
-
-typedef union pi_rt_compare_a_u {
-        bdrkreg_t       pi_rt_compare_a_regval;
-        struct  {
-                bdrkreg_t       rca_rsvd                  :      9;
-                bdrkreg_t       rca_rt_compare            :     55;
-        } pi_rt_compare_a_fld_s;
-} pi_rt_compare_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. When the real time    *
- * counter (RT_Counter) is equal to the value in this register, the     *
- * RT_INT_PEND register is set, which causes a Level-4 interrupt to     *
- * be sent to the processor.                                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_rt_compare_b_u {
-	bdrkreg_t	pi_rt_compare_b_regval;
-	struct  {
-		bdrkreg_t	rcb_rt_compare            :	55;
-		bdrkreg_t       rcb_rsvd                  :      9;
-	} pi_rt_compare_b_fld_s;
-} pi_rt_compare_b_u_t;
-
-#else
-
-typedef union pi_rt_compare_b_u {
-	bdrkreg_t	pi_rt_compare_b_regval;
-	struct	{
-		bdrkreg_t	rcb_rsvd		  :	 9;
-		bdrkreg_t	rcb_rt_compare		  :	55;
-	} pi_rt_compare_b_fld_s;
-} pi_rt_compare_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  When the least significant 32 bits of the real time counter         *
- * (RT_Counter) are equal to the value in this register, the            *
- * PROF_INT_PEND_A and PROF_INT_PEND_B registers are set to 0x1.        *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_profile_compare_u {
-	bdrkreg_t	pi_profile_compare_regval;
-	struct  {
-		bdrkreg_t	pc_profile_compare        :	32;
-		bdrkreg_t       pc_rsvd                   :     32;
-	} pi_profile_compare_fld_s;
-} pi_profile_compare_u_t;
-
-#else
-
-typedef union pi_profile_compare_u {
-	bdrkreg_t	pi_profile_compare_regval;
-	struct	{
-		bdrkreg_t	pc_rsvd			  :	32;
-		bdrkreg_t	pc_profile_compare	  :	32;
-	} pi_profile_compare_fld_s;
-} pi_profile_compare_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. If the bit in the     *
- * corresponding RT_INT_EN_A/B register is set, the processor's level   *
- * 5 interrupt is set to the value of the RTC_INT_PEND bit in this      *
- * register. Storing any value to this location will clear the          *
- * RTC_INT_PEND bit in the register.                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_rt_int_pend_a_u {
-	bdrkreg_t	pi_rt_int_pend_a_regval;
-	struct  {
-		bdrkreg_t	ripa_rtc_int_pend         :	 1;
-		bdrkreg_t       ripa_rsvd                 :     63;
-	} pi_rt_int_pend_a_fld_s;
-} pi_rt_int_pend_a_u_t;
-
-#else
-
-typedef union pi_rt_int_pend_a_u {
-	bdrkreg_t	pi_rt_int_pend_a_regval;
-	struct	{
-		bdrkreg_t	ripa_rsvd		  :	63;
-		bdrkreg_t	ripa_rtc_int_pend	  :	 1;
-	} pi_rt_int_pend_a_fld_s;
-} pi_rt_int_pend_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. If the bit in the     *
- * corresponding RT_INT_EN_A/B register is set, the processor's level   *
- * 5 interrupt is set to the value of the RTC_INT_PEND bit in this      *
- * register. Storing any value to this location will clear the          *
- * RTC_INT_PEND bit in the register.                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_rt_int_pend_b_u {
-	bdrkreg_t	pi_rt_int_pend_b_regval;
-	struct  {
-		bdrkreg_t	ripb_rtc_int_pend         :	 1;
-		bdrkreg_t       ripb_rsvd                 :     63;
-	} pi_rt_int_pend_b_fld_s;
-} pi_rt_int_pend_b_u_t;
-
-#else
-
-typedef union pi_rt_int_pend_b_u {
-	bdrkreg_t	pi_rt_int_pend_b_regval;
-	struct	{
-		bdrkreg_t	ripb_rsvd		  :	63;
-		bdrkreg_t	ripb_rtc_int_pend	  :	 1;
-	} pi_rt_int_pend_b_fld_s;
-} pi_rt_int_pend_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. Both registers are    *
- * set when the PROFILE_COMPARE register is equal to bits [31:0] of     *
- * the RT_Counter. If the bit in the corresponding PROF_INT_EN_A/B      *
- * register is set, the processor's level 5 interrupt is set to the     *
- * value of the PROF_INT_PEND bit in this register. Storing any value   *
- * to this location will clear the PROF_INT_PEND bit in the register.   *
- * The reason for having A and B versions of this register is that      *
- * they need to be cleared independently.                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_prof_int_pend_a_u {
-	bdrkreg_t	pi_prof_int_pend_a_regval;
-	struct  {
-		bdrkreg_t	pipa_prof_int_pend        :	 1;
-		bdrkreg_t       pipa_rsvd                 :     63;
-	} pi_prof_int_pend_a_fld_s;
-} pi_prof_int_pend_a_u_t;
-
-#else
-
-typedef union pi_prof_int_pend_a_u {
-	bdrkreg_t	pi_prof_int_pend_a_regval;
-	struct	{
-		bdrkreg_t	pipa_rsvd		  :	63;
-		bdrkreg_t	pipa_prof_int_pend	  :	 1;
-	} pi_prof_int_pend_a_fld_s;
-} pi_prof_int_pend_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. Both registers are    *
- * set when the PROFILE_COMPARE register is equal to bits [31:0] of     *
- * the RT_Counter. If the bit in the corresponding PROF_INT_EN_A/B      *
- * register is set, the processor's level 5 interrupt is set to the     *
- * value of the PROF_INT_PEND bit in this register. Storing any value   *
- * to this location will clear the PROF_INT_PEND bit in the register.   *
- * The reason for having A and B versions of this register is that      *
- * they need to be cleared independently.                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_prof_int_pend_b_u {
-	bdrkreg_t	pi_prof_int_pend_b_regval;
-	struct  {
-		bdrkreg_t	pipb_prof_int_pend        :	 1;
-		bdrkreg_t       pipb_rsvd                 :     63;
-	} pi_prof_int_pend_b_fld_s;
-} pi_prof_int_pend_b_u_t;
-
-#else
-
-typedef union pi_prof_int_pend_b_u {
-	bdrkreg_t	pi_prof_int_pend_b_regval;
-	struct	{
-		bdrkreg_t	pipb_rsvd		  :	63;
-		bdrkreg_t	pipb_prof_int_pend	  :	 1;
-	} pi_prof_int_pend_b_fld_s;
-} pi_prof_int_pend_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. Enables RTC           *
- * interrupt to the associated CPU.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_rt_int_en_a_u {
-	bdrkreg_t	pi_rt_int_en_a_regval;
-	struct  {
-		bdrkreg_t	riea_rtc_int_en           :	 1;
-		bdrkreg_t       riea_rsvd                 :     63;
-	} pi_rt_int_en_a_fld_s;
-} pi_rt_int_en_a_u_t;
-
-#else
-
-typedef union pi_rt_int_en_a_u {
-        bdrkreg_t       pi_rt_int_en_a_regval;
-        struct  {
-                bdrkreg_t       riea_rsvd                 :     63;
-                bdrkreg_t       riea_rtc_int_en           :      1;
-        } pi_rt_int_en_a_fld_s;
-} pi_rt_int_en_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. Enables RTC           *
- * interrupt to the associated CPU.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_rt_int_en_b_u {
-	bdrkreg_t	pi_rt_int_en_b_regval;
-	struct  {
-		bdrkreg_t	rieb_rtc_int_en           :	 1;
-		bdrkreg_t       rieb_rsvd                 :     63;
-	} pi_rt_int_en_b_fld_s;
-} pi_rt_int_en_b_u_t;
-
-#else
-
-typedef union pi_rt_int_en_b_u {
-        bdrkreg_t       pi_rt_int_en_b_regval;
-        struct  {
-                bdrkreg_t       rieb_rsvd                 :     63;
-                bdrkreg_t       rieb_rtc_int_en           :      1;
-        } pi_rt_int_en_b_fld_s;
-} pi_rt_int_en_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. Enables profiling     *
- * interrupt to the associated CPU.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_prof_int_en_a_u {
-	bdrkreg_t	pi_prof_int_en_a_regval;
-	struct  {
-		bdrkreg_t	piea_prof_int_en          :	 1;
-		bdrkreg_t       piea_rsvd                 :     63;
-	} pi_prof_int_en_a_fld_s;
-} pi_prof_int_en_a_u_t;
-
-#else
-
-typedef union pi_prof_int_en_a_u {
-	bdrkreg_t	pi_prof_int_en_a_regval;
-	struct	{
-		bdrkreg_t	piea_rsvd		  :	63;
-		bdrkreg_t	piea_prof_int_en	  :	 1;
-	} pi_prof_int_en_a_fld_s;
-} pi_prof_int_en_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. Enables profiling     *
- * interrupt to the associated CPU.                                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_prof_int_en_b_u {
-	bdrkreg_t	pi_prof_int_en_b_regval;
-	struct  {
-		bdrkreg_t	pieb_prof_int_en          :	 1;
-		bdrkreg_t       pieb_rsvd                 :     63;
-	} pi_prof_int_en_b_fld_s;
-} pi_prof_int_en_b_u_t;
-
-#else
-
-typedef union pi_prof_int_en_b_u {
-	bdrkreg_t	pi_prof_int_en_b_regval;
-	struct	{
-		bdrkreg_t	pieb_rsvd		  :	63;
-		bdrkreg_t	pieb_prof_int_en	  :	 1;
-	} pi_prof_int_en_b_fld_s;
-} pi_prof_int_en_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register controls operation of the debug data from the PI,     *
- * along with Debug_Sel[2:0] from the Debug module. For some values     *
- * of Debug_Sel[2:0], the B_SEL bit selects whether the debug bits      *
- * are looking at the processor A or processor B logic. The remaining   *
- * bits select which signal(s) are ORed to create DebugData bits 31     *
- * and 30 for all of the PI debug selections.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_debug_sel_u {
-	bdrkreg_t	pi_debug_sel_regval;
-	struct  {
-		bdrkreg_t	ds_low_t5cc_a             :	 1;
-                bdrkreg_t       ds_low_t5cc_b             :      1;
-                bdrkreg_t       ds_low_totcc_a            :      1;
-                bdrkreg_t       ds_low_totcc_b            :      1;
-                bdrkreg_t       ds_low_reqcc_a            :      1;
-                bdrkreg_t       ds_low_reqcc_b            :      1;
-                bdrkreg_t       ds_low_rplcc_a            :      1;
-                bdrkreg_t       ds_low_rplcc_b            :      1;
-                bdrkreg_t       ds_low_intcc              :      1;
-                bdrkreg_t       ds_low_perf_inc_a_0       :      1;
-                bdrkreg_t       ds_low_perf_inc_a_1       :      1;
-                bdrkreg_t       ds_low_perf_inc_b_0       :      1;
-                bdrkreg_t       ds_low_perf_inc_b_1       :      1;
-                bdrkreg_t       ds_high_t5cc_a            :      1;
-                bdrkreg_t       ds_high_t5cc_b            :      1;
-                bdrkreg_t       ds_high_totcc_a           :      1;
-                bdrkreg_t       ds_high_totcc_b           :      1;
-                bdrkreg_t       ds_high_reqcc_a           :      1;
-                bdrkreg_t       ds_high_reqcc_b           :      1;
-                bdrkreg_t       ds_high_rplcc_a           :      1;
-                bdrkreg_t       ds_high_rplcc_b           :      1;
-                bdrkreg_t       ds_high_intcc             :      1;
-                bdrkreg_t       ds_high_perf_inc_a_0      :      1;
-                bdrkreg_t       ds_high_perf_inc_a_1      :      1;
-                bdrkreg_t       ds_high_perf_inc_b_0      :      1;
-                bdrkreg_t       ds_high_perf_inc_b_1      :      1;
-                bdrkreg_t       ds_b_sel                  :      1;
-                bdrkreg_t       ds_rsvd                   :     37;
-	} pi_debug_sel_fld_s;
-} pi_debug_sel_u_t;
-
-#else
-
-typedef union pi_debug_sel_u {
-	bdrkreg_t	pi_debug_sel_regval;
-	struct	{
-		bdrkreg_t	ds_rsvd			  :	37;
-		bdrkreg_t	ds_b_sel		  :	 1;
-		bdrkreg_t	ds_high_perf_inc_b_1	  :	 1;
-		bdrkreg_t	ds_high_perf_inc_b_0	  :	 1;
-		bdrkreg_t	ds_high_perf_inc_a_1	  :	 1;
-		bdrkreg_t	ds_high_perf_inc_a_0	  :	 1;
-		bdrkreg_t	ds_high_intcc		  :	 1;
-		bdrkreg_t	ds_high_rplcc_b		  :	 1;
-		bdrkreg_t	ds_high_rplcc_a		  :	 1;
-		bdrkreg_t	ds_high_reqcc_b		  :	 1;
-		bdrkreg_t	ds_high_reqcc_a		  :	 1;
-		bdrkreg_t	ds_high_totcc_b		  :	 1;
-		bdrkreg_t	ds_high_totcc_a		  :	 1;
-		bdrkreg_t	ds_high_t5cc_b		  :	 1;
-		bdrkreg_t	ds_high_t5cc_a		  :	 1;
-		bdrkreg_t	ds_low_perf_inc_b_1	  :	 1;
-		bdrkreg_t	ds_low_perf_inc_b_0	  :	 1;
-		bdrkreg_t	ds_low_perf_inc_a_1	  :	 1;
-		bdrkreg_t	ds_low_perf_inc_a_0	  :	 1;
-		bdrkreg_t	ds_low_intcc		  :	 1;
-		bdrkreg_t	ds_low_rplcc_b		  :	 1;
-		bdrkreg_t	ds_low_rplcc_a		  :	 1;
-		bdrkreg_t	ds_low_reqcc_b		  :	 1;
-		bdrkreg_t	ds_low_reqcc_a		  :	 1;
-		bdrkreg_t	ds_low_totcc_b		  :	 1;
-		bdrkreg_t	ds_low_totcc_a		  :	 1;
-		bdrkreg_t	ds_low_t5cc_b		  :	 1;
-		bdrkreg_t	ds_low_t5cc_a		  :	 1;
-	} pi_debug_sel_fld_s;
-} pi_debug_sel_u_t;
-
-#endif
-
-
-/************************************************************************
- *                                                                      *
- *  A write to this register allows a single bit in the INT_PEND0 or    *
- * INT_PEND1 registers to be set or cleared. If 6 is clear, a bit is    *
- * modified in INT_PEND0, while if 6 is set, a bit is modified in       *
- * INT_PEND1. The value in 5:0 (ranging from 63 to 0) will determine    *
- * which bit in the register is effected. The value of 8 will           *
- * determine whether the desired bit is set (8=1) or cleared (8=0).     *
- * This is the only register which is accessible by IO issued PWRI      *
- * command and is protected through the IO_PROTECT register. If the     *
- * region bit in the IO_PROTECT is not set then a WERR reply is         *
- * issued. CPU access is controlled through CPU_PROTECT. The contents   *
- * of this register are masked with the contents of INT_MASK_A          *
- * (INT_MASK_B) to determine whether an L2 interrupt is issued to       *
- * CPU_A (CPU_B).                                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_int_pend_mod_alias_u {
-	bdrkreg_t	pi_int_pend_mod_alias_regval;
-	struct  {
-		bdrkreg_t	ipma_bit_select           :	 6;
-                bdrkreg_t       ipma_reg_select           :      1;
-                bdrkreg_t       ipma_rsvd_1               :      1;
-                bdrkreg_t       ipma_value                :      1;
-                bdrkreg_t       ipma_rsvd                 :     55;
-	} pi_int_pend_mod_alias_fld_s;
-} pi_int_pend_mod_alias_u_t;
-
-#else
-
-typedef union pi_int_pend_mod_alias_u {
-	bdrkreg_t	pi_int_pend_mod_alias_regval;
-	struct	{
-		bdrkreg_t	ipma_rsvd		  :	55;
-		bdrkreg_t	ipma_value		  :	 1;
-		bdrkreg_t	ipma_rsvd_1		  :	 1;
-		bdrkreg_t	ipma_reg_select		  :	 1;
-		bdrkreg_t	ipma_bit_select		  :	 6;
-	} pi_int_pend_mod_alias_fld_s;
-} pi_int_pend_mod_alias_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. This register         *
- * specifies the value of the Graphics Page. Uncached writes into the   *
- * Graphics Page (with uncached attribute of IO) are done with GFXWS    *
- * commands rather than the normal PWRI commands. GFXWS commands are    *
- * tracked with the graphics credit counters.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_page_a_u {
-	bdrkreg_t	pi_gfx_page_a_regval;
-	struct  {
-		bdrkreg_t	gpa_rsvd_1                :	17;
-                bdrkreg_t       gpa_gfx_page_addr         :     23;
-                bdrkreg_t       gpa_en_gfx_page           :      1;
-                bdrkreg_t       gpa_rsvd                  :     23;
-	} pi_gfx_page_a_fld_s;
-} pi_gfx_page_a_u_t;
-
-#else
-
-typedef union pi_gfx_page_a_u {
-	bdrkreg_t	pi_gfx_page_a_regval;
-	struct	{
-		bdrkreg_t	gpa_rsvd		  :	23;
-		bdrkreg_t	gpa_en_gfx_page		  :	 1;
-		bdrkreg_t	gpa_gfx_page_addr	  :	23;
-		bdrkreg_t	gpa_rsvd_1		  :	17;
-	} pi_gfx_page_a_fld_s;
-} pi_gfx_page_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. This register         *
- * counts graphics credits. This counter is decremented for each        *
- * doubleword sent to graphics with GFXWS or GFXWL commands. It is      *
- * incremented for each doubleword acknowledge from graphics. When      *
- * this counter has a smaller value than the GFX_BIAS register,         *
- * SysWrRdy_L is deasserted, an interrupt is sent to the processor,     *
- * and SysWrRdy_L is allowed to be asserted again. This is the basic    *
- * mechanism for flow-controlling graphics writes.                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_credit_cntr_a_u {
-	bdrkreg_t	pi_gfx_credit_cntr_a_regval;
-	struct  {
-		bdrkreg_t	gcca_gfx_credit_cntr      :	12;
-		bdrkreg_t       gcca_rsvd                 :     52;
-	} pi_gfx_credit_cntr_a_fld_s;
-} pi_gfx_credit_cntr_a_u_t;
-
-#else
-
-typedef union pi_gfx_credit_cntr_a_u {
-	bdrkreg_t	pi_gfx_credit_cntr_a_regval;
-	struct	{
-		bdrkreg_t	gcca_rsvd		  :	52;
-		bdrkreg_t	gcca_gfx_credit_cntr	  :	12;
-	} pi_gfx_credit_cntr_a_fld_s;
-} pi_gfx_credit_cntr_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. When the graphics     *
- * credit counter is less than or equal to this value, a flow control   *
- * interrupt is sent.                                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_bias_a_u {
-	bdrkreg_t	pi_gfx_bias_a_regval;
-	struct  {
-		bdrkreg_t	gba_gfx_bias              :	12;
-		bdrkreg_t       gba_rsvd                  :     52;
-	} pi_gfx_bias_a_fld_s;
-} pi_gfx_bias_a_u_t;
-
-#else
-
-typedef union pi_gfx_bias_a_u {
-	bdrkreg_t	pi_gfx_bias_a_regval;
-	struct	{
-		bdrkreg_t	gba_rsvd		  :	52;
-		bdrkreg_t	gba_gfx_bias		  :	12;
-	} pi_gfx_bias_a_fld_s;
-} pi_gfx_bias_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There is one of these registers for each CPU. When     *
- * this counter reaches the value of the GFX_INT_CMP register, an       *
- * interrupt is sent to the associated processor. At each clock         *
- * cycle, the value in this register can be changed by any one of the   *
- * following actions:                                                   *
- * - Written by software.                                               *
- * - Loaded with the value of GFX_INT_CMP, when an interrupt, NMI, or   *
- * soft reset occurs, thus preventing an additional interrupt.          *
- * - Zeroed, when the GFX_CREDIT_CNTR rises above the bias value.       *
- * - Incremented (by one at each clock) for each clock that the         *
- * GFX_CREDIT_CNTR is less than or equal to zero.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_int_cntr_a_u {
-	bdrkreg_t	pi_gfx_int_cntr_a_regval;
-	struct  {
-		bdrkreg_t	gica_gfx_int_cntr         :	26;
-		bdrkreg_t       gica_rsvd                 :     38;
-	} pi_gfx_int_cntr_a_fld_s;
-} pi_gfx_int_cntr_a_u_t;
-
-#else
-
-typedef union pi_gfx_int_cntr_a_u {
-	bdrkreg_t	pi_gfx_int_cntr_a_regval;
-	struct	{
-		bdrkreg_t	gica_rsvd		  :	38;
-		bdrkreg_t	gica_gfx_int_cntr	  :	26;
-	} pi_gfx_int_cntr_a_fld_s;
-} pi_gfx_int_cntr_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. The value in this     *
- * register is loaded into the GFX_INT_CNTR register when an            *
- * interrupt, NMI, or soft reset is sent to the processor. The value    *
- * in this register is compared to the value of GFX_INT_CNTR and an     *
- * interrupt is sent when they become equal.                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LINUX
-
-typedef union pi_gfx_int_cmp_a_u {
-	bdrkreg_t	pi_gfx_int_cmp_a_regval;
-	struct  {
-		bdrkreg_t	gica_gfx_int_cmp          :	26;
-		bdrkreg_t       gica_rsvd                 :     38;
-	} pi_gfx_int_cmp_a_fld_s;
-} pi_gfx_int_cmp_a_u_t;
-
-#else
-
-typedef union pi_gfx_int_cmp_a_u {
-	bdrkreg_t	pi_gfx_int_cmp_a_regval;
-	struct	{
-		bdrkreg_t	gica_rsvd		  :	38;
-		bdrkreg_t	gica_gfx_int_cmp	  :	26;
-	} pi_gfx_int_cmp_a_fld_s;
-} pi_gfx_int_cmp_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. This register         *
- * specifies the value of the Graphics Page. Uncached writes into the   *
- * Graphics Page (with uncached attribute of IO) are done with GFXWS    *
- * commands rather than the normal PWRI commands. GFXWS commands are    *
- * tracked with the graphics credit counters.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_page_b_u {
-	bdrkreg_t	pi_gfx_page_b_regval;
-	struct  {
-		bdrkreg_t	gpb_rsvd_1                :	17;
-                bdrkreg_t       gpb_gfx_page_addr         :     23;
-                bdrkreg_t       gpb_en_gfx_page           :      1;
-                bdrkreg_t       gpb_rsvd                  :     23;
-	} pi_gfx_page_b_fld_s;
-} pi_gfx_page_b_u_t;
-
-#else
-
-typedef union pi_gfx_page_b_u {
-	bdrkreg_t	pi_gfx_page_b_regval;
-	struct	{
-		bdrkreg_t	gpb_rsvd		  :	23;
-		bdrkreg_t	gpb_en_gfx_page		  :	 1;
-		bdrkreg_t	gpb_gfx_page_addr	  :	23;
-		bdrkreg_t	gpb_rsvd_1		  :	17;
-	} pi_gfx_page_b_fld_s;
-} pi_gfx_page_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. This register         *
- * counts graphics credits. This counter is decremented for each        *
- * doubleword sent to graphics with GFXWS or GFXWL commands. It is      *
- * incremented for each doubleword acknowledge from graphics. When      *
- * this counter has a smaller value than the GFX_BIAS register,         *
- * SysWrRdy_L is deasserted, an interrupt is sent to the processor,     *
- * and SysWrRdy_L is allowed to be asserted again. This is the basic    *
- * mechanism for flow-controlling graphics writes.                      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_credit_cntr_b_u {
-	bdrkreg_t	pi_gfx_credit_cntr_b_regval;
-	struct  {
-		bdrkreg_t	gccb_gfx_credit_cntr      :	12;
-		bdrkreg_t       gccb_rsvd                 :     52;
-	} pi_gfx_credit_cntr_b_fld_s;
-} pi_gfx_credit_cntr_b_u_t;
-
-#else
-
-typedef union pi_gfx_credit_cntr_b_u {
-	bdrkreg_t	pi_gfx_credit_cntr_b_regval;
-	struct	{
-		bdrkreg_t	gccb_rsvd		  :	52;
-		bdrkreg_t	gccb_gfx_credit_cntr	  :	12;
-	} pi_gfx_credit_cntr_b_fld_s;
-} pi_gfx_credit_cntr_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. When the graphics     *
- * credit counter is less than or equal to this value, a flow control   *
- * interrupt is sent.                                                   *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_bias_b_u {
-	bdrkreg_t	pi_gfx_bias_b_regval;
-	struct  {
-		bdrkreg_t	gbb_gfx_bias              :	12;
-		bdrkreg_t       gbb_rsvd                  :     52;
-	} pi_gfx_bias_b_fld_s;
-} pi_gfx_bias_b_u_t;
-
-#else
-
-typedef union pi_gfx_bias_b_u {
-	bdrkreg_t	pi_gfx_bias_b_regval;
-	struct	{
-		bdrkreg_t	gbb_rsvd		  :	52;
-		bdrkreg_t	gbb_gfx_bias		  :	12;
-	} pi_gfx_bias_b_fld_s;
-} pi_gfx_bias_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There is one of these registers for each CPU. When     *
- * this counter reaches the value of the GFX_INT_CMP register, an       *
- * interrupt is sent to the associated processor. At each clock         *
- * cycle, the value in this register can be changed by any one of the   *
- * following actions:                                                   *
- * - Written by software.                                               *
- * - Loaded with the value of GFX_INT_CMP, when an interrupt, NMI, or   *
- * soft reset occurs, thus preventing an additional interrupt.          *
- * - Zeroed, when the GFX_CREDIT_CNTR rises above the bias value.       *
- * - Incremented (by one at each clock) for each clock that the         *
- * GFX_CREDIT_CNTR is less than or equal to zero.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_int_cntr_b_u {
-	bdrkreg_t	pi_gfx_int_cntr_b_regval;
-	struct  {
-		bdrkreg_t	gicb_gfx_int_cntr         :	26;
-		bdrkreg_t       gicb_rsvd                 :     38;
-	} pi_gfx_int_cntr_b_fld_s;
-} pi_gfx_int_cntr_b_u_t;
-
-#else
-
-typedef union pi_gfx_int_cntr_b_u {
-	bdrkreg_t	pi_gfx_int_cntr_b_regval;
-	struct	{
-		bdrkreg_t	gicb_rsvd		  :	38;
-		bdrkreg_t	gicb_gfx_int_cntr	  :	26;
-	} pi_gfx_int_cntr_b_fld_s;
-} pi_gfx_int_cntr_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. The value in this     *
- * register is loaded into the GFX_INT_CNTR register when an            *
- * interrupt, NMI, or soft reset is sent to the processor. The value    *
- * in this register is compared to the value of GFX_INT_CNTR and an     *
- * interrupt is sent when they become equal.                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_int_cmp_b_u {
-	bdrkreg_t	pi_gfx_int_cmp_b_regval;
-	struct  {
-		bdrkreg_t	gicb_gfx_int_cmp          :	26;
-		bdrkreg_t       gicb_rsvd                 :     38;
-	} pi_gfx_int_cmp_b_fld_s;
-} pi_gfx_int_cmp_b_u_t;
-
-#else
-
-typedef union pi_gfx_int_cmp_b_u {
-	bdrkreg_t	pi_gfx_int_cmp_b_regval;
-	struct	{
-		bdrkreg_t	gicb_rsvd		  :	38;
-		bdrkreg_t	gicb_gfx_int_cmp	  :	26;
-	} pi_gfx_int_cmp_b_fld_s;
-} pi_gfx_int_cmp_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  A read of this register returns all sources of         *
- * Bedrock Error Interrupts. Storing to the write-with-clear location   *
- * clears any bit for which a one appears on the data bus. Storing to   *
- * the writable location does a direct write to all unreserved bits     *
- * (except for MEM_UNC).                                                *
- * In Synergy mode, the processor that is the source of the command     *
- * that got an error is independent of the A or B SysAD bus. So in      *
- * Synergy mode, Synergy provides the source processor number in bit    *
- * 52 of the SysAD bus in all commands. The PI saves this in the RRB    *
- * or WRB entry, and uses that value to determine which error bit (A    *
- * or B) to set, as well as which ERR_STATUS and spool registers to     *
- * use, for all error types in this register that are specified as an   *
- * error to CPU_A or CPU_B.                                             *
- * This register is not cleared at reset.                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_int_pend_wr_u {
-	bdrkreg_t	pi_err_int_pend_wr_regval;
-	struct  {
-		bdrkreg_t	eipw_spool_comp_b         :	 1;
-                bdrkreg_t       eipw_spool_comp_a         :      1;
-                bdrkreg_t       eipw_spurious_b           :      1;
-                bdrkreg_t       eipw_spurious_a           :      1;
-                bdrkreg_t       eipw_wrb_terr_b           :      1;
-                bdrkreg_t       eipw_wrb_terr_a           :      1;
-                bdrkreg_t       eipw_wrb_werr_b           :      1;
-                bdrkreg_t       eipw_wrb_werr_a           :      1;
-                bdrkreg_t       eipw_sysstate_par_b       :      1;
-                bdrkreg_t       eipw_sysstate_par_a       :      1;
-                bdrkreg_t       eipw_sysad_data_ecc_b     :      1;
-                bdrkreg_t       eipw_sysad_data_ecc_a     :      1;
-                bdrkreg_t       eipw_sysad_addr_ecc_b     :      1;
-                bdrkreg_t       eipw_sysad_addr_ecc_a     :      1;
-                bdrkreg_t       eipw_syscmd_data_par_b    :      1;
-                bdrkreg_t       eipw_syscmd_data_par_a    :      1;
-                bdrkreg_t       eipw_syscmd_addr_par_b    :      1;
-                bdrkreg_t       eipw_syscmd_addr_par_a    :      1;
-                bdrkreg_t       eipw_spool_err_b          :      1;
-                bdrkreg_t       eipw_spool_err_a          :      1;
-                bdrkreg_t       eipw_ue_uncached_b        :      1;
-                bdrkreg_t       eipw_ue_uncached_a        :      1;
-                bdrkreg_t       eipw_sysstate_tag_b       :      1;
-                bdrkreg_t       eipw_sysstate_tag_a       :      1;
-                bdrkreg_t       eipw_mem_unc              :      1;
-                bdrkreg_t       eipw_sysad_bad_data_b     :      1;
-                bdrkreg_t       eipw_sysad_bad_data_a     :      1;
-                bdrkreg_t       eipw_ue_cached_b          :      1;
-                bdrkreg_t       eipw_ue_cached_a          :      1;
-                bdrkreg_t       eipw_pkt_len_err_b        :      1;
-                bdrkreg_t       eipw_pkt_len_err_a        :      1;
-                bdrkreg_t       eipw_irb_err_b            :      1;
-                bdrkreg_t       eipw_irb_err_a            :      1;
-                bdrkreg_t       eipw_irb_timeout_b        :      1;
-                bdrkreg_t       eipw_irb_timeout_a        :      1;
-                bdrkreg_t       eipw_rsvd                 :     29;
-	} pi_err_int_pend_wr_fld_s;
-} pi_err_int_pend_wr_u_t;
-
-#else
-
-typedef union pi_err_int_pend_wr_u {
-	bdrkreg_t	pi_err_int_pend_wr_regval;
-	struct	{
-		bdrkreg_t	eipw_rsvd		  :	29;
-		bdrkreg_t	eipw_irb_timeout_a	  :	 1;
-		bdrkreg_t	eipw_irb_timeout_b	  :	 1;
-		bdrkreg_t	eipw_irb_err_a		  :	 1;
-		bdrkreg_t	eipw_irb_err_b		  :	 1;
-		bdrkreg_t	eipw_pkt_len_err_a	  :	 1;
-		bdrkreg_t	eipw_pkt_len_err_b	  :	 1;
-		bdrkreg_t	eipw_ue_cached_a	  :	 1;
-		bdrkreg_t	eipw_ue_cached_b	  :	 1;
-		bdrkreg_t	eipw_sysad_bad_data_a	  :	 1;
-		bdrkreg_t	eipw_sysad_bad_data_b	  :	 1;
-		bdrkreg_t	eipw_mem_unc		  :	 1;
-		bdrkreg_t	eipw_sysstate_tag_a	  :	 1;
-		bdrkreg_t	eipw_sysstate_tag_b	  :	 1;
-		bdrkreg_t	eipw_ue_uncached_a	  :	 1;
-		bdrkreg_t	eipw_ue_uncached_b	  :	 1;
-		bdrkreg_t	eipw_spool_err_a	  :	 1;
-		bdrkreg_t	eipw_spool_err_b	  :	 1;
-		bdrkreg_t	eipw_syscmd_addr_par_a	  :	 1;
-		bdrkreg_t	eipw_syscmd_addr_par_b	  :	 1;
-		bdrkreg_t	eipw_syscmd_data_par_a	  :	 1;
-		bdrkreg_t	eipw_syscmd_data_par_b	  :	 1;
-		bdrkreg_t	eipw_sysad_addr_ecc_a	  :	 1;
-		bdrkreg_t	eipw_sysad_addr_ecc_b	  :	 1;
-		bdrkreg_t	eipw_sysad_data_ecc_a	  :	 1;
-		bdrkreg_t	eipw_sysad_data_ecc_b	  :	 1;
-		bdrkreg_t	eipw_sysstate_par_a	  :	 1;
-		bdrkreg_t	eipw_sysstate_par_b	  :	 1;
-		bdrkreg_t	eipw_wrb_werr_a		  :	 1;
-		bdrkreg_t	eipw_wrb_werr_b		  :	 1;
-		bdrkreg_t	eipw_wrb_terr_a		  :	 1;
-		bdrkreg_t	eipw_wrb_terr_b		  :	 1;
-		bdrkreg_t	eipw_spurious_a		  :	 1;
-		bdrkreg_t	eipw_spurious_b		  :	 1;
-		bdrkreg_t	eipw_spool_comp_a	  :	 1;
-		bdrkreg_t	eipw_spool_comp_b	  :	 1;
-	} pi_err_int_pend_wr_fld_s;
-} pi_err_int_pend_wr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  A read of this register returns all sources of         *
- * Bedrock Error Interrupts. Storing to the write-with-clear location   *
- * clears any bit for which a one appears on the data bus. Storing to   *
- * the writable location does a direct write to all unreserved bits     *
- * (except for MEM_UNC).                                                *
- * In Synergy mode, the processor that is the source of the command     *
- * that got an error is independent of the A or B SysAD bus. So in      *
- * Synergy mode, Synergy provides the source processor number in bit    *
- * 52 of the SysAD bus in all commands. The PI saves this in the RRB    *
- * or WRB entry, and uses that value to determine which error bit (A    *
- * or B) to set, as well as which ERR_STATUS and spool registers to     *
- * use, for all error types in this register that are specified as an   *
- * error to CPU_A or CPU_B.                                             *
- * This register is not cleared at reset.                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_int_pend_u {
-	bdrkreg_t	pi_err_int_pend_regval;
-	struct  {
-		bdrkreg_t	eip_spool_comp_b          :	 1;
-                bdrkreg_t       eip_spool_comp_a          :      1;
-                bdrkreg_t       eip_spurious_b            :      1;
-                bdrkreg_t       eip_spurious_a            :      1;
-                bdrkreg_t       eip_wrb_terr_b            :      1;
-                bdrkreg_t       eip_wrb_terr_a            :      1;
-                bdrkreg_t       eip_wrb_werr_b            :      1;
-                bdrkreg_t       eip_wrb_werr_a            :      1;
-                bdrkreg_t       eip_sysstate_par_b        :      1;
-                bdrkreg_t       eip_sysstate_par_a        :      1;
-                bdrkreg_t       eip_sysad_data_ecc_b      :      1;
-                bdrkreg_t       eip_sysad_data_ecc_a      :      1;
-                bdrkreg_t       eip_sysad_addr_ecc_b      :      1;
-                bdrkreg_t       eip_sysad_addr_ecc_a      :      1;
-                bdrkreg_t       eip_syscmd_data_par_b     :      1;
-                bdrkreg_t       eip_syscmd_data_par_a     :      1;
-                bdrkreg_t       eip_syscmd_addr_par_b     :      1;
-                bdrkreg_t       eip_syscmd_addr_par_a     :      1;
-                bdrkreg_t       eip_spool_err_b           :      1;
-                bdrkreg_t       eip_spool_err_a           :      1;
-                bdrkreg_t       eip_ue_uncached_b         :      1;
-                bdrkreg_t       eip_ue_uncached_a         :      1;
-                bdrkreg_t       eip_sysstate_tag_b        :      1;
-                bdrkreg_t       eip_sysstate_tag_a        :      1;
-                bdrkreg_t       eip_mem_unc               :      1;
-                bdrkreg_t       eip_sysad_bad_data_b      :      1;
-                bdrkreg_t       eip_sysad_bad_data_a      :      1;
-                bdrkreg_t       eip_ue_cached_b           :      1;
-                bdrkreg_t       eip_ue_cached_a           :      1;
-                bdrkreg_t       eip_pkt_len_err_b         :      1;
-                bdrkreg_t       eip_pkt_len_err_a         :      1;
-                bdrkreg_t       eip_irb_err_b             :      1;
-                bdrkreg_t       eip_irb_err_a             :      1;
-                bdrkreg_t       eip_irb_timeout_b         :      1;
-                bdrkreg_t       eip_irb_timeout_a         :      1;
-                bdrkreg_t       eip_rsvd                  :     29;
-	} pi_err_int_pend_fld_s;
-} pi_err_int_pend_u_t;
-
-#else
-
-typedef union pi_err_int_pend_u {
-	bdrkreg_t	pi_err_int_pend_regval;
-	struct	{
-		bdrkreg_t	eip_rsvd		  :	29;
-		bdrkreg_t	eip_irb_timeout_a	  :	 1;
-		bdrkreg_t	eip_irb_timeout_b	  :	 1;
-		bdrkreg_t	eip_irb_err_a		  :	 1;
-		bdrkreg_t	eip_irb_err_b		  :	 1;
-		bdrkreg_t	eip_pkt_len_err_a	  :	 1;
-		bdrkreg_t	eip_pkt_len_err_b	  :	 1;
-		bdrkreg_t	eip_ue_cached_a		  :	 1;
-		bdrkreg_t	eip_ue_cached_b		  :	 1;
-		bdrkreg_t	eip_sysad_bad_data_a	  :	 1;
-		bdrkreg_t	eip_sysad_bad_data_b	  :	 1;
-		bdrkreg_t	eip_mem_unc		  :	 1;
-		bdrkreg_t	eip_sysstate_tag_a	  :	 1;
-		bdrkreg_t	eip_sysstate_tag_b	  :	 1;
-		bdrkreg_t	eip_ue_uncached_a	  :	 1;
-		bdrkreg_t	eip_ue_uncached_b	  :	 1;
-		bdrkreg_t	eip_spool_err_a		  :	 1;
-		bdrkreg_t	eip_spool_err_b		  :	 1;
-		bdrkreg_t	eip_syscmd_addr_par_a	  :	 1;
-		bdrkreg_t	eip_syscmd_addr_par_b	  :	 1;
-		bdrkreg_t	eip_syscmd_data_par_a	  :	 1;
-		bdrkreg_t	eip_syscmd_data_par_b	  :	 1;
-		bdrkreg_t	eip_sysad_addr_ecc_a	  :	 1;
-		bdrkreg_t	eip_sysad_addr_ecc_b	  :	 1;
-		bdrkreg_t	eip_sysad_data_ecc_a	  :	 1;
-		bdrkreg_t	eip_sysad_data_ecc_b	  :	 1;
-		bdrkreg_t	eip_sysstate_par_a	  :	 1;
-		bdrkreg_t	eip_sysstate_par_b	  :	 1;
-		bdrkreg_t	eip_wrb_werr_a		  :	 1;
-		bdrkreg_t	eip_wrb_werr_b		  :	 1;
-		bdrkreg_t	eip_wrb_terr_a		  :	 1;
-		bdrkreg_t	eip_wrb_terr_b		  :	 1;
-		bdrkreg_t	eip_spurious_a		  :	 1;
-		bdrkreg_t	eip_spurious_b		  :	 1;
-		bdrkreg_t	eip_spool_comp_a	  :	 1;
-		bdrkreg_t	eip_spool_comp_b	  :	 1;
-	} pi_err_int_pend_fld_s;
-} pi_err_int_pend_u_t;
-
-#endif
-
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. This read/write       *
- * register masks the contents of ERR_INT_PEND to determine which       *
- * conditions cause a Level-6 interrupt to CPU_A or CPU_B. A bit set    *
- * allows the interrupt. Only one processor in a Bedrock should         *
- * enable the Memory/Directory Uncorrectable Error bit.                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_int_mask_a_u {
-	bdrkreg_t	pi_err_int_mask_a_regval;
-	struct  {
-		bdrkreg_t	eima_mask                 :	35;
-		bdrkreg_t       eima_rsvd                 :     29;
-	} pi_err_int_mask_a_fld_s;
-} pi_err_int_mask_a_u_t;
-
-#else
-
-typedef union pi_err_int_mask_a_u {
-	bdrkreg_t	pi_err_int_mask_a_regval;
-	struct	{
-		bdrkreg_t	eima_rsvd		  :	29;
-		bdrkreg_t	eima_mask		  :	35;
-	} pi_err_int_mask_a_fld_s;
-} pi_err_int_mask_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. This read/write       *
- * register masks the contents of ERR_INT_PEND to determine which       *
- * conditions cause a Level-6 interrupt to CPU_A or CPU_B. A bit set    *
- * allows the interrupt. Only one processor in a Bedrock should         *
- * enable the Memory/Directory Uncorrectable Error bit.                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_int_mask_b_u {
-	bdrkreg_t	pi_err_int_mask_b_regval;
-	struct  {
-		bdrkreg_t	eimb_mask                 :	35;
-		bdrkreg_t       eimb_rsvd                 :     29;
-	} pi_err_int_mask_b_fld_s;
-} pi_err_int_mask_b_u_t;
-
-#else
-
-typedef union pi_err_int_mask_b_u {
-	bdrkreg_t	pi_err_int_mask_b_regval;
-	struct	{
-		bdrkreg_t	eimb_rsvd		  :	29;
-		bdrkreg_t	eimb_mask		  :	35;
-	} pi_err_int_mask_b_fld_s;
-} pi_err_int_mask_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There is one of these registers for each CPU. This     *
- * register is the address of the next write to the error stack. This   *
- * register is incremented after each such write. Only the low N bits   *
- * are incremented, where N is defined by the size of the error stack   *
- * specified in the ERR_STACK_SIZE register.                            *
- * This register is not reset by a soft reset.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_stack_addr_a_u {
-	bdrkreg_t	pi_err_stack_addr_a_regval;
-	struct  {
-		bdrkreg_t	esaa_rsvd_1               :	 3;
-                bdrkreg_t       esaa_addr                 :     30;
-                bdrkreg_t       esaa_rsvd                 :     31;
-	} pi_err_stack_addr_a_fld_s;
-} pi_err_stack_addr_a_u_t;
-
-#else
-
-typedef union pi_err_stack_addr_a_u {
-	bdrkreg_t	pi_err_stack_addr_a_regval;
-	struct	{
-		bdrkreg_t	esaa_rsvd		  :	31;
-		bdrkreg_t	esaa_addr		  :	30;
-		bdrkreg_t	esaa_rsvd_1		  :	 3;
-	} pi_err_stack_addr_a_fld_s;
-} pi_err_stack_addr_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  There is one of these registers for each CPU. This     *
- * register is the address of the next write to the error stack. This   *
- * register is incremented after each such write. Only the low N bits   *
- * are incremented, where N is defined by the size of the error stack   *
- * specified in the ERR_STACK_SIZE register.                            *
- * This register is not reset by a soft reset.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_stack_addr_b_u {
-	bdrkreg_t	pi_err_stack_addr_b_regval;
-	struct  {
-		bdrkreg_t	esab_rsvd_1               :	 3;
-                bdrkreg_t       esab_addr                 :     30;
-                bdrkreg_t       esab_rsvd                 :     31;
-	} pi_err_stack_addr_b_fld_s;
-} pi_err_stack_addr_b_u_t;
-
-#else
-
-typedef union pi_err_stack_addr_b_u {
-	bdrkreg_t	pi_err_stack_addr_b_regval;
-	struct	{
-		bdrkreg_t	esab_rsvd		  :	31;
-		bdrkreg_t	esab_addr		  :	30;
-		bdrkreg_t	esab_rsvd_1		  :	 3;
-	} pi_err_stack_addr_b_fld_s;
-} pi_err_stack_addr_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  Sets the size (number of 64-bit entries) in the        *
- * error stack that is spooled to local memory when an error occurs.    *
- * Table16 defines the format of each entry in the spooled error        *
- * stack.                                                               *
- * This register is not reset by a soft reset.                          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_stack_size_u {
-	bdrkreg_t	pi_err_stack_size_regval;
-	struct  {
-		bdrkreg_t	ess_size                  :	 4;
-                bdrkreg_t       ess_rsvd                  :     60;
-	} pi_err_stack_size_fld_s;
-} pi_err_stack_size_u_t;
-
-#else
-
-typedef union pi_err_stack_size_u {
-	bdrkreg_t	pi_err_stack_size_regval;
-	struct	{
-		bdrkreg_t	ess_rsvd		  :	60;
-		bdrkreg_t	ess_size		  :	 4;
-	} pi_err_stack_size_fld_s;
-} pi_err_stack_size_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. Writing this register with   *
- * the Write-clear address (with any data) clears both the              *
- * ERR_STATUS0_A and ERR_STATUS1_A registers.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_status0_a_u {
-	bdrkreg_t	pi_err_status0_a_regval;
-	struct  {
-		bdrkreg_t	esa_error_type            :	 3;
-                bdrkreg_t       esa_proc_req_num          :      3;
-                bdrkreg_t       esa_supplemental          :     11;
-                bdrkreg_t       esa_cmd                   :      8;
-                bdrkreg_t       esa_addr                  :     37;
-                bdrkreg_t       esa_over_run              :      1;
-                bdrkreg_t       esa_valid                 :      1;
-	} pi_err_status0_a_fld_s;
-} pi_err_status0_a_u_t;
-
-#else
-
-typedef union pi_err_status0_a_u {
-	bdrkreg_t	pi_err_status0_a_regval;
-	struct	{
-		bdrkreg_t	esa_valid		  :	 1;
-		bdrkreg_t	esa_over_run		  :	 1;
-		bdrkreg_t	esa_addr		  :	37;
-		bdrkreg_t	esa_cmd			  :	 8;
-		bdrkreg_t	esa_supplemental	  :	11;
-		bdrkreg_t	esa_proc_req_num	  :	 3;
-		bdrkreg_t	esa_error_type		  :	 3;
-	} pi_err_status0_a_fld_s;
-} pi_err_status0_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. Writing this register with   *
- * the Write-clear address (with any data) clears both the              *
- * ERR_STATUS0_A and ERR_STATUS1_A registers.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_status0_a_clr_u {
-	bdrkreg_t	pi_err_status0_a_clr_regval;
-	struct  {
-		bdrkreg_t	esac_error_type           :	 3;
-                bdrkreg_t       esac_proc_req_num         :      3;
-                bdrkreg_t       esac_supplemental         :     11;
-                bdrkreg_t       esac_cmd                  :      8;
-                bdrkreg_t       esac_addr                 :     37;
-                bdrkreg_t       esac_over_run             :      1;
-                bdrkreg_t       esac_valid                :      1;
-	} pi_err_status0_a_clr_fld_s;
-} pi_err_status0_a_clr_u_t;
-
-#else
-
-typedef union pi_err_status0_a_clr_u {
-	bdrkreg_t	pi_err_status0_a_clr_regval;
-	struct	{
-		bdrkreg_t	esac_valid		  :	 1;
-		bdrkreg_t	esac_over_run		  :	 1;
-		bdrkreg_t	esac_addr		  :	37;
-		bdrkreg_t	esac_cmd		  :	 8;
-		bdrkreg_t	esac_supplemental	  :	11;
-		bdrkreg_t	esac_proc_req_num	  :	 3;
-		bdrkreg_t	esac_error_type		  :	 3;
-	} pi_err_status0_a_clr_fld_s;
-} pi_err_status0_a_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. Writing this register with   *
- * the Write-clear address (with any data) clears both the              *
- * ERR_STATUS0_A and ERR_STATUS1_A registers.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_status1_a_u {
-	bdrkreg_t	pi_err_status1_a_regval;
-	struct  {
-		bdrkreg_t	esa_spool_count           :	21;
-                bdrkreg_t       esa_time_out_count        :      8;
-                bdrkreg_t       esa_inval_count           :     10;
-                bdrkreg_t       esa_crb_num               :      3;
-                bdrkreg_t       esa_wrb                   :      1;
-                bdrkreg_t       esa_e_bits                :      2;
-                bdrkreg_t       esa_t_bit                 :      1;
-                bdrkreg_t       esa_i_bit                 :      1;
-                bdrkreg_t       esa_h_bit                 :      1;
-                bdrkreg_t       esa_w_bit                 :      1;
-                bdrkreg_t       esa_a_bit                 :      1;
-                bdrkreg_t       esa_r_bit                 :      1;
-                bdrkreg_t       esa_v_bit                 :      1;
-                bdrkreg_t       esa_p_bit                 :      1;
-                bdrkreg_t       esa_source                :     11;
-	} pi_err_status1_a_fld_s;
-} pi_err_status1_a_u_t;
-
-#else
-
-typedef union pi_err_status1_a_u {
-	bdrkreg_t	pi_err_status1_a_regval;
-	struct	{
-		bdrkreg_t	esa_source		  :	11;
-		bdrkreg_t	esa_p_bit		  :	 1;
-		bdrkreg_t	esa_v_bit		  :	 1;
-		bdrkreg_t	esa_r_bit		  :	 1;
-		bdrkreg_t	esa_a_bit		  :	 1;
-		bdrkreg_t	esa_w_bit		  :	 1;
-		bdrkreg_t	esa_h_bit		  :	 1;
-		bdrkreg_t	esa_i_bit		  :	 1;
-		bdrkreg_t	esa_t_bit		  :	 1;
-		bdrkreg_t	esa_e_bits		  :	 2;
-		bdrkreg_t	esa_wrb			  :	 1;
-		bdrkreg_t	esa_crb_num		  :	 3;
-		bdrkreg_t	esa_inval_count		  :	10;
-		bdrkreg_t	esa_time_out_count	  :	 8;
-		bdrkreg_t	esa_spool_count		  :	21;
-	} pi_err_status1_a_fld_s;
-} pi_err_status1_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. Writing this register with   *
- * the Write-clear address (with any data) clears both the              *
- * ERR_STATUS0_A and ERR_STATUS1_A registers.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_status1_a_clr_u {
-	bdrkreg_t	pi_err_status1_a_clr_regval;
-	struct  {
-		bdrkreg_t	esac_spool_count          :	21;
-                bdrkreg_t       esac_time_out_count       :      8;
-                bdrkreg_t       esac_inval_count          :     10;
-                bdrkreg_t       esac_crb_num              :      3;
-                bdrkreg_t       esac_wrb                  :      1;
-                bdrkreg_t       esac_e_bits               :      2;
-                bdrkreg_t       esac_t_bit                :      1;
-                bdrkreg_t       esac_i_bit                :      1;
-                bdrkreg_t       esac_h_bit                :      1;
-                bdrkreg_t       esac_w_bit                :      1;
-                bdrkreg_t       esac_a_bit                :      1;
-                bdrkreg_t       esac_r_bit                :      1;
-                bdrkreg_t       esac_v_bit                :      1;
-                bdrkreg_t       esac_p_bit                :      1;
-                bdrkreg_t       esac_source               :     11;
-	} pi_err_status1_a_clr_fld_s;
-} pi_err_status1_a_clr_u_t;
-
-#else
-
-typedef union pi_err_status1_a_clr_u {
-	bdrkreg_t	pi_err_status1_a_clr_regval;
-	struct	{
-		bdrkreg_t	esac_source		  :	11;
-		bdrkreg_t	esac_p_bit		  :	 1;
-		bdrkreg_t	esac_v_bit		  :	 1;
-		bdrkreg_t	esac_r_bit		  :	 1;
-		bdrkreg_t	esac_a_bit		  :	 1;
-		bdrkreg_t	esac_w_bit		  :	 1;
-		bdrkreg_t	esac_h_bit		  :	 1;
-		bdrkreg_t	esac_i_bit		  :	 1;
-		bdrkreg_t	esac_t_bit		  :	 1;
-		bdrkreg_t	esac_e_bits		  :	 2;
-		bdrkreg_t	esac_wrb		  :	 1;
-		bdrkreg_t	esac_crb_num		  :	 3;
-		bdrkreg_t	esac_inval_count	  :	10;
-		bdrkreg_t	esac_time_out_count	  :	 8;
-		bdrkreg_t	esac_spool_count	  :	21;
-	} pi_err_status1_a_clr_fld_s;
-} pi_err_status1_a_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. Writing this register with   *
- * the Write-clear address (with any data) clears both the              *
- * ERR_STATUS0_B and ERR_STATUS1_B registers.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_status0_b_u {
-	bdrkreg_t	pi_err_status0_b_regval;
-	struct  {
-		bdrkreg_t	esb_error_type            :	 3;
-                bdrkreg_t       esb_proc_request_number   :      3;
-                bdrkreg_t       esb_supplemental          :     11;
-                bdrkreg_t       esb_cmd                   :      8;
-                bdrkreg_t       esb_addr                  :     37;
-                bdrkreg_t       esb_over_run              :      1;
-                bdrkreg_t       esb_valid                 :      1;
-	} pi_err_status0_b_fld_s;
-} pi_err_status0_b_u_t;
-
-#else
-
-typedef union pi_err_status0_b_u {
-	bdrkreg_t	pi_err_status0_b_regval;
-	struct	{
-		bdrkreg_t	esb_valid		  :	 1;
-		bdrkreg_t	esb_over_run		  :	 1;
-		bdrkreg_t	esb_addr		  :	37;
-		bdrkreg_t	esb_cmd			  :	 8;
-		bdrkreg_t	esb_supplemental	  :	11;
-		bdrkreg_t	esb_proc_request_number	  :	 3;
-		bdrkreg_t	esb_error_type		  :	 3;
-	} pi_err_status0_b_fld_s;
-} pi_err_status0_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. Writing this register with   *
- * the Write-clear address (with any data) clears both the              *
- * ERR_STATUS0_B and ERR_STATUS1_B registers.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_status0_b_clr_u {
-	bdrkreg_t	pi_err_status0_b_clr_regval;
-	struct  {
-		bdrkreg_t	esbc_error_type           :	 3;
-                bdrkreg_t       esbc_proc_request_number  :      3;
-                bdrkreg_t       esbc_supplemental         :     11;
-                bdrkreg_t       esbc_cmd                  :      8;
-                bdrkreg_t       esbc_addr                 :     37;
-                bdrkreg_t       esbc_over_run             :      1;
-                bdrkreg_t       esbc_valid                :      1;
-	} pi_err_status0_b_clr_fld_s;
-} pi_err_status0_b_clr_u_t;
-
-#else
-
-typedef union pi_err_status0_b_clr_u {
-	bdrkreg_t	pi_err_status0_b_clr_regval;
-	struct	{
-		bdrkreg_t	esbc_valid		  :	 1;
-		bdrkreg_t	esbc_over_run		  :	 1;
-		bdrkreg_t	esbc_addr		  :	37;
-		bdrkreg_t	esbc_cmd		  :	 8;
-		bdrkreg_t	esbc_supplemental	  :	11;
-		bdrkreg_t	esbc_proc_request_number  :	 3;
-		bdrkreg_t	esbc_error_type		  :	 3;
-	} pi_err_status0_b_clr_fld_s;
-} pi_err_status0_b_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. Writing this register with   *
- * the Write-clear address (with any data) clears both the              *
- * ERR_STATUS0_B and ERR_STATUS1_B registers.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_status1_b_u {
-	bdrkreg_t	pi_err_status1_b_regval;
-	struct  {
-		bdrkreg_t	esb_spool_count           :	21;
-                bdrkreg_t       esb_time_out_count        :      8;
-                bdrkreg_t       esb_inval_count           :     10;
-                bdrkreg_t       esb_crb_num               :      3;
-                bdrkreg_t       esb_wrb                   :      1;
-                bdrkreg_t       esb_e_bits                :      2;
-                bdrkreg_t       esb_t_bit                 :      1;
-                bdrkreg_t       esb_i_bit                 :      1;
-                bdrkreg_t       esb_h_bit                 :      1;
-                bdrkreg_t       esb_w_bit                 :      1;
-                bdrkreg_t       esb_a_bit                 :      1;
-                bdrkreg_t       esb_r_bit                 :      1;
-                bdrkreg_t       esb_v_bit                 :      1;
-                bdrkreg_t       esb_p_bit                 :      1;
-                bdrkreg_t       esb_source                :     11;
-	} pi_err_status1_b_fld_s;
-} pi_err_status1_b_u_t;
-
-#else
-
-typedef union pi_err_status1_b_u {
-	bdrkreg_t	pi_err_status1_b_regval;
-	struct	{
-		bdrkreg_t	esb_source		  :	11;
-		bdrkreg_t	esb_p_bit		  :	 1;
-		bdrkreg_t	esb_v_bit		  :	 1;
-		bdrkreg_t	esb_r_bit		  :	 1;
-		bdrkreg_t	esb_a_bit		  :	 1;
-		bdrkreg_t	esb_w_bit		  :	 1;
-		bdrkreg_t	esb_h_bit		  :	 1;
-		bdrkreg_t	esb_i_bit		  :	 1;
-		bdrkreg_t	esb_t_bit		  :	 1;
-		bdrkreg_t	esb_e_bits		  :	 2;
-		bdrkreg_t	esb_wrb			  :	 1;
-		bdrkreg_t	esb_crb_num		  :	 3;
-		bdrkreg_t	esb_inval_count		  :	10;
-		bdrkreg_t	esb_time_out_count	  :	 8;
-		bdrkreg_t	esb_spool_count		  :	21;
-	} pi_err_status1_b_fld_s;
-} pi_err_status1_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. Writing this register with   *
- * the Write-clear address (with any data) clears both the              *
- * ERR_STATUS0_B and ERR_STATUS1_B registers.                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_status1_b_clr_u {
-	bdrkreg_t	pi_err_status1_b_clr_regval;
-	struct  {
-		bdrkreg_t	esbc_spool_count          :	21;
-                bdrkreg_t       esbc_time_out_count       :      8;
-                bdrkreg_t       esbc_inval_count          :     10;
-                bdrkreg_t       esbc_crb_num              :      3;
-                bdrkreg_t       esbc_wrb                  :      1;
-                bdrkreg_t       esbc_e_bits               :      2;
-                bdrkreg_t       esbc_t_bit                :      1;
-                bdrkreg_t       esbc_i_bit                :      1;
-                bdrkreg_t       esbc_h_bit                :      1;
-                bdrkreg_t       esbc_w_bit                :      1;
-                bdrkreg_t       esbc_a_bit                :      1;
-                bdrkreg_t       esbc_r_bit                :      1;
-                bdrkreg_t       esbc_v_bit                :      1;
-                bdrkreg_t       esbc_p_bit                :      1;
-                bdrkreg_t       esbc_source               :     11;
-	} pi_err_status1_b_clr_fld_s;
-} pi_err_status1_b_clr_u_t;
-
-#else
-
-typedef union pi_err_status1_b_clr_u {
-	bdrkreg_t	pi_err_status1_b_clr_regval;
-	struct	{
-		bdrkreg_t	esbc_source		  :	11;
-		bdrkreg_t	esbc_p_bit		  :	 1;
-		bdrkreg_t	esbc_v_bit		  :	 1;
-		bdrkreg_t	esbc_r_bit		  :	 1;
-		bdrkreg_t	esbc_a_bit		  :	 1;
-		bdrkreg_t	esbc_w_bit		  :	 1;
-		bdrkreg_t	esbc_h_bit		  :	 1;
-		bdrkreg_t	esbc_i_bit		  :	 1;
-		bdrkreg_t	esbc_t_bit		  :	 1;
-		bdrkreg_t	esbc_e_bits		  :	 2;
-		bdrkreg_t	esbc_wrb		  :	 1;
-		bdrkreg_t	esbc_crb_num		  :	 3;
-		bdrkreg_t	esbc_inval_count	  :	10;
-		bdrkreg_t	esbc_time_out_count	  :	 8;
-		bdrkreg_t	esbc_spool_count	  :	21;
-	} pi_err_status1_b_clr_fld_s;
-} pi_err_status1_b_clr_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_spool_cmp_a_u {
-	bdrkreg_t	pi_spool_cmp_a_regval;
-	struct  {
-		bdrkreg_t	sca_compare               :	20;
-		bdrkreg_t       sca_rsvd                  :     44;
-	} pi_spool_cmp_a_fld_s;
-} pi_spool_cmp_a_u_t;
-
-#else
-
-typedef union pi_spool_cmp_a_u {
-	bdrkreg_t	pi_spool_cmp_a_regval;
-	struct	{
-		bdrkreg_t	sca_rsvd		  :	44;
-		bdrkreg_t	sca_compare		  :	20;
-	} pi_spool_cmp_a_fld_s;
-} pi_spool_cmp_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_spool_cmp_b_u {
-	bdrkreg_t	pi_spool_cmp_b_regval;
-	struct  {
-		bdrkreg_t	scb_compare               :	20;
-		bdrkreg_t       scb_rsvd                  :     44;
-	} pi_spool_cmp_b_fld_s;
-} pi_spool_cmp_b_u_t;
-
-#else
-
-typedef union pi_spool_cmp_b_u {
-	bdrkreg_t	pi_spool_cmp_b_regval;
-	struct	{
-		bdrkreg_t	scb_rsvd		  :	44;
-		bdrkreg_t	scb_compare		  :	20;
-	} pi_spool_cmp_b_fld_s;
-} pi_spool_cmp_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. A timeout can be      *
- * forced by writing one(s).                                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_crb_timeout_a_u {
-	bdrkreg_t	pi_crb_timeout_a_regval;
-	struct  {
-		bdrkreg_t	cta_rrb                   :	 4;
-                bdrkreg_t       cta_wrb                   :      8;
-                bdrkreg_t       cta_rsvd                  :     52;
-	} pi_crb_timeout_a_fld_s;
-} pi_crb_timeout_a_u_t;
-
-#else
-
-typedef union pi_crb_timeout_a_u {
-	bdrkreg_t	pi_crb_timeout_a_regval;
-	struct	{
-		bdrkreg_t	cta_rsvd		  :	52;
-		bdrkreg_t	cta_wrb			  :	 8;
-		bdrkreg_t	cta_rrb			  :	 4;
-	} pi_crb_timeout_a_fld_s;
-} pi_crb_timeout_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. A timeout can be      *
- * forced by writing one(s).                                            *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_crb_timeout_b_u {
-	bdrkreg_t	pi_crb_timeout_b_regval;
-	struct  {
-		bdrkreg_t	ctb_rrb                   :	 4;
-                bdrkreg_t       ctb_wrb                   :      8;
-                bdrkreg_t       ctb_rsvd                  :     52;
-	} pi_crb_timeout_b_fld_s;
-} pi_crb_timeout_b_u_t;
-
-#else
-
-typedef union pi_crb_timeout_b_u {
-	bdrkreg_t	pi_crb_timeout_b_regval;
-	struct	{
-		bdrkreg_t	ctb_rsvd		  :	52;
-		bdrkreg_t	ctb_wrb			  :	 8;
-		bdrkreg_t	ctb_rrb			  :	 4;
-	} pi_crb_timeout_b_fld_s;
-} pi_crb_timeout_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register controls error checking and forwarding of SysAD       *
- * errors.                                                              *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_sysad_errchk_en_u {
-	bdrkreg_t	pi_sysad_errchk_en_regval;
-	struct  {
-		bdrkreg_t	see_ecc_gen_en            :	 1;
-                bdrkreg_t       see_qual_gen_en           :      1;
-                bdrkreg_t       see_sadp_chk_en           :      1;
-                bdrkreg_t       see_cmdp_chk_en           :      1;
-                bdrkreg_t       see_state_chk_en          :      1;
-                bdrkreg_t       see_qual_chk_en           :      1;
-                bdrkreg_t       see_rsvd                  :     58;
-	} pi_sysad_errchk_en_fld_s;
-} pi_sysad_errchk_en_u_t;
-
-#else
-
-typedef union pi_sysad_errchk_en_u {
-	bdrkreg_t	pi_sysad_errchk_en_regval;
-	struct	{
-		bdrkreg_t	see_rsvd		  :	58;
-		bdrkreg_t	see_qual_chk_en		  :	 1;
-		bdrkreg_t	see_state_chk_en	  :	 1;
-		bdrkreg_t	see_cmdp_chk_en		  :	 1;
-		bdrkreg_t	see_sadp_chk_en		  :	 1;
-		bdrkreg_t	see_qual_gen_en		  :	 1;
-		bdrkreg_t	see_ecc_gen_en		  :	 1;
-	} pi_sysad_errchk_en_fld_s;
-} pi_sysad_errchk_en_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. If any bit in this    *
- * register is set, then whenever reply data arrives with the UE        *
- * (uncorrectable error) indication set, the check-bits that are        *
- * generated and sent to the SysAD will be inverted corresponding to    *
- * the bits set in the register. This will also prevent the assertion   *
- * of the data quality indicator.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_force_bad_check_bit_a_u {
-	bdrkreg_t	pi_force_bad_check_bit_a_regval;
-	struct  {
-		bdrkreg_t	fbcba_bad_check_bit       :	 8;
-		bdrkreg_t       fbcba_rsvd                :     56;
-	} pi_force_bad_check_bit_a_fld_s;
-} pi_force_bad_check_bit_a_u_t;
-
-#else
-
-typedef union pi_force_bad_check_bit_a_u {
-	bdrkreg_t	pi_force_bad_check_bit_a_regval;
-	struct	{
-		bdrkreg_t	fbcba_rsvd		  :	56;
-		bdrkreg_t	fbcba_bad_check_bit	  :	 8;
-	} pi_force_bad_check_bit_a_fld_s;
-} pi_force_bad_check_bit_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. If any bit in this    *
- * register is set, then whenever reply data arrives with the UE        *
- * (uncorrectable error) indication set, the check-bits that are        *
- * generated and sent to the SysAD will be inverted corresponding to    *
- * the bits set in the register. This will also prevent the assertion   *
- * of the data quality indicator.                                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_force_bad_check_bit_b_u {
-	bdrkreg_t	pi_force_bad_check_bit_b_regval;
-	struct  {
-		bdrkreg_t	fbcbb_bad_check_bit       :	 8;
-		bdrkreg_t       fbcbb_rsvd                :     56;
-	} pi_force_bad_check_bit_b_fld_s;
-} pi_force_bad_check_bit_b_u_t;
-
-#else
-
-typedef union pi_force_bad_check_bit_b_u {
-	bdrkreg_t	pi_force_bad_check_bit_b_regval;
-	struct	{
-		bdrkreg_t	fbcbb_rsvd		  :	56;
-		bdrkreg_t	fbcbb_bad_check_bit	  :	 8;
-	} pi_force_bad_check_bit_b_fld_s;
-} pi_force_bad_check_bit_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. When a counter is     *
- * enabled, it increments each time a DNACK reply is received. The      *
- * counter is cleared when any other reply is received. The register    *
- * is cleared when the CNT_EN bit is zero. If a DNACK reply is          *
- * received when the counter equals the value in the NACK_CMP           *
- * register, the counter is cleared, an error response is sent to the   *
- * CPU instead of a nack response, and the NACK_INT_A/B bit is set in   *
- * INT_PEND1.                                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_nack_cnt_a_u {
-	bdrkreg_t	pi_nack_cnt_a_regval;
-	struct  {
-		bdrkreg_t	nca_nack_cnt              :	20;
-                bdrkreg_t       nca_cnt_en                :      1;
-                bdrkreg_t       nca_rsvd                  :     43;
-	} pi_nack_cnt_a_fld_s;
-} pi_nack_cnt_a_u_t;
-
-#else
-
-typedef union pi_nack_cnt_a_u {
-	bdrkreg_t	pi_nack_cnt_a_regval;
-	struct	{
-		bdrkreg_t	nca_rsvd		  :	43;
-		bdrkreg_t	nca_cnt_en		  :	 1;
-		bdrkreg_t	nca_nack_cnt		  :	20;
-	} pi_nack_cnt_a_fld_s;
-} pi_nack_cnt_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  There is one of these registers for each CPU. When a counter is     *
- * enabled, it increments each time a DNACK reply is received. The      *
- * counter is cleared when any other reply is received. The register    *
- * is cleared when the CNT_EN bit is zero. If a DNACK reply is          *
- * received when the counter equals the value in the NACK_CMP           *
- * register, the counter is cleared, an error response is sent to the   *
- * CPU instead of a nack response, and the NACK_INT_A/B bit is set in   *
- * INT_PEND1.                                                           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_nack_cnt_b_u {
-	bdrkreg_t	pi_nack_cnt_b_regval;
-	struct  {
-		bdrkreg_t	ncb_nack_cnt              :	20;
-                bdrkreg_t       ncb_cnt_en                :      1;
-                bdrkreg_t       ncb_rsvd                  :     43;
-	} pi_nack_cnt_b_fld_s;
-} pi_nack_cnt_b_u_t;
-
-#else
-
-typedef union pi_nack_cnt_b_u {
-	bdrkreg_t	pi_nack_cnt_b_regval;
-	struct	{
-		bdrkreg_t	ncb_rsvd		  :	43;
-		bdrkreg_t	ncb_cnt_en		  :	 1;
-		bdrkreg_t	ncb_nack_cnt		  :	20;
-	} pi_nack_cnt_b_fld_s;
-} pi_nack_cnt_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  The setting of this register affects both CPUs on this PI.          *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_nack_cmp_u {
-	bdrkreg_t	pi_nack_cmp_regval;
-	struct  {
-		bdrkreg_t	nc_nack_cmp               :	20;
-		bdrkreg_t       nc_rsvd                   :     44;
-	} pi_nack_cmp_fld_s;
-} pi_nack_cmp_u_t;
-
-#else
-
-typedef union pi_nack_cmp_u {
-	bdrkreg_t	pi_nack_cmp_regval;
-	struct	{
-		bdrkreg_t	nc_rsvd			  :	44;
-		bdrkreg_t	nc_nack_cmp		  :	20;
-	} pi_nack_cmp_fld_s;
-} pi_nack_cmp_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register controls which errors are spooled. When a bit in      *
- * this register is set, the corresponding error is spooled. The        *
- * setting of this register affects both CPUs on this PI.               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_spool_mask_u {
-	bdrkreg_t	pi_spool_mask_regval;
-	struct  {
-		bdrkreg_t	sm_access_err             :	 1;
-                bdrkreg_t       sm_uncached_err           :      1;
-                bdrkreg_t       sm_dir_err                :      1;
-                bdrkreg_t       sm_timeout_err            :      1;
-                bdrkreg_t       sm_poison_err             :      1;
-                bdrkreg_t       sm_nack_oflow_err         :      1;
-                bdrkreg_t       sm_rsvd                   :     58;
-	} pi_spool_mask_fld_s;
-} pi_spool_mask_u_t;
-
-#else
-
-typedef union pi_spool_mask_u {
-	bdrkreg_t	pi_spool_mask_regval;
-	struct	{
-		bdrkreg_t	sm_rsvd			  :	58;
-		bdrkreg_t	sm_nack_oflow_err	  :	 1;
-		bdrkreg_t	sm_poison_err		  :	 1;
-		bdrkreg_t	sm_timeout_err		  :	 1;
-		bdrkreg_t	sm_dir_err		  :	 1;
-		bdrkreg_t	sm_uncached_err		  :	 1;
-		bdrkreg_t	sm_access_err		  :	 1;
-	} pi_spool_mask_fld_s;
-} pi_spool_mask_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. When the VALID bit is        *
- * zero, this register (along with SPURIOUS_HDR_1) will capture the     *
- * header of an incoming spurious message received from the XBar. A     *
- * spurious message is a message that does not match up with any of     *
- * the CRB entries. This is a read/write register, so it is cleared     *
- * by writing of all zeros.                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_spurious_hdr_0_u {
-	bdrkreg_t	pi_spurious_hdr_0_regval;
-	struct  {
-		bdrkreg_t	sh0_prev_valid_b          :	 1;
-                bdrkreg_t       sh0_prev_valid_a          :      1;
-                bdrkreg_t       sh0_rsvd                  :      4;
-                bdrkreg_t       sh0_supplemental          :     11;
-                bdrkreg_t       sh0_cmd                   :      8;
-                bdrkreg_t       sh0_addr                  :     37;
-                bdrkreg_t       sh0_tail                  :      1;
-                bdrkreg_t       sh0_valid                 :      1;
-	} pi_spurious_hdr_0_fld_s;
-} pi_spurious_hdr_0_u_t;
-
-#else
-
-typedef union pi_spurious_hdr_0_u {
-	bdrkreg_t	pi_spurious_hdr_0_regval;
-	struct	{
-		bdrkreg_t	sh0_valid		  :	 1;
-		bdrkreg_t	sh0_tail		  :	 1;
-		bdrkreg_t	sh0_addr		  :	37;
-		bdrkreg_t	sh0_cmd			  :	 8;
-		bdrkreg_t	sh0_supplemental	  :	11;
-		bdrkreg_t	sh0_rsvd		  :	 4;
-		bdrkreg_t	sh0_prev_valid_a	  :	 1;
-		bdrkreg_t	sh0_prev_valid_b	  :	 1;
-	} pi_spurious_hdr_0_fld_s;
-} pi_spurious_hdr_0_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is not cleared at reset. When the VALID bit in        *
- * SPURIOUS_HDR_0 is zero, this register (along with SPURIOUS_HDR_0)    *
- * will capture the header of an incoming spurious message received     *
- * from the XBar. A spurious message is a message that does not match   *
- * up with any of the CRB entries. This is a read/write register, so    *
- * it is cleared by writing of all zeros.                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_spurious_hdr_1_u {
-	bdrkreg_t	pi_spurious_hdr_1_regval;
-	struct  {
-		bdrkreg_t	sh1_rsvd                  :	53;
-		bdrkreg_t       sh1_source                :     11;
-	} pi_spurious_hdr_1_fld_s;
-} pi_spurious_hdr_1_u_t;
-
-#else
-
-typedef union pi_spurious_hdr_1_u {
-	bdrkreg_t	pi_spurious_hdr_1_regval;
-	struct	{
-		bdrkreg_t	sh1_source		  :	11;
-		bdrkreg_t	sh1_rsvd		  :	53;
-	} pi_spurious_hdr_1_fld_s;
-} pi_spurious_hdr_1_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- * Description:  This register controls the injection of errors in      *
- * outbound SysAD transfers. When a write sets a bit in this            *
- * register, the PI logic is "armed" to inject that error. At the       *
- * first transfer of the specified type, the error is injected and      *
- * the bit in this register is cleared. Writing to this register does   *
- * not cause a transaction to occur. A bit in this register will        *
- * remain set until a transaction of the specified type occurs as a     *
- * result of normal system activity. This register can be polled to     *
- * determine if an error has been injected or is still "armed".         *
- * This register does not control injection of data quality bad         *
- * indicator on a data cycle. This type of error can be created by      *
- * reading from a memory location that has an uncorrectable ECC         *
- * error.                                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_err_inject_u {
-	bdrkreg_t	pi_err_inject_regval;
-	struct  {
-		bdrkreg_t	ei_cmd_syscmd_par_a       :	 1;
-                bdrkreg_t       ei_data_syscmd_par_a      :      1;
-                bdrkreg_t       ei_cmd_sysad_corecc_a     :      1;
-                bdrkreg_t       ei_data_sysad_corecc_a    :      1;
-                bdrkreg_t       ei_cmd_sysad_uncecc_a     :      1;
-                bdrkreg_t       ei_data_sysad_uncecc_a    :      1;
-                bdrkreg_t       ei_sysresp_par_a          :      1;
-                bdrkreg_t       ei_reserved_1             :     25;
-                bdrkreg_t       ei_cmd_syscmd_par_b       :      1;
-                bdrkreg_t       ei_data_syscmd_par_b      :      1;
-                bdrkreg_t       ei_cmd_sysad_corecc_b     :      1;
-                bdrkreg_t       ei_data_sysad_corecc_b    :      1;
-                bdrkreg_t       ei_cmd_sysad_uncecc_b     :      1;
-                bdrkreg_t       ei_data_sysad_uncecc_b    :      1;
-                bdrkreg_t       ei_sysresp_par_b          :      1;
-                bdrkreg_t       ei_reserved               :     25;
-	} pi_err_inject_fld_s;
-} pi_err_inject_u_t;
-
-#else
-
-typedef union pi_err_inject_u {
-	bdrkreg_t	pi_err_inject_regval;
-	struct	{
-		bdrkreg_t	ei_reserved		  :	25;
-		bdrkreg_t	ei_sysresp_par_b	  :	 1;
-		bdrkreg_t	ei_data_sysad_uncecc_b	  :	 1;
-		bdrkreg_t	ei_cmd_sysad_uncecc_b	  :	 1;
-		bdrkreg_t	ei_data_sysad_corecc_b	  :	 1;
-		bdrkreg_t	ei_cmd_sysad_corecc_b	  :	 1;
-		bdrkreg_t	ei_data_syscmd_par_b	  :	 1;
-		bdrkreg_t	ei_cmd_syscmd_par_b	  :	 1;
-		bdrkreg_t	ei_reserved_1		  :	25;
-		bdrkreg_t	ei_sysresp_par_a	  :	 1;
-		bdrkreg_t	ei_data_sysad_uncecc_a	  :	 1;
-		bdrkreg_t	ei_cmd_sysad_uncecc_a	  :	 1;
-		bdrkreg_t	ei_data_sysad_corecc_a	  :	 1;
-		bdrkreg_t	ei_cmd_sysad_corecc_a	  :	 1;
-		bdrkreg_t	ei_data_syscmd_par_a	  :	 1;
-		bdrkreg_t	ei_cmd_syscmd_par_a	  :	 1;
-	} pi_err_inject_fld_s;
-} pi_err_inject_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This Read/Write location determines at what point the TRex+ is      *
- * stopped from issuing requests, based on the number of entries in     *
- * the incoming reply FIFO. When the number of entries in the Reply     *
- * FIFO is greater than the value of this register, the PI will         *
- * deassert both SysWrRdy and SysRdRdy to both processors. The Reply    *
- * FIFO has a depth of 0x3F entries, so setting this register to 0x3F   *
- * effectively disables this feature, allowing requests to be issued    *
- * always. Setting this register to 0x00 effectively lowers the         *
- * TRex+'s priority below the reply FIFO, disabling TRex+ requests      *
- * any time there is an entry waiting in the incoming FIFO.This         *
- * register is in its own 64KB page so that it can be mapped to user    *
- * space.                                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_reply_level_u {
-	bdrkreg_t	pi_reply_level_regval;
-	struct  {
-		bdrkreg_t	rl_reply_level            :	 6;
-		bdrkreg_t	rl_rsvd			  :	58;
-	} pi_reply_level_fld_s;
-} pi_reply_level_u_t;
-
-#else
-
-typedef union pi_reply_level_u {
-	bdrkreg_t	pi_reply_level_regval;
-	struct	{
-		bdrkreg_t	rl_rsvd			  :	58;
-		bdrkreg_t	rl_reply_level		  :	 6;
-	} pi_reply_level_fld_s;
-} pi_reply_level_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register is used to change the graphics credit counter         *
- * operation from "Doubleword" mode to "Transaction" mode. This         *
- * register is in its own 64KB page so that it can be mapped to user    *
- * space.                                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_gfx_credit_mode_u {
-	bdrkreg_t	pi_gfx_credit_mode_regval;
-	struct  {
-		bdrkreg_t	gcm_trans_mode            :	 1;
-		bdrkreg_t       gcm_rsvd                  :     63;
-	} pi_gfx_credit_mode_fld_s;
-} pi_gfx_credit_mode_u_t;
-
-#else
-
-typedef union pi_gfx_credit_mode_u {
-	bdrkreg_t	pi_gfx_credit_mode_regval;
-	struct	{
-		bdrkreg_t	gcm_rsvd		  :	63;
-		bdrkreg_t	gcm_trans_mode		  :	 1;
-	} pi_gfx_credit_mode_fld_s;
-} pi_gfx_credit_mode_u_t;
-
-#endif
-
-
-
-/************************************************************************
- *                                                                      *
- *  This location contains a 55-bit read/write counter that wraps to    *
- * zero when the maximum value is reached. This counter is              *
- * incremented at each rising edge of the global clock (GCLK). This     *
- * register is in its own 64KB page so that it can be mapped to user    *
- * space.                                                               *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_rt_counter_u {
-	bdrkreg_t	pi_rt_counter_regval;
-	struct  {
-		bdrkreg_t	rc_count                  :	55;
-		bdrkreg_t       rc_rsvd                   :      9;
-	} pi_rt_counter_fld_s;
-} pi_rt_counter_u_t;
-
-#else
-
-typedef union pi_rt_counter_u {
-	bdrkreg_t	pi_rt_counter_regval;
-	struct	{
-		bdrkreg_t	rc_rsvd			  :	 9;
-		bdrkreg_t	rc_count		  :	55;
-	} pi_rt_counter_fld_s;
-} pi_rt_counter_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register controls the performance counters for one CPU.        *
- * There are two counters for each CPU. Each counter can be             *
- * configured to count a variety of events. The performance counter     *
- * registers for each processor are in their own 64KB page so that      *
- * they can be mapped to user space.                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_perf_cntl_a_u {
-	bdrkreg_t	pi_perf_cntl_a_regval;
-	struct  {
-		bdrkreg_t	pca_cntr_0_select         :	28;
-                bdrkreg_t       pca_cntr_0_mode           :      3;
-                bdrkreg_t       pca_cntr_0_enable         :      1;
-                bdrkreg_t       pca_cntr_1_select         :     28;
-                bdrkreg_t       pca_cntr_1_mode           :      3;
-                bdrkreg_t       pca_cntr_1_enable         :      1;
-	} pi_perf_cntl_a_fld_s;
-} pi_perf_cntl_a_u_t;
-
-#else
-
-typedef union pi_perf_cntl_a_u {
-	bdrkreg_t	pi_perf_cntl_a_regval;
-	struct	{
-		bdrkreg_t	pca_cntr_1_enable	  :	 1;
-		bdrkreg_t	pca_cntr_1_mode		  :	 3;
-		bdrkreg_t	pca_cntr_1_select	  :	28;
-		bdrkreg_t	pca_cntr_0_enable	  :	 1;
-		bdrkreg_t	pca_cntr_0_mode		  :	 3;
-		bdrkreg_t	pca_cntr_0_select	  :	28;
-	} pi_perf_cntl_a_fld_s;
-} pi_perf_cntl_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register accesses the performance counter 0 for each CPU.      *
- * Each performance counter is 40-bits wide. On overflow, It wraps to   *
- * zero, sets the overflow bit in this register, and sets the           *
- * PERF_CNTR_OFLOW bit in the INT_PEND1 register.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_perf_cntr0_a_u {
-	bdrkreg_t	pi_perf_cntr0_a_regval;
-	struct  {
-		bdrkreg_t	pca_count_value           :	40;
-                bdrkreg_t       pca_overflow              :      1;
-                bdrkreg_t       pca_rsvd                  :     23;
-	} pi_perf_cntr0_a_fld_s;
-} pi_perf_cntr0_a_u_t;
-
-#else
-
-typedef union pi_perf_cntr0_a_u {
-	bdrkreg_t	pi_perf_cntr0_a_regval;
-	struct	{
-		bdrkreg_t	pca_rsvd		  :	23;
-		bdrkreg_t	pca_overflow		  :	 1;
-		bdrkreg_t	pca_count_value		  :	40;
-	} pi_perf_cntr0_a_fld_s;
-} pi_perf_cntr0_a_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register accesses the performance counter 1for each CPU.       *
- * Each performance counter is 40-bits wide. On overflow, It wraps to   *
- * zero, sets the overflow bit in this register, and sets the           *
- * PERF_CNTR_OFLOW bit in the INT_PEND1 register.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_perf_cntr1_a_u {
-	bdrkreg_t	pi_perf_cntr1_a_regval;
-	struct  {
-		bdrkreg_t	pca_count_value           :	40;
-                bdrkreg_t       pca_overflow              :      1;
-                bdrkreg_t       pca_rsvd                  :     23;
-	} pi_perf_cntr1_a_fld_s;
-} pi_perf_cntr1_a_u_t;
-
-#else
-
-typedef union pi_perf_cntr1_a_u {
-	bdrkreg_t	pi_perf_cntr1_a_regval;
-	struct	{
-		bdrkreg_t	pca_rsvd		  :	23;
-		bdrkreg_t	pca_overflow		  :	 1;
-		bdrkreg_t	pca_count_value		  :	40;
-	} pi_perf_cntr1_a_fld_s;
-} pi_perf_cntr1_a_u_t;
-
-#endif
-
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register controls the performance counters for one CPU.        *
- * There are two counters for each CPU. Each counter can be             *
- * configured to count a variety of events. The performance counter     *
- * registers for each processor are in their own 64KB page so that      *
- * they can be mapped to user space.                                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_perf_cntl_b_u {
-	bdrkreg_t	pi_perf_cntl_b_regval;
-	struct  {
-		bdrkreg_t	pcb_cntr_0_select         :	28;
-                bdrkreg_t       pcb_cntr_0_mode           :      3;
-                bdrkreg_t       pcb_cntr_0_enable         :      1;
-                bdrkreg_t       pcb_cntr_1_select         :     28;
-                bdrkreg_t       pcb_cntr_1_mode           :      3;
-                bdrkreg_t       pcb_cntr_1_enable         :      1;
-	} pi_perf_cntl_b_fld_s;
-} pi_perf_cntl_b_u_t;
-
-#else
-
-typedef union pi_perf_cntl_b_u {
-	bdrkreg_t	pi_perf_cntl_b_regval;
-	struct	{
-		bdrkreg_t	pcb_cntr_1_enable	  :	 1;
-		bdrkreg_t	pcb_cntr_1_mode		  :	 3;
-		bdrkreg_t	pcb_cntr_1_select	  :	28;
-		bdrkreg_t	pcb_cntr_0_enable	  :	 1;
-		bdrkreg_t	pcb_cntr_0_mode		  :	 3;
-		bdrkreg_t	pcb_cntr_0_select	  :	28;
-	} pi_perf_cntl_b_fld_s;
-} pi_perf_cntl_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register accesses the performance counter 0 for each CPU.      *
- * Each performance counter is 40-bits wide. On overflow, It wraps to   *
- * zero, sets the overflow bit in this register, and sets the           *
- * PERF_CNTR_OFLOW bit in the INT_PEND1 register.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_perf_cntr0_b_u {
-	bdrkreg_t	pi_perf_cntr0_b_regval;
-	struct  {
-		bdrkreg_t	pcb_count_value           :	40;
-                bdrkreg_t       pcb_overflow              :      1;
-                bdrkreg_t       pcb_rsvd                  :     23;
-	} pi_perf_cntr0_b_fld_s;
-} pi_perf_cntr0_b_u_t;
-
-#else
-
-typedef union pi_perf_cntr0_b_u {
-	bdrkreg_t	pi_perf_cntr0_b_regval;
-	struct	{
-		bdrkreg_t	pcb_rsvd		  :	23;
-		bdrkreg_t	pcb_overflow		  :	 1;
-		bdrkreg_t	pcb_count_value		  :	40;
-	} pi_perf_cntr0_b_fld_s;
-} pi_perf_cntr0_b_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  This register accesses the performance counter 1for each CPU.       *
- * Each performance counter is 40-bits wide. On overflow, It wraps to   *
- * zero, sets the overflow bit in this register, and sets the           *
- * PERF_CNTR_OFLOW bit in the INT_PEND1 register.                       *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union pi_perf_cntr1_b_u {
-	bdrkreg_t	pi_perf_cntr1_b_regval;
-	struct  {
-		bdrkreg_t	pcb_count_value           :	40;
-                bdrkreg_t       pcb_overflow              :      1;
-                bdrkreg_t       pcb_rsvd                  :     23;
-	} pi_perf_cntr1_b_fld_s;
-} pi_perf_cntr1_b_u_t;
-
-#else
-
-typedef union pi_perf_cntr1_b_u {
-	bdrkreg_t	pi_perf_cntr1_b_regval;
-	struct	{
-		bdrkreg_t	pcb_rsvd		  :	23;
-		bdrkreg_t	pcb_overflow		  :	 1;
-		bdrkreg_t	pcb_count_value		  :	40;
-	} pi_perf_cntr1_b_fld_s;
-} pi_perf_cntr1_b_u_t;
-
-#endif
-
-
-
-
-
-
-#endif /* __ASSEMBLY__ */
-
-/************************************************************************
- *                                                                      *
- *               MAKE ALL ADDITIONS AFTER THIS LINE                     *
- *                                                                      *
- ************************************************************************/
-
-
-#define PI_GFX_OFFSET		(PI_GFX_PAGE_B - PI_GFX_PAGE_A)
-#define PI_GFX_PAGE_ENABLE	0x0000010000000000LL
-
-
-#endif /* _ASM_IA64_SN_SN1_HUBPI_H */
diff -Nru a/include/asm-ia64/sn/sn1/hubpi_next.h b/include/asm-ia64/sn/sn1/hubpi_next.h
--- a/include/asm-ia64/sn/sn1/hubpi_next.h	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,331 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBPI_NEXT_H
-#define _ASM_IA64_SN_SN1_HUBPI_NEXT_H
-
-
-/* define for remote PI_1 space. It is always half of a node_addressspace
- * from PI_0. The normal REMOTE_HUB space for PI registers access
- * the PI_0 space, unless they are qualified by PI_1.
- */
-#define PI_0(x)			(x)
-#define PI_1(x)			((x) + 0x200000)
-#define PIREG(x,sn)		((sn) ? PI_1(x) : PI_0(x))
-
-#define PI_MIN_STACK_SIZE 4096  /* For figuring out the size to set */
-#define PI_STACK_SIZE_SHFT      12      /* 4k */
-
-#define PI_STACKADDR_OFFSET     (PI_ERR_STACK_ADDR_B - PI_ERR_STACK_ADDR_A)
-#define PI_ERRSTAT_OFFSET       (PI_ERR_STATUS0_B - PI_ERR_STATUS0_A)
-#define PI_RDCLR_OFFSET         (PI_ERR_STATUS0_A_RCLR - PI_ERR_STATUS0_A)
-/* these macros are correct, but fix their users to understand two PIs
-   and 4 CPUs (slices) per bedrock */
-#define PI_INT_MASK_OFFSET      (PI_INT_MASK0_B - PI_INT_MASK0_A)
-#define PI_INT_SET_OFFSET       (PI_CC_PEND_CLR_B - PI_CC_PEND_CLR_A)
-#define PI_NMI_OFFSET		(PI_NMI_B - PI_NMI_A)
-
-#define ERR_STACK_SIZE_BYTES(_sz) \
-       ((_sz) ? (PI_MIN_STACK_SIZE << ((_sz) - 1)) : 0)
-
-#define PI_CRB_STS_P	(1 << 9) 	/* "P" (partial word read/write) bit */
-#define PI_CRB_STS_V	(1 << 8)	/* "V" (valid) bit */
-#define PI_CRB_STS_R	(1 << 7)	/* "R" (response data sent to CPU) */
-#define PI_CRB_STS_A	(1 << 6)	/* "A" (data ack. received) bit */
-#define PI_CRB_STS_W	(1 << 5)	/* "W" (waiting for write compl.) */
-#define PI_CRB_STS_H	(1 << 4)	/* "H" (gathering invalidates) bit */
-#define PI_CRB_STS_I	(1 << 3)	/* "I" (targ. inbound invalidate) */
-#define PI_CRB_STS_T	(1 << 2)	/* "T" (targ. inbound intervention) */
-#define PI_CRB_STS_E	(0x3)		/* "E" (coherent read type) */
-
-/* When the "P" bit is set in the sk_crb_sts field of an error stack
- * entry, the "R," "A," "H," and "I" bits are actually bits 6..3 of
- * the address.  This macro extracts those address bits and shifts
- * them to their proper positions, ready to be ORed in to the rest of
- * the address (which is calculated as sk_addr << 7).
- */
-#define PI_CRB_STS_ADDR_BITS(sts) \
-    ((sts) & (PI_CRB_STS_I | PI_CRB_STS_H) | \
-     ((sts) & (PI_CRB_STS_A | PI_CRB_STS_R)) >> 1)
-
-#ifndef __ASSEMBLY__
-/*
- * format of error stack and error status registers.
- */
-
-#ifdef LITTLE_ENDIAN
-
-struct err_stack_format {
-        uint64_t      sk_err_type:  3,   /* error type        */
-                        sk_suppl   :  3,   /* lowest 3 bit of supplemental */
-                        sk_t5_req  :  3,   /* RRB T5 request number */
-                        sk_crb_num :  3,   /* WRB (0 to 7) or RRB (0 to 4) */
-                        sk_rw_rb   :  1,   /* RRB == 0, WRB == 1 */
-                        sk_crb_sts : 10,   /* status from RRB or WRB */
-                        sk_cmd     :  8,   /* message command */
-			sk_addr    : 33;   /* address */
-};
-
-#else
-
-struct err_stack_format {
-	uint64_t	sk_addr	   : 33,   /* address */
-			sk_cmd	   :  8,   /* message command */
-			sk_crb_sts : 10,   /* status from RRB or WRB */
-			sk_rw_rb   :  1,   /* RRB == 0, WRB == 1 */
-			sk_crb_num :  3,   /* WRB (0 to 7) or RRB (0 to 4) */
-			sk_t5_req  :  3,   /* RRB T5 request number */
-			sk_suppl   :  3,   /* lowest 3 bit of supplemental */
-			sk_err_type:  3;   /* error type	*/
-};
-
-#endif
-
-typedef union pi_err_stack {
-        uint64_t      pi_stk_word;
-        struct  err_stack_format pi_stk_fmt;
-} pi_err_stack_t;
-
-/* Simplified version of pi_err_status0_a_u_t (PI_ERR_STATUS0_A) */
-#ifdef LITTLE_ENDIAN
-
-struct err_status0_format {
-	uint64_t	s0_err_type	:  3,	/* Encoded error cause */
-                        s0_proc_req_num :  3,   /* Request number for RRB only */
-                        s0_supplemental : 11,   /* ncoming message sup field */
-                        s0_cmd          :  8,   /* Incoming message command */
-                        s0_addr         : 37,   /* Address */
-                        s0_over_run     :  1,   /* Subsequent errors spooled */
-			s0_valid        :  1;   /* error is valid */
-};
-
-#else
-
-struct err_status0_format {
-	uint64_t	s0_valid	:  1,	/* error is valid */
-			s0_over_run	:  1,	/* Subsequent errors spooled */
-			s0_addr		: 37,	/* Address */
-			s0_cmd		:  8,	/* Incoming message command */
-			s0_supplemental : 11,	/* ncoming message sup field */
-			s0_proc_req_num :  3,	/* Request number for RRB only */
-			s0_err_type	:  3;	/* Encoded error cause */
-};
-
-#endif
-
-
-typedef union pi_err_stat0 {
-	uint64_t	pi_stat0_word;
-        struct err_status0_format pi_stat0_fmt;
-} pi_err_stat0_t;
-
-/* Simplified version of pi_err_status1_a_u_t (PI_ERR_STATUS1_A) */
-
-#ifdef LITTLE_ENDIAN
-
-struct err_status1_format {
-	 uint64_t	s1_spl_cnt : 21,   /* number spooled to memory */
-                        s1_to_cnt  :  8,   /* crb timeout counter */
-                        s1_inval_cnt:10,   /* signed invalidate counter RRB */
-                        s1_crb_num :  3,   /* WRB (0 to 7) or RRB (0 to 4) */
-                        s1_rw_rb   :  1,   /* RRB == 0, WRB == 1 */
-                        s1_crb_sts : 10,   /* status from RRB or WRB */
-			s1_src     : 11;   /* message source */
-};
-
-#else
-
-struct err_status1_format {
-	uint64_t	s1_src	   : 11,   /* message source */
-			s1_crb_sts : 10,   /* status from RRB or WRB */
-			s1_rw_rb   :  1,   /* RRB == 0, WRB == 1 */
-			s1_crb_num :  3,   /* WRB (0 to 7) or RRB (0 to 4) */
-			s1_inval_cnt:10,   /* signed invalidate counter RRB */
-			s1_to_cnt  :  8,   /* crb timeout counter */
-			s1_spl_cnt : 21;   /* number spooled to memory */
-};
-
-#endif
-
-typedef union pi_err_stat1 {
-	uint64_t	pi_stat1_word;
-	struct err_status1_format pi_stat1_fmt;
-} pi_err_stat1_t;
-#endif
-
-/* Error stack types (sk_err_type) for reads:	*/
-#define PI_ERR_RD_AERR		0	/* Read Access Error */
-#define PI_ERR_RD_PRERR         1	/* Uncached Partitial Read */
-#define PI_ERR_RD_DERR          2	/* Directory Error */
-#define PI_ERR_RD_TERR          3	/* read timeout */
-#define PI_ERR_RD_PERR		4	/* Poison Access Violation */
-#define PI_ERR_RD_NACK		5	/* Excessive NACKs	*/
-#define PI_ERR_RD_RDE		6	/* Response Data Error	*/
-#define PI_ERR_RD_PLERR		7	/* Packet Length Error */
-/* Error stack types (sk_err_type) for writes:	*/
-#define PI_ERR_WR_WERR          0	/* Write Access Error */
-#define PI_ERR_WR_PWERR         1	/* Uncached Write Error */
-#define PI_ERR_WR_TERR          3	/* write timeout */
-#define PI_ERR_WR_RDE		6	/* Response Data Error */
-#define PI_ERR_WR_PLERR		7	/* Packet Length Error */
-
-
-/* For backwards compatibility */
-#define PI_RT_COUNT	PI_RT_COUNTER    /* Real Time Counter 		    */
-#define PI_RT_EN_A	PI_RT_INT_EN_A   /* RT int for CPU A enable         */
-#define PI_RT_EN_B	PI_RT_INT_EN_B   /* RT int for CPU B enable         */
-#define PI_PROF_EN_A	PI_PROF_INT_EN_A /* PROF int for CPU A enable       */
-#define PI_PROF_EN_B	PI_PROF_INT_EN_B /* PROF int for CPU B enable       */
-#define PI_RT_PEND_A    PI_RT_INT_PEND_A /* RT interrupt pending 	    */
-#define PI_RT_PEND_B    PI_RT_INT_PEND_B /* RT interrupt pending 	    */
-#define PI_PROF_PEND_A  PI_PROF_INT_PEND_A /* Profiling interrupt pending   */
-#define PI_PROF_PEND_B  PI_PROF_INT_PEND_B /* Profiling interrupt pending   */
-
-
-/* Bits in PI_SYSAD_ERRCHK_EN */
-#define PI_SYSAD_ERRCHK_ECCGEN  0x01    /* Enable ECC generation            */
-#define PI_SYSAD_ERRCHK_QUALGEN 0x02    /* Enable data quality signal gen.  */
-#define PI_SYSAD_ERRCHK_SADP    0x04    /* Enable SysAD parity checking     */
-#define PI_SYSAD_ERRCHK_CMDP    0x08    /* Enable SysCmd parity checking    */
-#define PI_SYSAD_ERRCHK_STATE   0x10    /* Enable SysState parity checking  */
-#define PI_SYSAD_ERRCHK_QUAL    0x20    /* Enable data quality checking     */
-#define PI_SYSAD_CHECK_ALL      0x3f    /* Generate and check all signals.  */
-
-/* CALIAS values */
-#define PI_CALIAS_SIZE_0        0
-#define PI_CALIAS_SIZE_4K       1
-#define PI_CALIAS_SIZE_8K       2
-#define PI_CALIAS_SIZE_16K      3
-#define PI_CALIAS_SIZE_32K      4
-#define PI_CALIAS_SIZE_64K      5
-#define PI_CALIAS_SIZE_128K     6
-#define PI_CALIAS_SIZE_256K     7
-#define PI_CALIAS_SIZE_512K     8
-#define PI_CALIAS_SIZE_1M       9
-#define PI_CALIAS_SIZE_2M       10
-#define PI_CALIAS_SIZE_4M       11
-#define PI_CALIAS_SIZE_8M       12
-#define PI_CALIAS_SIZE_16M      13
-#define PI_CALIAS_SIZE_32M      14
-#define PI_CALIAS_SIZE_64M      15
-
-/* Fields in PI_ERR_STATUS0_[AB] */
-#define PI_ERR_ST0_VALID_MASK	0x8000000000000000
-#define PI_ERR_ST0_VALID_SHFT	63
-
-/* Fields in PI_SPURIOUS_HDR_0 */
-#define PI_SPURIOUS_HDR_VALID_MASK	0x8000000000000000
-#define PI_SPURIOUS_HDR_VALID_SHFT	63
-
-/* Fields in PI_NACK_CNT_A/B */
-#define PI_NACK_CNT_EN_SHFT	20
-#define PI_NACK_CNT_EN_MASK	0x100000
-#define PI_NACK_CNT_MASK	0x0fffff
-#define PI_NACK_CNT_MAX		0x0fffff
-
-/* Bits in PI_ERR_INT_PEND */
-#define PI_ERR_SPOOL_CMP_B	0x000000001	/* Spool end hit high water */
-#define PI_ERR_SPOOL_CMP_A	0x000000002
-#define PI_ERR_SPUR_MSG_B	0x000000004	/* Spurious message intr.   */
-#define PI_ERR_SPUR_MSG_A	0x000000008
-#define PI_ERR_WRB_TERR_B	0x000000010	/* WRB TERR		    */
-#define PI_ERR_WRB_TERR_A	0x000000020
-#define PI_ERR_WRB_WERR_B	0x000000040	/* WRB WERR 		    */
-#define PI_ERR_WRB_WERR_A	0x000000080
-#define PI_ERR_SYSSTATE_B	0x000000100	/* SysState parity error    */
-#define PI_ERR_SYSSTATE_A	0x000000200
-#define PI_ERR_SYSAD_DATA_B	0x000000400	/* SysAD data parity error  */
-#define PI_ERR_SYSAD_DATA_A	0x000000800
-#define PI_ERR_SYSAD_ADDR_B	0x000001000	/* SysAD addr parity error  */
-#define PI_ERR_SYSAD_ADDR_A	0x000002000
-#define PI_ERR_SYSCMD_DATA_B	0x000004000	/* SysCmd data parity error */
-#define PI_ERR_SYSCMD_DATA_A	0x000008000
-#define PI_ERR_SYSCMD_ADDR_B	0x000010000	/* SysCmd addr parity error */
-#define PI_ERR_SYSCMD_ADDR_A	0x000020000
-#define PI_ERR_BAD_SPOOL_B	0x000040000	/* Error spooling to memory */
-#define PI_ERR_BAD_SPOOL_A	0x000080000
-#define PI_ERR_UNCAC_UNCORR_B	0x000100000	/* Uncached uncorrectable   */
-#define PI_ERR_UNCAC_UNCORR_A	0x000200000
-#define PI_ERR_SYSSTATE_TAG_B	0x000400000	/* SysState tag parity error */
-#define PI_ERR_SYSSTATE_TAG_A	0x000800000
-#define PI_ERR_MD_UNCORR	0x001000000	/* Must be cleared in MD    */
-#define PI_ERR_SYSAD_BAD_DATA_B	0x002000000	/* SysAD Data quality bad   */
-#define PI_ERR_SYSAD_BAD_DATA_A	0x004000000
-#define PI_ERR_UE_CACHED_B	0x008000000	/* UE during cached load    */
-#define PI_ERR_UE_CACHED_A	0x010000000
-#define PI_ERR_PKT_LEN_ERR_B	0x020000000	/* Xbar data too long/short */
-#define PI_ERR_PKT_LEN_ERR_A	0x040000000
-#define PI_ERR_IRB_ERR_B	0x080000000	/* Protocol error           */
-#define PI_ERR_IRB_ERR_A	0x100000000
-#define PI_ERR_IRB_TIMEOUT_B	0x200000000	/* IRB_B got a timeout      */
-#define PI_ERR_IRB_TIMEOUT_A	0x400000000
-
-#define PI_ERR_CLEAR_ALL_A	0x554aaaaaa
-#define PI_ERR_CLEAR_ALL_B	0x2aa555555
-
-
-/*
- * The following three macros define all possible error int pends. 
- */
-
-#define PI_FATAL_ERR_CPU_A	(PI_ERR_IRB_TIMEOUT_A	| \
-				 PI_ERR_IRB_ERR_A	| \
-				 PI_ERR_PKT_LEN_ERR_A	| \
-				 PI_ERR_SYSSTATE_TAG_A 	| \
-				 PI_ERR_BAD_SPOOL_A 	| \
-				 PI_ERR_SYSCMD_ADDR_A 	| \
-				 PI_ERR_SYSCMD_DATA_A 	| \
-				 PI_ERR_SYSAD_ADDR_A 	| \
-				 PI_ERR_SYSAD_DATA_A	| \
-				 PI_ERR_SYSSTATE_A)
-
-#define PI_MISC_ERR_CPU_A	(PI_ERR_UE_CACHED_A	| \
-				 PI_ERR_SYSAD_BAD_DATA_A| \
-				 PI_ERR_UNCAC_UNCORR_A 	| \
-				 PI_ERR_WRB_WERR_A 	| \
-				 PI_ERR_WRB_TERR_A 	| \
-				 PI_ERR_SPUR_MSG_A 	| \
-				 PI_ERR_SPOOL_CMP_A)
-
-#define PI_FATAL_ERR_CPU_B	(PI_ERR_IRB_TIMEOUT_B	| \
-				 PI_ERR_IRB_ERR_B	| \
-				 PI_ERR_PKT_LEN_ERR_B	| \
-				 PI_ERR_SYSSTATE_TAG_B 	| \
-				 PI_ERR_BAD_SPOOL_B 	| \
-				 PI_ERR_SYSCMD_ADDR_B 	| \
-				 PI_ERR_SYSCMD_DATA_B 	| \
-				 PI_ERR_SYSAD_ADDR_B 	| \
-				 PI_ERR_SYSAD_DATA_B	| \
-				 PI_ERR_SYSSTATE_B)
-
-#define PI_MISC_ERR_CPU_B	(PI_ERR_UE_CACHED_B	| \
-				 PI_ERR_SYSAD_BAD_DATA_B| \
-				 PI_ERR_UNCAC_UNCORR_B 	| \
-				 PI_ERR_WRB_WERR_B 	| \
-				 PI_ERR_WRB_TERR_B 	| \
-				 PI_ERR_SPUR_MSG_B 	| \
-				 PI_ERR_SPOOL_CMP_B)
-
-#define PI_ERR_GENERIC	(PI_ERR_MD_UNCORR)
-
-/* Values for PI_MAX_CRB_TIMEOUT and PI_CRB_SFACTOR */
-#define PMCT_MAX	0xff
-#define PCS_MAX		0xffffff
-
-/* pi_err_status0_a_u_t address shift */
-#define ERR_STAT0_ADDR_SHFT     3
-
-/* PI error read/write bit (RRB == 0, WRB == 1)	*/
-/* pi_err_status1_a_u_t.pi_err_status1_a_fld_s.esa_wrb */
-#define PI_ERR_RRB	0
-#define PI_ERR_WRB	1
-
-/* Error stack address shift, for use with pi_stk_fmt.sk_addr */
-#define ERR_STK_ADDR_SHFT	3
-
-#endif /* _ASM_IA64_SN_SN1_HUBPI_NEXT_H */
diff -Nru a/include/asm-ia64/sn/sn1/hubspc.h b/include/asm-ia64/sn/sn1/hubspc.h
--- a/include/asm-ia64/sn/sn1/hubspc.h	Wed Jun 18 23:42:09 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,24 +0,0 @@
-/*
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBSPC_H
-#define _ASM_IA64_SN_SN1_HUBSPC_H
-
-typedef enum {
-        HUBSPC_REFCOUNTERS,
-	HUBSPC_PROM
-} hubspc_subdevice_t;
-
-
-/*
- * Reference Counters
- */
-
-extern int refcounters_attach(devfs_handle_t hub);
-
-#endif /* _ASM_IA64_SN_SN1_HUBSPC_H */        
diff -Nru a/include/asm-ia64/sn/sn1/hubstat.h b/include/asm-ia64/sn/sn1/hubstat.h
--- a/include/asm-ia64/sn/sn1/hubstat.h	Wed Jun 18 23:42:05 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,56 +0,0 @@
-/*
- * 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) 2000 - 2001 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_SN1_HUBSTAT_H
-#define _ASM_IA64_SN_SN1_HUBSTAT_H
-
-typedef int64_t 	hub_count_t;
-
-#define HUBSTAT_VERSION	1
-
-typedef struct hubstat_s {
-        char            hs_version;		/* structure version    */
-        cnodeid_t       hs_cnode;       	/* cnode of this hub    */
-        nasid_t         hs_nasid;       	/* Nasid of same        */	
-	int64_t		hs_timebase;		/* Time of first sample */
-	int64_t		hs_timestamp;		/* Time of last sample	*/
-	int64_t		hs_per_minute;		/* Ticks per minute 	*/
-
-	union {
-		hubreg_t	hs_niu_stat_rev_id; /* SN0: Status rev ID */
-		hubreg_t	hs_niu_port_status; /* SN1: Port status */
-	} hs_niu;
-
-        hub_count_t	hs_ni_retry_errors;	/* Total retry errors   */
-        hub_count_t	hs_ni_sn_errors;	/* Total sn errors      */
-        hub_count_t	hs_ni_cb_errors;	/* Total cb errors      */
-        int		hs_ni_overflows;	/* NI count overflows   */
-        hub_count_t	hs_ii_sn_errors;	/* Total sn errors      */
-        hub_count_t	hs_ii_cb_errors;	/* Total cb errors      */
-        int		hs_ii_overflows;	/* II count overflows   */
-
-	/*
-	 * Anything below this comment is intended for kernel internal-use
-	 * only and may be changed at any time.
-	 *
-	 * Any members that contain pointers or are conditionally compiled
-	 * need to be below here also.
-	 */
-        int64_t		hs_last_print;		/* When we last printed */
-        char		hs_print;		/* Should we print      */
-
-	char	       *hs_name;		/* This hub's name */
-	unsigned char	hs_maint;		/* Should we print to availmon */
-} hubstat_t;
-
-#define       hs_ni_stat_rev_id       hs_niu.hs_niu_stat_rev_id
-#define       hs_ni_port_status       hs_niu.hs_niu_port_status
-
-extern struct file_operations hub_mon_fops;
-
-#endif /* _ASM_IA64_SN_SN1_HUBSTAT_H */
diff -Nru a/include/asm-ia64/sn/sn1/hubxb.h b/include/asm-ia64/sn/sn1/hubxb.h
--- a/include/asm-ia64/sn/sn1/hubxb.h	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,1288 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBXB_H
-#define _ASM_IA64_SN_SN1_HUBXB_H
-
-/************************************************************************
- *                                                                      *
- *      WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!  WARNING!!!      *
- *                                                                      *
- * This file is created by an automated script. Any (minimal) changes   *
- * made manually to this  file should be made with care.                *
- *                                                                      *
- *               MAKE ALL ADDITIONS TO THE END OF THIS FILE             *
- *                                                                      *
- ************************************************************************/
-
-
-#define    XB_PARMS                  0x00700000    /*
-                                                    * Controls
-                                                    * crossbar-wide
-                                                    * parameters.
-                                                    */
-
-
-
-#define    XB_SLOW_GNT               0x00700008    /*
-                                                    * Controls wavefront
-                                                    * arbiter grant
-                                                    * frequency, used to
-                                                    * slow XB grants
-                                                    */
-
-
-
-#define    XB_SPEW_CONTROL           0x00700010    /*
-                                                    * Controls spew
-                                                    * settings (debug
-                                                    * only).
-                                                    */
-
-
-
-#define    XB_IOQ_ARB_TRIGGER        0x00700018    /*
-                                                    * Controls IOQ
-                                                    * trigger level
-                                                    */
-
-
-
-#define    XB_FIRST_ERROR            0x00700090    /*
-                                                    * Records the first
-                                                    * crossbar error
-                                                    * seen.
-                                                    */
-
-
-
-#define    XB_POQ0_ERROR             0x00700020    /*
-                                                    * POQ0 error
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_PIQ0_ERROR             0x00700028    /*
-                                                    * PIQ0 error
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_POQ1_ERROR             0x00700030    /*
-                                                    * POQ1 error
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_PIQ1_ERROR             0x00700038    /*
-                                                    * PIQ1 error
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_MP0_ERROR              0x00700040    /*
-                                                    * MOQ for PI0 error
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_MP1_ERROR              0x00700048    /*
-                                                    * MOQ for PI1 error
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_MMQ_ERROR              0x00700050    /*
-                                                    * MOQ for misc. (LB,
-                                                    * NI, II) error
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_MIQ_ERROR              0x00700058    /*
-                                                    * MIQ error register,
-                                                    * addtional MIQ
-                                                    * errors are logged
-                                                    * in MD &quot;Input
-                                                    * Error
-                                                    * Registers&quot;.
-                                                    */
-
-
-
-#define    XB_NOQ_ERROR              0x00700060    /* NOQ error register.    */
-
-
-
-#define    XB_NIQ_ERROR              0x00700068    /* NIQ error register.    */
-
-
-
-#define    XB_IOQ_ERROR              0x00700070    /* IOQ error register.    */
-
-
-
-#define    XB_IIQ_ERROR              0x00700078    /* IIQ error register.    */
-
-
-
-#define    XB_LOQ_ERROR              0x00700080    /* LOQ error register.    */
-
-
-
-#define    XB_LIQ_ERROR              0x00700088    /* LIQ error register.    */
-
-
-
-#define    XB_DEBUG_DATA_CTL         0x00700098    /*
-                                                    * Debug Datapath
-                                                    * Select
-                                                    */
-
-
-
-#define    XB_DEBUG_ARB_CTL          0x007000A0    /*
-                                                    * XB master debug
-                                                    * control
-                                                    */
-
-
-
-#define    XB_POQ0_ERROR_CLEAR       0x00700120    /*
-                                                    * Clears
-                                                    * XB_POQ0_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_PIQ0_ERROR_CLEAR       0x00700128    /*
-                                                    * Clears
-                                                    * XB_PIQ0_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_POQ1_ERROR_CLEAR       0x00700130    /*
-                                                    * Clears
-                                                    * XB_POQ1_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_PIQ1_ERROR_CLEAR       0x00700138    /*
-                                                    * Clears
-                                                    * XB_PIQ1_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_MP0_ERROR_CLEAR        0x00700140    /*
-                                                    * Clears XB_MP0_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_MP1_ERROR_CLEAR        0x00700148    /*
-                                                    * Clears XB_MP1_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_MMQ_ERROR_CLEAR        0x00700150    /*
-                                                    * Clears XB_MMQ_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_XM_MIQ_ERROR_CLEAR     0x00700158    /*
-                                                    * Clears XB_MIQ_ERROR
-                                                    * register
-                                                    */
-
-
-
-#define    XB_NOQ_ERROR_CLEAR        0x00700160    /*
-                                                    * Clears XB_NOQ_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_NIQ_ERROR_CLEAR        0x00700168    /*
-                                                    * Clears XB_NIQ_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_IOQ_ERROR_CLEAR        0x00700170    /*
-                                                    * Clears XB_IOQ
-                                                    * _ERROR register.
-                                                    */
-
-
-
-#define    XB_IIQ_ERROR_CLEAR        0x00700178    /*
-                                                    * Clears XB_IIQ
-                                                    * _ERROR register.
-                                                    */
-
-
-
-#define    XB_LOQ_ERROR_CLEAR        0x00700180    /*
-                                                    * Clears XB_LOQ_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_LIQ_ERROR_CLEAR        0x00700188    /*
-                                                    * Clears XB_LIQ_ERROR
-                                                    * register.
-                                                    */
-
-
-
-#define    XB_FIRST_ERROR_CLEAR      0x00700190    /*
-                                                    * Clears
-                                                    * XB_FIRST_ERROR
-                                                    * register
-                                                    */
-
-
-
-
-
-#ifndef __ASSEMBLY__
-
-/************************************************************************
- *                                                                      *
- *  Access to parameters which control various aspects of the           *
- * crossbar's operation.                                                *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_parms_u {
-	bdrkreg_t	xb_parms_regval;
-	struct  {
-		bdrkreg_t	p_byp_en                  :	 1;
-                bdrkreg_t       p_rsrvd_1                 :      3;
-                bdrkreg_t       p_age_wrap                :      8;
-                bdrkreg_t       p_deadlock_to_wrap        :     20;
-                bdrkreg_t       p_tail_to_wrap            :     20;
-                bdrkreg_t       p_rsrvd                   :     12;
-	} xb_parms_fld_s;
-} xb_parms_u_t;
-
-#else
-
-typedef union xb_parms_u {
-	bdrkreg_t	xb_parms_regval;
-	struct	{
-		bdrkreg_t	p_rsrvd			  :	12;
-		bdrkreg_t	p_tail_to_wrap		  :	20;
-		bdrkreg_t	p_deadlock_to_wrap	  :	20;
-		bdrkreg_t	p_age_wrap		  :	 8;
-		bdrkreg_t	p_rsrvd_1		  :	 3;
-		bdrkreg_t	p_byp_en		  :	 1;
-	} xb_parms_fld_s;
-} xb_parms_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Sets the period of wavefront grants given to each unit. The         *
- * register's value corresponds to the number of cycles between each    *
- * wavefront grant opportunity given to the requesting unit. If set     *
- * to 0xF, no grants are given to this unit. If set to 0xE, the unit    *
- * is granted at the slowest rate (sometimes called "molasses mode").   *
- * This feature can be used to apply backpressure to a unit's output    *
- * queue(s). The setting does not affect bypass grants.                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_slow_gnt_u {
-	bdrkreg_t	xb_slow_gnt_regval;
-	struct  {
-		bdrkreg_t	sg_lb_slow_gnt            :	 4;
-                bdrkreg_t       sg_ii_slow_gnt            :      4;
-                bdrkreg_t       sg_ni_slow_gnt            :      4;
-                bdrkreg_t       sg_mmq_slow_gnt           :      4;
-                bdrkreg_t       sg_mp1_slow_gnt           :      4;
-                bdrkreg_t       sg_mp0_slow_gnt           :      4;
-                bdrkreg_t       sg_pi1_slow_gnt           :      4;
-                bdrkreg_t       sg_pi0_slow_gnt           :      4;
-                bdrkreg_t       sg_rsrvd                  :     32;
-	} xb_slow_gnt_fld_s;
-} xb_slow_gnt_u_t;
-
-#else
-
-typedef union xb_slow_gnt_u {
-	bdrkreg_t	xb_slow_gnt_regval;
-	struct	{
-		bdrkreg_t	sg_rsrvd		  :	32;
-		bdrkreg_t	sg_pi0_slow_gnt		  :	 4;
-		bdrkreg_t	sg_pi1_slow_gnt		  :	 4;
-		bdrkreg_t	sg_mp0_slow_gnt		  :	 4;
-		bdrkreg_t	sg_mp1_slow_gnt		  :	 4;
-		bdrkreg_t	sg_mmq_slow_gnt		  :	 4;
-		bdrkreg_t	sg_ni_slow_gnt		  :	 4;
-		bdrkreg_t	sg_ii_slow_gnt		  :	 4;
-		bdrkreg_t	sg_lb_slow_gnt		  :	 4;
-	} xb_slow_gnt_fld_s;
-} xb_slow_gnt_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Enables snooping of internal crossbar traffic by spewing all        *
- * traffic across a selected crossbar point to the PI1 port. Only one   *
- * bit should be set at any one time, and any bit set will preclude     *
- * using the P1 for anything but a debug connection.                    *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_spew_control_u {
-	bdrkreg_t	xb_spew_control_regval;
-	struct  {
-		bdrkreg_t	sc_snoop_liq              :	 1;
-                bdrkreg_t       sc_snoop_iiq              :      1;
-                bdrkreg_t       sc_snoop_niq              :      1;
-                bdrkreg_t       sc_snoop_miq              :      1;
-                bdrkreg_t       sc_snoop_piq0             :      1;
-                bdrkreg_t       sc_snoop_loq              :      1;
-                bdrkreg_t       sc_snoop_ioq              :      1;
-                bdrkreg_t       sc_snoop_noq              :      1;
-                bdrkreg_t       sc_snoop_mmq              :      1;
-                bdrkreg_t       sc_snoop_mp0              :      1;
-                bdrkreg_t       sc_snoop_poq0             :      1;
-                bdrkreg_t       sc_rsrvd                  :     53;
-	} xb_spew_control_fld_s;
-} xb_spew_control_u_t;
-
-#else
-
-typedef union xb_spew_control_u {
-	bdrkreg_t	xb_spew_control_regval;
-	struct	{
-		bdrkreg_t	sc_rsrvd		  :	53;
-		bdrkreg_t	sc_snoop_poq0		  :	 1;
-		bdrkreg_t	sc_snoop_mp0		  :	 1;
-		bdrkreg_t	sc_snoop_mmq		  :	 1;
-		bdrkreg_t	sc_snoop_noq		  :	 1;
-		bdrkreg_t	sc_snoop_ioq		  :	 1;
-		bdrkreg_t	sc_snoop_loq		  :	 1;
-		bdrkreg_t	sc_snoop_piq0		  :	 1;
-		bdrkreg_t	sc_snoop_miq		  :	 1;
-		bdrkreg_t	sc_snoop_niq		  :	 1;
-		bdrkreg_t	sc_snoop_iiq		  :	 1;
-		bdrkreg_t	sc_snoop_liq		  :	 1;
-	} xb_spew_control_fld_s;
-} xb_spew_control_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Number of clocks the IOQ will wait before beginning XB              *
- * arbitration. This is set so that the slower IOQ data rate can        *
- * catch up up with the XB data rate in the IOQ buffer.                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_ioq_arb_trigger_u {
-	bdrkreg_t	xb_ioq_arb_trigger_regval;
-	struct  {
-		bdrkreg_t	iat_ioq_arb_trigger       :	 4;
-	        bdrkreg_t       iat_rsrvd                 :     60;
-	} xb_ioq_arb_trigger_fld_s;
-} xb_ioq_arb_trigger_u_t;
-
-#else
-
-typedef union xb_ioq_arb_trigger_u {
-	bdrkreg_t	xb_ioq_arb_trigger_regval;
-	struct	{
-		bdrkreg_t	iat_rsrvd		  :	60;
-		bdrkreg_t	iat_ioq_arb_trigger	  :	 4;
-	} xb_ioq_arb_trigger_fld_s;
-} xb_ioq_arb_trigger_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by POQ0.Can be written to test software, will   *
- * cause an interrupt.                                                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_poq0_error_u {
-	bdrkreg_t	xb_poq0_error_regval;
-	struct  {
-		bdrkreg_t	pe_invalid_xsel           :	 2;
-                bdrkreg_t       pe_rsrvd_3                :      2;
-                bdrkreg_t       pe_overflow               :      2;
-                bdrkreg_t       pe_rsrvd_2                :      2;
-                bdrkreg_t       pe_underflow              :      2;
-                bdrkreg_t       pe_rsrvd_1                :      2;
-                bdrkreg_t       pe_tail_timeout           :      2;
-                bdrkreg_t       pe_unused                 :      6;
-                bdrkreg_t       pe_rsrvd                  :     44;
-	} xb_poq0_error_fld_s;
-} xb_poq0_error_u_t;
-
-#else
-
-typedef union xb_poq0_error_u {
-	bdrkreg_t	xb_poq0_error_regval;
-	struct	{
-		bdrkreg_t	pe_rsrvd		  :	44;
-		bdrkreg_t	pe_unused		  :	 6;
-		bdrkreg_t	pe_tail_timeout		  :	 2;
-		bdrkreg_t	pe_rsrvd_1		  :	 2;
-		bdrkreg_t	pe_underflow		  :	 2;
-		bdrkreg_t	pe_rsrvd_2		  :	 2;
-		bdrkreg_t	pe_overflow		  :	 2;
-		bdrkreg_t	pe_rsrvd_3		  :	 2;
-		bdrkreg_t	pe_invalid_xsel		  :	 2;
-	} xb_poq0_error_fld_s;
-} xb_poq0_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by PIQ0. Note that the PIQ/PI interface         *
- * precludes PIQ underflow.                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_piq0_error_u {
-	bdrkreg_t	xb_piq0_error_regval;
-	struct  {
-		bdrkreg_t	pe_overflow               :	 2;
-                bdrkreg_t       pe_rsrvd_1                :      2;
-                bdrkreg_t       pe_deadlock_timeout       :      2;
-                bdrkreg_t       pe_rsrvd                  :     58;
-	} xb_piq0_error_fld_s;
-} xb_piq0_error_u_t;
-
-#else
-
-typedef union xb_piq0_error_u {
-	bdrkreg_t	xb_piq0_error_regval;
-	struct	{
-		bdrkreg_t	pe_rsrvd		  :	58;
-		bdrkreg_t	pe_deadlock_timeout	  :	 2;
-		bdrkreg_t	pe_rsrvd_1		  :	 2;
-		bdrkreg_t	pe_overflow		  :	 2;
-	} xb_piq0_error_fld_s;
-} xb_piq0_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by MP0 queue (the MOQ for processor 0). Since   *
- * the xselect is decoded on the MD/MOQ interface, no invalid xselect   *
- * errors are possible.                                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_mp0_error_u {
-	bdrkreg_t	xb_mp0_error_regval;
-	struct  {
-		bdrkreg_t	me_rsrvd_3                :	 4;
-                bdrkreg_t       me_overflow               :      2;
-                bdrkreg_t       me_rsrvd_2                :      2;
-                bdrkreg_t       me_underflow              :      2;
-                bdrkreg_t       me_rsrvd_1                :      2;
-                bdrkreg_t       me_tail_timeout           :      2;
-                bdrkreg_t       me_rsrvd                  :     50;
-	} xb_mp0_error_fld_s;
-} xb_mp0_error_u_t;
-
-#else
-
-typedef union xb_mp0_error_u {
-	bdrkreg_t	xb_mp0_error_regval;
-	struct	{
-		bdrkreg_t	me_rsrvd		  :	50;
-		bdrkreg_t	me_tail_timeout		  :	 2;
-		bdrkreg_t	me_rsrvd_1		  :	 2;
-		bdrkreg_t	me_underflow		  :	 2;
-		bdrkreg_t	me_rsrvd_2		  :	 2;
-		bdrkreg_t	me_overflow		  :	 2;
-		bdrkreg_t	me_rsrvd_3		  :	 4;
-	} xb_mp0_error_fld_s;
-} xb_mp0_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by MIQ.                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_miq_error_u {
-	bdrkreg_t	xb_miq_error_regval;
-	struct  {
-		bdrkreg_t	me_rsrvd_1                :	 4;
-                bdrkreg_t       me_deadlock_timeout       :      4;
-                bdrkreg_t       me_rsrvd                  :     56;
-	} xb_miq_error_fld_s;
-} xb_miq_error_u_t;
-
-#else
-
-typedef union xb_miq_error_u {
-	bdrkreg_t	xb_miq_error_regval;
-	struct	{
-		bdrkreg_t	me_rsrvd		  :	56;
-		bdrkreg_t	me_deadlock_timeout	  :	 4;
-		bdrkreg_t	me_rsrvd_1		  :	 4;
-	} xb_miq_error_fld_s;
-} xb_miq_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by NOQ.                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_noq_error_u {
-	bdrkreg_t	xb_noq_error_regval;
-	struct  {
-		bdrkreg_t	ne_rsvd                   :	 4;
-                bdrkreg_t       ne_overflow               :      4;
-                bdrkreg_t       ne_underflow              :      4;
-                bdrkreg_t       ne_tail_timeout           :      4;
-                bdrkreg_t       ne_rsrvd                  :     48;
-	} xb_noq_error_fld_s;
-} xb_noq_error_u_t;
-
-#else
-
-typedef union xb_noq_error_u {
-	bdrkreg_t	xb_noq_error_regval;
-	struct	{
-		bdrkreg_t	ne_rsrvd		  :	48;
-		bdrkreg_t	ne_tail_timeout		  :	 4;
-		bdrkreg_t	ne_underflow		  :	 4;
-		bdrkreg_t	ne_overflow		  :	 4;
-		bdrkreg_t	ne_rsvd			  :	 4;
-	} xb_noq_error_fld_s;
-} xb_noq_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by LOQ.                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_loq_error_u {
-	bdrkreg_t	xb_loq_error_regval;
-	struct  {
-		bdrkreg_t	le_invalid_xsel           :	 2;
-                bdrkreg_t       le_rsrvd_1                :      6;
-                bdrkreg_t       le_underflow              :      2;
-                bdrkreg_t       le_rsvd                   :      2;
-                bdrkreg_t       le_tail_timeout           :      2;
-                bdrkreg_t       le_rsrvd                  :     50;
-	} xb_loq_error_fld_s;
-} xb_loq_error_u_t;
-
-#else
-
-typedef union xb_loq_error_u {
-	bdrkreg_t	xb_loq_error_regval;
-	struct	{
-		bdrkreg_t	le_rsrvd		  :	50;
-		bdrkreg_t	le_tail_timeout		  :	 2;
-		bdrkreg_t	le_rsvd			  :	 2;
-		bdrkreg_t	le_underflow		  :	 2;
-		bdrkreg_t	le_rsrvd_1		  :	 6;
-		bdrkreg_t	le_invalid_xsel		  :	 2;
-	} xb_loq_error_fld_s;
-} xb_loq_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by LIQ. Note that the LIQ only records errors   *
- * for the request channel. The reply channel can never deadlock or     *
- * overflow because it does not have hardware flow control.             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_liq_error_u {
-	bdrkreg_t	xb_liq_error_regval;
-	struct  {
-		bdrkreg_t	le_overflow               :	 1;
-                bdrkreg_t       le_rsrvd_1                :      3;
-                bdrkreg_t       le_deadlock_timeout       :      1;
-                bdrkreg_t       le_rsrvd                  :     59;
-	} xb_liq_error_fld_s;
-} xb_liq_error_u_t;
-
-#else
-
-typedef union xb_liq_error_u {
-	bdrkreg_t	xb_liq_error_regval;
-	struct	{
-		bdrkreg_t	le_rsrvd		  :	59;
-		bdrkreg_t	le_deadlock_timeout	  :	 1;
-		bdrkreg_t	le_rsrvd_1		  :	 3;
-		bdrkreg_t	le_overflow		  :	 1;
-	} xb_liq_error_fld_s;
-} xb_liq_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  First error is latched whenever the Valid bit is clear and an       *
- * error occurs. Any valid bit on in this register causes an            *
- * interrupt to PI0 and PI1. This interrupt bit will persist until      *
- * the specific error register to capture the error is cleared, then    *
- * the FIRST_ERROR register is cleared (in that oder.) The              *
- * FIRST_ERROR register is not writable, but will be set when any of    *
- * the corresponding error registers are written by software.           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_first_error_u {
-	bdrkreg_t	xb_first_error_regval;
-	struct  {
-		bdrkreg_t	fe_type                   :	 4;
-                bdrkreg_t       fe_channel                :      4;
-                bdrkreg_t       fe_source                 :      4;
-                bdrkreg_t       fe_valid                  :      1;
-                bdrkreg_t       fe_rsrvd                  :     51;
-	} xb_first_error_fld_s;
-} xb_first_error_u_t;
-
-#else
-
-typedef union xb_first_error_u {
-	bdrkreg_t	xb_first_error_regval;
-	struct	{
-		bdrkreg_t	fe_rsrvd		  :	51;
-		bdrkreg_t	fe_valid		  :	 1;
-		bdrkreg_t	fe_source		  :	 4;
-		bdrkreg_t	fe_channel		  :	 4;
-		bdrkreg_t	fe_type			  :	 4;
-	} xb_first_error_fld_s;
-} xb_first_error_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Controls DEBUG_DATA mux setting. Allows user to watch the output    *
- * of any OQ or input of any IQ on the DEBUG port. Note that bits       *
- * 13:0 are one-hot. If more than one bit is set in [13:0], the debug   *
- * output is undefined. Details on the debug output lines can be        *
- * found in the XB chapter of the Bedrock Interface Specification.      *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_debug_data_ctl_u {
-	bdrkreg_t	xb_debug_data_ctl_regval;
-	struct  {
-		bdrkreg_t	ddc_observe_liq_traffic   :	 1;
-                bdrkreg_t       ddc_observe_iiq_traffic   :      1;
-                bdrkreg_t       ddc_observe_niq_traffic   :      1;
-                bdrkreg_t       ddc_observe_miq_traffic   :      1;
-                bdrkreg_t       ddc_observe_piq1_traffic  :      1;
-                bdrkreg_t       ddc_observe_piq0_traffic  :      1;
-                bdrkreg_t       ddc_observe_loq_traffic   :      1;
-                bdrkreg_t       ddc_observe_ioq_traffic   :      1;
-                bdrkreg_t       ddc_observe_noq_traffic   :      1;
-                bdrkreg_t       ddc_observe_mp1_traffic   :      1;
-                bdrkreg_t       ddc_observe_mp0_traffic   :      1;
-                bdrkreg_t       ddc_observe_mmq_traffic   :      1;
-                bdrkreg_t       ddc_observe_poq1_traffic  :      1;
-                bdrkreg_t       ddc_observe_poq0_traffic  :      1;
-                bdrkreg_t       ddc_observe_source_field  :      1;
-                bdrkreg_t       ddc_observe_lodata        :      1;
-                bdrkreg_t       ddc_rsrvd                 :     48;
-	} xb_debug_data_ctl_fld_s;
-} xb_debug_data_ctl_u_t;
-
-#else
-
-typedef union xb_debug_data_ctl_u {
-	bdrkreg_t	xb_debug_data_ctl_regval;
-	struct	{
-		bdrkreg_t	ddc_rsrvd		  :	48;
-		bdrkreg_t	ddc_observe_lodata	  :	 1;
-		bdrkreg_t	ddc_observe_source_field  :	 1;
-		bdrkreg_t	ddc_observe_poq0_traffic  :	 1;
-		bdrkreg_t	ddc_observe_poq1_traffic  :	 1;
-		bdrkreg_t	ddc_observe_mmq_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_mp0_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_mp1_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_noq_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_ioq_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_loq_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_piq0_traffic  :	 1;
-		bdrkreg_t	ddc_observe_piq1_traffic  :	 1;
-		bdrkreg_t	ddc_observe_miq_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_niq_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_iiq_traffic	  :	 1;
-		bdrkreg_t	ddc_observe_liq_traffic	  :	 1;
-	} xb_debug_data_ctl_fld_s;
-} xb_debug_data_ctl_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Controls debug mux setting for XB Input/Output Queues and           *
- * Arbiter. Can select one of the following values. Details on the      *
- * debug output lines can be found in the XB chapter of the Bedrock     *
- * Interface Specification.                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_debug_arb_ctl_u {
-	bdrkreg_t	xb_debug_arb_ctl_regval;
-	struct  {
-		bdrkreg_t	dac_xb_debug_select       :	 3;
-		bdrkreg_t       dac_rsrvd                 :     61;
-	} xb_debug_arb_ctl_fld_s;
-} xb_debug_arb_ctl_u_t;
-
-#else
-
-typedef union xb_debug_arb_ctl_u {
-        bdrkreg_t       xb_debug_arb_ctl_regval;
-        struct  {
-                bdrkreg_t       dac_rsrvd                 :     61;
-                bdrkreg_t       dac_xb_debug_select       :      3;
-        } xb_debug_arb_ctl_fld_s;
-} xb_debug_arb_ctl_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by POQ0.Can be written to test software, will   *
- * cause an interrupt.                                                  *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_poq0_error_clear_u {
-	bdrkreg_t	xb_poq0_error_clear_regval;
-	struct  {
-		bdrkreg_t	pec_invalid_xsel          :	 2;
-                bdrkreg_t       pec_rsrvd_3               :      2;
-                bdrkreg_t       pec_overflow              :      2;
-                bdrkreg_t       pec_rsrvd_2               :      2;
-                bdrkreg_t       pec_underflow             :      2;
-                bdrkreg_t       pec_rsrvd_1               :      2;
-                bdrkreg_t       pec_tail_timeout          :      2;
-                bdrkreg_t       pec_unused                :      6;
-                bdrkreg_t       pec_rsrvd                 :     44;
-	} xb_poq0_error_clear_fld_s;
-} xb_poq0_error_clear_u_t;
-
-#else
-
-typedef union xb_poq0_error_clear_u {
-	bdrkreg_t	xb_poq0_error_clear_regval;
-	struct	{
-		bdrkreg_t	pec_rsrvd		  :	44;
-		bdrkreg_t	pec_unused		  :	 6;
-		bdrkreg_t	pec_tail_timeout	  :	 2;
-		bdrkreg_t	pec_rsrvd_1		  :	 2;
-		bdrkreg_t	pec_underflow		  :	 2;
-		bdrkreg_t	pec_rsrvd_2		  :	 2;
-		bdrkreg_t	pec_overflow		  :	 2;
-		bdrkreg_t	pec_rsrvd_3		  :	 2;
-		bdrkreg_t	pec_invalid_xsel	  :	 2;
-	} xb_poq0_error_clear_fld_s;
-} xb_poq0_error_clear_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by PIQ0. Note that the PIQ/PI interface         *
- * precludes PIQ underflow.                                             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_piq0_error_clear_u {
-	bdrkreg_t	xb_piq0_error_clear_regval;
-	struct  {
-		bdrkreg_t	pec_overflow              :	 2;
-                bdrkreg_t       pec_rsrvd_1               :      2;
-                bdrkreg_t       pec_deadlock_timeout      :      2;
-                bdrkreg_t       pec_rsrvd                 :     58;
-	} xb_piq0_error_clear_fld_s;
-} xb_piq0_error_clear_u_t;
-
-#else
-
-typedef union xb_piq0_error_clear_u {
-	bdrkreg_t	xb_piq0_error_clear_regval;
-	struct	{
-		bdrkreg_t	pec_rsrvd		  :	58;
-		bdrkreg_t	pec_deadlock_timeout	  :	 2;
-		bdrkreg_t	pec_rsrvd_1		  :	 2;
-		bdrkreg_t	pec_overflow		  :	 2;
-	} xb_piq0_error_clear_fld_s;
-} xb_piq0_error_clear_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by MP0 queue (the MOQ for processor 0). Since   *
- * the xselect is decoded on the MD/MOQ interface, no invalid xselect   *
- * errors are possible.                                                 *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_mp0_error_clear_u {
-	bdrkreg_t	xb_mp0_error_clear_regval;
-	struct  {
-		bdrkreg_t	mec_rsrvd_3               :	 4;
-                bdrkreg_t       mec_overflow              :      2;
-                bdrkreg_t       mec_rsrvd_2               :      2;
-                bdrkreg_t       mec_underflow             :      2;
-                bdrkreg_t       mec_rsrvd_1               :      2;
-                bdrkreg_t       mec_tail_timeout          :      2;
-                bdrkreg_t       mec_rsrvd                 :     50;
-	} xb_mp0_error_clear_fld_s;
-} xb_mp0_error_clear_u_t;
-
-#else
-
-typedef union xb_mp0_error_clear_u {
-	bdrkreg_t	xb_mp0_error_clear_regval;
-	struct	{
-		bdrkreg_t	mec_rsrvd		  :	50;
-		bdrkreg_t	mec_tail_timeout	  :	 2;
-		bdrkreg_t	mec_rsrvd_1		  :	 2;
-		bdrkreg_t	mec_underflow		  :	 2;
-		bdrkreg_t	mec_rsrvd_2		  :	 2;
-		bdrkreg_t	mec_overflow		  :	 2;
-		bdrkreg_t	mec_rsrvd_3		  :	 4;
-	} xb_mp0_error_clear_fld_s;
-} xb_mp0_error_clear_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by MIQ.                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_xm_miq_error_clear_u {
-	bdrkreg_t	xb_xm_miq_error_clear_regval;
-	struct  {
-		bdrkreg_t	xmec_rsrvd_1              :	 4;
-                bdrkreg_t       xmec_deadlock_timeout     :      4;
-                bdrkreg_t       xmec_rsrvd                :     56;
-	} xb_xm_miq_error_clear_fld_s;
-} xb_xm_miq_error_clear_u_t;
-
-#else
-
-typedef union xb_xm_miq_error_clear_u {
-	bdrkreg_t	xb_xm_miq_error_clear_regval;
-	struct	{
-		bdrkreg_t	xmec_rsrvd		  :	56;
-		bdrkreg_t	xmec_deadlock_timeout	  :	 4;
-		bdrkreg_t	xmec_rsrvd_1		  :	 4;
-	} xb_xm_miq_error_clear_fld_s;
-} xb_xm_miq_error_clear_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by NOQ.                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_noq_error_clear_u {
-	bdrkreg_t	xb_noq_error_clear_regval;
-	struct  {
-		bdrkreg_t	nec_rsvd                  :	 4;
-                bdrkreg_t       nec_overflow              :      4;
-                bdrkreg_t       nec_underflow             :      4;
-                bdrkreg_t       nec_tail_timeout          :      4;
-                bdrkreg_t       nec_rsrvd                 :     48;
-	} xb_noq_error_clear_fld_s;
-} xb_noq_error_clear_u_t;
-
-#else
-
-typedef union xb_noq_error_clear_u {
-	bdrkreg_t	xb_noq_error_clear_regval;
-	struct	{
-		bdrkreg_t	nec_rsrvd		  :	48;
-		bdrkreg_t	nec_tail_timeout	  :	 4;
-		bdrkreg_t	nec_underflow		  :	 4;
-		bdrkreg_t	nec_overflow		  :	 4;
-		bdrkreg_t	nec_rsvd		  :	 4;
-	} xb_noq_error_clear_fld_s;
-} xb_noq_error_clear_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by LOQ.                                         *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_loq_error_clear_u {
-	bdrkreg_t	xb_loq_error_clear_regval;
-	struct  {
-		bdrkreg_t	lec_invalid_xsel          :	 2;
-                bdrkreg_t       lec_rsrvd_1               :      6;
-                bdrkreg_t       lec_underflow             :      2;
-                bdrkreg_t       lec_rsvd                  :      2;
-                bdrkreg_t       lec_tail_timeout          :      2;
-                bdrkreg_t       lec_rsrvd                 :     50;
-	} xb_loq_error_clear_fld_s;
-} xb_loq_error_clear_u_t;
-
-#else
-
-typedef union xb_loq_error_clear_u {
-	bdrkreg_t	xb_loq_error_clear_regval;
-	struct	{
-		bdrkreg_t	lec_rsrvd		  :	50;
-		bdrkreg_t	lec_tail_timeout	  :	 2;
-		bdrkreg_t	lec_rsvd		  :	 2;
-		bdrkreg_t	lec_underflow		  :	 2;
-		bdrkreg_t	lec_rsrvd_1		  :	 6;
-		bdrkreg_t	lec_invalid_xsel	  :	 2;
-	} xb_loq_error_clear_fld_s;
-} xb_loq_error_clear_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  Records errors seen by LIQ. Note that the LIQ only records errors   *
- * for the request channel. The reply channel can never deadlock or     *
- * overflow because it does not have hardware flow control.             *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_liq_error_clear_u {
-	bdrkreg_t	xb_liq_error_clear_regval;
-	struct  {
-		bdrkreg_t	lec_overflow              :	 1;
-                bdrkreg_t       lec_rsrvd_1               :      3;
-                bdrkreg_t       lec_deadlock_timeout      :      1;
-                bdrkreg_t       lec_rsrvd                 :     59;
-	} xb_liq_error_clear_fld_s;
-} xb_liq_error_clear_u_t;
-
-#else
-
-typedef union xb_liq_error_clear_u {
-        bdrkreg_t       xb_liq_error_clear_regval;
-        struct  {
-                bdrkreg_t       lec_rsrvd                 :     59;
-                bdrkreg_t       lec_deadlock_timeout      :      1;
-                bdrkreg_t       lec_rsrvd_1               :      3;
-                bdrkreg_t       lec_overflow              :      1;
-        } xb_liq_error_clear_fld_s;
-} xb_liq_error_clear_u_t;
-
-#endif
-
-
-
-
-/************************************************************************
- *                                                                      *
- *  First error is latched whenever the Valid bit is clear and an       *
- * error occurs. Any valid bit on in this register causes an            *
- * interrupt to PI0 and PI1. This interrupt bit will persist until      *
- * the specific error register to capture the error is cleared, then    *
- * the FIRST_ERROR register is cleared (in that oder.) The              *
- * FIRST_ERROR register is not writable, but will be set when any of    *
- * the corresponding error registers are written by software.           *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-#ifdef LITTLE_ENDIAN
-
-typedef union xb_first_error_clear_u {
-	bdrkreg_t	xb_first_error_clear_regval;
-	struct  {
-		bdrkreg_t	fec_type                  :	 4;
-                bdrkreg_t       fec_channel               :      4;
-                bdrkreg_t       fec_source                :      4;
-                bdrkreg_t       fec_valid                 :      1;
-                bdrkreg_t       fec_rsrvd                 :     51;
-	} xb_first_error_clear_fld_s;
-} xb_first_error_clear_u_t;
-
-#else
-
-typedef union xb_first_error_clear_u {
-	bdrkreg_t	xb_first_error_clear_regval;
-	struct	{
-		bdrkreg_t	fec_rsrvd		  :	51;
-		bdrkreg_t	fec_valid		  :	 1;
-		bdrkreg_t	fec_source		  :	 4;
-		bdrkreg_t	fec_channel		  :	 4;
-		bdrkreg_t	fec_type		  :	 4;
-	} xb_first_error_clear_fld_s;
-} xb_first_error_clear_u_t;
-
-#endif
-
-
-
-
-
-
-#endif /* __ASSEMBLY__ */
-
-/************************************************************************
- *                                                                      *
- * The following defines were not formed into structures                *
- *                                                                      *
- * This could be because the document did not contain details of the    *
- * register, or because the automated script did not recognize the      *
- * register details in the documentation. If these register need        *
- * structure definition, please create them manually                    *
- *                                                                      *
- *           XB_POQ1_ERROR            0x700030                          *
- *           XB_PIQ1_ERROR            0x700038                          *
- *           XB_MP1_ERROR             0x700048                          *
- *           XB_MMQ_ERROR             0x700050                          *
- *           XB_NIQ_ERROR             0x700068                          *
- *           XB_IOQ_ERROR             0x700070                          *
- *           XB_IIQ_ERROR             0x700078                          *
- *           XB_POQ1_ERROR_CLEAR      0x700130                          *
- *           XB_PIQ1_ERROR_CLEAR      0x700138                          *
- *           XB_MP1_ERROR_CLEAR       0x700148                          *
- *           XB_MMQ_ERROR_CLEAR       0x700150                          *
- *           XB_NIQ_ERROR_CLEAR       0x700168                          *
- *           XB_IOQ_ERROR_CLEAR       0x700170                          *
- *           XB_IIQ_ERROR_CLEAR       0x700178                          *
- *                                                                      *
- ************************************************************************/
-
-
-/************************************************************************
- *                                                                      *
- *               MAKE ALL ADDITIONS AFTER THIS LINE                     *
- *                                                                      *
- ************************************************************************/
-
-
-
-
-
-#endif /* _ASM_IA64_SN_SN1_HUBXB_H */
diff -Nru a/include/asm-ia64/sn/sn1/hubxb_next.h b/include/asm-ia64/sn/sn1/hubxb_next.h
--- a/include/asm-ia64/sn/sn1/hubxb_next.h	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,32 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HUBXB_NEXT_H
-#define _ASM_IA64_SN_SN1_HUBXB_NEXT_H
-
-/* XB_FIRST_ERROR fe_source field encoding */
-#define XVE_SOURCE_POQ0 0xf	/* 1111 */
-#define XVE_SOURCE_PIQ0 0xe	/* 1110 */
-#define XVE_SOURCE_POQ1 0xd	/* 1101 */
-#define XVE_SOURCE_PIQ1 0xc	/* 1100 */
-#define XVE_SOURCE_MP0  0xb	/* 1011 */
-#define XVE_SOURCE_MP1  0xa	/* 1010 */
-#define XVE_SOURCE_MMQ  0x9	/* 1001 */
-#define XVE_SOURCE_MIQ  0x8	/* 1000 */
-#define XVE_SOURCE_NOQ  0x7	/* 0111 */
-#define XVE_SOURCE_NIQ  0x6	/* 0110 */
-#define XVE_SOURCE_IOQ  0x5	/* 0101 */
-#define XVE_SOURCE_IIQ  0x4	/* 0100 */
-#define XVE_SOURCE_LOQ  0x3	/* 0011 */
-#define XVE_SOURCE_LIQ  0x2	/* 0010 */
-
-/* XB_PARMS fields */
-#define XBP_RESET_DEFAULTS	0x0008000080000021LL
-#define XBP_ACTIVE_DEFAULTS	0x00080000fffff021LL
-
-#endif /* _ASM_IA64_SN_SN1_HUBXB_NEXT_H */
diff -Nru a/include/asm-ia64/sn/sn1/hwcntrs.h b/include/asm-ia64/sn/sn1/hwcntrs.h
--- a/include/asm-ia64/sn/sn1/hwcntrs.h	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,96 +0,0 @@
-/*
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_HWCNTRS_H
-#define _ASM_IA64_SN_SN1_HWCNTRS_H
-
-
-typedef  uint64_t refcnt_t;
-
-#define SN0_REFCNT_MAX_COUNTERS 64
-
-typedef struct sn0_refcnt_set {
-	refcnt_t    refcnt[SN0_REFCNT_MAX_COUNTERS];
-        uint64_t  flags;
-        uint64_t  reserved[4];
-} sn0_refcnt_set_t;
-
-typedef struct sn0_refcnt_buf {
-	sn0_refcnt_set_t   refcnt_set;
-	uint64_t         paddr;
-        uint64_t         page_size;
-        cnodeid_t          cnodeid;         /* cnodeid + pad[3] use 64 bits */
-        uint16_t           pad[3];
-        uint64_t         reserved[4];
-} sn0_refcnt_buf_t;
-
-typedef struct sn0_refcnt_args {
-	uint64_t          vaddr;
-	uint64_t          len;
-	sn0_refcnt_buf_t*   buf;
-        uint64_t          reserved[4];
-} sn0_refcnt_args_t;
-
-/*
- * Info needed by the user level program
- * to mmap the refcnt buffer
- */
-
-#define RCB_INFO_GET  1
-#define RCB_SLOT_GET  2
-
-typedef struct rcb_info {
-        uint64_t  rcb_len;                  /* total refcnt buffer len in bytes */
-
-        int         rcb_sw_sets;              /* number of sw counter sets in buffer */
-        int         rcb_sw_counters_per_set;  /* sw counters per set -- num_compact_nodes */
-        int         rcb_sw_counter_size;      /* sizeof(refcnt_t) -- size of sw cntr */
-
-        int         rcb_base_pages;           /* number of base pages in node */
-        int         rcb_base_page_size;       /* sw base page size */        
-        uint64_t  rcb_base_paddr;           /* base physical address for this node */
-
-        int         rcb_cnodeid;              /* cnodeid for this node */
-        int         rcb_granularity;          /* hw page size used for counter sets */
-        uint        rcb_hw_counter_max;       /* max hwcounter count (width mask) */
-        int         rcb_diff_threshold;       /* current node differential threshold */
-        int         rcb_abs_threshold;        /* current node absolute threshold */
-        int         rcb_num_slots;            /* physmem slots */
-        
-        int         rcb_reserved[512];
-        
-} rcb_info_t;
-
-typedef struct rcb_slot {
-        uint64_t  base;
-        uint64_t  size;
-} rcb_slot_t;
-
-#if defined(__KERNEL__)
-typedef struct sn0_refcnt_args_32 {
-	uint64_t    vaddr;
-	uint64_t    len;
-	app32_ptr_t   buf;
-        uint64_t    reserved[4];
-} sn0_refcnt_args_32_t;
-
-/* Defines and Macros  */
-/* A set of reference counts are for 4k bytes of physical memory */
-#define	NBPREFCNTP	0x1000	
-#define	BPREFCNTPSHIFT	12
-#define bytes_to_refcntpages(x)	(((__psunsigned_t)(x)+(NBPREFCNTP-1))>>BPREFCNTPSHIFT)
-#define refcntpage_offset(x)	((__psunsigned_t)(x)&((NBPP-1)&~(NBPREFCNTP-1)))
-#define align_to_refcntpage(x)	((__psunsigned_t)(x)&(~(NBPREFCNTP-1)))
-
-extern void migr_refcnt_read(sn0_refcnt_buf_t*);
-extern void migr_refcnt_read_extended(sn0_refcnt_buf_t*);
-extern int migr_refcnt_enabled(void);
-
-#endif /* __KERNEL__ */
-
-#endif /* _ASM_IA64_SN_SN1_HWCNTRS_H */
diff -Nru a/include/asm-ia64/sn/sn1/intr.h b/include/asm-ia64/sn/sn1/intr.h
--- a/include/asm-ia64/sn/sn1/intr.h	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,237 +0,0 @@
-/* $Id: intr.h,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_INTR_H
-#define _ASM_IA64_SN_SN1_INTR_H
-
-/* Subnode wildcard */
-#define SUBNODE_ANY		(-1)
-
-/* Number of interrupt levels associated with each interrupt register. */
-#define N_INTPEND_BITS		64
-
-#define INT_PEND0_BASELVL	0
-#define INT_PEND1_BASELVL	64
-
-#define	N_INTPENDJUNK_BITS	8
-#define	INTPENDJUNK_CLRBIT	0x80
-
-#include <asm/sn/intr_public.h>
-#include <asm/sn/driver.h>
-#include <asm/sn/xtalk/xtalk.h>
-#include <asm/sn/hack.h>
-
-#ifndef __ASSEMBLY__
-#define II_NAMELEN	24
-
-/*
- * Dispatch table entry - contains information needed to call an interrupt
- * routine.
- */
-typedef struct intr_vector_s {
-	intr_func_t	iv_func;	/* Interrupt handler function */
-	intr_func_t	iv_prefunc;	/* Interrupt handler prologue func */
-	void		*iv_arg;	/* Argument to pass to handler */
-	cpuid_t			iv_mustruncpu;	/* Where we must run. */
-} intr_vector_t;
-
-/* Interrupt information table. */
-typedef struct intr_info_s {
-	xtalk_intr_setfunc_t	ii_setfunc;	/* Function to set the interrupt
-						 * destination and level register.
-						 * It returns 0 (success) or an
-						 * error code.
-						 */
-	void			*ii_cookie;	/* arg passed to setfunc */
-	devfs_handle_t		ii_owner_dev;	/* device that owns this intr */
-	char			ii_name[II_NAMELEN];	/* Name of this intr. */
-	int			ii_flags;	/* informational flags */
-} intr_info_t;
-
-
-#define THD_CREATED	0x00000001	/*
-					 * We've created a thread for this
-					 * interrupt.
-					 */
-
-/*
- * Bits for ii_flags:
- */
-#define II_UNRESERVE	0
-#define II_RESERVE	1		/* Interrupt reserved. 			*/
-#define II_INUSE	2		/* Interrupt connected 			*/
-#define II_ERRORINT	4		/* INterrupt is an error condition 	*/
-#define II_THREADED	8		/* Interrupt handler is threaded.	*/
-
-/*
- * Interrupt level wildcard
- */
-#define INTRCONNECT_ANYBIT	(-1)
-
-/*
- * This structure holds information needed both to call and to maintain
- * interrupts.  The two are in separate arrays for the locality benefits.
- * Since there's only one set of vectors per hub chip (but more than one
- * CPU, the lock to change the vector tables must be here rather than in
- * the PDA.
- */
-
-typedef struct intr_vecblk_s {
-	intr_vector_t	vectors[N_INTPEND_BITS];  /* information needed to
-						     call an intr routine. */
-	intr_info_t	info[N_INTPEND_BITS];	  /* information needed only
-						     to maintain interrupts. */
-	spinlock_t	vector_lock;		  /* Lock for this and the
-						     masks in the PDA. */
-	splfunc_t	vector_spl;		  /* vector_lock req'd spl */
-	int		vector_state;		  /* Initialized to zero.
-						     Set to INTR_INITED
-						     by hubintr_init.
-						   */
-	int		vector_count;		  /* Number of vectors
-						   * reserved.
-						   */
-	int		cpu_count[CPUS_PER_SUBNODE]; /* How many interrupts are
-						   * connected to each CPU
-						   */
-	int		ithreads_enabled;	  /* Are interrupt threads
-						   * initialized on this node.
-						   * and block?
-						   */
-} intr_vecblk_t;
-
-/* Possible values for vector_state: */
-#define VECTOR_UNINITED	0
-#define VECTOR_INITED	1
-#define VECTOR_SET	2
-
-#define hub_intrvect0	private.p_intmasks.dispatch0->vectors
-#define hub_intrvect1	private.p_intmasks.dispatch1->vectors
-#define hub_intrinfo0	private.p_intmasks.dispatch0->info
-#define hub_intrinfo1	private.p_intmasks.dispatch1->info
-
-/*
- * Macros to manipulate the interrupt register on the calling hub chip.
- */
-
-#define LOCAL_HUB_SEND_INTR(_level)	LOCAL_HUB_S(PI_INT_PEND_MOD, \
-						    (0x100|(_level)))
-#define REMOTE_HUB_PI_SEND_INTR(_hub, _sn, _level) \
-		REMOTE_HUB_PI_S((_hub), _sn, PI_INT_PEND_MOD, (0x100|(_level)))
-
-#define REMOTE_CPU_SEND_INTR(_cpuid, _level) 					\
-		REMOTE_HUB_PI_S(cpuid_to_nasid(_cpuid),				\
-			SUBNODE(cpuid_to_slice(_cpuid)),				\
-			PI_INT_PEND_MOD, (0x100|(_level)))
-
-/*
- * When clearing the interrupt, make sure this clear does make it 
- * to the hub. Otherwise we could end up losing interrupts.
- * We do an uncached load of the int_pend0 register to ensure this.
- */
-
-#define LOCAL_HUB_CLR_INTR(_level)	  \
-                LOCAL_HUB_S(PI_INT_PEND_MOD, (_level)),	\
-                LOCAL_HUB_L(PI_INT_PEND0)
-#define REMOTE_HUB_PI_CLR_INTR(_hub, _sn, _level) \
-		REMOTE_HUB_PI_S((_hub), (_sn), PI_INT_PEND_MOD, (_level)),	\
-                REMOTE_HUB_PI_L((_hub), (_sn), PI_INT_PEND0)
-
-/* Special support for use by gfx driver only.  Supports special gfx hub interrupt. */
-extern void install_gfxintr(cpuid_t cpu, ilvl_t swlevel, intr_func_t intr_func, void *intr_arg);
-
-void setrtvector(intr_func_t func);
-
-/*
- * Interrupt blocking
- */
-extern void intr_block_bit(cpuid_t cpu, int bit);
-extern void intr_unblock_bit(cpuid_t cpu, int bit);
-
-#endif /* __ASSEMBLY__ */
-
-/*
- * Hard-coded interrupt levels:
- */
-
-/*
- *	L0 = SW1
- *	L1 = SW2
- *	L2 = INT_PEND0
- *	L3 = INT_PEND1
- *	L4 = RTC
- *	L5 = Profiling Timer
- *	L6 = Hub Errors
- *	L7 = Count/Compare (T5 counters)
- */
-
-
-/* INT_PEND0 hard-coded bits. */
-#ifdef DEBUG_INTR_TSTAMP
-/* hard coded interrupt level for interrupt latency test interrupt */
-#define	CPU_INTRLAT_B	62
-#define	CPU_INTRLAT_A	61
-#endif
-
-/* Hardcoded bits required by software. */
-#define MSC_MESG_INTR	9
-#define CPU_ACTION_B	8
-#define CPU_ACTION_A	7
-
-/* These are determined by hardware: */
-#define CC_PEND_B	6
-#define CC_PEND_A	5
-#define UART_INTR	4
-#define PG_MIG_INTR	3
-#define GFX_INTR_B	2
-#define GFX_INTR_A	1
-#define RESERVED_INTR	0
-
-/* INT_PEND1 hard-coded bits: */
-#define MSC_PANIC_INTR	63
-#define NI_ERROR_INTR	62
-#define MD_COR_ERR_INTR	61
-#define COR_ERR_INTR_B	60
-#define COR_ERR_INTR_A	59
-#define CLK_ERR_INTR	58
-
-# define NACK_INT_B	57
-# define NACK_INT_A	56
-# define LB_ERROR	55
-# define XB_ERROR	54
-
-#define BRIDGE_ERROR_INTR 53	/* Setup by PROM to catch Bridge Errors */
-
-#define IP27_INTR_0	52	/* Reserved for PROM use */
-#define IP27_INTR_1	51	/*   (do not use in Kernel) */
-#define IP27_INTR_2	50
-#define IP27_INTR_3	49
-#define IP27_INTR_4	48
-#define IP27_INTR_5	47
-#define IP27_INTR_6	46
-#define IP27_INTR_7	45
-
-#define	TLB_INTR_B	44	/* used for tlb flush random */
-#define	TLB_INTR_A	43
-
-#define LLP_PFAIL_INTR_B 42	/* see ml/SN/SN0/sysctlr.c */
-#define LLP_PFAIL_INTR_A 41
-
-#define NI_BRDCAST_ERR_B 40
-#define NI_BRDCAST_ERR_A 39
-
-# define IO_ERROR_INTR	38	/* set up by prom */
-# define DEBUG_INTR_B	37	/* used by symmon to stop all cpus */
-# define DEBUG_INTR_A	36
-
-// These aren't strictly accurate or complete.  See the
-// Synergy Spec. for details.
-#define SGI_UART_IRQ	(65)
-#define SGI_HUB_ERROR_IRQ	(182)
-
-#endif /* _ASM_IA64_SN_SN1_INTR_H */
diff -Nru a/include/asm-ia64/sn/sn1/intr_public.h b/include/asm-ia64/sn/sn1/intr_public.h
--- a/include/asm-ia64/sn/sn1/intr_public.h	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,53 +0,0 @@
-/* $Id: intr_public.h,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_INTR_PUBLIC_H
-#define _ASM_IA64_SN_SN1_INTR_PUBLIC_H
-
-/* REMEMBER: If you change these, the whole world needs to be recompiled.
- * It would also require changing the hubspl.s code and SN0/intr.c
- * Currently, the spl code has no support for multiple INTPEND1 masks.
- */
-
-#define	N_INTPEND0_MASKS	1
-#define	N_INTPEND1_MASKS	1
-
-#define INTPEND0_MAXMASK	(N_INTPEND0_MASKS - 1)
-#define INTPEND1_MAXMASK	(N_INTPEND1_MASKS - 1)
-
-#ifndef __ASSEMBLY__
-#include <asm/sn/arch.h>
-
-struct intr_vecblk_s;	/* defined in asm/sn/intr.h */
-
-/*
- * The following are necessary to create the illusion of a CEL
- * on the IP27 hub.  We'll add more priority levels soon, but for
- * now, any interrupt in a particular band effectively does an spl.
- * These must be in the PDA since they're different for each processor.
- * Users of this structure must hold the vector_lock in the appropriate vector
- * block before modifying the mask arrays.  There's only one vector block
- * for each Hub so a lock in the PDA wouldn't be adequate.
- */
-typedef struct hub_intmasks_s {
-	/*
-	 * The masks are stored with the lowest-priority (most inclusive)
-	 * in the lowest-numbered masks (i.e., 0, 1, 2...).
-	 */
-	/* INT_PEND0: */
-	hubreg_t		intpend0_masks[N_INTPEND0_MASKS]; 
-	/* INT_PEND1: */
-	hubreg_t		intpend1_masks[N_INTPEND1_MASKS];
-	/* INT_PEND0: */
-	struct intr_vecblk_s	*dispatch0;	
-	/* INT_PEND1: */
-	struct intr_vecblk_s	*dispatch1;
-} hub_intmasks_t;
-
-#endif /* __ASSEMBLY__ */
-#endif /* _ASM_IA64_SN_SN1_INTR_PUBLIC_H */
diff -Nru a/include/asm-ia64/sn/sn1/ip27config.h b/include/asm-ia64/sn/sn1/ip27config.h
--- a/include/asm-ia64/sn/sn1/ip27config.h	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,657 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_SN1_IP27CONFIG_H
-#define _ASM_IA64_SN_SN1_IP27CONFIG_H
-
-
-/*
- * Structure: 	ip27config_s
- * Typedef:	ip27config_t
- * Purpose: 	Maps out the region of the boot prom used to define
- *		configuration information.
- * Notes:       Corresponds to ip27config structure found in start.s.
- *		Fields are ulong where possible to facilitate IP27 PROM fetches.
- */
-
-#define CONFIG_INFO_OFFSET		0x60
-
-#define IP27CONFIG_ADDR			(LBOOT_BASE	    + \
-					 CONFIG_INFO_OFFSET)
-#define IP27CONFIG_ADDR_NODE(n)		(NODE_RBOOT_BASE(n) + \
-					 CONFIG_INFO_OFFSET)
-
-/* Offset to the config_type field within local ip27config structure */
-#define CONFIG_FLAGS_ADDR			(IP27CONFIG_ADDR + 72)
-/* Offset to the config_type field in the ip27config structure on 
- * node with nasid n
- */
-#define CONFIG_FLAGS_ADDR_NODE(n)		(IP27CONFIG_ADDR_NODE(n) + 72)
-
-/* Meaning of each valid bit in the config flags 
- * None are currently defined
- */
-
-/* Meaning of each mach_type value
- */
-#define SN1_MACH_TYPE 0
-
-/*
- * Since 800 ns works well with various HUB frequencies, (such as 360,
- * 380, 390, and 400 MHZ), we now use 800ns rtc cycle time instead of
- * 1 microsec.
- */
-#define IP27_RTC_FREQ			1250	/* 800ns cycle time */
-
-#ifndef __ASSEMBLY__
-
-typedef	struct ip27config_s {		/* KEEP IN SYNC w/ start.s & below  */
-    uint		time_const;	/* Time constant 		    */
-    uint		r10k_mode;	/* R10k boot mode bits 		    */
-
-    uint64_t		magic;		/* CONFIG_MAGIC			    */
-
-    uint64_t		freq_cpu;	/* Hz 				    */
-    uint64_t		freq_hub;	/* Hz 				    */
-    uint64_t		freq_rtc;	/* Hz 				    */
-
-    uint		ecc_enable;	/* ECC enable flag		    */
-    uint		fprom_cyc;	/* FPROM_CYC speed control  	    */
-
-    uint		mach_type;	/* Inidicate IP27 (0) or Sn00 (1)    */
-
-    uint		check_sum_adj;	/* Used after config hdr overlay    */
-					/* to make the checksum 0 again     */
-    uint		flash_count;	/* Value incr'd on each PROM flash  */
-    uint		fprom_wr;	/* FPROM_WR speed control  	    */
-
-    uint		pvers_vers;	/* Prom version number		    */
-    uint		pvers_rev;	/* Prom revision number		    */
-    uint		config_type;	/* To support special configurations
-					 * (none currently defined)
-					 */
-} ip27config_t;
-
-typedef	struct {
-    uint		r10k_mode;	/* R10k boot mode bits 		    */
-    uint		freq_cpu;	/* Hz 				    */
-    uint		freq_hub;	/* Hz 				    */
-    char		fprom_cyc;	/* FPROM_CYC speed control  	    */
-    char		mach_type;	/* IP35(0) is only type defined      */
-    char		fprom_wr;	/* FPROM_WR speed control  	    */
-} config_modifiable_t;
-
-#define IP27CONFIG		(*(ip27config_t *) IP27CONFIG_ADDR)
-#define IP27CONFIG_NODE(n)	(*(ip27config_t *) IP27CONFIG_ADDR_NODE(n))
-#define SN00			0 /* IP35 has no Speedo equivalent */
-
-/* Get the config flags from local ip27config */
-#define CONFIG_FLAGS		(*(uint *) (CONFIG_FLAGS_ADDR))
-
-/* Get the config flags from ip27config on the node
- * with nasid n
- */
-#define CONFIG_FLAGS_NODE(n)	(*(uint *) (CONFIG_FLAGS_ADDR_NODE(n)))
-
-/* Macro to check if the local ip27config indicates a config
- * of 12 p 4io
- */
-#define CONFIG_12P4I		(0) /* IP35 has no 12p4i equivalent */
-
-/* Macro to check if the ip27config on node with nasid n
- * indicates a config of 12 p 4io
- */
-#define CONFIG_12P4I_NODE(n)	(0)
-
-#endif /* __ASSEMBLY__ */
-
-#if __ASSEMBLY__
-	.struct		0		/* KEEP IN SYNC WITH C structure */
-
-ip27c_time_const:	.word	0
-ip27c_r10k_mode:	.word	0
-
-ip27c_magic:		.dword	0
-
-ip27c_freq_cpu:		.dword	0
-ip27c_freq_hub:		.dword	0
-ip27c_freq_rtc:		.dword	0
-
-ip27c_ecc_enable:	.word	1
-ip27c_fprom_cyc:	.word	0
-
-ip27c_mach_type:	.word	0
-ip27c_check_sum_adj:	.word	0
-
-ip27c_flash_count:	.word	0
-ip27c_fprom_wr:		.word	0
-
-ip27c_pvers_vers:	.word	0
-ip27c_pvers_rev:	.word	0
-
-ip27c_config_type:	.word 	0	/* To recognize special configs */
-#endif /* __ASSEMBLY__ */
-
-/*
- * R10000 Configuration Cycle - These define the SYSAD values used
- * during the reset cycle.
- */
-
-#define	IP27C_R10000_KSEG0CA_SHFT	0
-#define	IP27C_R10000_KSEG0CA_MASK	(7 << IP27C_R10000_KSEG0CA_SHFT)
-#define	IP27C_R10000_KSEG0CA(_B)	 ((_B) << IP27C_R10000_KSEG0CA_SHFT)
-
-#define	IP27C_R10000_DEVNUM_SHFT	3
-#define	IP27C_R10000_DEVNUM_MASK	(3 << IP27C_R10000_DEVNUM_SHFT)
-#define	IP27C_R10000_DEVNUM(_B)		((_B) << IP27C_R10000_DEVNUM_SHFT)
-
-#define	IP27C_R10000_CRPT_SHFT		5
-#define	IP27C_R10000_CRPT_MASK		(1 << IP27C_R10000_CRPT_SHFT)
-#define	IP27C_R10000_CPRT(_B)		((_B)<<IP27C_R10000_CRPT_SHFT)
-
-#define	IP27C_R10000_PER_SHFT		6
-#define	IP27C_R10000_PER_MASK		(1 << IP27C_R10000_PER_SHFT)
-#define	IP27C_R10000_PER(_B)		((_B) << IP27C_R10000_PER_SHFT)
-
-#define	IP27C_R10000_PRM_SHFT		7
-#define	IP27C_R10000_PRM_MASK		(3 << IP27C_R10000_PRM_SHFT)
-#define	IP27C_R10000_PRM(_B)		((_B) << IP27C_R10000_PRM_SHFT)
-
-#define	IP27C_R10000_SCD_SHFT		9
-#define	IP27C_R10000_SCD_MASK		(0xf << IP27C_R10000_SCD_MASK)
-#define	IP27C_R10000_SCD(_B)		((_B) << IP27C_R10000_SCD_SHFT)
-
-#define	IP27C_R10000_SCBS_SHFT		13
-#define	IP27C_R10000_SCBS_MASK		(1 << IP27C_R10000_SCBS_SHFT)
-#define	IP27C_R10000_SCBS(_B)		(((_B)) << IP27C_R10000_SCBS_SHFT)
-
-#define	IP27C_R10000_SCCE_SHFT		14
-#define	IP27C_R10000_SCCE_MASK		(1 << IP27C_R10000_SCCE_SHFT)
-#define	IP27C_R10000_SCCE(_B)		((_B) << IP27C_R10000_SCCE_SHFT)
-
-#define	IP27C_R10000_ME_SHFT		15
-#define	IP27C_R10000_ME_MASK		(1 << IP27C_R10000_ME_SHFT)
-#define	IP27C_R10000_ME(_B)		((_B) << IP27C_R10000_ME_SHFT)
-
-#define	IP27C_R10000_SCS_SHFT		16
-#define	IP27C_R10000_SCS_MASK		(7 << IP27C_R10000_SCS_SHFT)
-#define	IP27C_R10000_SCS(_B)		((_B) << IP27C_R10000_SCS_SHFT)
-
-#define	IP27C_R10000_SCCD_SHFT		19
-#define	IP27C_R10000_SCCD_MASK		(7 << IP27C_R10000_SCCD_SHFT)
-#define	IP27C_R10000_SCCD(_B)		((_B) << IP27C_R10000_SCCD_SHFT)
-
-#define	IP27C_R10000_DDR_SHFT		23
-#define	IP27C_R10000_DDR_MASK		(1 << IP27C_R10000_DDR_SHFT)
-#define	IP27C_R10000_DDR(_B)		((_B) << IP27C_R10000_DDR_SHFT)
-
-#define	IP27C_R10000_SCCT_SHFT		25
-#define	IP27C_R10000_SCCT_MASK		(0xf << IP27C_R10000_SCCT_SHFT)
-#define	IP27C_R10000_SCCT(_B)		((_B) << IP27C_R10000_SCCT_SHFT)
-
-#define	IP27C_R10000_ODSC_SHFT		29
-#define IP27C_R10000_ODSC_MASK		(1 << IP27C_R10000_ODSC_SHFT)
-#define	IP27C_R10000_ODSC(_B)		((_B) << IP27C_R10000_ODSC_SHFT)
-
-#define	IP27C_R10000_ODSYS_SHFT		30
-#define	IP27C_R10000_ODSYS_MASK		(1 << IP27C_R10000_ODSYS_SHFT)
-#define	IP27C_R10000_ODSYS(_B)		((_B) << IP27C_R10000_ODSYS_SHFT)
-
-#define	IP27C_R10000_CTM_SHFT		31
-#define	IP27C_R10000_CTM_MASK		(1 << IP27C_R10000_CTM_SHFT)
-#define	IP27C_R10000_CTM(_B)		((_B) << IP27C_R10000_CTM_SHFT)
-
-#define IP27C_MHZ(x)			(1000000 * (x))
-#define IP27C_KHZ(x)			(1000 * (x))
-#define IP27C_MB(x)			((x) << 20)
-
-/*
- * PROM Configurations
- */
-
-#define CONFIG_MAGIC		0x69703237636f6e66
-
-/* The high 32 bits of the "mode bits".  Bits 7..0 contain one more
- * than the number of 5ms clocks in the 100ms "long delay" intervals
- * of the TRex reset sequence.  Bit 8 is the "synergy mode" bit.
- */
-#define CONFIG_TIME_CONST	0x15
-
-#define CONFIG_ECC_ENABLE	1
-#define CONFIG_CHECK_SUM_ADJ	0
-#define CONFIG_DEFAULT_FLASH_COUNT    0
-
-/*
- * Some promICEs have trouble if CONFIG_FPROM_SETUP is too low.
- * The nominal value for 100 MHz hub is 5, for 200MHz bedrock is 16.
- * any update to the below should also reflected in the logic in
- *   IO7prom/flashprom.c function _verify_config_info and _fill_in_config_info
- */
-
-/* default junk bus timing values to use */
-#define CONFIG_SYNERGY_ENABLE	0xff
-#define CONFIG_SYNERGY_SETUP	0xff
-#define CONFIG_UART_ENABLE	0x0c
-#define CONFIG_UART_SETUP	0x02
-#define CONFIG_FPROM_ENABLE	0x10
-#define CONFIG_FPROM_SETUP	0x10
-
-#define CONFIG_FREQ_RTC	IP27C_KHZ(IP27_RTC_FREQ)
-
-#ifndef __ASSEMBLY__
-
-/* we are going to define all the known configs is a table
- * for building hex images we will pull out the particular
- * slice we care about by using the IP27_CONFIG_XX_XX as
- * entries into the table
- * to keep the table of reasonable size we only include the
- * values that differ across configurations
- * please note then that this makes assumptions about what
- * will and will not change across configurations
- */
-
-/* these numbers are as the are ordered in the table below */
-#define	IP27_CONFIG_UNKNOWN (-1)
-#define IP27_CONFIG_SN1_1MB_200_400_200_TABLE 0
-#define IP27_CONFIG_SN00_4MB_100_200_133_TABLE 1
-#define IP27_CONFIG_SN1_4MB_200_400_267_TABLE 2
-#define IP27_CONFIG_SN1_8MB_200_500_250_TABLE 3
-#define IP27_CONFIG_SN1_8MB_200_400_267_TABLE 4
-#define IP27_CONFIG_SN1_4MB_180_360_240_TABLE 5
-#define NUMB_IP_CONFIGS 6
-
-#ifdef DEF_IP_CONFIG_TABLE
-/*
- * N.B.: A new entry needs to be added here everytime a new config is added
- * The table is indexed by the PIMM PSC value
- */
-
-static int psc_to_flash_config[] = {
-        IP27_CONFIG_SN1_4MB_200_400_267_TABLE,	/* 0x0 */
-        IP27_CONFIG_SN1_8MB_200_500_250_TABLE,	/* 0x1 */
-        IP27_CONFIG_SN1_8MB_200_400_267_TABLE,	/* 0x2 */
-        IP27_CONFIG_UNKNOWN,	/* 0x3 */
-        IP27_CONFIG_UNKNOWN,	/* 0x4 */
-        IP27_CONFIG_UNKNOWN,	/* 0x5 */
-        IP27_CONFIG_UNKNOWN,	/* 0x6 */
-        IP27_CONFIG_UNKNOWN,	/* 0x7 */
-        IP27_CONFIG_SN1_4MB_180_360_240_TABLE,	/* 0x8 */
-        IP27_CONFIG_UNKNOWN,	/* 0x9 */
-        IP27_CONFIG_UNKNOWN,	/* 0xa */
-        IP27_CONFIG_UNKNOWN,	/* 0xb */
-        IP27_CONFIG_UNKNOWN,	/* 0xc */
-        IP27_CONFIG_UNKNOWN,	/* 0xd */
-        IP27_CONFIG_SN00_4MB_100_200_133_TABLE, /* 0xe  O200 PIMM for bringup */
-        IP27_CONFIG_UNKNOWN	/* 0xf == PIMM not installed */
-};
-
-static config_modifiable_t ip_config_table[NUMB_IP_CONFIGS] = {
-/* the 1MB_200_400_200 values (Generic settings, will work for any config.) */
-{
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(1)	 + \
-	 IP27C_R10000_SCCD(3)	 + \
-	 IP27C_R10000_SCCT(9)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0)),
-	IP27C_MHZ(400),
-	IP27C_MHZ(200),
-	CONFIG_FPROM_SETUP,
-	SN1_MACH_TYPE,
-	CONFIG_FPROM_ENABLE
-},
-
-/* the 4MB_100_200_133 values (O200 PIMM w/translation board, PSC 0xe)
- * (SysAD at 100MHz (SCD=3), and bedrock core at 200 MHz) */
-{
- /* ODSYS == 0 means HSTL1 on SysAD bus; other PIMMs use HSTL2 */
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(3)	 + \
-	 IP27C_R10000_SCCD(2)	 + \
-	 IP27C_R10000_SCCT(9)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(0)	 + \
-	 IP27C_R10000_CTM(0)),
-	IP27C_MHZ(200),
-	IP27C_MHZ(200),
-	CONFIG_FPROM_SETUP,
-	SN1_MACH_TYPE,
-	CONFIG_FPROM_ENABLE
-},
-
-/* 4MB_200_400_267 values (R12KS, 3.7ns, LWR, 030-1602-001, PSC 0x0) */
-{
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(3)	 + \
-	 IP27C_R10000_SCCD(2)	 + \
-	 IP27C_R10000_SCCT(0xa)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0)),
-	IP27C_MHZ(400),
-	IP27C_MHZ(200),
-	CONFIG_FPROM_SETUP,
-	SN1_MACH_TYPE,
-	CONFIG_FPROM_ENABLE
-},
-
-/* 8MB_200_500_250 values (R14K, 4.0ns, DDR1, 030-1520-001, PSC 0x1) */
-{
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(4)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(4)	 + \
-	 IP27C_R10000_DDR(1)     + \
-	 IP27C_R10000_SCCD(3)	 + \
-	 IP27C_R10000_SCCT(0xa)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0)),
-	IP27C_MHZ(500),
-	IP27C_MHZ(200),
-	CONFIG_FPROM_SETUP,
-	SN1_MACH_TYPE,
-	CONFIG_FPROM_ENABLE
-},
-
-/* 8MB_200_400_267 values (R12KS, 3.7ns, LWR, 030-1616-001, PSC 0x2) */
-{
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(4)	 + \
-	 IP27C_R10000_SCCD(2)	 + \
-	 IP27C_R10000_SCCT(0xa)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0)),
-	IP27C_MHZ(400),
-	IP27C_MHZ(200),
-	CONFIG_FPROM_SETUP,
-	SN1_MACH_TYPE,
-	CONFIG_FPROM_ENABLE
-},
-
-/* 4MB_180_360_240 values (R12KS, 3.7ns, LWR, 030-1627-001, PSC 0x8)
- * (SysAD at 180 MHz (SCD=3, the fastest possible), bedrock core at 200MHz) */
-{
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(3)	 + \
-	 IP27C_R10000_SCCD(2)	 + \
-	 IP27C_R10000_SCCT(9)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0)),
-	IP27C_MHZ(360),
-	IP27C_MHZ(200),
-	CONFIG_FPROM_SETUP,
-	SN1_MACH_TYPE,
-	CONFIG_FPROM_ENABLE
-},
-
-};
-#else
-extern	config_modifiable_t	ip_config_table[];
-#endif /* DEF_IP27_CONFIG_TABLE */
-
-#ifdef IP27_CONFIG_SN00_4MB_100_200_133
-#define CONFIG_CPU_MODE	ip_config_table[IP27_CONFIG_SN00_4MB_100_200_133_TABLE].r10k_mode
-#define CONFIG_FREQ_CPU	ip_config_table[IP27_CONFIG_SN00_4MB_100_200_133_TABLE].freq_cpu
-#define CONFIG_FREQ_HUB	ip_config_table[IP27_CONFIG_SN00_4MB_100_200_133_TABLE].freq_hub
-#define CONFIG_FPROM_CYC ip_config_table[IP27_CONFIG_SN00_4MB_100_200_133_TABLE].fprom_cyc
-#define CONFIG_MACH_TYPE ip_config_table[IP27_CONFIG_SN00_4MB_100_200_133_TABLE].mach_type
-#define CONFIG_FPROM_WR	ip_config_table[IP27_CONFIG_SN00_4MB_100_200_133_TABLE].fprom_wr
-#endif /* IP27_CONFIG_SN00_4MB_100_200_133 */
-
-#ifdef IP27_CONFIG_SN1_1MB_200_400_200
-#define CONFIG_CPU_MODE	ip_config_table[IP27_CONFIG_SN1_1MB_200_400_200_TABLE].r10k_mode
-#define CONFIG_FREQ_CPU	ip_config_table[IP27_CONFIG_SN1_1MB_200_400_200_TABLE].freq_cpu
-#define CONFIG_FREQ_HUB	ip_config_table[IP27_CONFIG_SN1_1MB_200_400_200_TABLE].freq_hub
-#define CONFIG_FPROM_CYC ip_config_table[IP27_CONFIG_SN1_1MB_200_400_200_TABLE].fprom_cyc
-#define CONFIG_MACH_TYPE ip_config_table[IP27_CONFIG_SN1_1MB_200_400_200_TABLE].mach_type
-#define CONFIG_FPROM_WR	ip_config_table[IP27_CONFIG_SN1_1MB_200_400_200_TABLE].fprom_wr
-#endif /* IP27_CONFIG_SN1_1MB_200_400_200 */
-
-#ifdef IP27_CONFIG_SN1_4MB_200_400_267
-#define CONFIG_CPU_MODE	ip_config_table[IP27_CONFIG_SN1_4MB_200_400_267_TABLE].r10k_mode
-#define CONFIG_FREQ_CPU	ip_config_table[IP27_CONFIG_SN1_4MB_200_400_267_TABLE].freq_cpu
-#define CONFIG_FREQ_HUB	ip_config_table[IP27_CONFIG_SN1_4MB_200_400_267_TABLE].freq_hub
-#define CONFIG_FPROM_CYC ip_config_table[IP27_CONFIG_SN1_4MB_200_400_267_TABLE].fprom_cyc
-#define CONFIG_MACH_TYPE ip_config_table[IP27_CONFIG_SN1_4MB_200_400_267_TABLE].mach_type
-#define CONFIG_FPROM_WR	ip_config_table[IP27_CONFIG_SN1_4MB_200_400_267_TABLE].fprom_wr
-#endif /* IP27_CONFIG_SN1_4MB_200_400_267 */
-
-#ifdef IP27_CONFIG_SN1_8MB_200_500_250
-#define CONFIG_CPU_MODE	ip_config_table[IP27_CONFIG_SN1_8MB_200_500_250_TABLE].r10k_mode
-#define CONFIG_FREQ_CPU	ip_config_table[IP27_CONFIG_SN1_8MB_200_500_250_TABLE].freq_cpu
-#define CONFIG_FREQ_HUB	ip_config_table[IP27_CONFIG_SN1_8MB_200_500_250_TABLE].freq_hub
-#define CONFIG_FPROM_CYC ip_config_table[IP27_CONFIG_SN1_8MB_200_500_250_TABLE].fprom_cyc
-#define CONFIG_MACH_TYPE ip_config_table[IP27_CONFIG_SN1_8MB_200_500_250_TABLE].mach_type
-#define CONFIG_FPROM_WR	ip_config_table[IP27_CONFIG_SN1_8MB_200_500_250_TABLE].fprom_wr
-#endif /* IP27_CONFIG_SN1_8MB_200_500_250 */
-
-#ifdef IP27_CONFIG_SN1_8MB_200_400_267
-#define CONFIG_CPU_MODE	ip_config_table[IP27_CONFIG_SN1_8MB_200_400_267_TABLE].r10k_mode
-#define CONFIG_FREQ_CPU	ip_config_table[IP27_CONFIG_SN1_8MB_200_400_267_TABLE].freq_cpu
-#define CONFIG_FREQ_HUB	ip_config_table[IP27_CONFIG_SN1_8MB_200_400_267_TABLE].freq_hub
-#define CONFIG_FPROM_CYC ip_config_table[IP27_CONFIG_SN1_8MB_200_400_267_TABLE].fprom_cyc
-#define CONFIG_MACH_TYPE ip_config_table[IP27_CONFIG_SN1_8MB_200_400_267_TABLE].mach_type
-#define CONFIG_FPROM_WR	ip_config_table[IP27_CONFIG_SN1_8MB_200_400_267_TABLE].fprom_wr
-#endif /* IP27_CONFIG_SN1_8MB_200_400_267 */
-
-#ifdef IP27_CONFIG_SN1_4MB_180_360_240
-#define CONFIG_CPU_MODE	ip_config_table[IP27_CONFIG_SN1_4MB_180_360_240_TABLE].r10k_mode
-#define CONFIG_FREQ_CPU	ip_config_table[IP27_CONFIG_SN1_4MB_180_360_240_TABLE].freq_cpu
-#define CONFIG_FREQ_HUB	ip_config_table[IP27_CONFIG_SN1_4MB_180_360_240_TABLE].freq_hub
-#define CONFIG_FPROM_CYC ip_config_table[IP27_CONFIG_SN1_4MB_180_360_240_TABLE].fprom_cyc
-#define CONFIG_MACH_TYPE ip_config_table[IP27_CONFIG_SN1_4MB_180_360_240_TABLE].mach_type
-#define CONFIG_FPROM_WR	ip_config_table[IP27_CONFIG_SN1_4MB_180_360_240_TABLE].fprom_wr
-#endif /* IP27_CONFIG_SN1_4MB_180_360_240 */
-
-#endif /* __ASSEMBLY__ */
-
-#if __ASSEMBLY__
-
-/* these need to be in here since we need assembly definitions
- * for building hex images (as required by start.s)
- */
-#ifdef IP27_CONFIG_SN00_4MB_100_200_133
-#define	BRINGUP_PRM_VAL	3
-#define CONFIG_CPU_MODE \
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(BRINGUP_PRM_VAL)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(3)	 + \
-	 IP27C_R10000_SCCD(2)	 + \
-	 IP27C_R10000_SCCT(9)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(0)	 + \
-	 IP27C_R10000_CTM(0))
-#define CONFIG_FREQ_CPU IP27C_MHZ(200)
-#define CONFIG_FREQ_HUB IP27C_MHZ(200)
-#define CONFIG_FPROM_CYC CONFIG_FPROM_SETUP
-#define CONFIG_MACH_TYPE SN1_MACH_TYPE
-#define CONFIG_FPROM_WR CONFIG_FPROM_ENABLE
-#endif /* IP27_CONFIG_SN00_4MB_100_200_133 */
-
-#ifdef IP27_CONFIG_SN1_1MB_200_400_200
-#define CONFIG_CPU_MODE \
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(1)	 + \
-	 IP27C_R10000_SCCD(3)	 + \
-	 IP27C_R10000_SCCT(9)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0))
-#define CONFIG_FREQ_CPU IP27C_MHZ(400)
-#define CONFIG_FREQ_HUB IP27C_MHZ(200)
-#define CONFIG_FPROM_CYC CONFIG_FPROM_SETUP
-#define CONFIG_MACH_TYPE SN1_MACH_TYPE
-#define CONFIG_FPROM_WR CONFIG_FPROM_ENABLE
-#endif /* IP27_CONFIG_SN1_1MB_200_400_200 */
-
-#ifdef IP27_CONFIG_SN1_4MB_200_400_267
-#define CONFIG_CPU_MODE \
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(3)	 + \
-	 IP27C_R10000_SCCD(2)	 + \
-	 IP27C_R10000_SCCT(0xa)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0))
-#define CONFIG_FREQ_CPU IP27C_MHZ(400)
-#define CONFIG_FREQ_HUB IP27C_MHZ(200)
-#define CONFIG_FPROM_CYC CONFIG_FPROM_SETUP
-#define CONFIG_MACH_TYPE SN1_MACH_TYPE
-#define CONFIG_FPROM_WR CONFIG_FPROM_ENABLE
-#endif /* IP27_CONFIG_SN1_4MB_200_400_267 */
-
-#ifdef IP27_CONFIG_SN1_8MB_200_500_250
-#define CONFIG_CPU_MODE \
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(4)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(4)	 + \
-	 IP27C_R10000_SCCD(3)	 + \
-         IP27C_R10000_DDR(1)     + \
-	 IP27C_R10000_SCCT(0xa)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0))
-#define CONFIG_FREQ_CPU IP27C_MHZ(500)
-#define CONFIG_FREQ_HUB IP27C_MHZ(200)
-#define CONFIG_FPROM_CYC CONFIG_FPROM_SETUP
-#define CONFIG_MACH_TYPE SN1_MACH_TYPE
-#define CONFIG_FPROM_WR CONFIG_FPROM_ENABLE
-#endif /* IP27_CONFIG_SN1_8MB_200_500_250 */
-
-#ifdef IP27_CONFIG_SN1_8MB_200_400_267
-#define CONFIG_CPU_MODE \
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(4)	 + \
-	 IP27C_R10000_SCCD(2)	 + \
-	 IP27C_R10000_SCCT(0xa)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0))
-#define CONFIG_FREQ_CPU IP27C_MHZ(400)
-#define CONFIG_FREQ_HUB IP27C_MHZ(200)
-#define CONFIG_FPROM_CYC CONFIG_FPROM_SETUP
-#define CONFIG_MACH_TYPE SN1_MACH_TYPE
-#define CONFIG_FPROM_WR CONFIG_FPROM_ENABLE
-#endif /* IP27_CONFIG_SN1_8MB_200_400_267 */
-
-#ifdef IP27_CONFIG_SN1_4MB_180_360_240
-#define CONFIG_CPU_MODE \
-	(IP27C_R10000_KSEG0CA(5) + \
-	 IP27C_R10000_DEVNUM(0)	 + \
-	 IP27C_R10000_CPRT(0)	 + \
-	 IP27C_R10000_PER(0)	 + \
-	 IP27C_R10000_PRM(3)	 + \
-	 IP27C_R10000_SCD(3)	 + \
-	 IP27C_R10000_SCBS(1)	 + \
-	 IP27C_R10000_SCCE(0)	 + \
-	 IP27C_R10000_ME(1)	 + \
-	 IP27C_R10000_SCS(3)	 + \
-	 IP27C_R10000_SCCD(2)	 + \
-	 IP27C_R10000_SCCT(9)	 + \
-	 IP27C_R10000_ODSC(0)	 + \
-	 IP27C_R10000_ODSYS(1)	 + \
-	 IP27C_R10000_CTM(0))
-#define CONFIG_FREQ_CPU IP27C_MHZ(360)
-#define CONFIG_FREQ_HUB IP27C_MHZ(200)
-#define CONFIG_FPROM_CYC CONFIG_FPROM_SETUP
-#define CONFIG_MACH_TYPE SN1_MACH_TYPE
-#define CONFIG_FPROM_WR CONFIG_FPROM_ENABLE
-#endif /* IP27_CONFIG_SN1_4MB_180_360_240 */
-
-#endif /* __ASSEMBLY__ */
-
-#endif /* _ASM_IA64_SN_SN1_IP27CONFIG_H */
diff -Nru a/include/asm-ia64/sn/sn1/mem_refcnt.h b/include/asm-ia64/sn/sn1/mem_refcnt.h
--- a/include/asm-ia64/sn/sn1/mem_refcnt.h	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,25 +0,0 @@
-/*
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_MEM_REFCNT_H
-#define _ASM_IA64_SN_SN1_MEM_REFCNT_H
-
-extern int mem_refcnt_attach(devfs_handle_t hub);
-extern int mem_refcnt_open(devfs_handle_t *devp, mode_t oflag, int otyp, cred_t *crp);
-extern int mem_refcnt_close(devfs_handle_t dev, int oflag, int otyp, cred_t *crp);
-extern int mem_refcnt_mmap(devfs_handle_t dev, vhandl_t *vt, off_t off, size_t len, uint prot);
-extern int mem_refcnt_unmap(devfs_handle_t dev, vhandl_t *vt);
-extern int mem_refcnt_ioctl(devfs_handle_t dev,
-                 int cmd,
-                 void *arg,
-                 int mode,
-                 cred_t *cred_p,
-                 int *rvalp);
-        
-
-#endif /* _ASM_IA64_SN_SN1_MEM_REFCNT_H */
diff -Nru a/include/asm-ia64/sn/sn1/mmzone_sn1.h b/include/asm-ia64/sn/sn1/mmzone_sn1.h
--- a/include/asm-ia64/sn/sn1/mmzone_sn1.h	Wed Jun 18 23:42:09 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,149 +0,0 @@
-#ifndef _ASM_IA64_SN_MMZONE_SN1_H
-#define _ASM_IA64_SN_MMZONE_SN1_H
-
-/*
- * 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) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#include <linux/config.h>
-
-
-/*
- * SGI SN1 Arch defined values
- *
- * 	An SN1 physical address is broken down as follows:
- *
- *             +-----------------------------------------+
- *             |         |    |      |   node offset     |
- *             | unused  | AS | node |-------------------|
- *             |         |    |      | cn | clump offset |
- *             +-----------------------------------------+
- *              6       4 4  4 3    3 3  3 2            0
- *              3       4 3  0 9    3 2  0 9            0
- *
- *		bits 63-44	Unused - must be zero
- *		bits 43-40	Address space ID. Cached memory has a value of 0.
- *				Chipset & IO addresses have non-zero values.
- *		bits 39-33	Node number. Note that some configurations do NOT
- *				have a node zero.
- *		bits 32-0	Node offset.
- *
- *	The node offset can be further broken down as:
- *		bits 32-30	Clump (bank) number.
- *		bits 29-0	Clump (bank) offset.
- *
- *	A node consists of up to 8 clumps (banks) of memory. A clump may be empty, or may be
- *	populated with a single contiguous block of memory starting at clump
- *	offset 0. The size of the block is (2**n) * 64MB, where 0<n<5.
- *
- *
- * NOTE: This file exports symbols prefixed with "PLAT_". Symbols prefixed with
- *	 "SN_" are intended for internal use only and should not be used in
- *	 any platform independent code. 
- *
- *	 This file is also responsible for exporting the following definitions:
- *		cnodeid_t	Define a compact node id. 
- */
-
-typedef signed short cnodeid_t;
-
-#define SN1_BANKS_PER_NODE		8
-#define SN1_NODE_SIZE			(8UL*1024*1024*1024)	/* 8 GB per node */
-#define SN1_BANK_SIZE			(SN1_NODE_SIZE/SN1_BANKS_PER_NODE)
-#define SN1_NODE_SHIFT			33
-#define SN1_NODE_MASK			0x7fUL
-#define SN1_NODE_OFFSET_MASK		(SN1_NODE_SIZE-1)
-#define SN1_NODE_NUMBER(addr)		(((unsigned long)(addr) >> SN1_NODE_SHIFT) & SN1_NODE_MASK)
-#define SN1_NODE_CLUMP_NUMBER(addr)	(((unsigned long)(addr) >>30) & 7)
-#define SN1_NODE_OFFSET(addr)		(((unsigned long)(addr)) & SN1_NODE_OFFSET_MASK)
-#define SN1_KADDR(nasid, offset)	(((unsigned long)(nasid)<<SN1_NODE_SHIFT) | (offset) | PAGE_OFFSET)
-
-
-#define PLAT_MAX_NODE_NUMBER		128			/* Maximum node number +1 */
-#define PLAT_MAX_COMPACT_NODES		128			/* Maximum number of nodes in SSI */
-
-#define PLAT_MAX_PHYS_MEMORY		(1UL << 40)
-
-
-
-/*
- * On the SN platforms, a clump is the same as a memory bank.
- */
-#define PLAT_CLUMPS_PER_NODE		SN1_BANKS_PER_NODE
-#define PLAT_CLUMP_OFFSET(addr)		((unsigned long)(addr) & 0x3fffffffUL)
-#define PLAT_CLUMPSIZE                  (SN1_NODE_SIZE/PLAT_CLUMPS_PER_NODE)
-#define PLAT_MAXCLUMPS			(PLAT_CLUMPS_PER_NODE*PLAT_MAX_COMPACT_NODES)
-
-
-
-
-/*
- * PLAT_VALID_MEM_KADDR returns a boolean to indicate if a kaddr is potentially a
- * valid cacheable identity mapped RAM memory address.
- * Note that the RAM may or may not actually be present!!
- */
-#define SN1_VALID_KERN_ADDR_MASK	0xffffff0000000000UL
-#define SN1_VALID_KERN_ADDR_VALUE	0xe000000000000000UL
-#define PLAT_VALID_MEM_KADDR(kaddr)	(((unsigned long)(kaddr) & SN1_VALID_KERN_ADDR_MASK) == SN1_VALID_KERN_ADDR_VALUE)
-
-
-
-/*
- * Memory is conceptually divided into chunks. A chunk is either
- * completely present, or else the kernel assumes it is completely
- * absent. Each node consists of a number of possibly discontiguous chunks.
- */
-#define SN1_CHUNKSHIFT			26			/* 64 MB */
-#define PLAT_CHUNKSIZE			(1UL << SN1_CHUNKSHIFT)
-#define PLAT_CHUNKNUM(addr)		(((addr) & (PLAT_MAX_PHYS_MEMORY-1)) >> SN1_CHUNKSHIFT)
-
-
-/*
- * Given a kaddr, find the nid (compact nodeid)
- */
-#ifdef CONFIG_IA64_SGI_SN_DEBUG
-#define DISCONBUG(kaddr)		panic("DISCONTIG BUG: line %d, %s. kaddr 0x%lx",	 	\
-						__LINE__, __FILE__, (long)(kaddr))
-
-#define KVADDR_TO_NID(kaddr)		({long _ktn=(long)(kaddr);					\
-						kern_addr_valid(_ktn) ? 				\
-						local_node_data->physical_node_map[SN1_NODE_NUMBER(_ktn)] :\
-						(DISCONBUG(_ktn), 0UL);})
-#else
-#define KVADDR_TO_NID(kaddr)		(local_node_data->physical_node_map[SN1_NODE_NUMBER(kaddr)])
-#endif
-
-
-
-/*
- * Given a kaddr, find the index into the clump_mem_map_base array of the page struct entry
- * for the first page of the clump.
- */
-#define PLAT_CLUMP_MEM_MAP_INDEX(kaddr)		({long _kmmi=(long)(kaddr);				\
-							KVADDR_TO_NID(_kmmi) * PLAT_CLUMPS_PER_NODE +	\
-							SN1_NODE_CLUMP_NUMBER(_kmmi);})
-
-
-/*
- * Calculate a "goal" value to be passed to __alloc_bootmem_node for allocating structures on
- * nodes so that they don't alias to the same line in the cache as the previous allocated structure.
- * This macro takes an address of the end of previous allocation, rounds it to a page boundary & 
- * changes the node number.
- */
-#define PLAT_BOOTMEM_ALLOC_GOAL(cnode,kaddr)	__pa(SN1_KADDR(PLAT_PXM_TO_PHYS_NODE_NUMBER(nid_to_pxm_map[cnode]),		\
-						  (SN1_NODE_OFFSET(kaddr) + PAGE_SIZE - 1) >> PAGE_SHIFT << PAGE_SHIFT))
-
-
-
-
-/*
- * Convert a proximity domain number (from the ACPI tables) into a physical node number.
- */
-
-#define PLAT_PXM_TO_PHYS_NODE_NUMBER(pxm)	(pxm)
-
-#endif /* _ASM_IA64_SN_MMZONE_SN1_H */
diff -Nru a/include/asm-ia64/sn/sn1/slotnum.h b/include/asm-ia64/sn/sn1/slotnum.h
--- a/include/asm-ia64/sn/sn1/slotnum.h	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,87 +0,0 @@
-/* $Id$
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-
-#ifndef _ASM_IA64_SN_SN1_SLOTNUM_H
-#define _ASM_IA64_SN_SN1_SLOTNUM_H
-
-#define SLOTNUM_MAXLENGTH	16
-
-/*
- * This file attempts to define a slot number space across all slots.
- *
- *	Node slots
- *	Router slots
- *	Crosstalk slots
- *
- *	Other slots are children of their parent crosstalk slot:
- *		PCI slots
- *		VME slots
- *
- *	The PCI class has been added since the XBridge ASIC on SN-MIPS
- *	has built-in PCI bridges (2). On IBricks, widget E & F serve
- *	PCI busses, and on PBricks all widgets serve as PCI busses
- *	with the use of the super-bridge mode of the XBridge ASIC.
- */
-
-#define SLOTNUM_NODE_CLASS	0x00	/* Node   */
-#define SLOTNUM_ROUTER_CLASS	0x10	/* Router */
-#define SLOTNUM_XTALK_CLASS	0x20	/* Xtalk  */
-#define SLOTNUM_MIDPLANE_CLASS	0x30	/* Midplane */
-#define SLOTNUM_XBOW_CLASS	0x40	/* Xbow  */
-#define SLOTNUM_KNODE_CLASS	0x50	/* Kego node */
-#define SLOTNUM_PCI_CLASS	0x60	/* PCI widgets on XBridge */
-#define SLOTNUM_INVALID_CLASS	0xf0	/* Invalid */
-
-#define SLOTNUM_CLASS_MASK	0xf0
-#define SLOTNUM_SLOT_MASK	0x0f
-
-#define SLOTNUM_GETCLASS(_sn)	((_sn) & SLOTNUM_CLASS_MASK)
-#define SLOTNUM_GETSLOT(_sn)	((_sn) & SLOTNUM_SLOT_MASK)
-
-/* This determines module to pnode mapping. */
-/* NODESLOTS_PER_MODULE has changed from 4 to 6
- * to support the 12P 4IO configuration. This change
- * helps in minimum  number of changes to code which
- * depend on the number of node boards within a module.
- */
-#define NODESLOTS_PER_MODULE		6
-#define NODESLOTS_PER_MODULE_SHFT	2
-
-#define HIGHEST_I2C_VISIBLE_NODESLOT	4
-#define	RTRSLOTS_PER_MODULE		2
-
-#if __KERNEL__
-#include <asm/sn/xtalk/xtalk.h>
-
-extern slotid_t xbwidget_to_xtslot(int crossbow, int widget);
-extern slotid_t hub_slotbits_to_slot(slotid_t slotbits);
-extern slotid_t hub_slot_to_crossbow(slotid_t hub_slot);
-extern slotid_t router_slotbits_to_slot(slotid_t slotbits);
-extern slotid_t get_node_slotid(nasid_t nasid);
-extern slotid_t get_my_slotid(void);
-extern slotid_t get_node_crossbow(nasid_t);
-extern xwidgetnum_t hub_slot_to_widget(slotid_t);
-extern void get_slotname(slotid_t, char *);
-extern void get_my_slotname(char *);
-extern slotid_t get_widget_slotnum(int xbow, int widget);
-extern void get_widget_slotname(int, int, char *);
-extern void router_slotbits_to_slotname(int, char *);
-extern slotid_t meta_router_slotbits_to_slot(slotid_t) ;
-extern slotid_t hub_slot_get(void);
-
-extern int node_can_talk_to_elsc(void);
-
-extern int  slot_to_widget(int) ;
-#define MAX_IO_SLOT_NUM		12
-#define MAX_NODE_SLOT_NUM	4
-#define MAX_ROUTER_SLOTNUM	2
-
-#endif /* __KERNEL__ */
-
-#endif /* _ASM_IA64_SN_SN1_SLOTNUM_H */
diff -Nru a/include/asm-ia64/sn/sn1/sn_private.h b/include/asm-ia64/sn/sn1/sn_private.h
--- a/include/asm-ia64/sn/sn1/sn_private.h	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,292 +0,0 @@
-/* $Id: sn_private.h,v 1.1 2002/02/28 17:31:25 marcelo Exp $
- *
- * 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) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
- */
-#ifndef _ASM_IA64_SN_SN1_SN_PRIVATE_H
-#define _ASM_IA64_SN_SN1_SN_PRIVATE_H
-
-#include <asm/sn/nodepda.h>
-#include <asm/sn/xtalk/xwidget.h>
-#include <asm/sn/xtalk/xtalk_private.h>
-
-extern nasid_t master_nasid;
-
-/* promif.c */
-#ifdef	LATER
-extern cpuid_t cpu_node_probe(cpumask_t *cpumask, int *numnodes);
-#endif
-extern void he_arcs_set_vectors(void);
-extern void mem_init(void);
-#ifdef	LATER
-extern int cpu_enabled(cpuid_t);
-#endif
-extern void cpu_unenable(cpuid_t);
-extern nasid_t get_lowest_nasid(void);
-extern __psunsigned_t get_master_bridge_base(void);
-extern void set_master_bridge_base(void);
-extern int check_nasid_equiv(nasid_t, nasid_t);
-extern nasid_t get_console_nasid(void);
-extern char get_console_pcislot(void);
-#ifdef	LATER
-extern void intr_init_vecblk(nodepda_t *npda, cnodeid_t, int);
-#endif
-
-extern int is_master_nasid_widget(nasid_t test_nasid, xwidgetnum_t test_wid);
-
-/* memsupport.c */
-extern void poison_state_alter_range(__psunsigned_t start, int len, int poison);
-extern int memory_present(paddr_t);
-extern int memory_read_accessible(paddr_t);
-extern int memory_write_accessible(paddr_t);
-extern void memory_set_access(paddr_t, int, int);
-extern void show_dir_state(paddr_t, void (*)(char *, ...));
-extern void check_dir_state(nasid_t, int, void (*)(char *, ...));
-extern void set_dir_owner(paddr_t, int);
-extern void set_dir_state(paddr_t, int);
-extern void set_dir_state_POISONED(paddr_t);
-extern void set_dir_state_UNOWNED(paddr_t);
-extern int is_POISONED_dir_state(paddr_t);
-extern int is_UNOWNED_dir_state(paddr_t);
-extern void get_dir_ent(paddr_t paddr, int *state,
-			uint64_t *vec_ptr, hubreg_t *elo);
-
-/* intr.c */
-extern int intr_reserve_level(cpuid_t cpu, int level, int err, devfs_handle_t owner_dev, char *name);
-extern void intr_unreserve_level(cpuid_t cpu, int level);
-extern int intr_connect_level(cpuid_t cpu, int bit, ilvl_t mask_no, 
-			intr_func_t intr_prefunc);
-extern int intr_disconnect_level(cpuid_t cpu, int bit);
-extern cpuid_t intr_heuristic(devfs_handle_t dev, device_desc_t dev_desc,
-			      int req_bit,int intr_resflags,devfs_handle_t owner_dev,
-			      char *intr_name,int *resp_bit);
-extern void intr_block_bit(cpuid_t cpu, int bit);
-extern void intr_unblock_bit(cpuid_t cpu, int bit);
-extern void setrtvector(intr_func_t);
-extern void install_cpuintr(cpuid_t cpu);
-extern void install_dbgintr(cpuid_t cpu);
-extern void install_tlbintr(cpuid_t cpu);
-extern void hub_migrintr_init(cnodeid_t /*cnode*/);
-extern int cause_intr_connect(int level, intr_func_t handler, uint intr_spl_mask);
-extern int cause_intr_disconnect(int level);
-extern void intr_reserve_hardwired(cnodeid_t);
-extern void intr_clear_all(nasid_t);
-extern void intr_dumpvec(cnodeid_t cnode, void (*pf)(char *, ...));
-
-/* error_dump.c */
-extern char *hub_rrb_err_type[];
-extern char *hub_wrb_err_type[];
-
-void nmi_dump(void);
-void install_cpu_nmi_handler(int slice);
-
-/* klclock.c */
-extern void hub_rtc_init(cnodeid_t);
-
-/* bte.c */
-void bte_lateinit(void);
-void bte_wait_for_xfer_completion(void *);
-
-/* klgraph.c */
-void klhwg_add_all_nodes(devfs_handle_t);
-void klhwg_add_all_modules(devfs_handle_t);
-
-/* klidbg.c */
-void install_klidbg_functions(void);
-
-/* klnuma.c */
-extern void replicate_kernel_text(int numnodes);
-extern __psunsigned_t get_freemem_start(cnodeid_t cnode);
-extern void setup_replication_mask(int maxnodes);
-
-/* init.c */
-extern cnodeid_t get_compact_nodeid(void);	/* get compact node id */
-extern void init_platform_nodepda(nodepda_t *npda, cnodeid_t node);
-extern void init_platform_pda(cpuid_t cpu);
-extern void per_cpu_init(void);
-#ifdef	LATER
-extern cpumask_t boot_cpumask;
-#endif
-extern int is_fine_dirmode(void);
-extern void update_node_information(cnodeid_t);
- 
-#ifdef	LATER
-/* clksupport.c */
-extern void early_counter_intr(eframe_t *);
-#endif
-
-/* hubio.c */
-extern void hubio_init(void);
-extern void hub_merge_clean(nasid_t nasid);
-extern void hub_set_piomode(nasid_t nasid, int conveyor);
-
-/* huberror.c */
-extern void hub_error_init(cnodeid_t);
-extern void dump_error_spool(cpuid_t cpu, void (*pf)(char *, ...));
-extern void hubni_error_handler(char *, int);
-extern int check_ni_errors(void);
-
-/* Used for debugger to signal upper software a breakpoint has taken place */
-
-extern void		*debugger_update;
-extern __psunsigned_t	debugger_stopped;
-
-/* 
- * IP27 piomap, created by hub_pio_alloc.
- * xtalk_info MUST BE FIRST, since this structure is cast to a
- * xtalk_piomap_s by generic xtalk routines.
- */
-struct hub_piomap_s {
-	struct xtalk_piomap_s	hpio_xtalk_info;/* standard crosstalk pio info */
-	devfs_handle_t		hpio_hub;	/* which hub's mapping registers are set up */
-	short			hpio_holdcnt;	/* count of current users of bigwin mapping */
-	char			hpio_bigwin_num;/* if big window map, which one */
-	int 			hpio_flags;	/* defined below */
-};
-/* hub_piomap flags */
-#define HUB_PIOMAP_IS_VALID		0x1
-#define HUB_PIOMAP_IS_BIGWINDOW		0x2
-#define HUB_PIOMAP_IS_FIXED		0x4
-
-#define	hub_piomap_xt_piomap(hp)	(&hp->hpio_xtalk_info)
-#define	hub_piomap_hub_v(hp)	(hp->hpio_hub)
-#define	hub_piomap_winnum(hp)	(hp->hpio_bigwin_num)
-
-#if TBD
- /* Ensure that hpio_xtalk_info is first */
- #assert (&(((struct hub_piomap_s *)0)->hpio_xtalk_info) == 0)
-#endif
-
-
-/* 
- * IP27 dmamap, created by hub_pio_alloc.
- * xtalk_info MUST BE FIRST, since this structure is cast to a
- * xtalk_dmamap_s by generic xtalk routines.
- */
-struct hub_dmamap_s {
-	struct xtalk_dmamap_s	hdma_xtalk_info;/* standard crosstalk dma info */
-	devfs_handle_t		hdma_hub;	/* which hub we go through */
-	int			hdma_flags;	/* defined below */
-};
-/* hub_dmamap flags */
-#define HUB_DMAMAP_IS_VALID		0x1
-#define HUB_DMAMAP_USED			0x2
-#define	HUB_DMAMAP_IS_FIXED		0x4
-
-#if TBD
- /* Ensure that hdma_xtalk_info is first */
- #assert (&(((struct hub_dmamap_s *)0)->hdma_xtalk_info) == 0)
-#endif
-
-/* 
- * IP27 interrupt handle, created by hub_intr_alloc.
- * xtalk_info MUST BE FIRST, since this structure is cast to a
- * xtalk_intr_s by generic xtalk routines.
- */
-struct hub_intr_s {
-	struct xtalk_intr_s	i_xtalk_info;	/* standard crosstalk intr info */
-	ilvl_t			i_swlevel;	/* software level for blocking intr */
-	cpuid_t			i_cpuid;	/* which cpu */
-	int			i_bit;		/* which bit */
-	int			i_flags;
-};
-/* flag values */
-#define HUB_INTR_IS_ALLOCED	0x1	/* for debug: allocated */
-#define HUB_INTR_IS_CONNECTED	0x4	/* for debug: connected to a software driver */
-
-#if TBD
- /* Ensure that i_xtalk_info is first */
- #assert (&(((struct hub_intr_s *)0)->i_xtalk_info) == 0)
-#endif
-
-
-/* IP27 hub-specific information stored under INFO_LBL_HUB_INFO */
-/* TBD: IP27-dependent stuff currently in nodepda.h should be here */
-typedef struct hubinfo_s {
-	nodepda_t			*h_nodepda;	/* pointer to node's private data area */
-	cnodeid_t			h_cnodeid;	/* compact nodeid */
-	nasid_t				h_nasid;	/* nasid */
-
-	/* structures for PIO management */
-	xwidgetnum_t			h_widgetid;	/* my widget # (as viewed from xbow) */
-	struct hub_piomap_s		h_small_window_piomap[HUB_WIDGET_ID_MAX+1];
-	sv_t				h_bwwait;	/* wait for big window to free */
-	spinlock_t			h_bwlock;	/* guard big window piomap's */
-	spinlock_t			h_crblock;      /* gaurd CRB error handling */
-	int				h_num_big_window_fixed;	/* count number of FIXED maps */
-	struct hub_piomap_s		h_big_window_piomap[HUB_NUM_BIG_WINDOW];
-	hub_intr_t			hub_ii_errintr;
-} *hubinfo_t;
-
-#define hubinfo_get(vhdl, infoptr) ((void)hwgraph_info_get_LBL \
-	(vhdl, INFO_LBL_NODE_INFO, (arbitrary_info_t *)infoptr))
-
-#define hubinfo_set(vhdl, infoptr) (void)hwgraph_info_add_LBL \
-	(vhdl, INFO_LBL_NODE_INFO, (arbitrary_info_t)infoptr)
-
-#define	hubinfo_to_hubv(hinfo, hub_v)	(hinfo->h_nodepda->node_vertex)
-
-/*
- * Hub info PIO map access functions.
- */
-#define	hubinfo_bwin_piomap_get(hinfo, win) 	\
-			(&hinfo->h_big_window_piomap[win])
-#define	hubinfo_swin_piomap_get(hinfo, win)	\
-			(&hinfo->h_small_window_piomap[win])
-	
-/* IP27 cpu-specific information stored under INFO_LBL_CPU_INFO */
-/* TBD: IP27-dependent stuff currently in pda.h should be here */
-typedef struct cpuinfo_s {
-#ifdef	LATER
-	pda_t		*ci_cpupda;	/* pointer to CPU's private data area */
-#endif
-	cpuid_t		ci_cpuid;	/* CPU ID */
-} *cpuinfo_t;
-
-#define cpuinfo_get(vhdl, infoptr) ((void)hwgraph_info_get_LBL \
-	(vhdl, INFO_LBL_CPU_INFO, (arbitrary_info_t *)infoptr))
-
-#define cpuinfo_set(vhdl, infoptr) (void)hwgraph_info_add_LBL \
-	(vhdl, INFO_LBL_CPU_INFO, (arbitrary_info_t)infoptr)
-
-/* Special initialization function for xswitch vertices created during startup. */
-extern void xswitch_vertex_init(devfs_handle_t xswitch);
-
-extern xtalk_provider_t hub_provider;
-
-/* du.c */
-int ducons_write(char *buf, int len);
-
-/* memerror.c */
-
-extern void install_eccintr(cpuid_t cpu);
-extern void memerror_get_stats(cnodeid_t cnode,
-			       int *bank_stats, int *bank_stats_max);
-extern void probe_md_errors(nasid_t);
-/* sysctlr.c */
-extern void sysctlr_init(void);
-extern void sysctlr_power_off(int sdonly);
-extern void sysctlr_keepalive(void);
-
-#define valid_cpuid(_x)		(((_x) >= 0) && ((_x) < maxcpus))
-
-/* Useful definitions to get the memory dimm given a physical
- * address.
- */
-#define paddr_dimm(_pa)		((_pa & MD_BANK_MASK) >> MD_BANK_SHFT)
-#define paddr_cnode(_pa)	(NASID_TO_COMPACT_NODEID(NASID_GET(_pa)))
-extern void membank_pathname_get(paddr_t,char *);
-
-/* To redirect the output into the error buffer */
-#define errbuf_print(_s)	printf("#%s",_s)
-
-extern void crbx(nasid_t nasid, void (*pf)(char *, ...));
-void bootstrap(void);
-
-/* sndrv.c */
-extern int sndrv_attach(devfs_handle_t vertex);
-
-#endif /* _ASM_IA64_SN_SN1_SN_PRIVATE_H */
diff -Nru a/include/asm-ia64/sn/sn1/synergy.h b/include/asm-ia64/sn/sn1/synergy.h
--- a/include/asm-ia64/sn/sn1/synergy.h	Wed Jun 18 23:42:06 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,184 +0,0 @@
-#ifndef _ASM_IA64_SN_SN1_SYNERGY_H
-#define _ASM_IA64_SN_SN1_SYNERGY_H
-
-#include <asm/io.h>
-#include <asm/sn/hcl.h>
-#include <asm/sn/addrs.h>
-#include <asm/sn/intr_public.h>
-
-
-/*
- * Definitions for the synergy asic driver
- * 
- * These are for SGI platforms only.
- *
- * 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) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-
-#define SYNERGY_L4_BYTES		(64UL*1024*1024)
-#define SYNERGY_L4_WAYS			8
-#define SYNERGY_L4_BYTES_PER_WAY	(SYNERGY_L4_BYTES/SYNERGY_L4_WAYS)
-#define SYNERGY_BLOCK_SIZE		512UL
-
-
-#define SSPEC_BASE	(0xe0000000000UL)
-#define LB_REG_BASE	(SSPEC_BASE + 0x0)
-
-#define VEC_MASK3A_ADDR	(0x2a0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK3B_ADDR	(0x2a8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK3A	(0x2a0)
-#define VEC_MASK3B	(0x2a8)
-
-#define VEC_MASK2A_ADDR	(0x2b0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK2B_ADDR	(0x2b8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK2A	(0x2b0)
-#define VEC_MASK2B	(0x2b8)
-
-#define VEC_MASK1A_ADDR	(0x2c0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK1B_ADDR	(0x2c8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK1A	(0x2c0)
-#define VEC_MASK1B	(0x2c8)
-
-#define VEC_MASK0A_ADDR	(0x2d0 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK0B_ADDR	(0x2d8 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define VEC_MASK0A	(0x2d0)
-#define VEC_MASK0B	(0x2d8)
-
-#define GBL_PERF_A_ADDR (0x330 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-#define GBL_PERF_B_ADDR (0x338 + LB_REG_BASE + __IA64_UNCACHED_OFFSET)
-
-#define WRITE_LOCAL_SYNERGY_REG(addr, value)	__synergy_out(addr, value)
-
-#define HSPEC_SYNERGY0_0        0x04000000    /* Synergy0 Registers     */
-#define HSPEC_SYNERGY1_0        0x05000000    /* Synergy1 Registers     */
-#define HS_SYNERGY_STRIDE       (HSPEC_SYNERGY1_0 - HSPEC_SYNERGY0_0)
-#define REMOTE_HSPEC(_n, _x)    (HUBREG_CAST (RREG_BASE(_n) + (_x)))
-
-#define RREG_BASE(_n)           (NODE_LREG_BASE(_n))
-#define NODE_LREG_BASE(_n)      (NODE_HSPEC_BASE(_n) + 0x30000000)
-#define NODE_HSPEC_BASE(_n)     (HSPEC_BASE + NODE_OFFSET(_n))
-#ifndef HSPEC_BASE
-#define HSPEC_BASE              (SYN_UNCACHED_SPACE | HSPEC_BASE_SYN)
-#endif
-#define SYN_UNCACHED_SPACE      0xc000000000000000
-#define HSPEC_BASE_SYN          0x00000b0000000000
-#define NODE_OFFSET(_n)         (UINT64_CAST (_n) << NODE_SIZE_BITS)
-#define NODE_SIZE_BITS		33
-
-#define SYN_TAG_DISABLE_WAY	(SSPEC_BASE+0xae0)
-
-
-#define RSYN_REG_OFFSET(fsb, reg) (((fsb) ? HSPEC_SYNERGY1_0 : HSPEC_SYNERGY0_0) | (reg))
-
-#define REMOTE_SYNERGY_LOAD(nasid, fsb, reg)  __remote_synergy_in(nasid, fsb, reg)
-#define REMOTE_SYNERGY_STORE(nasid, fsb, reg, val) __remote_synergy_out(nasid, fsb, reg, val)
-
-static inline uint64_t
-__remote_synergy_in(int nasid, int fsb, uint64_t reg) {
-	volatile uint64_t *addr;
-
-	addr = (uint64_t *)(RREG_BASE(nasid) + RSYN_REG_OFFSET(fsb, reg));
-	return (*addr);
-}
-
-static inline void
-__remote_synergy_out(int nasid, int fsb, uint64_t reg, uint64_t value) {
-	volatile uint64_t *addr;
-
-        addr = (uint64_t *)(RREG_BASE(nasid) + RSYN_REG_OFFSET(fsb, (reg<<2)));
-        *(addr+0) = value >> 48;
-        *(addr+1) = value >> 32;
-        *(addr+2) = value >> 16;
-        *(addr+3) = value;
-        __ia64_mf_a();
-}
-
-/* XX this doesn't make a lot of sense. Which fsb?  */
-static inline void
-__synergy_out(unsigned long addr, unsigned long value)
-{
-	volatile unsigned long *adr = (unsigned long *)
-			(addr | __IA64_UNCACHED_OFFSET);
-
-	*adr = value;
-	__ia64_mf_a();
-}
-
-#define READ_LOCAL_SYNERGY_REG(addr)	__synergy_in(addr)
-
-/* XX this doesn't make a lot of sense. Which fsb? */
-static inline unsigned long
-__synergy_in(unsigned long addr)
-{
-	unsigned long ret, *adr = (unsigned long *)
-			(addr | __IA64_UNCACHED_OFFSET);
-
-	ret = *adr;
-	__ia64_mf_a();
-	return ret;
-}
-
-struct sn1_intr_action {
-	void (*handler)(int, void *, struct pt_regs *);
-	void *intr_arg;
-	unsigned long flags;
-	struct sn1_intr_action * next;
-};
-
-typedef struct synergy_da_s {
-	hub_intmasks_t	s_intmasks;
-}synergy_da_t;
-
-struct sn1_cnode_action_list {
-	spinlock_t action_list_lock;
-	struct sn1_intr_action *action_list;
-};
-
-/*
- * ioctl cmds for node/hub/synergy/[01]/mon for synergy
- * perf monitoring are defined in sndrv.h
- */
-
-/* multiplex the counters every 10 timer interrupts */ 
-#define SYNERGY_PERF_FREQ_DEFAULT 10
-
-/* macros for synergy "mon" device ioctl handler */
-#define SYNERGY_PERF_INFO(_s, _f)	(arbitrary_info_t)(((_s) << 16)|(_f))
-#define SYNERGY_PERF_INFO_CNODE(_x)	(cnodeid_t)(((uint64_t)_x) >> 16)
-#define SYNERGY_PERF_INFO_FSB(_x)	(((uint64_t)_x) & 1)
-
-/* synergy perf control registers */
-#define PERF_CNTL0_A            0xab0UL /* control A on FSB0 */
-#define PERF_CNTL0_B            0xab8UL /* control B on FSB0 */
-#define PERF_CNTL1_A            0xac0UL /* control A on FSB1 */
-#define PERF_CNTL1_B            0xac8UL /* control B on FSB1 */
-
-/* synergy perf counters */
-#define PERF_CNTR0_A            0xad0UL /* counter A on FSB0 */
-#define PERF_CNTR0_B            0xad8UL /* counter B on FSB0 */
-#define PERF_CNTR1_A            0xaf0UL /* counter A on FSB1 */
-#define PERF_CNTR1_B            0xaf8UL /* counter B on FSB1 */
-
-/* Synergy perf data. Each nodepda keeps a list of these */
-struct synergy_perf_s {
-        uint64_t        intervals;      /* count of active intervals for this event */
-        uint64_t        total_intervals;/* snapshot of total intervals */
-        uint64_t        modesel;        /* mode and sel bits, both A and B registers */
-        struct synergy_perf_s *next;	/* next in circular linked list */
-        uint64_t        counts[2];      /* [0] is synergy-A counter, [1] synergy-B counter */
-};
-
-typedef struct synergy_perf_s synergy_perf_t;
-
-typedef struct synergy_info_s synergy_info_t;
-
-extern void synergy_perf_init(void);
-extern void synergy_perf_update(int);
-extern struct file_operations synergy_mon_fops;
-
-#endif /* _ASM_IA64_SN_SN1_SYNERGY_H */
diff -Nru a/include/asm-ia64/sn/sn2/addrs.h b/include/asm-ia64/sn/sn2/addrs.h
--- a/include/asm-ia64/sn/sn2/addrs.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/sn2/addrs.h	Wed Jun 18 23:42:06 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_SN2_ADDRS_H
@@ -57,7 +57,7 @@
 #define LOCAL_MEM_SPACE		0xc000010000000000	/* Local Memory space */
 #define GLOBAL_MMR_SPACE	0xc000000800000000	/* Global MMR space */
 #define GLOBAL_PHYS_MMR_SPACE	0x0000000800000000	/* Global Physical MMR space */
-#define GET_SPACE		0xc000001000000000	/* GET space */
+#define GET_SPACE		0xe000001000000000	/* GET space */
 #define AMO_SPACE		0xc000002000000000	/* AMO space */
 #define CACHEABLE_MEM_SPACE	0xe000003000000000	/* Cacheable memory space */
 #define UNCACHED                0xc000000000000000      /* UnCacheable memory space */
diff -Nru a/include/asm-ia64/sn/sn2/arch.h b/include/asm-ia64/sn/sn2/arch.h
--- a/include/asm-ia64/sn/sn2/arch.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/sn2/arch.h	Wed Jun 18 23:42:06 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_SN2_ARCH_H
 #define _ASM_IA64_SN_SN2_ARCH_H
@@ -46,6 +46,7 @@
 
 
 #define NASID_MASK_BYTES	((MAX_NASIDS + 7) / 8)
+#define CNASID_MASK_BYTES	(NASID_MASK_BYTES / 2)
 
 
 /*
diff -Nru a/include/asm-ia64/sn/sn2/intr.h b/include/asm-ia64/sn/sn2/intr.h
--- a/include/asm-ia64/sn/sn2/intr.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/sn/sn2/intr.h	Wed Jun 18 23:42:08 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_SN2_INTR_H
 #define _ASM_IA64_SN_SN2_INTR_H
@@ -14,13 +14,17 @@
 
 // These two IRQ's are used by partitioning.
 #define SGI_XPC_ACTIVATE		(0x30)
+#define SGI_II_ERROR			(0x31)
+#define SGI_XBOW_ERROR			(0x32)
+#define SGI_PCIBR_ERROR			(0x33)
 #define SGI_XPC_NOTIFY			(0xe7)
 
-#define IA64_SN2_FIRST_DEVICE_VECTOR	(0x31)
+#define IA64_SN2_FIRST_DEVICE_VECTOR	(0x34)
 #define IA64_SN2_LAST_DEVICE_VECTOR	(0xe6)
 
 #define SN2_IRQ_RESERVED        (0x1)
 #define SN2_IRQ_CONNECTED       (0x2)
+#define SN2_IRQ_SHARED		(0x4)
 
 #define SN2_IRQ_PER_HUB         (2048)
 
diff -Nru a/include/asm-ia64/sn/sn2/io.h b/include/asm-ia64/sn/sn2/io.h
--- a/include/asm-ia64/sn/sn2/io.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/sn/sn2/io.h	Wed Jun 18 23:42:07 2003
@@ -32,8 +32,8 @@
 	unsigned char ret;
 
 	ret = *addr;
-	sn_dma_flush((unsigned long)addr);
 	__sn_mf_a();
+	sn_dma_flush((unsigned long)addr);
 	return ret;
 }
 
@@ -44,8 +44,8 @@
 	unsigned short ret;
 
 	ret = *addr;
-	sn_dma_flush((unsigned long)addr);
 	__sn_mf_a();
+	sn_dma_flush((unsigned long)addr);
 	return ret;
 }
 
@@ -56,8 +56,8 @@
 	unsigned int ret;
 
 	ret = *addr;
-	sn_dma_flush((unsigned long)addr);
 	__sn_mf_a();
+	sn_dma_flush((unsigned long)addr);
 	return ret;
 }
 
@@ -103,6 +103,7 @@
 	unsigned char val;
 
 	val = *(volatile unsigned char *)addr;
+	__sn_mf_a();
 	sn_dma_flush((unsigned long)addr);
         return val;
 }
@@ -113,6 +114,7 @@
 	unsigned short val;
 
 	val = *(volatile unsigned short *)addr;
+	__sn_mf_a();
 	sn_dma_flush((unsigned long)addr);
         return val;
 }
@@ -123,6 +125,7 @@
 	unsigned int val;
 
 	val = *(volatile unsigned int *) addr;
+	__sn_mf_a();
 	sn_dma_flush((unsigned long)addr);
         return val;
 }
@@ -133,6 +136,7 @@
 	unsigned long val;
 
 	val = *(volatile unsigned long *) addr;
+	__sn_mf_a();
 	sn_dma_flush((unsigned long)addr);
         return val;
 }
diff -Nru a/include/asm-ia64/sn/sn2/mmzone_sn2.h b/include/asm-ia64/sn/sn2/mmzone_sn2.h
--- a/include/asm-ia64/sn/sn2/mmzone_sn2.h	Wed Jun 18 23:42:09 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,165 +0,0 @@
-#ifndef _ASM_IA64_SN_MMZONE_SN2_H
-#define _ASM_IA64_SN_MMZONE_SN2_H
-
-/*
- * 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) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
- */
-
-#include <linux/config.h>
-
-
-/*
- * SGI SN2 Arch defined values
- *
- * 	An SN2 physical address is broken down as follows:
- *
- *             +-----------------------------------------+
- *             |         |      |    |   node offset     |
- *             | unused  | node | AS |-------------------|
- *             |         |      |    | cn | clump offset |
- *             +-----------------------------------------+
- *              6       4 4    3 3  3 3  3 3            0
- *              3       9 8    8 7  6 5  4 3            0
- *
- *		bits 63-49	Unused - must be zero
- *		bits 48-38	Node number. Note that some configurations do NOT
- *				have a node zero.
- *		bits 37-36	Address space ID. Cached memory has a value of 3 (!!!).
- *				Chipset & IO addresses have other values.
- *				  (Yikes!! The hardware folks hate us...)
- *		bits 35-0	Node offset.
- *
- *	The node offset can be further broken down as:
- *		bits 35-34	Clump (bank) number.
- *		bits 33-0	Clump (bank) offset.
- *
- *	A node consists of up to 4 clumps (banks) of memory. A clump may be empty, or may be
- *	populated with a single contiguous block of memory starting at clump
- *	offset 0. The size of the block is (2**n) * 64MB, where 0<n<9.
- *
- *	Important notes:
- *		- IO space addresses are embedded with the range of valid memory addresses.
- *		- All cached memory addresses have bits 36 & 37 set to 1's.
- *		- There is no physical address 0.
- *
- * NOTE: This file exports symbols prefixed with "PLAT_". Symbols prefixed with
- *	 "SN_" are intended for internal use only and should not be used in
- *	 any platform independent code. 
- *
- *	 This file is also responsible for exporting the following definitions:
- *		cnodeid_t	Define a compact node id. 
- */
-
-typedef signed short cnodeid_t;
-
-#define SN2_BANKS_PER_NODE		4
-#define SN2_NODE_SIZE			(64UL*1024*1024*1024)	/* 64GB per node */
-#define SN2_BANK_SIZE			(SN2_NODE_SIZE/SN2_BANKS_PER_NODE)
-#define SN2_NODE_SHIFT			38
-#define SN2_NODE_MASK			0x7ffUL
-#define SN2_NODE_OFFSET_MASK		(SN2_NODE_SIZE-1)
-#define SN2_NODE_NUMBER(addr)		(((unsigned long)(addr) >> SN2_NODE_SHIFT) & SN2_NODE_MASK)
-#define SN2_NODE_CLUMP_NUMBER(kaddr)	(((unsigned long)(kaddr) >>34) & 3)
-#define SN2_NODE_OFFSET(addr)		(((unsigned long)(addr)) & SN2_NODE_OFFSET_MASK)
-#define SN2_KADDR(nasid, offset)	(((unsigned long)(nasid)<<SN2_NODE_SHIFT) | (offset) | SN2_PAGE_OFFSET)
-#define SN2_PAGE_OFFSET			0xe000003000000000UL      /* Cacheable memory space */
-
-
-#define PLAT_MAX_NODE_NUMBER		2048			/* Maximum node number + 1 */
-#define PLAT_MAX_COMPACT_NODES		128			/* Maximum number of nodes in SSI system */
-
-#define PLAT_MAX_PHYS_MEMORY		(1UL << 49)
-
-
-
-/*
- * On the SN platforms, a clump is the same as a memory bank.
- */
-#define PLAT_CLUMPS_PER_NODE		SN2_BANKS_PER_NODE
-#define PLAT_CLUMP_OFFSET(addr)		((unsigned long)(addr) & 0x3ffffffffUL)
-#define PLAT_CLUMPSIZE			(SN2_NODE_SIZE/PLAT_CLUMPS_PER_NODE)
-#define PLAT_MAXCLUMPS			(PLAT_CLUMPS_PER_NODE * PLAT_MAX_COMPACT_NODES)
-
-
-
-/*
- * PLAT_VALID_MEM_KADDR returns a boolean to indicate if a kaddr is potentially a
- * valid cacheable identity mapped RAM memory address.
- * Note that the RAM may or may not actually be present!!
- */
-#define SN2_VALID_KERN_ADDR_MASK	0xffff003000000000UL
-#define SN2_VALID_KERN_ADDR_VALUE	0xe000003000000000UL
-#define PLAT_VALID_MEM_KADDR(kaddr)	(((unsigned long)(kaddr) & SN2_VALID_KERN_ADDR_MASK) == SN2_VALID_KERN_ADDR_VALUE)
-
-
-
-/*
- * Memory is conceptually divided into chunks. A chunk is either
- * completely present, or else the kernel assumes it is completely
- * absent. Each node consists of a number of possibly contiguous chunks.
- */
-#define SN2_CHUNKSHIFT			25			/* 32 MB */
-#define PLAT_CHUNKSIZE			(1UL << SN2_CHUNKSHIFT)
-#define PLAT_CHUNKNUM(addr)		({unsigned long _p=(unsigned long)(addr);		\
-						(((_p&SN2_NODE_MASK)>>2) | 			\
-						(_p&SN2_NODE_OFFSET_MASK)) >>SN2_CHUNKSHIFT;})
-
-/*
- * Given a kaddr, find the nid (compact nodeid)
- */
-#ifdef CONFIG_IA64_SGI_SN_DEBUG
-#define DISCONBUG(kaddr)		panic("DISCONTIG BUG: line %d, %s. kaddr 0x%lx",	 	\
-						__LINE__, __FILE__, (long)(kaddr))
-
-#define KVADDR_TO_NID(kaddr)		({long _ktn=(long)(kaddr);					\
-						kern_addr_valid(_ktn) ? 				\
-						local_node_data->physical_node_map[SN2_NODE_NUMBER(_ktn)] :	\
-						(DISCONBUG(_ktn), 0UL);})
-#else
-#define KVADDR_TO_NID(kaddr)		(local_node_data->physical_node_map[SN2_NODE_NUMBER(kaddr)])
-#endif
-
-
-
-/*
- * Given a kaddr, find the index into the clump_mem_map_base array of the page struct entry 
- * for the first page of the clump.
- */
-#define PLAT_CLUMP_MEM_MAP_INDEX(kaddr)		({long _kmmi=(long)(kaddr);				\
-							KVADDR_TO_NID(_kmmi) * PLAT_CLUMPS_PER_NODE +	\
-							SN2_NODE_CLUMP_NUMBER(_kmmi);})
-
-
-
-/*
- * Calculate a "goal" value to be passed to __alloc_bootmem_node for allocating structures on
- * nodes so that they don't alias to the same line in the cache as the previous allocated structure.
- * This macro takes an address of the end of previous allocation, rounds it to a page boundary & 
- * changes the node number.
- */
-#define PLAT_BOOTMEM_ALLOC_GOAL(cnode,kaddr)	__pa(SN2_KADDR(PLAT_PXM_TO_PHYS_NODE_NUMBER(nid_to_pxm_map[cnode]),	       \
-						 (SN2_NODE_OFFSET(kaddr) + PAGE_SIZE - 1) >> PAGE_SHIFT << PAGE_SHIFT))
-
-
-
-
-/*
- * Convert a proximity domain number (from the ACPI tables) into a physical node number.
- *	Note: on SN2, the promity domain number is the same as bits [8:1] of the NASID. The following
- *	algorithm relies on:
- *		- bit 0 of the NASID for cpu nodes is always 0
- *		- bits [10:9] of all NASIDs in a partition are always the same
- *		- hard_smp_processor_id return the SAPIC of the current cpu &
- *			bits 0..11 contain the NASID.
- *
- *	All of this complexity is because MS architectually limited proximity domain numbers to
- *	8 bits. 
- */
-
-#define PLAT_PXM_TO_PHYS_NODE_NUMBER(pxm)	(((pxm)<<1) | (hard_smp_processor_id() & 0x300))
-
-#endif /* _ASM_IA64_SN_MMZONE_SN2_H */
diff -Nru a/include/asm-ia64/sn/sn2/shub.h b/include/asm-ia64/sn/sn2/shub.h
--- a/include/asm-ia64/sn/sn2/shub.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-ia64/sn/sn2/shub.h	Wed Jun 18 23:42:09 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
diff -Nru a/include/asm-ia64/sn/sn2/shub_md.h b/include/asm-ia64/sn/sn2/shub_md.h
--- a/include/asm-ia64/sn/sn2/shub_md.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-ia64/sn/sn2/shub_md.h	Wed Jun 18 23:42:09 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001, 2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001, 2002-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
diff -Nru a/include/asm-ia64/sn/sn2/shub_mmr.h b/include/asm-ia64/sn/sn2/shub_mmr.h
--- a/include/asm-ia64/sn/sn2/shub_mmr.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/sn/sn2/shub_mmr.h	Wed Jun 18 23:42:08 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
@@ -25746,14 +25746,14 @@
 /*                           Real-time Clock                            */
 /* ==================================================================== */
 
-#define SH_RTC                                   0x00000001101c0000
-#define SH_RTC_MASK                              0x007fffffffffffff
+#define SH_RTC                                   0x00000001101c0000UL
+#define SH_RTC_MASK                              0x007fffffffffffffUL
 #define SH_RTC_INIT                              0x0000000000000000
 
 /*   SH_RTC_REAL_TIME_CLOCK                                             */
 /*   Description:  Real-time Clock                                      */
 #define SH_RTC_REAL_TIME_CLOCK_SHFT              0
-#define SH_RTC_REAL_TIME_CLOCK_MASK              0x007fffffffffffff
+#define SH_RTC_REAL_TIME_CLOCK_MASK              0x007fffffffffffffUL
 
 /* ==================================================================== */
 /*                        Register "SH_SCRATCH0"                        */
diff -Nru a/include/asm-ia64/sn/sn2/shub_mmr_t.h b/include/asm-ia64/sn/sn2/shub_mmr_t.h
--- a/include/asm-ia64/sn/sn2/shub_mmr_t.h	Wed Jun 18 23:42:05 2003
+++ b/include/asm-ia64/sn/sn2/shub_mmr_t.h	Wed Jun 18 23:42:06 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2001-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2001-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
diff -Nru a/include/asm-ia64/sn/sn2/shubio.h b/include/asm-ia64/sn/sn2/shubio.h
--- a/include/asm-ia64/sn/sn2/shubio.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/sn/sn2/shubio.h	Wed Jun 18 23:42:07 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_SN2_SHUBIO_H
@@ -3035,31 +3035,31 @@
 /* Scratch registers (all bits available) */
 #define IIO_SCRATCH_REG0        IIO_ISCR0
 #define IIO_SCRATCH_REG1        IIO_ISCR1
-#define IIO_SCRATCH_MASK        0xffffffffffffffff
+#define IIO_SCRATCH_MASK        0xffffffffffffffffUL
 
-#define IIO_SCRATCH_BIT0_0      0x0000000000000001
-#define IIO_SCRATCH_BIT0_1      0x0000000000000002
-#define IIO_SCRATCH_BIT0_2      0x0000000000000004
-#define IIO_SCRATCH_BIT0_3      0x0000000000000008
-#define IIO_SCRATCH_BIT0_4      0x0000000000000010
-#define IIO_SCRATCH_BIT0_5      0x0000000000000020
-#define IIO_SCRATCH_BIT0_6      0x0000000000000040
-#define IIO_SCRATCH_BIT0_7      0x0000000000000080
-#define IIO_SCRATCH_BIT0_8      0x0000000000000100
-#define IIO_SCRATCH_BIT0_9      0x0000000000000200
-#define IIO_SCRATCH_BIT0_A      0x0000000000000400
+#define IIO_SCRATCH_BIT0_0      0x0000000000000001UL
+#define IIO_SCRATCH_BIT0_1      0x0000000000000002UL
+#define IIO_SCRATCH_BIT0_2      0x0000000000000004UL
+#define IIO_SCRATCH_BIT0_3      0x0000000000000008UL
+#define IIO_SCRATCH_BIT0_4      0x0000000000000010UL
+#define IIO_SCRATCH_BIT0_5      0x0000000000000020UL
+#define IIO_SCRATCH_BIT0_6      0x0000000000000040UL
+#define IIO_SCRATCH_BIT0_7      0x0000000000000080UL
+#define IIO_SCRATCH_BIT0_8      0x0000000000000100UL
+#define IIO_SCRATCH_BIT0_9      0x0000000000000200UL
+#define IIO_SCRATCH_BIT0_A      0x0000000000000400UL
 
-#define IIO_SCRATCH_BIT1_0      0x0000000000000001
-#define IIO_SCRATCH_BIT1_1      0x0000000000000002
+#define IIO_SCRATCH_BIT1_0      0x0000000000000001UL
+#define IIO_SCRATCH_BIT1_1      0x0000000000000002UL
 /* IO Translation Table Entries */
 #define IIO_NUM_ITTES   7               /* ITTEs numbered 0..6 */
                                         /* Hw manuals number them 1..7! */
 /*
  * IIO_IMEM Register fields.
  */
-#define IIO_IMEM_W0ESD  0x1             /* Widget 0 shut down due to error */
-#define IIO_IMEM_B0ESD  (1 << 4)        /* BTE 0 shut down due to error */
-#define IIO_IMEM_B1ESD  (1 << 8)        /* BTE 1 Shut down due to error */
+#define IIO_IMEM_W0ESD  0x1UL             /* Widget 0 shut down due to error */
+#define IIO_IMEM_B0ESD  (1UL << 4)        /* BTE 0 shut down due to error */
+#define IIO_IMEM_B1ESD  (1UL << 8)        /* BTE 1 Shut down due to error */
 
 /*
  * As a permanent workaround for a bug in the PI side of the shub, we've
@@ -3191,23 +3191,23 @@
 /* 
  * IO BTE Length/Status (IIO_IBLS) register bit field definitions
  */
-#define IBLS_BUSY		(0x1 << 20)
+#define IBLS_BUSY		(0x1UL << 20)
 #define IBLS_ERROR_SHFT		16
-#define IBLS_ERROR		(0x1 << IBLS_ERROR_SHFT)
+#define IBLS_ERROR		(0x1UL << IBLS_ERROR_SHFT)
 #define IBLS_LENGTH_MASK	0xffff
 
 /*
  * IO BTE Control/Terminate register (IBCT) register bit field definitions
  */
-#define IBCT_POISON		(0x1 << 8)
-#define IBCT_NOTIFY		(0x1 << 4)
-#define IBCT_ZFIL_MODE		(0x1 << 0)
+#define IBCT_POISON		(0x1UL << 8)
+#define IBCT_NOTIFY		(0x1UL << 4)
+#define IBCT_ZFIL_MODE		(0x1UL << 0)
 
 /*
  * IIO Incoming Error Packet Header (IIO_IIEPH1/IIO_IIEPH2)
  */
-#define IIEPH1_VALID		(1 << 44)
-#define IIEPH1_OVERRUN		(1 << 40)
+#define IIEPH1_VALID		(1UL << 44)
+#define IIEPH1_OVERRUN		(1UL << 40)
 #define IIEPH1_ERR_TYPE_SHFT	32
 #define IIEPH1_ERR_TYPE_MASK	0xf
 #define IIEPH1_SOURCE_SHFT	20
@@ -3217,7 +3217,7 @@
 #define IIEPH1_CMD_SHFT		0
 #define IIEPH1_CMD_MASK		7
 
-#define IIEPH2_TAIL		(1 << 40)
+#define IIEPH2_TAIL		(1UL << 40)
 #define IIEPH2_ADDRESS_SHFT	0
 #define IIEPH2_ADDRESS_MASK	38
 
@@ -3229,21 +3229,21 @@
 /*
  * IO Error Clear register bit field definitions
  */
-#define IECLR_PI1_FWD_INT	(1 << 31)  /* clear PI1_FORWARD_INT in iidsr */
-#define IECLR_PI0_FWD_INT	(1 << 30)  /* clear PI0_FORWARD_INT in iidsr */
-#define IECLR_SPUR_RD_HDR	(1 << 29)  /* clear valid bit in ixss reg */
-#define IECLR_BTE1		(1 << 18)  /* clear bte error 1 */
-#define IECLR_BTE0		(1 << 17)  /* clear bte error 0 */
-#define IECLR_CRAZY		(1 << 16)  /* clear crazy bit in wstat reg */
-#define IECLR_PRB_F		(1 << 15)  /* clear err bit in PRB_F reg */
-#define IECLR_PRB_E		(1 << 14)  /* clear err bit in PRB_E reg */
-#define IECLR_PRB_D		(1 << 13)  /* clear err bit in PRB_D reg */
-#define IECLR_PRB_C		(1 << 12)  /* clear err bit in PRB_C reg */
-#define IECLR_PRB_B		(1 << 11)  /* clear err bit in PRB_B reg */
-#define IECLR_PRB_A		(1 << 10)  /* clear err bit in PRB_A reg */
-#define IECLR_PRB_9		(1 << 9)   /* clear err bit in PRB_9 reg */
-#define IECLR_PRB_8		(1 << 8)   /* clear err bit in PRB_8 reg */
-#define IECLR_PRB_0		(1 << 0)   /* clear err bit in PRB_0 reg */
+#define IECLR_PI1_FWD_INT	(1UL << 31)  /* clear PI1_FORWARD_INT in iidsr */
+#define IECLR_PI0_FWD_INT	(1UL << 30)  /* clear PI0_FORWARD_INT in iidsr */
+#define IECLR_SPUR_RD_HDR	(1UL << 29)  /* clear valid bit in ixss reg */
+#define IECLR_BTE1		(1UL << 18)  /* clear bte error 1 */
+#define IECLR_BTE0		(1UL << 17)  /* clear bte error 0 */
+#define IECLR_CRAZY		(1UL << 16)  /* clear crazy bit in wstat reg */
+#define IECLR_PRB_F		(1UL << 15)  /* clear err bit in PRB_F reg */
+#define IECLR_PRB_E		(1UL << 14)  /* clear err bit in PRB_E reg */
+#define IECLR_PRB_D		(1UL << 13)  /* clear err bit in PRB_D reg */
+#define IECLR_PRB_C		(1UL << 12)  /* clear err bit in PRB_C reg */
+#define IECLR_PRB_B		(1UL << 11)  /* clear err bit in PRB_B reg */
+#define IECLR_PRB_A		(1UL << 10)  /* clear err bit in PRB_A reg */
+#define IECLR_PRB_9		(1UL << 9)   /* clear err bit in PRB_9 reg */
+#define IECLR_PRB_8		(1UL << 8)   /* clear err bit in PRB_8 reg */
+#define IECLR_PRB_0		(1UL << 0)   /* clear err bit in PRB_0 reg */
 
 /*
  * IIO CRB control register Fields: IIO_ICCR 
@@ -3495,7 +3495,7 @@
 typedef struct hub_piomap_s *hub_piomap_t;
 
 extern hub_piomap_t
-hub_piomap_alloc(devfs_handle_t dev,      /* set up mapping for this device */
+hub_piomap_alloc(vertex_hdl_t dev,      /* set up mapping for this device */
                 device_desc_t dev_desc, /* device descriptor */
                 iopaddr_t xtalk_addr,   /* map for this xtalk_addr range */
                 size_t byte_count,
@@ -3513,7 +3513,7 @@
 hub_piomap_done(hub_piomap_t hub_piomap);
 
 extern caddr_t
-hub_piotrans_addr(      devfs_handle_t dev,       /* translate to this device */
+hub_piotrans_addr(      vertex_hdl_t dev,       /* translate to this device */
                         device_desc_t dev_desc, /* device descriptor */
                         iopaddr_t xtalk_addr,   /* Crosstalk address */
                         size_t byte_count,      /* map this many bytes */
@@ -3523,7 +3523,7 @@
 typedef struct hub_dmamap_s *hub_dmamap_t;
 
 extern hub_dmamap_t
-hub_dmamap_alloc(       devfs_handle_t dev,       /* set up mappings for dev */
+hub_dmamap_alloc(       vertex_hdl_t dev,       /* set up mappings for dev */
                         device_desc_t dev_desc, /* device descriptor */
                         size_t byte_count_max,  /* max size of a mapping */
                         unsigned flags);        /* defined in dma.h */
@@ -3545,14 +3545,14 @@
 hub_dmamap_done(        hub_dmamap_t dmamap);   /* done w/ mapping resources */
 
 extern iopaddr_t
-hub_dmatrans_addr(      devfs_handle_t dev,       /* translate for this device */
+hub_dmatrans_addr(      vertex_hdl_t dev,       /* translate for this device */
                         device_desc_t dev_desc, /* device descriptor */
                         paddr_t paddr,          /* system physical address */
                         size_t byte_count,      /* length */
                         unsigned flags);                /* defined in dma.h */
 
 extern alenlist_t
-hub_dmatrans_list(      devfs_handle_t dev,       /* translate for this device */
+hub_dmatrans_list(      vertex_hdl_t dev,       /* translate for this device */
                         device_desc_t dev_desc, /* device descriptor */
                         alenlist_t palenlist,   /* system addr/length list */
                         unsigned flags);                /* defined in dma.h */
@@ -3561,12 +3561,12 @@
 hub_dmamap_drain(       hub_dmamap_t map);
 
 extern void
-hub_dmaaddr_drain(      devfs_handle_t vhdl,
+hub_dmaaddr_drain(      vertex_hdl_t vhdl,
                         paddr_t addr,
                         size_t bytes);
 
 extern void
-hub_dmalist_drain(      devfs_handle_t vhdl,
+hub_dmalist_drain(      vertex_hdl_t vhdl,
                         alenlist_t list);
 
 
@@ -3574,14 +3574,14 @@
 typedef struct hub_intr_s *hub_intr_t;
 
 extern hub_intr_t
-hub_intr_alloc( devfs_handle_t dev,               /* which device */
+hub_intr_alloc( vertex_hdl_t dev,               /* which device */
                 device_desc_t dev_desc,         /* device descriptor */
-                devfs_handle_t owner_dev);        /* owner of this interrupt */
+                vertex_hdl_t owner_dev);        /* owner of this interrupt */
 
 extern hub_intr_t
-hub_intr_alloc_nothd(devfs_handle_t dev,          /* which device */
+hub_intr_alloc_nothd(vertex_hdl_t dev,          /* which device */
                 device_desc_t dev_desc,         /* device descriptor */
-                devfs_handle_t owner_dev);        /* owner of this interrupt */
+                vertex_hdl_t owner_dev);        /* owner of this interrupt */
 
 extern void
 hub_intr_free(hub_intr_t intr_hdl);
@@ -3596,16 +3596,14 @@
 extern void
 hub_intr_disconnect(hub_intr_t intr_hdl);
 
-extern devfs_handle_t
-hub_intr_cpu_get(hub_intr_t intr_hdl);
 
 /* CONFIGURATION MANAGEMENT */
 
 extern void
-hub_provider_startup(devfs_handle_t hub);
+hub_provider_startup(vertex_hdl_t hub);
 
 extern void
-hub_provider_shutdown(devfs_handle_t hub);
+hub_provider_shutdown(vertex_hdl_t hub);
 
 #define HUB_PIO_CONVEYOR        0x1     /* PIO in conveyor belt mode */
 #define HUB_PIO_FIRE_N_FORGET   0x2     /* PIO in fire-and-forget mode */
@@ -3619,38 +3617,17 @@
 
 typedef int     hub_widget_flags_t;
 
-/* Set the PIO mode for a widget.  These two functions perform the
- * same operation, but hub_device_flags_set() takes a hardware graph
- * vertex while hub_widget_flags_set() takes a nasid and widget
- * number.  In most cases, hub_device_flags_set() should be used.
- */
+/* Set the PIO mode for a widget. */
 extern int      hub_widget_flags_set(nasid_t            nasid,
                                      xwidgetnum_t       widget_num,
                                      hub_widget_flags_t flags);
 
-/* Depending on the flags set take the appropriate actions */
-extern int      hub_device_flags_set(devfs_handle_t       widget_dev,
-                                     hub_widget_flags_t flags);
-                                                    
-
 /* Error Handling. */
-extern int hub_ioerror_handler(devfs_handle_t, int, int, struct io_error_s *);
+extern int hub_ioerror_handler(vertex_hdl_t, int, int, struct io_error_s *);
 extern int kl_ioerror_handler(cnodeid_t, cnodeid_t, cpuid_t,
                               int, paddr_t, caddr_t, ioerror_mode_t);
-extern void hub_widget_reset(devfs_handle_t, xwidgetnum_t);
-extern int hub_error_devenable(devfs_handle_t, int, int);
-extern void hub_widgetdev_enable(devfs_handle_t, int);
-extern void hub_widgetdev_shutdown(devfs_handle_t, int);
-extern int  hub_dma_enabled(devfs_handle_t);
-
-/* hubdev */
-extern void hubdev_init(void);
-extern void hubdev_register(int (*attach_method)(devfs_handle_t));
-extern int hubdev_unregister(int (*attach_method)(devfs_handle_t));
-extern int hubdev_docallouts(devfs_handle_t hub);
-
-extern caddr_t hubdev_prombase_get(devfs_handle_t hub);
-extern cnodeid_t hubdev_cnodeid_get(devfs_handle_t hub);
+extern int hub_error_devenable(vertex_hdl_t, int, int);
+extern int  hub_dma_enabled(vertex_hdl_t);
 
 #endif /* __ASSEMBLY__ */
 #endif /* _KERNEL */
diff -Nru a/include/asm-ia64/sn/sn2/slotnum.h b/include/asm-ia64/sn/sn2/slotnum.h
--- a/include/asm-ia64/sn/sn2/slotnum.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/sn/sn2/slotnum.h	Wed Jun 18 23:42:07 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 1992 - 1997,2001 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 1992-1997,2001-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_SN2_SLOTNUM_H
diff -Nru a/include/asm-ia64/sn/sn2/sn_private.h b/include/asm-ia64/sn/sn2/sn_private.h
--- a/include/asm-ia64/sn/sn2/sn_private.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/sn2/sn_private.h	Wed Jun 18 23:42:06 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_SN2_SN_PRIVATE_H
 #define _ASM_IA64_SN_SN2_SN_PRIVATE_H
@@ -49,13 +49,13 @@
 #endif
 
 /* intr.c */
-extern int intr_reserve_level(cpuid_t cpu, int level, int err, devfs_handle_t owner_dev, char *name);
+extern int intr_reserve_level(cpuid_t cpu, int level, int err, vertex_hdl_t owner_dev, char *name);
 extern void intr_unreserve_level(cpuid_t cpu, int level);
 extern int intr_connect_level(cpuid_t cpu, int bit, ilvl_t mask_no, 
 			intr_func_t intr_prefunc);
 extern int intr_disconnect_level(cpuid_t cpu, int bit);
-extern cpuid_t intr_heuristic(devfs_handle_t dev, device_desc_t dev_desc,
-			      int req_bit,int intr_resflags,devfs_handle_t owner_dev,
+extern cpuid_t intr_heuristic(vertex_hdl_t dev, device_desc_t dev_desc,
+			      int req_bit,int intr_resflags,vertex_hdl_t owner_dev,
 			      char *intr_name,int *resp_bit);
 extern void intr_block_bit(cpuid_t cpu, int bit);
 extern void intr_unblock_bit(cpuid_t cpu, int bit);
@@ -83,8 +83,8 @@
 void bte_wait_for_xfer_completion(void *);
 
 /* klgraph.c */
-void klhwg_add_all_nodes(devfs_handle_t);
-void klhwg_add_all_modules(devfs_handle_t);
+void klhwg_add_all_nodes(vertex_hdl_t);
+void klhwg_add_all_modules(vertex_hdl_t);
 
 /* klidbg.c */
 void install_klidbg_functions(void);
@@ -97,7 +97,6 @@
 /* init.c */
 extern cnodeid_t get_compact_nodeid(void);	/* get compact node id */
 extern void init_platform_nodepda(nodepda_t *npda, cnodeid_t node);
-extern void init_platform_pda(cpuid_t cpu);
 extern void per_cpu_init(void);
 extern int is_fine_dirmode(void);
 extern void update_node_information(cnodeid_t);
@@ -125,7 +124,7 @@
  */
 struct hub_piomap_s {
 	struct xtalk_piomap_s	hpio_xtalk_info;/* standard crosstalk pio info */
-	devfs_handle_t		hpio_hub;	/* which shub's mapping registers are set up */
+	vertex_hdl_t		hpio_hub;	/* which shub's mapping registers are set up */
 	short			hpio_holdcnt;	/* count of current users of bigwin mapping */
 	char			hpio_bigwin_num;/* if big window map, which one */
 	int 			hpio_flags;	/* defined below */
@@ -146,7 +145,7 @@
  */
 struct hub_dmamap_s {
 	struct xtalk_dmamap_s	hdma_xtalk_info;/* standard crosstalk dma info */
-	devfs_handle_t		hdma_hub;	/* which shub we go through */
+	vertex_hdl_t		hdma_hub;	/* which shub we go through */
 	int			hdma_flags;	/* defined below */
 };
 /* shub_dmamap flags */
@@ -214,7 +213,7 @@
 	(vhdl, INFO_LBL_CPU_INFO, (arbitrary_info_t)infoptr)
 
 /* Special initialization function for xswitch vertices created during startup. */
-extern void xswitch_vertex_init(devfs_handle_t xswitch);
+extern void xswitch_vertex_init(vertex_hdl_t xswitch);
 
 extern xtalk_provider_t hub_provider;
 
@@ -248,6 +247,6 @@
 void bootstrap(void);
 
 /* sndrv.c */
-extern int sndrv_attach(devfs_handle_t vertex);
+extern int sndrv_attach(vertex_hdl_t vertex);
 
 #endif /* _ASM_IA64_SN_SN2_SN_PRIVATE_H */
diff -Nru a/include/asm-ia64/sn/sn_cpuid.h b/include/asm-ia64/sn/sn_cpuid.h
--- a/include/asm-ia64/sn/sn_cpuid.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/sn_cpuid.h	Wed Jun 18 23:42:06 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 
@@ -18,6 +18,7 @@
 #include <asm/sn/types.h>
 #include <asm/current.h>
 #include <asm/nodedata.h>
+#include <asm/sn/pda.h>
 
 
 /*
@@ -51,11 +52,6 @@
  *
  *         LID - processor defined register (see PRM V2).
  *
- *           On SN1
- *		31:24 - id   Contains the NASID
- *		23:16 - eid  Contains 0-3 to identify the cpu on the node
- *				bit 17 - synergy number
- *				bit 16 - FSB slot number 
  *           On SN2
  *		31:28 - id   Contains 0-3 to identify the cpu on the node
  *		27:16 - eid  Contains the NASID
@@ -64,34 +60,30 @@
  *
  * The following assumes the following mappings for LID register values:
  *
- * The macros convert between cpu physical ids & slice/fsb/synergy/nasid/cnodeid.
+ * The macros convert between cpu physical ids & slice/nasid/cnodeid.
  * These terms are described below:
  *
  *
+ * Brick
  *          -----   -----           -----   -----       CPU
- *          | 0 |   | 1 |           | 2 |   | 3 |       SLICE
+ *          | 0 |   | 1 |           | 0 |   | 1 |       SLICE
  *          -----   -----           -----   -----
  *            |       |               |       |
  *            |       |               |       |
- *          0 |       | 1           0 |       | 1       FSB SLOT
+ *          0 |       | 2           0 |       | 2       FSB SLOT
  *             -------                 -------  
  *                |                       |
  *                |                       |
- *             -------                 -------
- *             |     |                 |     |
- *             |  0  |                 |  1  |         SYNERGY (SN1 only)
- *             |     |                 |     |
- *             -------                 -------
  *                |                       |
- *                |                       |
- *             -------------------------------
- *             |                             |
- *             |         BEDROCK / SHUB      |        NASID   (0..MAX_NASIDS)
- *             |                             |        CNODEID (0..num_compact_nodes-1)
- *             |                             |
- *             |                             |
- *             -------------------------------
- *                           |
+ *             ------------      -------------
+ *             |          |      |           |
+ *             |    SHUB  |      |   SHUB    |        NASID   (0..MAX_NASIDS)
+ *             |          |----- |           |        CNODEID (0..num_compact_nodes-1)
+ *             |          |      |           |
+ *             |          |      |           |
+ *             ------------      -------------
+ *                   |                 |
+ *                           
  *
  */
 
@@ -100,25 +92,15 @@
 #define cpu_physical_id(cpuid)			((ia64_get_lid() >> 16) & 0xffff)
 #endif
 
-#ifdef CONFIG_IA64_SGI_SN1
 /*
  * macros for some of these exist in sn/addrs.h & sn/arch.h, etc. However, 
  * trying #include these files here causes circular dependencies.
  */
-#define cpu_physical_id_to_nasid(cpi)		((cpi) >> 8)
-#define cpu_physical_id_to_synergy(cpi)		(((cpi) >> 1) & 1)
-#define cpu_physical_id_to_fsb_slot(cpi)	((cpi) & 1)
-#define cpu_physical_id_to_slice(cpi)		((cpi) & 3)
-#define get_nasid()				((ia64_get_lid() >> 24))
-#define get_slice()				((ia64_get_lid() >> 16) & 3)
-#define get_node_number(addr)			(((unsigned long)(addr)>>33) & 0x7f)
-#else
 #define cpu_physical_id_to_nasid(cpi)		((cpi) &0xfff)
 #define cpu_physical_id_to_slice(cpi)		((cpi>>12) & 3)
 #define get_nasid()				((ia64_get_lid() >> 16) & 0xfff)
 #define get_slice()				((ia64_get_lid() >> 28) & 0xf)
 #define get_node_number(addr)			(((unsigned long)(addr)>>38) & 0x7ff)
-#endif
 
 /*
  * NOTE: id & eid refer to Intel's definitions of the LID register
@@ -129,11 +111,7 @@
 
 #define nasid_slice_to_cpuid(nasid,slice)		(cpu_logical_id(nasid_slice_to_cpu_physical_id((nasid),(slice))))
 
-#ifdef CONFIG_IA64_SGI_SN1
-#define nasid_slice_to_cpu_physical_id(nasid, slice)	(((nasid)<<8) | (slice))
-#else
 #define nasid_slice_to_cpu_physical_id(nasid, slice)	(((slice)<<12) | (nasid))
-#endif
 
 /*
  * The following table/struct  is used for managing PTC coherency domains.
@@ -145,26 +123,9 @@
 } sn_sapicid_info_t;
 
 extern sn_sapicid_info_t	sn_sapicid_info[];	/* indexed by cpuid */
+extern short physical_node_map[];			/* indexed by nasid to get cnode */
 
 
-
-#ifdef CONFIG_IA64_SGI_SN1
-/*
- * cpuid_to_fsb_slot  - convert a cpuid to the fsb slot number that it is in.
- *   (there are 2 cpus per FSB. This function returns 0 or 1)
- */
-#define cpuid_to_fsb_slot(cpuid)	(cpu_physical_id_to_fsb_slot(cpu_physical_id(cpuid)))
-
-
-/*
- * cpuid_to_synergy  - convert a cpuid to the synergy that it resides on
- *   (there are 2 synergies per node. Function returns 0 or 1 to
- *    specify which synergy the cpu is on)
- */
-#define cpuid_to_synergy(cpuid)		(cpu_physical_id_to_synergy(cpu_physical_id(cpuid)))
-
-#endif
-
 /*
  * cpuid_to_slice  - convert a cpuid to the slice that it resides on
  *  There are 4 cpus per node. This function returns 0 .. 3)
@@ -181,7 +142,7 @@
 /*
  * cpuid_to_cnodeid  - convert a cpuid to the cnode that it resides on
  */
-#define cpuid_to_cnodeid(cpuid)		(local_node_data->physical_node_map[cpuid_to_nasid(cpuid)])
+#define cpuid_to_cnodeid(cpuid)		(physical_node_map[cpuid_to_nasid(cpuid)])
 
 
 /*
@@ -190,13 +151,13 @@
  *	Just extract the NASID from the pointer.
  *
  */
-#define cnodeid_to_nasid(cnodeid)	(get_node_number(local_node_data->pg_data_ptrs[cnodeid]))
+#define cnodeid_to_nasid(cnodeid)	pda->cnodeid_to_nasid_table[cnodeid]
  
 
 /*
  * nasid_to_cnodeid - convert a NASID to a cnodeid
  */
-#define nasid_to_cnodeid(nasid)		(nasid) /* (local_node_data->physical_node_map[nasid]) */
+#define nasid_to_cnodeid(nasid)		(physical_node_map[nasid])
 
 
 /*
@@ -214,22 +175,7 @@
 #define cpuid_to_subnode(cpuid)		((cpuid_to_slice(cpuid)<2) ? 0 : 1)
  
 
-/*
- * cpuid_to_localslice - convert a cpuid to a local slice
- *    slice 0 & 2 are local slice 0
- *    slice 1 & 3 are local slice 1
- */
-#define cpuid_to_localslice(cpuid)	(cpuid_to_slice(cpuid) & 1)
- 
-
 #define smp_physical_node_id()			(cpuid_to_nasid(smp_processor_id()))
-
-
-/*
- * cnodeid_to_cpuid - convert a cnode  to a cpuid of a cpu on the node.
- *	returns -1 if no cpus exist on the node
- */
-extern int cnodeid_to_cpuid(int cnode);
 
 
 #endif /* _ASM_IA64_SN_SN_CPUID_H */
diff -Nru a/include/asm-ia64/sn/sn_fru.h b/include/asm-ia64/sn/sn_fru.h
--- a/include/asm-ia64/sn/sn_fru.h	Wed Jun 18 23:42:05 2003
+++ b/include/asm-ia64/sn/sn_fru.h	Wed Jun 18 23:42:05 2003
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 1999-2001 Silicon Graphics, Inc. 
- * All rights reserved.
+ * Copyright (C) 1992-1997,1999-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_SN_FRU_H
 #define _ASM_IA64_SN_SN_FRU_H
diff -Nru a/include/asm-ia64/sn/sn_pio_sync.h b/include/asm-ia64/sn/sn_pio_sync.h
--- a/include/asm-ia64/sn/sn_pio_sync.h	Wed Jun 18 23:42:08 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,53 +0,0 @@
-/*
- *
- * 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) 2001-2002 Silicon Graphics, Inc. All rights reserved.
- */
-
-
-#ifndef _ASM_IA64_SN_SN_PIO_WRITE_SYNC_H
-#define _ASM_IA64_SN_SN_PIO_WRITE_SYNC_H
-
-#include <linux/config.h>
-#ifdef CONFIG_IA64_SGI_SN2
-#include <asm/sn/sn_cpuid.h>
-#include <asm/sn/sn2/addrs.h>
-#include <asm/sn/sn2/shub_mmr.h>
-#include <asm/sn/sn2/shub_mmr_t.h>
-
-/*
- * This macro flushes all outstanding PIOs performed by this cpu to the 
- * intended destination SHUB.  This in essence ensures that all PIO's
- * issues by this cpu has landed at it's destination.
- *
- * This macro expects the caller:
- *	1.  The thread is locked.
- *	2.  All prior PIO operations has been fenced with __ia64_mf_a().
- *
- * The expectation is that get_slice() will return either 0 or 2.
- * When we have multi-core cpu's, the expectation is get_slice() will 
- * return either 0,1 or 2,3.
- */
-
-#define SN_PIO_WRITE_SYNC \
-	{ \
-		volatile unsigned long sn_pio_writes_done; \
-	do { \
-		sn_pio_writes_done = (volatile unsigned long) (SH_PIO_WRITE_STATUS_0_WRITES_OK_MASK & HUB_L( (unsigned long *)GLOBAL_MMR_ADDR(get_nasid(), (get_slice() < 2) ? SH_PIO_WRITE_STATUS_0 : SH_PIO_WRITE_STATUS_1 ))); \
-	} while (!sn_pio_writes_done); \
-	__ia64_mf_a(); \
-	}
-#else
-
-/*
- * For all ARCHITECTURE type, this is a NOOP.
- */
-
-#define SN_PIO_WRITE_SYNC
-
-#endif
-
-#endif /* _ASM_IA64_SN_SN_PIO_WRITE_SYNC_H */
diff -Nru a/include/asm-ia64/sn/sn_private.h b/include/asm-ia64/sn/sn_private.h
--- a/include/asm-ia64/sn/sn_private.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/sn_private.h	Wed Jun 18 23:42:06 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_SN_PRIVATE_H
 #define _ASM_IA64_SN_SN_PRIVATE_H
@@ -14,10 +14,6 @@
 #include <asm/sn/xtalk/xwidget.h>
 #include <asm/sn/xtalk/xtalk_private.h>
 
-#if defined(CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/sn_private.h>
-#elif defined(CONFIG_IA64_SGI_SN2)
 #include <asm/sn/sn2/sn_private.h>
-#endif
 
 #endif /* _ASM_IA64_SN_SN_PRIVATE_H */
diff -Nru a/include/asm-ia64/sn/sn_sal.h b/include/asm-ia64/sn/sn_sal.h
--- a/include/asm-ia64/sn/sn_sal.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-ia64/sn/sn_sal.h	Wed Jun 18 23:42:09 2003
@@ -8,7 +8,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (c) 2000-2002 Silicon Graphics, Inc.  All rights reserved.
+ * Copyright (c) 2000-2003 Silicon Graphics, Inc.  All rights reserved.
  */
 
 
@@ -36,6 +36,8 @@
 #define  SN_SAL_CONSOLE_POLL                       0x02000026
 #define  SN_SAL_CONSOLE_INTR                       0x02000027
 #define  SN_SAL_CONSOLE_PUTB			   0x02000028
+#define  SN_SAL_CONSOLE_XMIT_CHARS		   0x0200002a
+#define  SN_SAL_CONSOLE_READC			   0x0200002b
 #define  SN_SAL_SYSCTL_MODID_GET	           0x02000031
 #define  SN_SAL_SYSCTL_GET                         0x02000032
 #define  SN_SAL_SYSCTL_IOBRICK_MODULE_GET          0x02000033
@@ -47,17 +49,22 @@
 #define  SN_SAL_SYSCTL_PARTITION_GET		   0x0200003a
 #define  SN_SAL_SYSTEM_POWER_DOWN		   0x0200003b
 #define  SN_SAL_GET_MASTER_BASEIO_NASID		   0x0200003c
+#define  SN_SAL_COHERENCE                          0x0200003d
+#define  SN_SAL_SYSCTL_FRU_CAPTURE		   0x0200003f
 
 
 /*
  * Service-specific constants
  */
-#define SAL_CONSOLE_INTR_IN     0       /* manipulate input interrupts */
-#define SAL_CONSOLE_INTR_OUT    1       /* manipulate output low-water
-                                         * interrupts
-                                         */
+
+/* Console interrupt manipulation */
+	/* action codes */
 #define SAL_CONSOLE_INTR_OFF    0       /* turn the interrupt off */
 #define SAL_CONSOLE_INTR_ON     1       /* turn the interrupt on */
+#define SAL_CONSOLE_INTR_STATUS 2	/* retrieve the interrupt status */
+	/* interrupt specification & status return codes */
+#define SAL_CONSOLE_INTR_XMIT	1	/* output interrupt */
+#define SAL_CONSOLE_INTR_RECV	2	/* input interrupt */
 
 
 /*
@@ -103,15 +110,8 @@
  * Specify the minimum PROM revsion required for this kernel.
  * Note that they're stored in hex format...
  */
-#ifdef CONFIG_IA64_SGI_SN1
-#define SN_SAL_MIN_MAJOR	0x0
-#define SN_SAL_MIN_MINOR	0x03 /* SN1 PROMs are stuck at rev 0.03 */
-#elif defined(CONFIG_IA64_SGI_SN2)
-#define SN_SAL_MIN_MAJOR	0x0
-#define SN_SAL_MIN_MINOR	0x11
-#else
-#error "must specify which PROM revisions this kernel needs"
-#endif /* CONFIG_IA64_SGI_SN1 */
+#define SN_SAL_MIN_MAJOR	0x1  /* SN2 kernels need at least PROM 1.0 */
+#define SN_SAL_MIN_MINOR	0x0
 
 u64 ia64_sn_probe_io_slot(long paddr, long size, void *data_ptr);
 
@@ -124,10 +124,10 @@
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
 	SAL_CALL(ret_stuff, SN_SAL_GET_MASTER_NASID, 0, 0, 0, 0, 0, 0, 0);
 
 	if (ret_stuff.status < 0)
@@ -146,10 +146,10 @@
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
 	SAL_CALL(ret_stuff, SN_SAL_GET_MASTER_BASEIO_NASID, 0, 0, 0, 0, 0, 0, 0);
 
 	if (ret_stuff.status < 0)
@@ -166,12 +166,12 @@
 	extern u64 klgraph_addr[];
 	int cnodeid;
 
-	cnodeid = 0 /* nasid_to_cnodeid(nasid) */;
+	cnodeid = nasid_to_cnodeid(nasid);
 	if (klgraph_addr[cnodeid] == 0) {
-		ret_stuff.status = (uint64_t)0;
-		ret_stuff.v0 = (uint64_t)0;
-		ret_stuff.v1 = (uint64_t)0;
-		ret_stuff.v2 = (uint64_t)0;
+		ret_stuff.status = 0;
+		ret_stuff.v0 = 0;
+		ret_stuff.v1 = 0;
+		ret_stuff.v2 = 0;
 		SAL_CALL(ret_stuff, SN_SAL_GET_KLCONFIG_ADDR, (u64)nasid, 0, 0, 0, 0, 0, 0);
 
 		/*
@@ -195,11 +195,11 @@
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
-	__SAL_CALL(ret_stuff, SN_SAL_CONSOLE_GETC, 0, 0, 0, 0, 0, 0, 0);
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_GETC, 0, 0, 0, 0, 0, 0, 0);
 
 	/* character is in 'v0' */
 	*ch = (int)ret_stuff.v0;
@@ -208,6 +208,26 @@
 }
 
 /*
+ * Read a character from the SAL console device, after a previous interrupt
+ * or poll operation has given us to know that a character is available
+ * to be read.
+ */
+static inline u64
+ia64_sn_console_readc(void)
+{
+	struct ia64_sal_retval ret_stuff;
+
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_READC, 0, 0, 0, 0, 0, 0, 0);
+
+	/* character is in 'v0' */
+	return ret_stuff.v0;
+}
+
+/*
  * Sends the given character to the console.
  */
 static inline u64
@@ -215,11 +235,11 @@
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
-	__SAL_CALL(ret_stuff, SN_SAL_CONSOLE_PUTC, (uint64_t)ch, 0, 0, 0, 0, 0, 0);
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTC, (uint64_t)ch, 0, 0, 0, 0, 0, 0);
 
 	return ret_stuff.status;
 }
@@ -228,17 +248,20 @@
  * Sends the given buffer to the console.
  */
 static inline u64
-ia64_sn_console_putb(char *buf, int len)
+ia64_sn_console_putb(const char *buf, int len)
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
-	__SAL_CALL(ret_stuff, SN_SAL_CONSOLE_PUTB, (uint64_t)buf, (uint64_t)len, 0, 0, 0, 0, 0);
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0; 
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_PUTB, (uint64_t)buf, (uint64_t)len, 0, 0, 0, 0, 0);
 
-	return ret_stuff.status;
+	if ( ret_stuff.status == 0 ) {
+		return ret_stuff.v0;
+	}
+	return (u64)0;
 }
 
 /*
@@ -249,11 +272,11 @@
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
-	__SAL_CALL(ret_stuff, SN_SAL_PRINT_ERROR, (uint64_t)hook, (uint64_t)rec, 0, 0, 0, 0, 0);
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_PRINT_ERROR, (uint64_t)hook, (uint64_t)rec, 0, 0, 0, 0, 0);
 
 	return ret_stuff.status;
 }
@@ -266,11 +289,11 @@
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
-	__SAL_CALL(ret_stuff, SN_SAL_LOG_CE, 0, 0, 0, 0, 0, 0, 0);
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_LOG_CE, 0, 0, 0, 0, 0, 0, 0);
 
 	return ret_stuff.status;
 }
@@ -283,11 +306,11 @@
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
-	__SAL_CALL(ret_stuff, SN_SAL_CONSOLE_POLL, 0, 0, 0, 0, 0, 0, 0);
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_POLL, 0, 0, 0, 0, 0, 0, 0);
 
 	/* result is in 'v0' */
 	*result = (int)ret_stuff.v0;
@@ -296,6 +319,86 @@
 }
 
 /*
+ * Checks console interrupt status
+ */
+static inline u64
+ia64_sn_console_intr_status(void)
+{
+	struct ia64_sal_retval ret_stuff;
+
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
+		 0, SAL_CONSOLE_INTR_STATUS,
+		 0, 0, 0, 0, 0);
+
+	if (ret_stuff.status == 0) {
+	    return ret_stuff.v0;
+	}
+	
+	return 0;
+}
+
+/*
+ * Enable an interrupt on the SAL console device.
+ */
+static inline void
+ia64_sn_console_intr_enable(uint64_t intr)
+{
+	struct ia64_sal_retval ret_stuff;
+
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
+		 intr, SAL_CONSOLE_INTR_ON,
+		 0, 0, 0, 0, 0);
+}
+
+/*
+ * Disable an interrupt on the SAL console device.
+ */
+static inline void
+ia64_sn_console_intr_disable(uint64_t intr)
+{
+	struct ia64_sal_retval ret_stuff;
+
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_INTR, 
+		 intr, SAL_CONSOLE_INTR_OFF,
+		 0, 0, 0, 0, 0);
+}
+
+/*
+ * Sends a character buffer to the console asynchronously.
+ */
+static inline u64
+ia64_sn_console_xmit_chars(char *buf, int len)
+{
+	struct ia64_sal_retval ret_stuff;
+
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_CONSOLE_XMIT_CHARS,
+		 (uint64_t)buf, (uint64_t)len,
+		 0, 0, 0, 0, 0);
+
+	if (ret_stuff.status == 0) {
+	    return ret_stuff.v0;
+	}
+
+	return 0;
+}
+
+/*
  * Returns the iobrick module Id
  */
 static inline u64
@@ -303,11 +406,11 @@
 {
 	struct ia64_sal_retval ret_stuff;
 
-	ret_stuff.status = (uint64_t)0;
-	ret_stuff.v0 = (uint64_t)0;
-	ret_stuff.v1 = (uint64_t)0;
-	ret_stuff.v2 = (uint64_t)0;
-	SAL_CALL(ret_stuff, SN_SAL_SYSCTL_IOBRICK_MODULE_GET, nasid, 0, 0, 0, 0, 0, 0);
+	ret_stuff.status = 0;
+	ret_stuff.v0 = 0;
+	ret_stuff.v1 = 0;
+	ret_stuff.v2 = 0;
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SYSCTL_IOBRICK_MODULE_GET, nasid, 0, 0, 0, 0, 0, 0);
 
 	/* result is in 'v0' */
 	*result = (int)ret_stuff.v0;
@@ -339,7 +442,7 @@
 ia64_sn_sys_serial_get(char *buf)
 {
 	struct ia64_sal_retval ret_stuff;
-	SAL_CALL(ret_stuff, SN_SAL_SYS_SERIAL_GET, buf, 0, 0, 0, 0, 0, 0);
+	SAL_CALL_NOLOCK(ret_stuff, SN_SAL_SYS_SERIAL_GET, buf, 0, 0, 0, 0, 0, 0);
 	return ret_stuff.status;
 }
 
@@ -395,7 +498,6 @@
 	return ((partid_t)ret_stuff.v0);
 }
 
-#ifdef CONFIG_IA64_SGI_SN2
 /*
  * Returns the partition id of the current processor.
  */
@@ -411,7 +513,25 @@
 	}
 }
 
-#endif /* CONFIG_IA64_SGI_SN2 */
+/*
+ * Change or query the coherence domain for this partition. Each cpu-based
+ * nasid is represented by a bit in an array of 64-bit words:
+ *      0 = not in this partition's coherency domain
+ *      1 = in this partition's coherency domain
+ * It is not possible for the local system's nasids to be removed from
+ * the coherency domain.
+ *
+ *      new_domain = set the coherence domain to the given nasids
+ *      old_domain = return the current coherence domain
+ */
+static inline int
+sn_change_coherence(u64 *new_domain, u64 *old_domain)
+{
+	struct ia64_sal_retval ret_stuff;
+	SAL_CALL(ret_stuff, SN_SAL_COHERENCE, new_domain, old_domain, 0, 0,
+		 0, 0, 0);
+	return ret_stuff.status;
+}
 
 /*
  * Turns off system power.
@@ -425,5 +545,20 @@
 	/* never returns */
 }
 
+/**
+ * ia64_sn_fru_capture - tell the system controller to capture hw state
+ *
+ * This routine will call the SAL which will tell the system controller(s)
+ * to capture hw mmr information from each SHub in the system.
+ */
+static inline u64
+ia64_sn_fru_capture(void)
+{
+        struct ia64_sal_retval isrv;
+        SAL_CALL(isrv, SN_SAL_SYSCTL_FRU_CAPTURE, 0, 0, 0, 0, 0, 0, 0);
+        if (isrv.status)
+                return 0;
+        return isrv.v0;
+}
 
 #endif /* _ASM_IA64_SN_SN_SAL_H */
diff -Nru a/include/asm-ia64/sn/snconfig.h b/include/asm-ia64/sn/snconfig.h
--- a/include/asm-ia64/sn/snconfig.h	Wed Jun 18 23:42:07 2003
+++ /dev/null	Wed Dec 31 16:00:00 1969
@@ -1,18 +0,0 @@
-/*
- * 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) 2000-2001 Silicon Graphics, Inc.
- */
-#ifndef _ASM_IA64_SN_SNCONFIG_H
-#define _ASM_IA64_SN_SNCONFIG_H
-
-#include <linux/config.h>
-
-#if defined(CONFIG_IA64_SGI_SN1)
-#include <asm/sn/sn1/ip27config.h>
-#elif defined(CONFIG_IA64_SGI_SN2)
-#endif
-
-#endif /* _ASM_IA64_SN_SNCONFIG_H */
diff -Nru a/include/asm-ia64/sn/sndrv.h b/include/asm-ia64/sn/sndrv.h
--- a/include/asm-ia64/sn/sndrv.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/sn/sndrv.h	Wed Jun 18 23:42:07 2003
@@ -1,3 +1,35 @@
+/*
+ * Copyright (c) 2002-2003 Silicon Graphics, Inc.  All Rights Reserved.
+ * 
+ * This program is free software; you can redistribute it and/or modify it 
+ * under the terms of version 2 of the GNU General Public License 
+ * as published by the Free Software Foundation.
+ * 
+ * This program is distributed in the hope that it would be useful, but 
+ * WITHOUT ANY WARRANTY; without even the implied warranty of 
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 
+ * 
+ * Further, this software is distributed without any warranty that it is 
+ * free of the rightful claim of any third person regarding infringement 
+ * or the like.  Any license provided herein, whether implied or 
+ * otherwise, applies only to this software file.  Patent licenses, if 
+ * any, provided herein do not apply to combinations of this program with 
+ * other software, or any other product whatsoever.
+ * 
+ * You should have received a copy of the GNU General Public 
+ * License along with this program; if not, write the Free Software 
+ * Foundation, Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
+ * 
+ * Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pkwy, 
+ * Mountain View, CA  94043, or:
+ * 
+ * http://www.sgi.com 
+ * 
+ * For further information regarding this notice, see: 
+ * 
+ * http://oss.sgi.com/projects/GenInfo/NoticeExplan
+ */
+
 #ifndef _ASM_IA64_SN_SNDRV_H
 #define _ASM_IA64_SN_SNDRV_H
 
diff -Nru a/include/asm-ia64/sn/sv.h b/include/asm-ia64/sn/sv.h
--- a/include/asm-ia64/sn/sv.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/sv.h	Wed Jun 18 23:42:06 2003
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 2000-2001 Silicon Graphics, Inc.  All rights reserved
+ * Copyright (C) 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  *
  * This implemenation of synchronization variables is heavily based on
  * one done by Steve Lord <lord@sgi.com>
diff -Nru a/include/asm-ia64/sn/systeminfo.h b/include/asm-ia64/sn/systeminfo.h
--- a/include/asm-ia64/sn/systeminfo.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/sn/systeminfo.h	Wed Jun 18 23:42:07 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_SYSTEMINFO_H
 #define _ASM_IA64_SN_SYSTEMINFO_H
diff -Nru a/include/asm-ia64/sn/types.h b/include/asm-ia64/sn/types.h
--- a/include/asm-ia64/sn/types.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-ia64/sn/types.h	Wed Jun 18 23:42:09 2003
@@ -3,7 +3,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1999,2001-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1999,2001-2003 Silicon Graphics, Inc.  All Rights Reserved.
  * Copyright (C) 1999 by Ralf Baechle
  */
 #ifndef _ASM_IA64_SN_TYPES_H
@@ -13,16 +13,10 @@
 #include <linux/types.h>
 
 typedef unsigned long 	cpuid_t;
-typedef unsigned long 	cpumask_t;
 typedef signed short	nasid_t;	/* node id in numa-as-id space */
 typedef signed char	partid_t;	/* partition ID type */
-#ifdef CONFIG_IA64_SGI_SN2
 typedef unsigned int    moduleid_t;     /* user-visible module number type */
 typedef unsigned int    cmoduleid_t;    /* kernel compact module id type */
-#else
-typedef signed short	moduleid_t;	/* user-visible module number type */
-typedef signed short	cmoduleid_t;	/* kernel compact module id type */
-#endif
 typedef signed char slabid_t;
 typedef unsigned char	clusterid_t;	/* Clusterid of the cell */
 
@@ -32,5 +26,6 @@
 typedef unsigned char uchar_t;
 typedef unsigned long paddr_t;
 typedef unsigned long pfn_t;
+typedef short cnodeid_t;
 
 #endif /* _ASM_IA64_SN_TYPES_H */
diff -Nru a/include/asm-ia64/sn/uart16550.h b/include/asm-ia64/sn/uart16550.h
--- a/include/asm-ia64/sn/uart16550.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/uart16550.h	Wed Jun 18 23:42:06 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 
 #ifndef _ASM_IA64_SN_UART16550_H
diff -Nru a/include/asm-ia64/sn/vector.h b/include/asm-ia64/sn/vector.h
--- a/include/asm-ia64/sn/vector.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/vector.h	Wed Jun 18 23:42:06 2003
@@ -4,29 +4,16 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2002 Silicon Graphics, Inc. All rights reserved.
+ * Copyright (C) 1992 - 1997, 2000-2003 Silicon Graphics, Inc. All rights reserved.
  */
 #ifndef _ASM_IA64_SN_VECTOR_H
 #define _ASM_IA64_SN_VECTOR_H
 
 #include <linux/config.h>
-#include <asm/sn/arch.h>
 
 #define NET_VEC_NULL            ((net_vec_t)  0)
 #define NET_VEC_BAD             ((net_vec_t) -1)
 
-#ifdef RTL
-
-#define VEC_POLLS_W		16	/* Polls before write times out */
-#define VEC_POLLS_R		16	/* Polls before read times out */
-#define VEC_POLLS_X		16	/* Polls before exch times out */
-
-#define VEC_RETRIES_W		1	/* Retries before write fails */
-#define VEC_RETRIES_R		1	/* Retries before read fails */
-#define VEC_RETRIES_X		1	/* Retries before exch fails */
-
-#else /* RTL */
-
 #define VEC_POLLS_W		128	/* Polls before write times out */
 #define VEC_POLLS_R		128	/* Polls before read times out */
 #define VEC_POLLS_X		128	/* Polls before exch times out */
@@ -34,37 +21,6 @@
 #define VEC_RETRIES_W		8	/* Retries before write fails */
 #define VEC_RETRIES_R           8	/* Retries before read fails */
 #define VEC_RETRIES_X		4	/* Retries before exch fails */
-
-#endif /* RTL */
-
-#if defined(CONFIG_IA64_SGI_SN1) || defined(CONFIG_IA64_GENERIC)
-#define VECTOR_PARMS		LB_VECTOR_PARMS
-#define VECTOR_ROUTE		LB_VECTOR_ROUTE
-#define VECTOR_DATA		LB_VECTOR_DATA
-#define VECTOR_STATUS		LB_VECTOR_STATUS
-#define VECTOR_RETURN		LB_VECTOR_RETURN
-#define VECTOR_READ_DATA	LB_VECTOR_READ_DATA
-#define VECTOR_STATUS_CLEAR	LB_VECTOR_STATUS_CLEAR
-#define VP_PIOID_SHFT		LVP_PIOID_SHFT
-#define VP_PIOID_MASK		LVP_PIOID_MASK
-#define VP_WRITEID_SHFT		LVP_WRITEID_SHFT
-#define VP_WRITEID_MASK		LVP_WRITEID_MASK
-#define VP_ADDRESS_MASK		LVP_ADDRESS_MASK
-#define VP_TYPE_SHFT		LVP_TYPE_SHFT
-#define VP_TYPE_MASK		LVP_TYPE_MASK
-#define VS_VALID		LVS_VALID
-#define VS_OVERRUN		LVS_OVERRUN
-#define VS_TARGET_SHFT		LVS_TARGET_SHFT
-#define VS_TARGET_MASK		LVS_TARGET_MASK
-#define VS_PIOID_SHFT		LVS_PIOID_SHFT
-#define VS_PIOID_MASK		LVS_PIOID_MASK
-#define VS_WRITEID_SHFT		LVS_WRITEID_SHFT
-#define VS_WRITEID_MASK		LVS_WRITEID_MASK
-#define VS_ADDRESS_MASK		LVS_ADDRESS_MASK
-#define VS_TYPE_SHFT		LVS_TYPE_SHFT
-#define VS_TYPE_MASK		LVS_TYPE_MASK
-#define VS_ERROR_MASK		LVS_ERROR_MASK
-#endif
 
 #define NET_ERROR_NONE		0	/* No error		*/
 #define NET_ERROR_HARDWARE	(-1)	/* Hardware error	*/
diff -Nru a/include/asm-ia64/sn/xtalk/xbow.h b/include/asm-ia64/sn/xtalk/xbow.h
--- a/include/asm-ia64/sn/xtalk/xbow.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/sn/xtalk/xbow.h	Wed Jun 18 23:42:06 2003
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All Rights Reserved.
  */
 #ifndef _ASM_SN_SN_XTALK_XBOW_H
 #define _ASM_SN_SN_XTALK_XBOW_H
@@ -405,12 +404,6 @@
 
 /* XBOW_WID_ARB_RELOAD */
 #define	XBOW_WID_ARB_RELOAD_INT	0x3f	/* GBR reload interval */
-
-
-#ifdef	CONFIG_IA64_SGI_SN1
-#define nasid_has_xbridge(nasid)        \
-        (XWIDGET_PART_NUM(XWIDGET_ID_READ(nasid, 0)) == XXBOW_WIDGET_PART_NUM)
-#endif
 
 #define IS_XBRIDGE_XBOW(wid) \
         (XWIDGET_PART_NUM(wid) == XXBOW_WIDGET_PART_NUM && \
diff -Nru a/include/asm-ia64/sn/xtalk/xbow_info.h b/include/asm-ia64/sn/xtalk/xbow_info.h
--- a/include/asm-ia64/sn/xtalk/xbow_info.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/sn/xtalk/xbow_info.h	Wed Jun 18 23:42:08 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 #ifndef _ASM_SN_XTALK_XBOW_INFO_H
 #define _ASM_SN_XTALK_XBOW_INFO_H
@@ -48,9 +48,9 @@
     volatile uint32_t    *xp_perf_reg;
 } xbow_perf_t;
 
-extern void             xbow_update_perf_counters(devfs_handle_t);
-extern xbow_perf_link_t *xbow_get_perf_counters(devfs_handle_t);
-extern int              xbow_enable_perf_counter(devfs_handle_t, int, int, int);
+extern void             xbow_update_perf_counters(vertex_hdl_t);
+extern xbow_perf_link_t *xbow_get_perf_counters(vertex_hdl_t);
+extern int              xbow_enable_perf_counter(vertex_hdl_t, int, int, int);
 
 #define XBOWIOC_PERF_ENABLE	  	1
 #define XBOWIOC_PERF_DISABLE	 	2
diff -Nru a/include/asm-ia64/sn/xtalk/xswitch.h b/include/asm-ia64/sn/xtalk/xswitch.h
--- a/include/asm-ia64/sn/xtalk/xswitch.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/sn/xtalk/xswitch.h	Wed Jun 18 23:42:08 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997,2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 #ifndef _ASM_SN_XTALK_XSWITCH_H
 #define _ASM_SN_XTALK_XSWITCH_H
@@ -23,38 +23,35 @@
 typedef struct xswitch_info_s *xswitch_info_t;
 
 typedef int
-                        xswitch_reset_link_f(devfs_handle_t xconn);
+                        xswitch_reset_link_f(vertex_hdl_t xconn);
 
 typedef struct xswitch_provider_s {
     xswitch_reset_link_f   *reset_link;
 } xswitch_provider_t;
 
-extern void             xswitch_provider_register(devfs_handle_t sw_vhdl, xswitch_provider_t * xsw_fns);
+extern void             xswitch_provider_register(vertex_hdl_t sw_vhdl, xswitch_provider_t * xsw_fns);
 
 xswitch_reset_link_f    xswitch_reset_link;
 
-extern xswitch_info_t   xswitch_info_new(devfs_handle_t vhdl);
+extern xswitch_info_t   xswitch_info_new(vertex_hdl_t vhdl);
 
 extern void             xswitch_info_link_is_ok(xswitch_info_t xswitch_info,
 						xwidgetnum_t port);
 extern void             xswitch_info_vhdl_set(xswitch_info_t xswitch_info,
 					      xwidgetnum_t port,
-					      devfs_handle_t xwidget);
+					      vertex_hdl_t xwidget);
 extern void             xswitch_info_master_assignment_set(xswitch_info_t xswitch_info,
 						       xwidgetnum_t port,
-					       devfs_handle_t master_vhdl);
+					       vertex_hdl_t master_vhdl);
 
-extern xswitch_info_t   xswitch_info_get(devfs_handle_t vhdl);
+extern xswitch_info_t   xswitch_info_get(vertex_hdl_t vhdl);
 
 extern int              xswitch_info_link_ok(xswitch_info_t xswitch_info,
 					     xwidgetnum_t port);
-extern devfs_handle_t     xswitch_info_vhdl_get(xswitch_info_t xswitch_info,
+extern vertex_hdl_t     xswitch_info_vhdl_get(xswitch_info_t xswitch_info,
 					      xwidgetnum_t port);
-extern devfs_handle_t     xswitch_info_master_assignment_get(xswitch_info_t xswitch_info,
+extern vertex_hdl_t     xswitch_info_master_assignment_get(xswitch_info_t xswitch_info,
 						      xwidgetnum_t port);
-
-extern int		xswitch_id_get(devfs_handle_t vhdl);
-extern void		xswitch_id_set(devfs_handle_t vhdl,int xbow_num);
 
 #endif				/* __ASSEMBLY__ */
 
diff -Nru a/include/asm-ia64/sn/xtalk/xtalk.h b/include/asm-ia64/sn/xtalk/xtalk.h
--- a/include/asm-ia64/sn/xtalk/xtalk.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/sn/xtalk/xtalk.h	Wed Jun 18 23:42:08 2003
@@ -4,12 +4,15 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 #ifndef _ASM_SN_XTALK_XTALK_H
 #define _ASM_SN_XTALK_XTALK_H
 #include <linux/config.h>
 
+#include "asm/sn/sgi.h"
+
+
 /*
  * xtalk.h -- platform-independent crosstalk interface
  */
@@ -85,7 +88,7 @@
 
 /* PIO MANAGEMENT */
 typedef xtalk_piomap_t
-xtalk_piomap_alloc_f    (devfs_handle_t dev,	/* set up mapping for this device */
+xtalk_piomap_alloc_f    (vertex_hdl_t dev,	/* set up mapping for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 iopaddr_t xtalk_addr,	/* map for this xtalk_addr range */
 			 size_t byte_count,
@@ -103,14 +106,14 @@
 xtalk_piomap_done_f     (xtalk_piomap_t xtalk_piomap);
 
 typedef caddr_t
-xtalk_piotrans_addr_f   (devfs_handle_t dev,	/* translate for this device */
+xtalk_piotrans_addr_f   (vertex_hdl_t dev,	/* translate for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 iopaddr_t xtalk_addr,	/* Crosstalk address */
 			 size_t byte_count,	/* map this many bytes */
 			 unsigned flags);	/* (currently unused) */
 
 extern caddr_t
-xtalk_pio_addr		(devfs_handle_t dev,	/* translate for this device */
+xtalk_pio_addr		(vertex_hdl_t dev,	/* translate for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 iopaddr_t xtalk_addr,	/* Crosstalk address */
 			 size_t byte_count,	/* map this many bytes */
@@ -122,7 +125,7 @@
 typedef struct xtalk_dmamap_s *xtalk_dmamap_t;
 
 typedef xtalk_dmamap_t
-xtalk_dmamap_alloc_f    (devfs_handle_t dev,	/* set up mappings for this device */
+xtalk_dmamap_alloc_f    (vertex_hdl_t dev,	/* set up mappings for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 size_t byte_count_max,		/* max size of a mapping */
 			 unsigned flags);	/* defined in dma.h */
@@ -144,14 +147,14 @@
 xtalk_dmamap_done_f     (xtalk_dmamap_t dmamap);
 
 typedef iopaddr_t
-xtalk_dmatrans_addr_f   (devfs_handle_t dev,	/* translate for this device */
+xtalk_dmatrans_addr_f   (vertex_hdl_t dev,	/* translate for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 paddr_t paddr,		/* system physical address */
 			 size_t byte_count,	/* length */
 			 unsigned flags);
 
 typedef alenlist_t
-xtalk_dmatrans_list_f   (devfs_handle_t dev,	/* translate for this device */
+xtalk_dmatrans_list_f   (vertex_hdl_t dev,	/* translate for this device */
 			 device_desc_t dev_desc,	/* device descriptor */
 			 alenlist_t palenlist,	/* system address/length list */
 			 unsigned flags);
@@ -160,12 +163,12 @@
 xtalk_dmamap_drain_f	(xtalk_dmamap_t map);	/* drain this map's channel */
 
 typedef void
-xtalk_dmaaddr_drain_f	(devfs_handle_t vhdl,	/* drain channel from this device */
+xtalk_dmaaddr_drain_f	(vertex_hdl_t vhdl,	/* drain channel from this device */
 			 paddr_t addr,		/* to this physical address */
 			 size_t bytes);		/* for this many bytes */
 
 typedef void
-xtalk_dmalist_drain_f	(devfs_handle_t vhdl,	/* drain channel from this device */
+xtalk_dmalist_drain_f	(vertex_hdl_t vhdl,	/* drain channel from this device */
 			 alenlist_t list);	/* for this set of physical blocks */
 
 
@@ -196,54 +199,47 @@
 xtalk_intr_setfunc_f    (xtalk_intr_t intr_hdl);	/* interrupt handle */
 
 typedef xtalk_intr_t
-xtalk_intr_alloc_f      (devfs_handle_t dev,	/* which crosstalk device */
+xtalk_intr_alloc_f      (vertex_hdl_t dev,	/* which crosstalk device */
 			 device_desc_t dev_desc,	/* device descriptor */
-			 devfs_handle_t owner_dev);	/* owner of this intr */
+			 vertex_hdl_t owner_dev);	/* owner of this intr */
 
 typedef void
 xtalk_intr_free_f       (xtalk_intr_t intr_hdl);
 
-#ifdef CONFIG_IA64_SGI_SN1
-typedef int
-xtalk_intr_connect_f    (xtalk_intr_t intr_hdl,		/* xtalk intr resource handle */
-			 xtalk_intr_setfunc_f *setfunc,		/* func to set intr hw */
-			 void *setfunc_arg);	/* arg to setfunc */
-#else
 typedef int
 xtalk_intr_connect_f    (xtalk_intr_t intr_hdl,		/* xtalk intr resource handle */
 			intr_func_t intr_func,         /* xtalk intr handler */
 			void *intr_arg,	/* arg to intr handler */
 			xtalk_intr_setfunc_f *setfunc,		/* func to set intr hw */
 			void *setfunc_arg);	/* arg to setfunc */
-#endif
 
 typedef void
 xtalk_intr_disconnect_f (xtalk_intr_t intr_hdl);
 
-typedef devfs_handle_t
+typedef vertex_hdl_t
 xtalk_intr_cpu_get_f    (xtalk_intr_t intr_hdl);	/* xtalk intr resource handle */
 
 /* CONFIGURATION MANAGEMENT */
 
 typedef void
-xtalk_provider_startup_f (devfs_handle_t xtalk_provider);
+xtalk_provider_startup_f (vertex_hdl_t xtalk_provider);
 
 typedef void
-xtalk_provider_shutdown_f (devfs_handle_t xtalk_provider);
+xtalk_provider_shutdown_f (vertex_hdl_t xtalk_provider);
 
 typedef void
-xtalk_widgetdev_enable_f (devfs_handle_t, int);
+xtalk_widgetdev_enable_f (vertex_hdl_t, int);
 
 typedef void
-xtalk_widgetdev_shutdown_f (devfs_handle_t, int);
+xtalk_widgetdev_shutdown_f (vertex_hdl_t, int);
 
 typedef int
-xtalk_dma_enabled_f (devfs_handle_t);
+xtalk_dma_enabled_f (vertex_hdl_t);
 
 /* Error Management */
 
 typedef int
-xtalk_error_devenable_f (devfs_handle_t xconn_vhdl,
+xtalk_error_devenable_f (vertex_hdl_t xconn_vhdl,
 			 int devnum,
 			 int error_code);
 
@@ -285,7 +281,6 @@
     xtalk_intr_free_f      *intr_free;
     xtalk_intr_connect_f   *intr_connect;
     xtalk_intr_disconnect_f *intr_disconnect;
-    xtalk_intr_cpu_get_f   *intr_cpu_get;
 
     /* CONFIGURATION MANAGEMENT */
     xtalk_provider_startup_f *provider_startup;
@@ -327,7 +322,7 @@
 
 /* error management */
 
-extern int              xtalk_error_handler(devfs_handle_t,
+extern int              xtalk_error_handler(vertex_hdl_t,
 					    int,
 					    ioerror_mode_t,
 					    ioerror_t *);
@@ -341,33 +336,33 @@
 #define XTALK_INTR_VECTOR_NONE	(xtalk_intr_vector_t)0
 
 /* Generic crosstalk interrupt interfaces */
-extern devfs_handle_t     xtalk_intr_dev_get(xtalk_intr_t xtalk_intr);
+extern vertex_hdl_t     xtalk_intr_dev_get(xtalk_intr_t xtalk_intr);
 extern xwidgetnum_t     xtalk_intr_target_get(xtalk_intr_t xtalk_intr);
 extern xtalk_intr_vector_t xtalk_intr_vector_get(xtalk_intr_t xtalk_intr);
 extern iopaddr_t        xtalk_intr_addr_get(xtalk_intr_t xtalk_intr);
-extern devfs_handle_t     xtalk_intr_cpu_get(xtalk_intr_t xtalk_intr);
+extern vertex_hdl_t     xtalk_intr_cpu_get(xtalk_intr_t xtalk_intr);
 extern void            *xtalk_intr_sfarg_get(xtalk_intr_t xtalk_intr);
 
 /* Generic crosstalk pio interfaces */
-extern devfs_handle_t     xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap);
+extern vertex_hdl_t     xtalk_pio_dev_get(xtalk_piomap_t xtalk_piomap);
 extern xwidgetnum_t     xtalk_pio_target_get(xtalk_piomap_t xtalk_piomap);
 extern iopaddr_t        xtalk_pio_xtalk_addr_get(xtalk_piomap_t xtalk_piomap);
 extern size_t           xtalk_pio_mapsz_get(xtalk_piomap_t xtalk_piomap);
 extern caddr_t          xtalk_pio_kvaddr_get(xtalk_piomap_t xtalk_piomap);
 
 /* Generic crosstalk dma interfaces */
-extern devfs_handle_t     xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap);
+extern vertex_hdl_t     xtalk_dma_dev_get(xtalk_dmamap_t xtalk_dmamap);
 extern xwidgetnum_t     xtalk_dma_target_get(xtalk_dmamap_t xtalk_dmamap);
 
 /* Register/unregister Crosstalk providers and get implementation handle */
 extern void             xtalk_set_early_piotrans_addr(xtalk_early_piotrans_addr_f *);
-extern void             xtalk_provider_register(devfs_handle_t provider, xtalk_provider_t *xtalk_fns);
-extern void             xtalk_provider_unregister(devfs_handle_t provider);
-extern xtalk_provider_t *xtalk_provider_fns_get(devfs_handle_t provider);
+extern void             xtalk_provider_register(vertex_hdl_t provider, xtalk_provider_t *xtalk_fns);
+extern void             xtalk_provider_unregister(vertex_hdl_t provider);
+extern xtalk_provider_t *xtalk_provider_fns_get(vertex_hdl_t provider);
 
 /* Crosstalk Switch generic layer, for use by initialization code */
-extern void             xswitch_census(devfs_handle_t xswitchv);
-extern void             xswitch_init_widgets(devfs_handle_t xswitchv);
+extern void             xswitch_census(vertex_hdl_t xswitchv);
+extern void             xswitch_init_widgets(vertex_hdl_t xswitchv);
 
 /* early init interrupt management */
 
@@ -397,7 +392,7 @@
 
 typedef xtalk_intr_setfunc_f *xtalk_intr_setfunc_t;
 
-typedef void		xtalk_iter_f(devfs_handle_t vhdl);
+typedef void		xtalk_iter_f(vertex_hdl_t vhdl);
 
 extern void		xtalk_iterate(char *prefix, xtalk_iter_f *func);
 
diff -Nru a/include/asm-ia64/sn/xtalk/xtalk_private.h b/include/asm-ia64/sn/xtalk/xtalk_private.h
--- a/include/asm-ia64/sn/xtalk/xtalk_private.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/sn/xtalk/xtalk_private.h	Wed Jun 18 23:42:08 2003
@@ -4,7 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992-1997, 2000-2002 Silicon Graphics, Inc.  All Rights Reserved.
+ * Copyright (C) 1992-1997, 2000-2003 Silicon Graphics, Inc.  All Rights Reserved.
  */
 #ifndef _ASM_SN_XTALK_XTALK_PRIVATE_H
 #define _ASM_SN_XTALK_XTALK_PRIVATE_H
@@ -23,7 +23,7 @@
  * All Crosstalk providers set up PIO using this information.
  */
 struct xtalk_piomap_s {
-    devfs_handle_t            xp_dev;	/* a requestor of this mapping */
+    vertex_hdl_t            xp_dev;	/* a requestor of this mapping */
     xwidgetnum_t            xp_target;	/* target (node's widget number) */
     iopaddr_t               xp_xtalk_addr;	/* which crosstalk addr is mapped */
     size_t                  xp_mapsz;	/* size of this mapping */
@@ -34,7 +34,7 @@
  * All Crosstalk providers set up DMA using this information.
  */
 struct xtalk_dmamap_s {
-    devfs_handle_t            xd_dev;	/* a requestor of this mapping */
+    vertex_hdl_t            xd_dev;	/* a requestor of this mapping */
     xwidgetnum_t            xd_target;	/* target (node's widget number) */
 };
 
@@ -42,7 +42,7 @@
  * All Crosstalk providers set up interrupts using this information.
  */
 struct xtalk_intr_s {
-    devfs_handle_t            xi_dev;	/* requestor of this intr */
+    vertex_hdl_t            xi_dev;	/* requestor of this intr */
     xwidgetnum_t            xi_target;	/* master's widget number */
     xtalk_intr_vector_t     xi_vector;	/* 8-bit interrupt vector */
     iopaddr_t               xi_addr;	/* xtalk address to generate intr */
@@ -72,10 +72,10 @@
  */
 struct xwidget_info_s {
     char                   *w_fingerprint;
-    devfs_handle_t            w_vertex;	/* back pointer to vertex */
+    vertex_hdl_t            w_vertex;	/* back pointer to vertex */
     xwidgetnum_t            w_id;	/* widget id */
     struct xwidget_hwid_s   w_hwid;	/* hardware identification (part/rev/mfg) */
-    devfs_handle_t            w_master;	/* CACHED widget's master */
+    vertex_hdl_t            w_master;	/* CACHED widget's master */
     xwidgetnum_t            w_masterid;		/* CACHED widget's master's widgetnum */
     error_handler_f        *w_efunc;	/* error handling function */
     error_handler_arg_t     w_einfo;	/* first parameter for efunc */
diff -Nru a/include/asm-ia64/sn/xtalk/xtalkaddrs.h b/include/asm-ia64/sn/xtalk/xtalkaddrs.h
--- a/include/asm-ia64/sn/xtalk/xtalkaddrs.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/sn/xtalk/xtalkaddrs.h	Wed Jun 18 23:42:08 2003
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All Rights Reserved.
  */
 #ifndef _ASM_SN_XTALK_XTALKADDRS_H
 #define _ASM_SN_XTALK_XTALKADDRS_H
diff -Nru a/include/asm-ia64/sn/xtalk/xwidget.h b/include/asm-ia64/sn/xtalk/xwidget.h
--- a/include/asm-ia64/sn/xtalk/xwidget.h	Wed Jun 18 23:42:05 2003
+++ b/include/asm-ia64/sn/xtalk/xwidget.h	Wed Jun 18 23:42:05 2003
@@ -4,8 +4,7 @@
  * License.  See the file "COPYING" in the main directory of this archive
  * for more details.
  *
- * Copyright (C) 1992 - 1997, 2000-2001 Silicon Graphics, Inc.
- * Copyright (C) 2000 by Colin Ngam
+ * Copyright (C) 1992-1997,2000-2003 Silicon Graphics, Inc. All Rights Reserved.
  */
 #ifndef __ASM_SN_XTALK_XWIDGET_H__
 #define __ASM_SN_XTALK_XWIDGET_H__
@@ -261,27 +260,26 @@
 extern void             xwidget_driver_unregister(char *driver_prefix);
 
 extern int              xwidget_register(struct xwidget_hwid_s *hwid,
-					 devfs_handle_t dev,
+					 vertex_hdl_t dev,
 					 xwidgetnum_t id,
-					 devfs_handle_t master,
-					 xwidgetnum_t targetid,
-					 async_attach_t aa);
-
-extern int		xwidget_unregister(devfs_handle_t);
-
-extern void             xwidget_reset(devfs_handle_t xwidget);
-extern void             xwidget_gfx_reset(devfs_handle_t xwidget);
-extern char		*xwidget_name_get(devfs_handle_t xwidget);	
+					 vertex_hdl_t master,
+					 xwidgetnum_t targetid);
+
+extern int		xwidget_unregister(vertex_hdl_t);
+
+extern void             xwidget_reset(vertex_hdl_t xwidget);
+extern void             xwidget_gfx_reset(vertex_hdl_t xwidget);
+extern char		*xwidget_name_get(vertex_hdl_t xwidget);	
 
 /* Generic crosstalk widget information access interface */
-extern xwidget_info_t   xwidget_info_chk(devfs_handle_t widget);
-extern xwidget_info_t   xwidget_info_get(devfs_handle_t widget);
-extern void             xwidget_info_set(devfs_handle_t widget, xwidget_info_t widget_info);
-extern devfs_handle_t     xwidget_info_dev_get(xwidget_info_t xwidget_info);
+extern xwidget_info_t   xwidget_info_chk(vertex_hdl_t widget);
+extern xwidget_info_t   xwidget_info_get(vertex_hdl_t widget);
+extern void             xwidget_info_set(vertex_hdl_t widget, xwidget_info_t widget_info);
+extern vertex_hdl_t     xwidget_info_dev_get(xwidget_info_t xwidget_info);
 extern xwidgetnum_t     xwidget_info_id_get(xwidget_info_t xwidget_info);
 extern int              xwidget_info_type_get(xwidget_info_t xwidget_info);
 extern int              xwidget_info_state_get(xwidget_info_t xwidget_info);
-extern devfs_handle_t     xwidget_info_master_get(xwidget_info_t xwidget_info);
+extern vertex_hdl_t     xwidget_info_master_get(xwidget_info_t xwidget_info);
 extern xwidgetnum_t     xwidget_info_masterid_get(xwidget_info_t xwidget_info);
 extern xwidget_part_num_t xwidget_info_part_num_get(xwidget_info_t xwidget_info);
 extern xwidget_rev_num_t xwidget_info_rev_num_get(xwidget_info_t xwidget_info);
diff -Nru a/include/asm-ia64/spinlock.h b/include/asm-ia64/spinlock.h
--- a/include/asm-ia64/spinlock.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/spinlock.h	Wed Jun 18 23:42:06 2003
@@ -32,7 +32,7 @@
  * carefully coded to touch only those registers that spin_lock() marks "clobbered".
  */
 
-#define IA64_SPINLOCK_CLOBBERS "ar.pfs", "p14", "r28", "r29", "r30", "b6", "memory"
+#define IA64_SPINLOCK_CLOBBERS "ar.ccv", "ar.pfs", "p14", "r28", "r29", "r30", "b6", "memory"
 
 static inline void
 _raw_spin_lock (spinlock_t *lock)
@@ -133,8 +133,7 @@
 	while (unlikely(ia64_fetchadd(1, (int *) __read_lock_ptr, "acq") < 0)) {	\
 		ia64_fetchadd(-1, (int *) __read_lock_ptr, "rel");			\
 		while (*(volatile int *)__read_lock_ptr < 0)				\
-			barrier();							\
-											\
+			cpu_relax();							\
 	}										\
 } while (0)
 
diff -Nru a/include/asm-ia64/system.h b/include/asm-ia64/system.h
--- a/include/asm-ia64/system.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/system.h	Wed Jun 18 23:42:07 2003
@@ -19,11 +19,10 @@
 #include <asm/pal.h>
 #include <asm/percpu.h>
 
-#define KERNEL_START		(PAGE_OFFSET + 68*1024*1024)
-
-/* 0xa000000000000000 - 0xa000000000000000+PERCPU_MAX_SIZE remain unmapped */
+/* 0xa000000000000000 - 0xa000000000000000+PERCPU_PAGE_SIZE remain unmapped */
 #define PERCPU_ADDR		(0xa000000000000000 + PERCPU_PAGE_SIZE)
 #define GATE_ADDR		(0xa000000000000000 + 2*PERCPU_PAGE_SIZE)
+#define KERNEL_START		 0xa000000100000000
 
 #ifndef __ASSEMBLY__
 
@@ -217,13 +216,11 @@
 	 || IS_IA32_PROCESS(ia64_task_regs(t)) || PERFMON_IS_SYSWIDE())
 
 #define __switch_to(prev,next,last) do {							 \
-	struct task_struct *__fpu_owner = ia64_get_fpu_owner();					 \
 	if (IA64_HAS_EXTRA_STATE(prev))								 \
 		ia64_save_extra(prev);								 \
 	if (IA64_HAS_EXTRA_STATE(next))								 \
 		ia64_load_extra(next);								 \
-	ia64_psr(ia64_task_regs(next))->dfh =							 \
-		!(__fpu_owner == (next) && ((next)->thread.last_fph_cpu == smp_processor_id())); \
+	ia64_psr(ia64_task_regs(next))->dfh = !ia64_is_local_fpu_owner(next);			 \
 	(last) = ia64_switch_to((next));							 \
 } while (0)
 
@@ -239,7 +236,6 @@
 		ia64_psr(ia64_task_regs(prev))->mfh = 0;			\
 		(prev)->thread.flags |= IA64_THREAD_FPH_VALID;			\
 		__ia64_save_fpu((prev)->thread.fph);				\
-		(prev)->thread.last_fph_cpu = smp_processor_id();		\
 	}									\
 	__switch_to(prev, next, last);						\
 } while (0)
@@ -278,6 +274,8 @@
 } while (0)
 #define finish_arch_switch(rq, prev)	spin_unlock_irq(&(prev)->switch_lock)
 #define task_running(rq, p) 		((rq)->curr == (p) || spin_is_locked(&(p)->switch_lock))
+
+#define ia64_platform_is(x) (strcmp(x, platform_name) == 0)
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/asm-ia64/thread_info.h b/include/asm-ia64/thread_info.h
--- a/include/asm-ia64/thread_info.h	Wed Jun 18 23:42:09 2003
+++ b/include/asm-ia64/thread_info.h	Wed Jun 18 23:42:09 2003
@@ -9,11 +9,13 @@
 #include <asm/processor.h>
 #include <asm/ptrace.h>
 
-#define TI_EXEC_DOMAIN	0x00
-#define TI_FLAGS	0x08
-#define TI_CPU		0x0c
-#define TI_ADDR_LIMIT	0x10
-#define TI_PRE_COUNT	0x18
+#define TI_TASK			0x00
+#define TI_EXEC_DOMAIN		0x08
+#define TI_FLAGS		0x10
+#define TI_CPU			0x14
+#define TI_ADDR_LIMIT		0x18
+#define TI_PRE_COUNT		0x20
+#define TI_RESTART_BLOCK	0x28
 
 #define PREEMPT_ACTIVE_BIT 30
 #define PREEMPT_ACTIVE	(1 << PREEMPT_ACTIVE_BIT)
@@ -26,6 +28,7 @@
  * without having to do pointer masking.
  */
 struct thread_info {
+	struct task_struct *task;	/* XXX not really needed, except for dup_task_struct() */
 	struct exec_domain *exec_domain;/* execution domain */
 	__u32 flags;			/* thread_info flags (see TIF_*) */
 	__u32 cpu;			/* current CPU */
@@ -37,8 +40,9 @@
 #define INIT_THREAD_SIZE		/* tell sched.h not to declare the thread_union */
 #define THREAD_SIZE			KERNEL_STACK_SIZE
 
-#define INIT_THREAD_INFO(ti)			\
+#define INIT_THREAD_INFO(tsk)			\
 {						\
+	.task		= &tsk,			\
 	.exec_domain	= &default_exec_domain,	\
 	.flags		= 0,			\
 	.cpu		= 0,			\
@@ -50,8 +54,13 @@
 }
 
 /* how to get the thread information struct from C */
-#define current_thread_info() ((struct thread_info *) ((char *) current + IA64_TASK_SIZE))
+#define current_thread_info()	((struct thread_info *) ((char *) current + IA64_TASK_SIZE))
+#define alloc_thread_info(tsk)	((struct thread_info *) ((char *) (tsk) + IA64_TASK_SIZE))
 #define free_thread_info(ti)	/* nothing */
+
+#define __HAVE_ARCH_TASK_STRUCT_ALLOCATOR
+#define alloc_task_struct()	((task_t *)__get_free_pages(GFP_KERNEL, KERNEL_STACK_SIZE_ORDER))
+#define free_task_struct(tsk)	free_pages((unsigned long) (tsk), KERNEL_STACK_SIZE_ORDER)
 
 #endif /* !__ASSEMBLY */
 
diff -Nru a/include/asm-ia64/timex.h b/include/asm-ia64/timex.h
--- a/include/asm-ia64/timex.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-ia64/timex.h	Wed Jun 18 23:42:08 2003
@@ -2,7 +2,7 @@
 #define _ASM_IA64_TIMEX_H
 
 /*
- * Copyright (C) 1998-2001 Hewlett-Packard Co
+ * Copyright (C) 1998-2001, 2003 Hewlett-Packard Co
  *	David Mosberger-Tang <davidm@hpl.hp.com>
  */
 /*
diff -Nru a/include/asm-ia64/tlb.h b/include/asm-ia64/tlb.h
--- a/include/asm-ia64/tlb.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/tlb.h	Wed Jun 18 23:42:07 2003
@@ -63,7 +63,7 @@
 };
 
 /* Users of the generic TLB shootdown code must declare this storage space. */
-extern struct mmu_gather	mmu_gathers[NR_CPUS];
+DECLARE_PER_CPU(struct mmu_gather, mmu_gathers);
 
 /*
  * Flush the TLB for address range START to END and, if not in fast mode, release the
@@ -125,7 +125,7 @@
 static inline struct mmu_gather *
 tlb_gather_mmu (struct mm_struct *mm, unsigned int full_mm_flush)
 {
-	struct mmu_gather *tlb = &mmu_gathers[smp_processor_id()];
+	struct mmu_gather *tlb = &per_cpu(mmu_gathers, smp_processor_id());
 
 	tlb->mm = mm;
 	/*
diff -Nru a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h
--- a/include/asm-ia64/topology.h	Wed Jun 18 23:42:05 2003
+++ b/include/asm-ia64/topology.h	Wed Jun 18 23:42:05 2003
@@ -63,4 +63,6 @@
 /* Cross-node load balancing interval. */
 #define NODE_BALANCE_RATE 10
 
+void build_cpu_to_node_map(void);
+
 #endif /* _ASM_IA64_TOPOLOGY_H */
diff -Nru a/include/asm-ia64/unistd.h b/include/asm-ia64/unistd.h
--- a/include/asm-ia64/unistd.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-ia64/unistd.h	Wed Jun 18 23:42:06 2003
@@ -247,6 +247,10 @@
 #define __NR_sys_clock_getres		1255
 #define __NR_sys_clock_nanosleep	1256
 
+#ifdef __KERNEL__
+
+#define NR_syscalls			256 /* length of syscall table */
+
 #if !defined(__ASSEMBLY__) && !defined(ASSEMBLER)
 
 extern long __ia64_syscall (long a0, long a1, long a2, long a3, long a4, long nr);
@@ -348,10 +352,12 @@
 /*
  * "Conditional" syscalls
  *
- * What we want is __attribute__((weak,alias("sys_ni_syscall"))),
- * but it doesn't work on all toolchains, so we just do it by hand
+ * What we want is __attribute__((weak,alias("sys_ni_syscall"))), but it doesn't work on
+ * all toolchains, so we just do it by hand.  Note, this macro can only be used in the
+ * file which defines sys_ni_syscall, i.e., in kernel/sys.c.
  */
 #define cond_syscall(x) asm(".weak\t" #x "\n\t.set\t" #x ",sys_ni_syscall");
 
 #endif /* !__ASSEMBLY__ */
+#endif /* __KERNEL__ */
 #endif /* _ASM_IA64_UNISTD_H */
diff -Nru a/include/asm-ia64/unwind.h b/include/asm-ia64/unwind.h
--- a/include/asm-ia64/unwind.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/unwind.h	Wed Jun 18 23:42:07 2003
@@ -26,7 +26,9 @@
 	UNW_AR_EC,
 	UNW_AR_FPSR,
 	UNW_AR_RSC,
-	UNW_AR_CCV
+	UNW_AR_CCV,
+	UNW_AR_CSD,
+	UNW_AR_SSD
 };
 
 /*
@@ -95,7 +97,6 @@
  * Initialize unwind support.
  */
 extern void unw_init (void);
-extern void unw_create_gate_table (void);
 
 extern void *unw_add_unwind_table (const char *name, unsigned long segment_base, unsigned long gp,
 				   const void *table_start, const void *table_end);
diff -Nru a/include/asm-ia64/ustack.h b/include/asm-ia64/ustack.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/asm-ia64/ustack.h	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,16 @@
+#ifndef _ASM_IA64_USTACK_H
+#define _ASM_IA64_USTACK_H
+
+/*
+ * Constants for the user stack size
+ */
+
+#include <asm/page.h>
+
+/* The absolute hard limit for stack size is 1/2 of the mappable space in the region */
+#define MAX_USER_STACK_SIZE	(RGN_MAP_LIMIT/2)
+/* Make a default stack size of 2GB */
+#define DEFAULT_USER_STACK_SIZE	(1UL << 31)
+#define STACK_TOP		(0x6000000000000000UL + RGN_MAP_LIMIT)
+
+#endif /* _ASM_IA64_USTACK_H */
diff -Nru a/include/asm-ia64/xor.h b/include/asm-ia64/xor.h
--- a/include/asm-ia64/xor.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-ia64/xor.h	Wed Jun 18 23:42:07 2003
@@ -22,262 +22,12 @@
 extern void xor_ia64_5(unsigned long, unsigned long *, unsigned long *,
 		       unsigned long *, unsigned long *, unsigned long *);
 
-asm ("
-	.text
-
-	// Assume L2 memory latency of 6 cycles.
-
-	.proc xor_ia64_2
-xor_ia64_2:
-	.prologue
-	.fframe 0
-	{ .mii
-	  .save ar.pfs, r31
-	  alloc r31 = ar.pfs, 3, 0, 13, 16
-	  .save ar.lc, r30
-	  mov r30 = ar.lc
-	  .save pr, r29
-	  mov r29 = pr
-	  ;;
-	}
-	.body
-	{ .mii
-	  mov r8 = in1
-	  mov ar.ec = 6 + 2
-	  shr in0 = in0, 3
-	  ;;
-	}
-	{ .mmi
-	  adds in0 = -1, in0
-	  mov r16 = in1
-	  mov r17 = in2
-	  ;;
-	}
-	{ .mii
-	  mov ar.lc = in0
-	  mov pr.rot = 1 << 16
-	  ;;
-	}
-	.rotr s1[6+1], s2[6+1], d[2]
-	.rotp p[6+2]
-0:	 { .mmi
-(p[0])	  ld8.nta s1[0] = [r16], 8
-(p[0])	  ld8.nta s2[0] = [r17], 8
-(p[6])	  xor d[0] = s1[6], s2[6]
-	}
-	{ .mfb
-(p[6+1])  st8.nta [r8] = d[1], 8
-	  nop.f 0
-	  br.ctop.dptk.few 0b
-	  ;;
-	}
-	{ .mii
-	  mov ar.lc = r30
-	  mov pr = r29, -1
-	}
-	{ .bbb
-	  br.ret.sptk.few rp
-	}
-	.endp xor_ia64_2
-
-	.proc xor_ia64_3
-xor_ia64_3:
-	.prologue
-	.fframe 0
-	{ .mii
-	  .save ar.pfs, r31
-	  alloc r31 = ar.pfs, 4, 0, 20, 24
-	  .save ar.lc, r30
-	  mov r30 = ar.lc
-	  .save pr, r29
-	  mov r29 = pr
-	  ;;
-	}
-	.body
-	{ .mii
-	  mov r8 = in1
-	  mov ar.ec = 6 + 2
-	  shr in0 = in0, 3
-	  ;;
-	}
-	{ .mmi
-	  adds in0 = -1, in0
-	  mov r16 = in1
-	  mov r17 = in2
-	  ;;
-	}
-	{ .mii
-	  mov r18 = in3
-	  mov ar.lc = in0
-	  mov pr.rot = 1 << 16
-	  ;;
-	}
-	.rotr s1[6+1], s2[6+1], s3[6+1], d[2]
-	.rotp p[6+2]
-0:	{ .mmi
-(p[0])	  ld8.nta s1[0] = [r16], 8
-(p[0])	  ld8.nta s2[0] = [r17], 8
-(p[6])	  xor d[0] = s1[6], s2[6]
-	  ;;
-	}
-	{ .mmi
-(p[0])	  ld8.nta s3[0] = [r18], 8
-(p[6+1])  st8.nta [r8] = d[1], 8
-(p[6])	  xor d[0] = d[0], s3[6]
-	}
-	{ .bbb
-	  br.ctop.dptk.few 0b
-	  ;;
-	}
-	{ .mii
-	  mov ar.lc = r30
-	  mov pr = r29, -1
-	}
-	{ .bbb
-	  br.ret.sptk.few rp
-	}
-	.endp xor_ia64_3
-
-	.proc xor_ia64_4
-xor_ia64_4:
-	.prologue
-	.fframe 0
-	{ .mii
-	  .save ar.pfs, r31
-	  alloc r31 = ar.pfs, 5, 0, 27, 32
-	  .save ar.lc, r30
-	  mov r30 = ar.lc
-	  .save pr, r29
-	  mov r29 = pr
-	  ;;
-	}
-	.body
-	{ .mii
-	  mov r8 = in1
-	  mov ar.ec = 6 + 2
-	  shr in0 = in0, 3
-	  ;;
-	}
-	{ .mmi
-	  adds in0 = -1, in0
-	  mov r16 = in1
-	  mov r17 = in2
-	  ;;
-	}
-	{ .mii
-	  mov r18 = in3
-	  mov ar.lc = in0
-	  mov pr.rot = 1 << 16
-	}
-	{ .mfb
-	  mov r19 = in4
-	  ;;
-	}
-	.rotr s1[6+1], s2[6+1], s3[6+1], s4[6+1], d[2]
-	.rotp p[6+2]
-0:	{ .mmi
-(p[0])	  ld8.nta s1[0] = [r16], 8
-(p[0])	  ld8.nta s2[0] = [r17], 8
-(p[6])	  xor d[0] = s1[6], s2[6]
-	}
-	{ .mmi
-(p[0])	  ld8.nta s3[0] = [r18], 8
-(p[0])	  ld8.nta s4[0] = [r19], 8
-(p[6])	  xor r20 = s3[6], s4[6]
-	  ;;
-	}
-	{ .mib
-(p[6+1])  st8.nta [r8] = d[1], 8
-(p[6])	  xor d[0] = d[0], r20
-	  br.ctop.dptk.few 0b
-	  ;;
-	}
-	{ .mii
-	  mov ar.lc = r30
-	  mov pr = r29, -1
-	}
-	{ .bbb
-	  br.ret.sptk.few rp
-	}
-	.endp xor_ia64_4
-
-	.proc xor_ia64_5
-xor_ia64_5:
-	.prologue
-	.fframe 0
-	{ .mii
-	  .save ar.pfs, r31
-	  alloc r31 = ar.pfs, 6, 0, 34, 40
-	  .save ar.lc, r30
-	  mov r30 = ar.lc
-	  .save pr, r29
-	  mov r29 = pr
-	  ;;
-	}
-	.body
-	{ .mii
-	  mov r8 = in1
-	  mov ar.ec = 6 + 2
-	  shr in0 = in0, 3
-	  ;;
-	}
-	{ .mmi
-	  adds in0 = -1, in0
-	  mov r16 = in1
-	  mov r17 = in2
-	  ;;
-	}
-	{ .mii
-	  mov r18 = in3
-	  mov ar.lc = in0
-	  mov pr.rot = 1 << 16
-	}
-	{ .mib
-	  mov r19 = in4
-	  mov r20 = in5
-	  ;;
-	}
-	.rotr s1[6+1], s2[6+1], s3[6+1], s4[6+1], s5[6+1], d[2]
-	.rotp p[6+2]
-0:	{ .mmi
-(p[0])	  ld8.nta s1[0] = [r16], 8
-(p[0])	  ld8.nta s2[0] = [r17], 8
-(p[6])	  xor d[0] = s1[6], s2[6]
-	}
-	{ .mmi
-(p[0])	  ld8.nta s3[0] = [r18], 8
-(p[0])	  ld8.nta s4[0] = [r19], 8
-(p[6])	  xor r21 = s3[6], s4[6]
-	  ;;
-	}
-	{ .mmi
-(p[0])	  ld8.nta s5[0] = [r20], 8
-(p[6+1])  st8.nta [r8] = d[1], 8
-(p[6])	  xor d[0] = d[0], r21
-	  ;;
-	}
-	{ .mfb
-(p[6])	  xor d[0] = d[0], s5[6]
-	  nop.f 0
-	  br.ctop.dptk.few 0b
-	  ;;
-	}
-	{ .mii
-	  mov ar.lc = r30
-	  mov pr = r29, -1
-	}
-	{ .bbb
-	  br.ret.sptk.few rp
-	}
-	.endp xor_ia64_5
-");
-
 static struct xor_block_template xor_block_ia64 = {
-	name: "ia64",
-	do_2: xor_ia64_2,
-	do_3: xor_ia64_3,
-	do_4: xor_ia64_4,
-	do_5: xor_ia64_5,
+	.name =	"ia64",
+	.do_2 =	xor_ia64_2,
+	.do_3 =	xor_ia64_3,
+	.do_4 =	xor_ia64_4,
+	.do_5 =	xor_ia64_5,
 };
 
 #define XOR_TRY_TEMPLATES	xor_speed(&xor_block_ia64)
diff -Nru a/include/asm-sparc/xor.h b/include/asm-sparc/xor.h
--- a/include/asm-sparc/xor.h	Wed Jun 18 23:42:08 2003
+++ b/include/asm-sparc/xor.h	Wed Jun 18 23:42:08 2003
@@ -250,11 +250,11 @@
 }
 
 static struct xor_block_template xor_block_SPARC = {
-	name: "SPARC",
-	do_2: sparc_2,
-	do_3: sparc_3,
-	do_4: sparc_4,
-	do_5: sparc_5,
+	.name	= "SPARC",
+	.do_2	= sparc_2,
+	.do_3	= sparc_3,
+	.do_4	= sparc_4,
+	.do_5	= sparc_5,
 };
 
 /* For grins, also test the generic routines.  */
diff -Nru a/include/asm-sparc64/xor.h b/include/asm-sparc64/xor.h
--- a/include/asm-sparc64/xor.h	Wed Jun 18 23:42:07 2003
+++ b/include/asm-sparc64/xor.h	Wed Jun 18 23:42:07 2003
@@ -388,11 +388,11 @@
 ");
 
 static struct xor_block_template xor_block_VIS = {
-        name: "VIS",
-        do_2: xor_vis_2,
-        do_3: xor_vis_3,
-        do_4: xor_vis_4,
-        do_5: xor_vis_5,
+        .name	= "VIS",
+        .do_2	= xor_vis_2,
+        .do_3	= xor_vis_3,
+        .do_4	= xor_vis_4,
+        .do_5	= xor_vis_5,
 };
 
 #define XOR_TRY_TEMPLATES       xor_speed(&xor_block_VIS)
diff -Nru a/include/asm-v850/hardirq.h b/include/asm-v850/hardirq.h
--- a/include/asm-v850/hardirq.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-v850/hardirq.h	Wed Jun 18 23:42:06 2003
@@ -80,12 +80,12 @@
 # define IRQ_EXIT_OFFSET HARDIRQ_OFFSET
 #endif
 
-#define irq_exit()							\
-do {									\
-		preempt_count() -= IRQ_EXIT_OFFSET;			\
-		if (!in_interrupt() && softirq_pending(smp_processor_id())) \
-			do_softirq();					\
-		preempt_enable_no_resched();				\
+#define irq_exit()							      \
+do {									      \
+	preempt_count() -= IRQ_EXIT_OFFSET;				      \
+	if (!in_interrupt() && softirq_pending(smp_processor_id()))	      \
+		do_softirq();						      \
+	preempt_enable_no_resched();					      \
 } while (0)
 
 #ifndef CONFIG_SMP
diff -Nru a/include/asm-v850/io.h b/include/asm-v850/io.h
--- a/include/asm-v850/io.h	Wed Jun 18 23:42:06 2003
+++ b/include/asm-v850/io.h	Wed Jun 18 23:42:06 2003
@@ -1,8 +1,8 @@
 /*
  * include/asm-v850/io.h -- Misc I/O operations
  *
- *  Copyright (C) 2001,02  NEC Corporation
- *  Copyright (C) 2001,02  Miles Bader <miles@gnu.org>
+ *  Copyright (C) 2001,02,03  NEC Electronics Corporation
+ *  Copyright (C) 2001,02,03  Miles Bader <miles@gnu.org>
  *
  * 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
@@ -29,6 +29,13 @@
   (void)((*(volatile unsigned short *) (addr)) = (b))
 #define writel(b, addr) \
   (void)((*(volatile unsigned int *) (addr)) = (b))
+
+#define __raw_readb readb
+#define __raw_readw readw
+#define __raw_readl readl
+#define __raw_writeb writeb
+#define __raw_writew writew
+#define __raw_writel writel
 
 #define inb(addr)	readb (addr)
 #define inw(addr)	readw (addr)
diff -Nru a/include/linux/atmdev.h b/include/linux/atmdev.h
--- a/include/linux/atmdev.h	Wed Jun 18 23:42:08 2003
+++ b/include/linux/atmdev.h	Wed Jun 18 23:42:08 2003
@@ -452,7 +452,7 @@
 int atm_find_ci(struct atm_vcc *vcc,short *vpi,int *vci);
 int atm_pcr_goal(struct atm_trafprm *tp);
 
-void atm_async_release_vcc(struct atm_vcc *vcc,int reply);
+void vcc_release_async(struct atm_vcc *vcc, int reply);
 
 #endif /* __KERNEL__ */
 
diff -Nru a/include/linux/ext3_fs.h b/include/linux/ext3_fs.h
--- a/include/linux/ext3_fs.h	Wed Jun 18 23:42:07 2003
+++ b/include/linux/ext3_fs.h	Wed Jun 18 23:42:07 2003
@@ -344,7 +344,9 @@
 #endif
 
 #define ext3_set_bit			ext2_set_bit
+#define ext3_set_bit_atomic		ext2_set_bit_atomic
 #define ext3_clear_bit			ext2_clear_bit
+#define ext3_clear_bit_atomic		ext2_clear_bit_atomic
 #define ext3_test_bit			ext2_test_bit
 #define ext3_find_first_zero_bit	ext2_find_first_zero_bit
 #define ext3_find_next_zero_bit		ext2_find_next_zero_bit
@@ -733,6 +735,7 @@
 extern int ext3_change_inode_journal_flag(struct inode *, int);
 extern void ext3_truncate (struct inode *);
 extern void ext3_set_inode_flags(struct inode *);
+extern void ext3_set_aops(struct inode *inode);
 
 /* ioctl.c */
 extern int ext3_ioctl (struct inode *, struct file *, unsigned int,
@@ -780,10 +783,6 @@
 /* file.c */
 extern struct inode_operations ext3_file_inode_operations;
 extern struct file_operations ext3_file_operations;
-
-/* inode.c */
-extern struct address_space_operations ext3_aops;
-extern struct address_space_operations ext3_writeback_aops;
 
 /* namei.c */
 extern struct inode_operations ext3_dir_inode_operations;
diff -Nru a/include/linux/ext3_fs_sb.h b/include/linux/ext3_fs_sb.h
--- a/include/linux/ext3_fs_sb.h	Wed Jun 18 23:42:09 2003
+++ b/include/linux/ext3_fs_sb.h	Wed Jun 18 23:42:09 2003
@@ -19,6 +19,8 @@
 #ifdef __KERNEL__
 #include <linux/timer.h>
 #include <linux/wait.h>
+#include <linux/blockgroup_lock.h>
+#include <linux/percpu_counter.h>
 #endif
 
 /*
@@ -50,8 +52,11 @@
 	u32 s_next_generation;
 	u32 s_hash_seed[4];
 	int s_def_hash_version;
-	unsigned long s_dir_count;
-	u8 *s_debts;
+        u8 *s_debts;
+	struct percpu_counter s_freeblocks_counter;
+	struct percpu_counter s_freeinodes_counter;
+	struct percpu_counter s_dirs_counter;
+	struct blockgroup_lock s_blockgroup_lock;
 
 	/* Journaling */
 	struct inode * s_journal_inode;
diff -Nru a/include/linux/ext3_jbd.h b/include/linux/ext3_jbd.h
--- a/include/linux/ext3_jbd.h	Wed Jun 18 23:42:06 2003
+++ b/include/linux/ext3_jbd.h	Wed Jun 18 23:42:06 2003
@@ -97,26 +97,33 @@
 		struct buffer_head *bh, handle_t *handle, int err);
 
 static inline int
-__ext3_journal_get_undo_access(const char *where,
-			       handle_t *handle, struct buffer_head *bh)
+__ext3_journal_get_undo_access(const char *where, handle_t *handle,
+				struct buffer_head *bh, int *credits)
 {
-	int err = journal_get_undo_access(handle, bh);
+	int err = journal_get_undo_access(handle, bh, credits);
 	if (err)
 		ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err);
 	return err;
 }
 
 static inline int
-__ext3_journal_get_write_access(const char *where,
-				handle_t *handle, struct buffer_head *bh)
+__ext3_journal_get_write_access(const char *where, handle_t *handle,
+				struct buffer_head *bh, int *credits)
 {
-	int err = journal_get_write_access(handle, bh);
+	int err = journal_get_write_access(handle, bh, credits);
 	if (err)
 		ext3_journal_abort_handle(where, __FUNCTION__, bh, handle,err);
 	return err;
 }
 
 static inline void
+ext3_journal_release_buffer(handle_t *handle, struct buffer_head *bh,
+				int credits)
+{
+	journal_release_buffer(handle, bh, credits);
+}
+
+static inline void
 ext3_journal_forget(handle_t *handle, struct buffer_head *bh)
 {
 	journal_forget(handle, bh);
@@ -153,10 +160,12 @@
 }
 
 
-#define ext3_journal_get_undo_access(handle, bh) \
-	__ext3_journal_get_undo_access(__FUNCTION__, (handle), (bh))
+#define ext3_journal_get_undo_access(handle, bh, credits) \
+	__ext3_journal_get_undo_access(__FUNCTION__, (handle), (bh), (credits))
 #define ext3_journal_get_write_access(handle, bh) \
-	__ext3_journal_get_write_access(__FUNCTION__, (handle), (bh))
+	__ext3_journal_get_write_access(__FUNCTION__, (handle), (bh), NULL)
+#define ext3_journal_get_write_access_credits(handle, bh, credits) \
+	__ext3_journal_get_write_access(__FUNCTION__, (handle), (bh), (credits))
 #define ext3_journal_revoke(handle, blocknr, bh) \
 	__ext3_journal_revoke(__FUNCTION__, (handle), (blocknr), (bh))
 #define ext3_journal_get_create_access(handle, bh) \
@@ -173,17 +182,6 @@
 static inline handle_t *ext3_journal_current_handle(void)
 {
 	return journal_current_handle();
-}
-
-static inline void
-ext3_log_start_commit(journal_t *journal, transaction_t *transaction)
-{
-	log_start_commit(journal, transaction);
-}
-
-static inline void ext3_log_wait_commit(journal_t *journal, tid_t tid)
-{
-	log_wait_commit(journal, tid);
 }
 
 static inline int ext3_journal_extend(handle_t *handle, int nblocks)
diff -Nru a/include/linux/jbd.h b/include/linux/jbd.h
--- a/include/linux/jbd.h	Wed Jun 18 23:42:08 2003
+++ b/include/linux/jbd.h	Wed Jun 18 23:42:08 2003
@@ -178,7 +178,7 @@
 	__u32	s_blocksize;		/* journal device blocksize */
 	__u32	s_maxlen;		/* total blocks in journal file */
 	__u32	s_first;		/* first block of log information */
-	
+
 /* 0x0018 */
 	/* Dynamic information describing the current state of the log */
 	__u32	s_sequence;		/* first commit ID expected in log */
@@ -198,9 +198,9 @@
 
 /* 0x0040 */
 	__u32	s_nr_users;		/* Nr of filesystems sharing log */
-	
+
 	__u32	s_dynsuper;		/* Blocknr of dynamic superblock copy*/
-	
+
 /* 0x0048 */
 	__u32	s_max_transaction;	/* Limit of journal blocks per trans.*/
 	__u32	s_max_trans_data;	/* Limit of data blocks per trans. */
@@ -286,15 +286,18 @@
 
 enum jbd_state_bits {
 	BH_JBD			/* Has an attached ext3 journal_head */
-	  = BH_PrivateStart,	
+	  = BH_PrivateStart,
 	BH_JWrite,		/* Being written to log (@@@ DEBUGGING) */
 	BH_Freed,		/* Has been freed (truncated) */
 	BH_Revoked,		/* Has been revoked from the log */
 	BH_RevokeValid,		/* Revoked flag is valid */
 	BH_JBDDirty,		/* Is dirty but journaled */
+	BH_State,		/* Pins most journal_head state */
+	BH_JournalHead,		/* Pins bh->b_private and jh->b_bh */
 };
 
 BUFFER_FNS(JBD, jbd)
+BUFFER_FNS(JWrite, jwrite)
 BUFFER_FNS(JBDDirty, jbddirty)
 TAS_BUFFER_FNS(JBDDirty, jbddirty)
 BUFFER_FNS(Freed, freed)
@@ -309,6 +312,36 @@
 	return bh->b_private;
 }
 
+static inline void jbd_lock_bh_state(struct buffer_head *bh)
+{
+	bit_spin_lock(BH_State, &bh->b_state);
+}
+
+static inline int jbd_trylock_bh_state(struct buffer_head *bh)
+{
+	return bit_spin_trylock(BH_State, &bh->b_state);
+}
+
+static inline int jbd_is_locked_bh_state(struct buffer_head *bh)
+{
+	return bit_spin_is_locked(BH_State, &bh->b_state);
+}
+
+static inline void jbd_unlock_bh_state(struct buffer_head *bh)
+{
+	bit_spin_unlock(BH_State, &bh->b_state);
+}
+
+static inline void jbd_lock_bh_journal_head(struct buffer_head *bh)
+{
+	bit_spin_lock(BH_JournalHead, &bh->b_state);
+}
+
+static inline void jbd_unlock_bh_journal_head(struct buffer_head *bh)
+{
+	bit_spin_unlock(BH_JournalHead, &bh->b_state);
+}
+
 #define HAVE_JOURNAL_CALLBACK_STATUS
 /**
  *   struct journal_callback - Base structure for callback information.
@@ -325,7 +358,7 @@
  *   See journal_callback_set for more information.
  **/
 struct journal_callback {
-	struct list_head jcb_list;
+	struct list_head jcb_list;		/* t_jcb_lock */
 	void (*jcb_func)(struct journal_callback *jcb, int error);
 	/* user data goes here */
 };
@@ -333,7 +366,8 @@
 struct jbd_revoke_table_s;
 
 /**
- * struct handle_s - The handle_s type is the concrete type associated with handle_t.
+ * struct handle_s - The handle_s type is the concrete type associated with
+ *     handle_t.
  * @h_transaction: Which compound transaction is this update a part of?
  * @h_buffer_credits: Number of remaining buffers we are allowed to dirty.
  * @h_ref: Reference count on this handle
@@ -351,7 +385,7 @@
 struct handle_s 
 {
 	/* Which compound transaction is this update a part of? */
-	transaction_t	      * h_transaction;
+	transaction_t		*h_transaction;
 
 	/* Number of remaining buffers we are allowed to dirty: */
 	int			h_buffer_credits;
@@ -363,13 +397,14 @@
 	/* operations */
 	int			h_err;
 
-	/* List of application registered callbacks for this handle.
-	 * The function(s) will be called after the transaction that
-	 * this handle is part of has been committed to disk.
+	/*
+	 * List of application registered callbacks for this handle. The
+	 * function(s) will be called after the transaction that this handle is
+	 * part of has been committed to disk. [t_jcb_lock]
 	 */
 	struct list_head	h_jcb;
 
-	/* Flags */
+	/* Flags [no locking] */
 	unsigned int	h_sync:		1;	/* sync-on-close */
 	unsigned int	h_jdata:	1;	/* force data journaling */
 	unsigned int	h_aborted:	1;	/* fatal error on handle */
@@ -392,15 +427,42 @@
  * flushed to home for finished transactions.
  */
 
+/*
+ * Lock ranking:
+ *
+ *    j_list_lock
+ *      ->jbd_lock_bh_journal_head()	(This is "innermost")
+ *
+ *    j_state_lock
+ *    ->jbd_lock_bh_state()
+ *
+ *    jbd_lock_bh_state()
+ *    ->j_list_lock
+ *
+ *    j_state_lock
+ *    ->t_handle_lock
+ *
+ *    j_state_lock
+ *    ->j_list_lock			(journal_unmap_buffer)
+ *
+ *    t_handle_lock
+ *    ->t_jcb_lock
+ */
+
 struct transaction_s 
 {
-	/* Pointer to the journal for this transaction. */
-	journal_t *		t_journal;
-	
-	/* Sequence number for this transaction */
+	/* Pointer to the journal for this transaction. [no locking] */
+	journal_t		*t_journal;
+
+	/* Sequence number for this transaction [no locking] */
 	tid_t			t_tid;
-	
-	/* Transaction's current state */
+
+	/*
+	 * Transaction's current state
+	 * [no locking - only kjournald alters this]
+	 * FIXME: needs barriers
+	 * KLUDGE: [use j_state_lock]
+	 */
 	enum {
 		T_RUNNING,
 		T_LOCKED,
@@ -410,87 +472,115 @@
 		T_FINISHED 
 	}			t_state;
 
-	/* Where in the log does this transaction's commit start? */
+	/*
+	 * Where in the log does this transaction's commit start? [no locking]
+	 */
 	unsigned long		t_log_start;
-	
-	/* Doubly-linked circular list of all inodes owned by this
-           transaction */	/* AKPM: unused */
-	struct inode *		t_ilist;
-	
-	/* Number of buffers on the t_buffers list */
+
+	/* Number of buffers on the t_buffers list [j_list_lock] */
 	int			t_nr_buffers;
-	
-	/* Doubly-linked circular list of all buffers reserved but not
-           yet modified by this transaction */
-	struct journal_head *	t_reserved_list;
-	
-	/* Doubly-linked circular list of all metadata buffers owned by this
-           transaction */
-	struct journal_head *	t_buffers;
-	
+
+	/*
+	 * Doubly-linked circular list of all buffers reserved but not yet
+	 * modified by this transaction [j_list_lock]
+	 */
+	struct journal_head	*t_reserved_list;
+
+	/*
+	 * Doubly-linked circular list of all metadata buffers owned by this
+	 * transaction [j_list_lock]
+	 */
+	struct journal_head	*t_buffers;
+
 	/*
 	 * Doubly-linked circular list of all data buffers still to be
-	 * flushed before this transaction can be committed.
-	 * Protected by journal_datalist_lock.
+	 * flushed before this transaction can be committed [j_list_lock]
+	 */
+	struct journal_head	*t_sync_datalist;
+
+	/*
+	 * Doubly-linked circular list of all forget buffers (superseded
+	 * buffers which we can un-checkpoint once this transaction commits)
+	 * [j_list_lock]
+	 */
+	struct journal_head	*t_forget;
+
+	/*
+	 * Doubly-linked circular list of all buffers still to be flushed before
+	 * this transaction can be checkpointed. [j_list_lock]
+	 */
+	struct journal_head	*t_checkpoint_list;
+
+	/*
+	 * Doubly-linked circular list of temporary buffers currently undergoing
+	 * IO in the log [j_list_lock]
+	 */
+	struct journal_head	*t_iobuf_list;
+
+	/*
+	 * Doubly-linked circular list of metadata buffers being shadowed by log
+	 * IO.  The IO buffers on the iobuf list and the shadow buffers on this
+	 * list match each other one for one at all times. [j_list_lock]
+	 */
+	struct journal_head	*t_shadow_list;
+
+	/*
+	 * Doubly-linked circular list of control buffers being written to the
+	 * log. [j_list_lock]
+	 */
+	struct journal_head	*t_log_list;
+
+	/*
+	 * Protects info related to handles
+	 */
+	spinlock_t		t_handle_lock;
+
+	/*
+	 * Number of outstanding updates running on this transaction
+	 * [t_handle_lock]
 	 */
-	struct journal_head *	t_sync_datalist;
-	
-	/* Doubly-linked circular list of all forget buffers (superseded
-           buffers which we can un-checkpoint once this transaction
-           commits) */
-	struct journal_head *	t_forget;
-	
-	/*
-	 * Doubly-linked circular list of all buffers still to be
-	 * flushed before this transaction can be checkpointed.
-	 */
-	/* Protected by journal_datalist_lock */
-	struct journal_head *	t_checkpoint_list;
-	
-	/* Doubly-linked circular list of temporary buffers currently
-           undergoing IO in the log */
-	struct journal_head *	t_iobuf_list;
-	
-	/* Doubly-linked circular list of metadata buffers being
-           shadowed by log IO.  The IO buffers on the iobuf list and the
-           shadow buffers on this list match each other one for one at
-           all times. */
-	struct journal_head *	t_shadow_list;
-	
-	/* Doubly-linked circular list of control buffers being written
-           to the log. */
-	struct journal_head *	t_log_list;
-	
-	/* Number of outstanding updates running on this transaction */
 	int			t_updates;
 
-	/* Number of buffers reserved for use by all handles in this
-	 * transaction handle but not yet modified. */
+	/*
+	 * Number of buffers reserved for use by all handles in this transaction
+	 * handle but not yet modified. [t_handle_lock]
+	 */
 	int			t_outstanding_credits;
-	
+
 	/*
-	 * Forward and backward links for the circular list of all
-	 * transactions awaiting checkpoint.
+	 * Forward and backward links for the circular list of all transactions
+	 * awaiting checkpoint. [j_list_lock]
 	 */
-	/* Protected by journal_datalist_lock */
 	transaction_t		*t_cpnext, *t_cpprev;
 
-	/* When will the transaction expire (become due for commit), in
-	 * jiffies ? */
+	/*
+	 * When will the transaction expire (become due for commit), in jiffies?
+	 * [no locking]
+	 */
 	unsigned long		t_expires;
 
-	/* How many handles used this transaction? */
+	/*
+	 * How many handles used this transaction? [t_handle_lock]
+	 */
 	int t_handle_count;
 
-	/* List of registered callback functions for this transaction.
-	 * Called when the transaction is committed. */
+	/*
+	 * Protects the callback list
+	 */
+	spinlock_t		t_jcb_lock;
+	/*
+	 * List of registered callback functions for this transaction.
+	 * Called when the transaction is committed. [t_jcb_lock]
+	 */
 	struct list_head	t_jcb;
 };
 
 /**
- * struct journal_s - The journal_s type is the concrete type associated with journal_t.
+ * struct journal_s - The journal_s type is the concrete type associated with
+ *     journal_t.
  * @j_flags:  General journaling state flags
- * @j_errno:  Is there an outstanding uncleared error on the journal (from a prior abort)? 
+ * @j_errno:  Is there an outstanding uncleared error on the journal (from a
+ *     prior abort)? 
  * @j_sb_buffer: First part of superblock buffer
  * @j_superblock: Second part of superblock buffer
  * @j_format_version: Version of the superblock format
@@ -498,171 +588,232 @@
  * @j_barrier: The barrier lock itself
  * @j_running_transaction: The current running transaction..
  * @j_committing_transaction: the transaction we are pushing to disk
- * @j_checkpoint_transactions: a linked circular list of all transactions waiting for checkpointing
- * @j_wait_transaction_locked: Wait queue for waiting for a locked transaction to start committing, or for a barrier lock to be released
+ * @j_checkpoint_transactions: a linked circular list of all transactions
+ *  waiting for checkpointing
+ * @j_wait_transaction_locked: Wait queue for waiting for a locked transaction
+ *  to start committing, or for a barrier lock to be released
  * @j_wait_logspace: Wait queue for waiting for checkpointing to complete
  * @j_wait_done_commit: Wait queue for waiting for commit to complete 
  * @j_wait_checkpoint:  Wait queue to trigger checkpointing
  * @j_wait_commit: Wait queue to trigger commit
  * @j_wait_updates: Wait queue to wait for updates to complete
  * @j_checkpoint_sem: Semaphore for locking against concurrent checkpoints
- * @j_sem: The main journal lock, used by lock_journal() 
  * @j_head: Journal head - identifies the first unused block in the journal
- * @j_tail: Journal tail - identifies the oldest still-used block in the journal.
+ * @j_tail: Journal tail - identifies the oldest still-used block in the
+ *  journal.
  * @j_free: Journal free - how many free blocks are there in the journal?
  * @j_first: The block number of the first usable block 
  * @j_last: The block number one beyond the last usable block
  * @j_dev: Device where we store the journal
  * @j_blocksize: blocksize for the location where we store the journal.
- * @j_blk_offset: starting block offset for into the device where we store the journal
- * @j_fs_dev: Device which holds the client fs.  For internal journal this will be equal to j_dev
+ * @j_blk_offset: starting block offset for into the device where we store the
+ *     journal
+ * @j_fs_dev: Device which holds the client fs.  For internal journal this will
+ *     be equal to j_dev
  * @j_maxlen: Total maximum capacity of the journal region on disk.
- * @j_inode: Optional inode where we store the journal.  If present, all  journal block numbers are mapped into this inode via bmap().
+ * @j_inode: Optional inode where we store the journal.  If present, all journal
+ *     block numbers are mapped into this inode via bmap().
  * @j_tail_sequence:  Sequence number of the oldest transaction in the log 
  * @j_transaction_sequence: Sequence number of the next transaction to grant
- * @j_commit_sequence: Sequence number of the most recently committed transaction
- * @j_commit_request: Sequence number of the most recent transaction wanting commit 
+ * @j_commit_sequence: Sequence number of the most recently committed
+ *  transaction
+ * @j_commit_request: Sequence number of the most recent transaction wanting
+ *     commit 
  * @j_uuid: Uuid of client object.
  * @j_task: Pointer to the current commit thread for this journal
- * @j_max_transaction_buffers:  Maximum number of metadata buffers to allow in a single compound commit transaction
- * @j_commit_interval: What is the maximum transaction lifetime before we begin a commit?
+ * @j_max_transaction_buffers:  Maximum number of metadata buffers to allow in a
+ *     single compound commit transaction
+ * @j_commit_interval: What is the maximum transaction lifetime before we begin
+ *  a commit?
  * @j_commit_timer:  The timer used to wakeup the commit thread
- * @j_commit_timer_active: Timer flag
- * @j_all_journals:  Link all journals together - system-wide 
- * @j_revoke: The revoke table - maintains the list of revoked blocks in the current transaction.
- **/
+ * @j_revoke: The revoke table - maintains the list of revoked blocks in the
+ *     current transaction.
+ */
 
 struct journal_s
 {
-	/* General journaling state flags */
+	/* General journaling state flags [j_state_lock] */
 	unsigned long		j_flags;
 
-	/* Is there an outstanding uncleared error on the journal (from */
-	/* a prior abort)? */
+	/*
+	 * Is there an outstanding uncleared error on the journal (from a prior
+	 * abort)? [j_state_lock]
+	 */
 	int			j_errno;
-	
+
 	/* The superblock buffer */
-	struct buffer_head *	j_sb_buffer;
-	journal_superblock_t *	j_superblock;
+	struct buffer_head	*j_sb_buffer;
+	journal_superblock_t	*j_superblock;
 
 	/* Version of the superblock format */
 	int			j_format_version;
 
-	/* Number of processes waiting to create a barrier lock */
+	/*
+	 * Protect the various scalars in the journal
+	 */
+	spinlock_t		j_state_lock;
+
+	/*
+	 * Number of processes waiting to create a barrier lock [j_state_lock]
+	 */
 	int			j_barrier_count;
-	
+
 	/* The barrier lock itself */
 	struct semaphore	j_barrier;
-	
-	/* Transactions: The current running transaction... */
-	transaction_t *		j_running_transaction;
-	
-	/* ... the transaction we are pushing to disk ... */
-	transaction_t *		j_committing_transaction;
-	
-	/* ... and a linked circular list of all transactions waiting */
-	/* for checkpointing. */
-	/* Protected by journal_datalist_lock */
-	transaction_t *		j_checkpoint_transactions;
 
-	/* Wait queue for waiting for a locked transaction to start */
-        /*  committing, or for a barrier lock to be released */
+	/*
+	 * Transactions: The current running transaction...
+	 * [j_state_lock] [caller holding open handle]
+	 */
+	transaction_t		*j_running_transaction;
+
+	/*
+	 * the transaction we are pushing to disk
+	 * [j_state_lock] [caller holding open handle]
+	 */
+	transaction_t		*j_committing_transaction;
+
+	/*
+	 * ... and a linked circular list of all transactions waiting for
+	 * checkpointing. [j_list_lock]
+	 */
+	transaction_t		*j_checkpoint_transactions;
+
+	/*
+	 * Wait queue for waiting for a locked transaction to start committing,
+	 * or for a barrier lock to be released
+	 */
 	wait_queue_head_t	j_wait_transaction_locked;
-	
+
 	/* Wait queue for waiting for checkpointing to complete */
 	wait_queue_head_t	j_wait_logspace;
-	
+
 	/* Wait queue for waiting for commit to complete */
 	wait_queue_head_t	j_wait_done_commit;
-	
+
 	/* Wait queue to trigger checkpointing */
 	wait_queue_head_t	j_wait_checkpoint;
-	
+
 	/* Wait queue to trigger commit */
 	wait_queue_head_t	j_wait_commit;
-	
+
 	/* Wait queue to wait for updates to complete */
 	wait_queue_head_t	j_wait_updates;
 
 	/* Semaphore for locking against concurrent checkpoints */
 	struct semaphore 	j_checkpoint_sem;
 
-	/* The main journal lock, used by lock_journal() */
-	struct semaphore	j_sem;
-		
-	/* Journal head: identifies the first unused block in the journal. */
+	/*
+	 * Journal head: identifies the first unused block in the journal.
+	 * [j_state_lock]
+	 */
 	unsigned long		j_head;
-	
-	/* Journal tail: identifies the oldest still-used block in the */
-	/* journal. */
+
+	/*
+	 * Journal tail: identifies the oldest still-used block in the journal.
+	 * [j_state_lock]
+	 */
 	unsigned long		j_tail;
 
-	/* Journal free: how many free blocks are there in the journal? */
+	/*
+	 * Journal free: how many free blocks are there in the journal?
+	 * [j_state_lock]
+	 */
 	unsigned long		j_free;
 
-	/* Journal start and end: the block numbers of the first usable */
-	/* block and one beyond the last usable block in the journal.   */
-	unsigned long		j_first, j_last;
-
-	/* Device, blocksize and starting block offset for the location */
-	/* where we store the journal. */
-	struct block_device *	j_dev;
+	/*
+	 * Journal start and end: the block numbers of the first usable block
+	 * and one beyond the last usable block in the journal. [j_state_lock]
+	 */
+	unsigned long		j_first;
+	unsigned long		j_last;
+
+	/*
+	 * Device, blocksize and starting block offset for the location where we
+	 * store the journal.
+	 */
+	struct block_device	*j_dev;
 	int			j_blocksize;
 	unsigned int		j_blk_offset;
 
-	/* Device which holds the client fs.  For internal journal this */
-	/* will be equal to j_dev. */
-	struct block_device *	j_fs_dev;
+	/*
+	 * Device which holds the client fs.  For internal journal this will be
+	 * equal to j_dev.
+	 */
+	struct block_device	*j_fs_dev;
 
 	/* Total maximum capacity of the journal region on disk. */
 	unsigned int		j_maxlen;
 
+	/*
+	 * Protects the buffer lists and internal buffer state.
+	 */
+	spinlock_t		j_list_lock;
+
 	/* Optional inode where we store the journal.  If present, all */
 	/* journal block numbers are mapped into this inode via */
 	/* bmap(). */
-	struct inode *		j_inode;
+	struct inode		*j_inode;
 
-	/* Sequence number of the oldest transaction in the log */
+	/*
+	 * Sequence number of the oldest transaction in the log [j_state_lock]
+	 */
 	tid_t			j_tail_sequence;
-	/* Sequence number of the next transaction to grant */
+
+	/*
+	 * Sequence number of the next transaction to grant [j_state_lock]
+	 */
 	tid_t			j_transaction_sequence;
-	/* Sequence number of the most recently committed transaction */
+
+	/*
+	 * Sequence number of the most recently committed transaction
+	 * [j_state_lock].
+	 */
 	tid_t			j_commit_sequence;
-	/* Sequence number of the most recent transaction wanting commit */
-	tid_t			j_commit_request;
 
-	/* Journal uuid: identifies the object (filesystem, LVM volume   */
-	/* etc) backed by this journal.  This will eventually be         */
-	/* replaced by an array of uuids, allowing us to index multiple  */
-	/* devices within a single journal and to perform atomic updates */
-	/* across them.  */
+	/*
+	 * Sequence number of the most recent transaction wanting commit
+	 * [j_state_lock]
+	 */
+	tid_t			j_commit_request;
 
+	/*
+	 * Journal uuid: identifies the object (filesystem, LVM volume etc)
+	 * backed by this journal.  This will eventually be replaced by an array
+	 * of uuids, allowing us to index multiple devices within a single
+	 * journal and to perform atomic updates across them.
+	 */
 	__u8			j_uuid[16];
 
 	/* Pointer to the current commit thread for this journal */
-	struct task_struct *	j_task;
+	struct task_struct	*j_task;
 
-	/* Maximum number of metadata buffers to allow in a single */
-	/* compound commit transaction */
+	/*
+	 * Maximum number of metadata buffers to allow in a single compound
+	 * commit transaction
+	 */
 	int			j_max_transaction_buffers;
 
-	/* What is the maximum transaction lifetime before we begin a */
-	/* commit? */
+	/*
+	 * What is the maximum transaction lifetime before we begin a commit?
+	 */
 	unsigned long		j_commit_interval;
 
 	/* The timer used to wakeup the commit thread: */
-	struct timer_list *	j_commit_timer;
-	int			j_commit_timer_active;
+	struct timer_list	*j_commit_timer;
 
-	/* Link all journals together - system-wide */
-	struct list_head	j_all_journals;
-
-	/* The revoke table: maintains the list of revoked blocks in the */
-        /*  current transaction. */
+	/*
+	 * The revoke table: maintains the list of revoked blocks in the
+	 * current transaction.  [j_revoke_lock]
+	 */
+	spinlock_t		j_revoke_lock;
 	struct jbd_revoke_table_s *j_revoke;
+	struct jbd_revoke_table_s *j_revoke_table[2];
 
-	/* An opaque pointer to fs-private information.  ext3 puts its
-	 * superblock pointer here */
+	/*
+	 * An opaque pointer to fs-private information.  ext3 puts its
+	 * superblock pointer here
+	 */
 	void *j_private;
 };
 
@@ -681,10 +832,10 @@
  */
 
 /* Filing buffers */
+extern void journal_unfile_buffer(journal_t *, struct journal_head *);
 extern void __journal_unfile_buffer(struct journal_head *);
-extern void journal_unfile_buffer(struct journal_head *);
 extern void __journal_refile_buffer(struct journal_head *);
-extern void journal_refile_buffer(struct journal_head *);
+extern void journal_refile_buffer(journal_t *, struct journal_head *);
 extern void __journal_file_buffer(struct journal_head *, transaction_t *, int);
 extern void __journal_free_buffer(struct journal_head *bh);
 extern void journal_file_buffer(struct journal_head *, transaction_t *, int);
@@ -699,10 +850,8 @@
 
 /* Checkpoint list management */
 int __journal_clean_checkpoint_list(journal_t *journal);
-extern void journal_remove_checkpoint(struct journal_head *);
-extern void __journal_remove_checkpoint(struct journal_head *);
-extern void journal_insert_checkpoint(struct journal_head *, transaction_t *);
-extern void __journal_insert_checkpoint(struct journal_head *,transaction_t *);
+void __journal_remove_checkpoint(struct journal_head *);
+void __journal_insert_checkpoint(struct journal_head *, transaction_t *);
 
 /* Buffer IO */
 extern int 
@@ -717,34 +866,14 @@
 /*
  * Journal locking.
  *
- * We need to lock the journal during transaction state changes so that
- * nobody ever tries to take a handle on the running transaction while
- * we are in the middle of moving it to the commit phase.  
+ * We need to lock the journal during transaction state changes so that nobody
+ * ever tries to take a handle on the running transaction while we are in the
+ * middle of moving it to the commit phase.  j_state_lock does this.
  *
  * Note that the locking is completely interrupt unsafe.  We never touch
  * journal structures from interrupts.
- *
- * In 2.2, the BKL was required for lock_journal.  This is no longer
- * the case.
  */
 
-static inline void lock_journal(journal_t *journal)
-{
-	down(&journal->j_sem);
-}
-
-/* This returns zero if we acquired the semaphore */
-static inline int try_lock_journal(journal_t * journal)
-{
-	return down_trylock(&journal->j_sem);
-}
-
-static inline void unlock_journal(journal_t * journal)
-{
-	up(&journal->j_sem);
-}
-
-
 static inline handle_t *journal_current_handle(void)
 {
 	return current->journal_info;
@@ -759,12 +888,15 @@
 extern handle_t *journal_start(journal_t *, int nblocks);
 extern int	 journal_restart (handle_t *, int nblocks);
 extern int	 journal_extend (handle_t *, int nblocks);
-extern int	 journal_get_write_access (handle_t *, struct buffer_head *);
+extern int	 journal_get_write_access(handle_t *, struct buffer_head *,
+						int *credits);
 extern int	 journal_get_create_access (handle_t *, struct buffer_head *);
-extern int	 journal_get_undo_access (handle_t *, struct buffer_head *);
+extern int	 journal_get_undo_access(handle_t *, struct buffer_head *,
+						int *credits);
 extern int	 journal_dirty_data (handle_t *, struct buffer_head *);
 extern int	 journal_dirty_metadata (handle_t *, struct buffer_head *);
-extern void	 journal_release_buffer (handle_t *, struct buffer_head *);
+extern void	 journal_release_buffer (handle_t *, struct buffer_head *,
+						int credits);
 extern void	 journal_forget (handle_t *, struct buffer_head *);
 extern void	 journal_sync_buffer (struct buffer_head *);
 extern int	 journal_invalidatepage(journal_t *,
@@ -809,11 +941,10 @@
 /*
  * journal_head management
  */
-extern struct journal_head
-		*journal_add_journal_head(struct buffer_head *bh);
-extern void	journal_remove_journal_head(struct buffer_head *bh);
-extern void	__journal_remove_journal_head(struct buffer_head *bh);
-extern void	journal_unlock_journal_head(struct journal_head *jh);
+struct journal_head *journal_add_journal_head(struct buffer_head *bh);
+struct journal_head *journal_grab_journal_head(struct buffer_head *bh);
+void journal_remove_journal_head(struct buffer_head *bh);
+void journal_put_journal_head(struct journal_head *jh);
 
 /*
  * handle management
@@ -843,29 +974,30 @@
 extern void	   journal_write_revoke_records(journal_t *, transaction_t *);
 
 /* Recovery revoke support */
-extern int	   journal_set_revoke(journal_t *, unsigned long, tid_t);
-extern int	   journal_test_revoke(journal_t *, unsigned long, tid_t);
-extern void	   journal_clear_revoke(journal_t *);
-extern void	   journal_brelse_array(struct buffer_head *b[], int n);
+extern int	journal_set_revoke(journal_t *, unsigned long, tid_t);
+extern int	journal_test_revoke(journal_t *, unsigned long, tid_t);
+extern void	journal_clear_revoke(journal_t *);
+extern void	journal_brelse_array(struct buffer_head *b[], int n);
+extern void	journal_switch_revoke_table(journal_t *journal);
 
-/* The log thread user interface:
+/*
+ * The log thread user interface:
  *
  * Request space in the current transaction, and force transaction commit
  * transitions on demand.
  */
 
-extern int	log_space_left (journal_t *); /* Called with journal locked */
-extern tid_t	log_start_commit (journal_t *, transaction_t *);
-extern int	log_wait_commit (journal_t *, tid_t);
-extern int	log_do_checkpoint (journal_t *, int);
+int __log_space_left(journal_t *); /* Called with journal locked */
+int log_start_commit(journal_t *journal, tid_t tid);
+int __log_start_commit(journal_t *journal, tid_t tid);
+int journal_start_commit(journal_t *journal, tid_t *tid);
+int log_wait_commit(journal_t *journal, tid_t tid);
+int log_do_checkpoint(journal_t *journal, int nblocks);
 
-extern void	log_wait_for_space(journal_t *, int nblocks);
+void __log_wait_for_space(journal_t *journal, int nblocks);
 extern void	__journal_drop_transaction(journal_t *, transaction_t *);
 extern int	cleanup_journal_tail(journal_t *);
 
-/* Reduce journal memory usage by flushing */
-extern void shrink_journal_memory(void);
-
 /* Debugging code only: */
 
 #define jbd_ENOSYS() \
@@ -940,50 +1072,6 @@
 
 #ifdef __KERNEL__
 
-extern spinlock_t jh_splice_lock;
-/*
- * Once `expr1' has been found true, take jh_splice_lock
- * and then reevaluate everything.
- */
-#define SPLICE_LOCK(expr1, expr2)				\
-	({							\
-		int ret = (expr1);				\
-		if (ret) {					\
-			spin_lock(&jh_splice_lock);		\
-			ret = (expr1) && (expr2);		\
-			spin_unlock(&jh_splice_lock);		\
-		}						\
-		ret;						\
-	})
-
-/*
- * A number of buffer state predicates.  They test for
- * buffer_jbd() because they are used in core kernel code.
- *
- * These will be racy on SMP unless we're *sure* that the
- * buffer won't be detached from the journalling system
- * in parallel.
- */
-
-/* Return true if the buffer is on journal list `list' */
-static inline int buffer_jlist_eq(struct buffer_head *bh, int list)
-{
-	return SPLICE_LOCK(buffer_jbd(bh), bh2jh(bh)->b_jlist == list);
-}
-
-/* Return true if this bufer is dirty wrt the journal */
-static inline int buffer_jdirty(struct buffer_head *bh)
-{
-	return buffer_jbd(bh) && buffer_jbddirty(bh);
-}
-
-/* Return true if it's a data buffer which journalling is managing */
-static inline int buffer_jbd_data(struct buffer_head *bh)
-{
-	return SPLICE_LOCK(buffer_jbd(bh),
-			bh2jh(bh)->b_jlist == BJ_SyncData);
-}
-
 #ifdef CONFIG_SMP
 #define assert_spin_locked(lock)	J_ASSERT(spin_is_locked(lock))
 #else
@@ -1011,7 +1099,6 @@
 #define J_ASSERT(expr)			do {} while (0)
 #define J_ASSERT_BH(bh, expr)		do {} while (0)
 #define buffer_jbd(bh)			0
-#define buffer_jlist_eq(bh, val)	0
 #define journal_buffer_journal_lru(bh)	0
 
 #endif	/* defined(__KERNEL__) && !defined(CONFIG_JBD) */
diff -Nru a/include/linux/journal-head.h b/include/linux/journal-head.h
--- a/include/linux/journal-head.h	Wed Jun 18 23:42:09 2003
+++ b/include/linux/journal-head.h	Wed Jun 18 23:42:09 2003
@@ -3,7 +3,7 @@
  *
  * buffer_head fields for JBD
  *
- * 27 May 2001 ANdrew Morton <andrewm@uow.edu.au>
+ * 27 May 2001 Andrew Morton <akpm@digeo.com>
  *	Created - pulled out of fs.h
  */
 
@@ -15,55 +15,70 @@
 struct buffer_head;
 
 struct journal_head {
-#ifndef CONFIG_JBD_UNIFIED_BUFFERS
-	/* Points back to our buffer_head. */
+	/*
+	 * Points back to our buffer_head. [jbd_lock_bh_journal_head()]
+	 */
 	struct buffer_head *b_bh;
-#endif
 
-	/* Reference count - see description in journal.c */
+	/*
+	 * Reference count - see description in journal.c
+	 * [jbd_lock_bh_journal_head()]
+	 */
 	int b_jcount;
 
-	/* Journaling list for this buffer */
+	/*
+	 * Journalling list for this buffer [jbd_lock_bh_state()]
+	 */
 	unsigned b_jlist;
 
-	/* Copy of the buffer data frozen for writing to the log. */
-	char * b_frozen_data;
+	/*
+	 * Copy of the buffer data frozen for writing to the log.
+	 * [jbd_lock_bh_state()]
+	 */
+	char *b_frozen_data;
+
+	/*
+	 * Pointer to a saved copy of the buffer containing no uncommitted
+	 * deallocation references, so that allocations can avoid overwriting
+	 * uncommitted deletes. [jbd_lock_bh_state()]
+	 */
+	char *b_committed_data;
+
+	/*
+	 * Pointer to the compound transaction which owns this buffer's
+	 * metadata: either the running transaction or the committing
+	 * transaction (if there is one).  Only applies to buffers on a
+	 * transaction's data or metadata journaling list.
+	 * [j_list_lock] [jbd_lock_bh_state()]
+	 */
+	transaction_t *b_transaction;
+
+	/*
+	 * Pointer to the running compound transaction which is currently
+	 * modifying the buffer's metadata, if there was already a transaction
+	 * committing it when the new transaction touched it.
+	 * [t_list_lock] [jbd_lock_bh_state()]
+	 */
+	transaction_t *b_next_transaction;
 
-	/* Pointer to a saved copy of the buffer containing no
-           uncommitted deallocation references, so that allocations can
-           avoid overwriting uncommitted deletes. */
-	char * b_committed_data;
-
-	/* Pointer to the compound transaction which owns this buffer's
-           metadata: either the running transaction or the committing
-           transaction (if there is one).  Only applies to buffers on a
-           transaction's data or metadata journaling list. */
-	/* Protected by journal_datalist_lock */
-	transaction_t * b_transaction;
-	
-	/* Pointer to the running compound transaction which is
-           currently modifying the buffer's metadata, if there was
-           already a transaction committing it when the new transaction
-           touched it. */
-	transaction_t * b_next_transaction;
-	
-	/* Doubly-linked list of buffers on a transaction's data,
-           metadata or forget queue. */
-	/* Protected by journal_datalist_lock */
+	/*
+	 * Doubly-linked list of buffers on a transaction's data, metadata or
+	 * forget queue. [t_list_lock] [jbd_lock_bh_state()]
+	 */
 	struct journal_head *b_tnext, *b_tprev;
 
 	/*
 	 * Pointer to the compound transaction against which this buffer
 	 * is checkpointed.  Only dirty buffers can be checkpointed.
+	 * [j_list_lock]
 	 */
-	/* Protected by journal_datalist_lock */
-	transaction_t * b_cp_transaction;
-	
+	transaction_t *b_cp_transaction;
+
 	/*
 	 * Doubly-linked list of buffers still remaining to be flushed
 	 * before an old transaction can be checkpointed.
+	 * [j_list_lock]
 	 */
-	/* Protected by journal_datalist_lock */
 	struct journal_head *b_cpnext, *b_cpprev;
 };
 
diff -Nru a/include/linux/nfsd/nfsd.h b/include/linux/nfsd/nfsd.h
--- a/include/linux/nfsd/nfsd.h	Wed Jun 18 23:42:09 2003
+++ b/include/linux/nfsd/nfsd.h	Wed Jun 18 23:42:09 2003
@@ -69,6 +69,8 @@
 int		fh_lock_parent(struct svc_fh *, struct dentry *);
 int		nfsd_racache_init(int);
 void		nfsd_racache_shutdown(void);
+int		nfsd_cross_mnt(struct svc_rqst *rqstp, struct dentry **dpp,
+		                struct svc_export **expp);
 int		nfsd_lookup(struct svc_rqst *, struct svc_fh *,
 				const char *, int, struct svc_fh *);
 int		nfsd_setattr(struct svc_rqst *, struct svc_fh *,
@@ -226,6 +228,7 @@
 #define COMPOUND_ERR_SLACK_SPACE	12     /* OP_SETATTR */
 
 #define NFSD_LEASE_TIME			60  /* seconds */
+#define NFSD_LAUNDROMAT_MINTIMEOUT      10   /* seconds */
 
 /*
  * The following attributes are currently not supported by the NFSv4 server:
diff -Nru a/include/linux/nfsd/state.h b/include/linux/nfsd/state.h
--- a/include/linux/nfsd/state.h	Wed Jun 18 23:42:05 2003
+++ b/include/linux/nfsd/state.h	Wed Jun 18 23:42:05 2003
@@ -73,13 +73,18 @@
 	struct list_head	cl_idhash; 	/* hash by cl_clientid.id */
 	struct list_head	cl_strhash; 	/* hash by cl_name */
 	struct list_head	cl_perclient; 	/* list: stateowners */
+	struct list_head        cl_lru;         /* tail queue */
 	struct xdr_netobj	cl_name; 	/* id generated by client */
 	nfs4_verifier		cl_verifier; 	/* generated by client */
+	time_t                  cl_time;        /* time of last lease renewal */
 	u32			cl_addr; 	/* client ipaddress */
 	struct svc_cred		cl_cred; 	/* setclientid principal */
 	clientid_t		cl_clientid;	/* generated by server */
 	nfs4_verifier		cl_confirm;	/* generated by server */
 };
+
+extern time_t nfs4_laundromat(void);
+int nfsd4_renew(clientid_t *clid);
 
 static inline void
 update_stateid(stateid_t *stateid)
diff -Nru a/include/linux/page-flags.h b/include/linux/page-flags.h
--- a/include/linux/page-flags.h	Wed Jun 18 23:42:08 2003
+++ b/include/linux/page-flags.h	Wed Jun 18 23:42:08 2003
@@ -200,6 +200,7 @@
 
 #define PageChecked(page)	test_bit(PG_checked, &(page)->flags)
 #define SetPageChecked(page)	set_bit(PG_checked, &(page)->flags)
+#define ClearPageChecked(page)	clear_bit(PG_checked, &(page)->flags)
 
 #define PageReserved(page)	test_bit(PG_reserved, &(page)->flags)
 #define SetPageReserved(page)	set_bit(PG_reserved, &(page)->flags)
diff -Nru a/include/linux/rmap-locking.h b/include/linux/rmap-locking.h
--- a/include/linux/rmap-locking.h	Wed Jun 18 23:42:06 2003
+++ b/include/linux/rmap-locking.h	Wed Jun 18 23:42:06 2003
@@ -10,32 +10,8 @@
 struct pte_chain;
 extern kmem_cache_t *pte_chain_cache;
 
-static inline void pte_chain_lock(struct page *page)
-{
-	/*
-	 * Assuming the lock is uncontended, this never enters
-	 * the body of the outer loop. If it is contended, then
-	 * within the inner loop a non-atomic test is used to
-	 * busywait with less bus contention for a good time to
-	 * attempt to acquire the lock bit.
-	 */
-	preempt_disable();
-#ifdef CONFIG_SMP
-	while (test_and_set_bit(PG_chainlock, &page->flags)) {
-		while (test_bit(PG_chainlock, &page->flags))
-			cpu_relax();
-	}
-#endif
-}
-
-static inline void pte_chain_unlock(struct page *page)
-{
-#ifdef CONFIG_SMP
-	smp_mb__before_clear_bit();
-	clear_bit(PG_chainlock, &page->flags);
-#endif
-	preempt_enable();
-}
+#define pte_chain_lock(page)	bit_spin_lock(PG_chainlock, &page->flags)
+#define pte_chain_unlock(page)	bit_spin_unlock(PG_chainlock, &page->flags)
 
 struct pte_chain *pte_chain_alloc(int gfp_flags);
 void __pte_chain_free(struct pte_chain *pte_chain);
diff -Nru a/include/linux/skbuff.h b/include/linux/skbuff.h
--- a/include/linux/skbuff.h	Wed Jun 18 23:42:07 2003
+++ b/include/linux/skbuff.h	Wed Jun 18 23:42:07 2003
@@ -16,6 +16,7 @@
 
 #include <linux/config.h>
 #include <linux/kernel.h>
+#include <linux/compiler.h>
 #include <linux/time.h>
 #include <linux/cache.h>
 
@@ -1127,7 +1128,11 @@
  *	If there is no free memory -ENOMEM is returned, otherwise zero
  *	is returned and the old skb data released.
  */
-int skb_linearize(struct sk_buff *skb, int gfp);
+extern int __skb_linearize(struct sk_buff *skb, int gfp);
+static inline int __deprecated skb_linearize(struct sk_buff *skb, int gfp)
+{
+	return __skb_linearize(skb, gfp);
+}
 
 static inline void *kmap_skb_frag(const skb_frag_t *frag)
 {
diff -Nru a/include/linux/spinlock.h b/include/linux/spinlock.h
--- a/include/linux/spinlock.h	Wed Jun 18 23:42:07 2003
+++ b/include/linux/spinlock.h	Wed Jun 18 23:42:07 2003
@@ -395,4 +395,74 @@
 extern int atomic_dec_and_lock(atomic_t *atomic, spinlock_t *lock);
 #endif
 
+/*
+ *  bit-based spin_lock()
+ *
+ * Don't use this unless you really need to: spin_lock() and spin_unlock()
+ * are significantly faster.
+ */
+static inline void bit_spin_lock(int bitnum, unsigned long *addr)
+{
+	/*
+	 * Assuming the lock is uncontended, this never enters
+	 * the body of the outer loop. If it is contended, then
+	 * within the inner loop a non-atomic test is used to
+	 * busywait with less bus contention for a good time to
+	 * attempt to acquire the lock bit.
+	 */
+	preempt_disable();
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+	while (test_and_set_bit(bitnum, addr)) {
+		while (test_bit(bitnum, addr))
+			cpu_relax();
+	}
+#endif
+}
+
+/*
+ * Return true if it was acquired
+ */
+static inline int bit_spin_trylock(int bitnum, unsigned long *addr)
+{
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+	int ret;
+
+	preempt_disable();
+	ret = !test_and_set_bit(bitnum, addr);
+	if (!ret)
+		preempt_enable();
+	return ret;
+#else
+	preempt_disable();
+	return 1;
+#endif
+}
+
+/*
+ *  bit-based spin_unlock()
+ */
+static inline void bit_spin_unlock(int bitnum, unsigned long *addr)
+{
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+	BUG_ON(!test_bit(bitnum, addr));
+	smp_mb__before_clear_bit();
+	clear_bit(bitnum, addr);
+#endif
+	preempt_enable();
+}
+
+/*
+ * Return true if the lock is held.
+ */
+static inline int bit_spin_is_locked(int bitnum, unsigned long *addr)
+{
+#if defined(CONFIG_SMP) || defined(CONFIG_DEBUG_SPINLOCK)
+	return test_bit(bitnum, addr);
+#elif defined CONFIG_PREEMPT
+	return preempt_count();
+#else
+	return 1;
+#endif
+}
+
 #endif /* __LINUX_SPINLOCK_H */
diff -Nru a/include/linux/sunrpc/cache.h b/include/linux/sunrpc/cache.h
--- a/include/linux/sunrpc/cache.h	Wed Jun 18 23:42:07 2003
+++ b/include/linux/sunrpc/cache.h	Wed Jun 18 23:42:07 2003
@@ -115,6 +115,8 @@
 	struct list_head	recent; /* on fifo */
 	struct cache_head	*item;  /* cache item we wait on */
 	time_t			recv_time;
+	void			*owner; /* we might need to discard all defered requests
+					 * owned by someone */
 	void			(*revisit)(struct cache_deferred_req *req,
 					   int too_many);
 };
@@ -168,12 +170,14 @@
 		tmp = container_of(*hp, RTN, MEMBER);					\
 		if (TEST) { /* found a match */						\
 											\
+			if (set == 1 && test_bit(CACHE_VALID, &tmp->MEMBER.flags) && !new) \
+				break;							\
+											\
 			atomic_inc(&tmp->MEMBER.refcnt);				\
 			if (set) {							\
-				if (set!= 2 && test_bit(CACHE_VALID, &tmp->MEMBER.flags))\
+				if (set == 1 && test_bit(CACHE_VALID, &tmp->MEMBER.flags))\
 				{ /* need to swap in new */				\
 					RTN *t2;					\
-					if (!new) break;				\
 											\
 					new->MEMBER.next = tmp->MEMBER.next;		\
 					*hp = &new->MEMBER;				\
@@ -242,6 +246,7 @@
 
 extern void cache_defer_req(struct cache_req *req, struct cache_head *item);
 extern void cache_revisit_request(struct cache_head *item);
+extern void cache_clean_deferred(void *owner);
 
 static inline struct cache_head  *cache_get(struct cache_head *h)
 {
diff -Nru a/include/linux/sunrpc/svc.h b/include/linux/sunrpc/svc.h
--- a/include/linux/sunrpc/svc.h	Wed Jun 18 23:42:07 2003
+++ b/include/linux/sunrpc/svc.h	Wed Jun 18 23:42:07 2003
@@ -125,7 +125,6 @@
 	u32			rq_proc;	/* procedure number */
 	u32			rq_prot;	/* IP protocol */
 	unsigned short
-				rq_userset : 1,	/* auth->setuser OK */
 				rq_secure  : 1;	/* secure port */
 
 
@@ -196,14 +195,14 @@
 
 static inline void svc_pushback_unused_pages(struct svc_rqst *rqstp)
 {
-        while (rqstp->rq_resused) {
+	while (rqstp->rq_resused &&
+	       rqstp->rq_res.pages != &rqstp->rq_respages[rqstp->rq_resused]) {
+
 		if (rqstp->rq_respages[--rqstp->rq_resused] != NULL) {
 			rqstp->rq_argpages[rqstp->rq_arghi++] =
 				rqstp->rq_respages[rqstp->rq_resused];
 			rqstp->rq_respages[rqstp->rq_resused] = NULL;
 		}
-		if (rqstp->rq_res.pages == &rqstp->rq_respages[rqstp->rq_resused])
-			break;
 	}
 }
 
@@ -218,7 +217,6 @@
 }
 
 struct svc_deferred_req {
-	struct svc_serv		*serv;
 	u32			prot;	/* protocol (UDP or TCP) */
 	struct sockaddr_in	addr;
 	struct svc_sock		*svsk;	/* where reply must go */
diff -Nru a/include/linux/tcp.h b/include/linux/tcp.h
--- a/include/linux/tcp.h	Wed Jun 18 23:42:07 2003
+++ b/include/linux/tcp.h	Wed Jun 18 23:42:07 2003
@@ -219,7 +219,7 @@
  	__u32	snd_sml;	/* Last byte of the most recently transmitted small packet */
 	__u32	rcv_tstamp;	/* timestamp of last received ACK (for keepalives) */
 	__u32	lsndtime;	/* timestamp of last sent data packet (for restart window) */
-
+	struct tcp_bind_bucket *bind_hash;
 	/* Delayed ACK control data */
 	struct {
 		__u8	pending;	/* ACK is pending */
diff -Nru a/include/linux/usb.h b/include/linux/usb.h
--- a/include/linux/usb.h	Wed Jun 18 23:42:07 2003
+++ b/include/linux/usb.h	Wed Jun 18 23:42:07 2003
@@ -492,8 +492,9 @@
  */
 #define URB_SHORT_NOT_OK	0x0001	/* report short reads as errors */
 #define URB_ISO_ASAP		0x0002	/* iso-only, urb->start_frame ignored */
-#define URB_NO_DMA_MAP		0x0004	/* urb->*_dma are valid on submit */
-#define URB_ASYNC_UNLINK	0x0008	/* usb_unlink_urb() returns asap */
+#define URB_NO_TRANSFER_DMA_MAP	0x0004	/* urb->transfer_dma valid on submit */
+#define URB_NO_SETUP_DMA_MAP	0x0008	/* urb->setup_dma valid on submit */
+#define URB_ASYNC_UNLINK	0x0010	/* usb_unlink_urb() returns asap */
 #define URB_NO_FSBR		0x0020	/* UHCI-specific */
 #define URB_ZERO_PACKET		0x0040	/* Finish bulk OUTs with short packet */
 #define URB_NO_INTERRUPT	0x0080	/* HINT: no non-error interrupt needed */
@@ -531,14 +532,15 @@
  *	submission, unlinking, or operation are handled.  Different
  *	kinds of URB can use different flags.
  * @transfer_buffer:  This identifies the buffer to (or from) which
- * 	the I/O request will be performed (unless URB_NO_DMA_MAP is set).
- *	This buffer must be suitable for DMA; allocate it with kmalloc()
- *	or equivalent.  For transfers to "in" endpoints, contents of
- *	this buffer will be modified.  This buffer is used for data
+ * 	the I/O request will be performed (unless URB_NO_TRANSFER_DMA_MAP
+ *	is set).  This buffer must be suitable for DMA; allocate it with
+ *	kmalloc() or equivalent.  For transfers to "in" endpoints, contents
+ *	of this buffer will be modified.  This buffer is used for data
  *	phases of control transfers.
- * @transfer_dma: When transfer_flags includes URB_NO_DMA_MAP, the device
- * 	driver is saying that it provided this DMA address, which the host
- * 	controller driver should use instead of the transfer_buffer.
+ * @transfer_dma: When transfer_flags includes URB_NO_TRANSFER_DMA_MAP,
+ *	the device driver is saying that it provided this DMA address,
+ *	which the host controller driver should use in preference to the
+ *	transfer_buffer.
  * @transfer_buffer_length: How big is transfer_buffer.  The transfer may
  *	be broken up into chunks according to the current maximum packet
  *	size for the endpoint, which is a function of the configuration
@@ -553,11 +555,10 @@
  * @setup_packet: Only used for control transfers, this points to eight bytes
  *	of setup data.  Control transfers always start by sending this data
  *	to the device.  Then transfer_buffer is read or written, if needed.
- *	(Not used when URB_NO_DMA_MAP is set.)
- * @setup_dma: For control transfers with URB_NO_DMA_MAP set, the device
- * 	driver has provided this DMA address for the setup packet.  The
- * 	host controller driver should use this instead of setup_buffer.
- * 	If there is a data phase, its buffer is identified by transfer_dma.
+ * @setup_dma: For control transfers with URB_NO_SETUP_DMA_MAP set, the
+ *	device driver has provided this DMA address for the setup packet.
+ *	The host controller driver should use this in preference to
+ *	setup_packet.
  * @start_frame: Returns the initial frame for interrupt or isochronous
  *	transfers.
  * @number_of_packets: Lists the number of ISO transfer buffers.
@@ -589,13 +590,15 @@
  * bounce buffer or talking to an IOMMU),
  * although they're cheap on commodity x86 and ppc hardware.
  *
- * Alternatively, drivers may pass the URB_NO_DMA_MAP transfer flag, which
- * tells the host controller driver that no such mapping is needed since
- * the device driver is DMA-aware.  For example, they might allocate a DMA
- * buffer with usb_buffer_alloc(), or call usb_buffer_map().
- * When this transfer flag is provided, host controller drivers will use the
- * dma addresses found in the transfer_dma and/or setup_dma fields rather than
- * determing a dma address themselves.
+ * Alternatively, drivers may pass the URB_NO_xxx_DMA_MAP transfer flags,
+ * which tell the host controller driver that no such mapping is needed since
+ * the device driver is DMA-aware.  For example, a device driver might
+ * allocate a DMA buffer with usb_buffer_alloc() or call usb_buffer_map().
+ * When these transfer flags are provided, host controller drivers will
+ * attempt to use the dma addresses found in the transfer_dma and/or
+ * setup_dma fields rather than determining a dma address themselves.  (Note
+ * that transfer_buffer and setup_packet must still be set because not all
+ * host controllers use DMA, nor do virtual root hubs).
  *
  * Initialization:
  *
@@ -614,7 +617,11 @@
  * should always terminate with a short packet, even if it means adding an
  * extra zero length packet.
  *
- * Control URBs must provide a setup_packet.
+ * Control URBs must provide a setup_packet.  The setup_packet and
+ * transfer_buffer may each be mapped for DMA or not, independently of
+ * the other.  The transfer_flags bits URB_NO_TRANSFER_DMA_MAP and
+ * URB_NO_SETUP_DMA_MAP indicate which buffers have already been mapped.
+ * URB_NO_SETUP_DMA_MAP is ignored for non-control URBs.
  *
  * Interrupt UBS must provide an interval, saying how often (in milliseconds
  * or, for highspeed devices, 125 microsecond units)
diff -Nru a/include/net/llc_pdu.h b/include/net/llc_pdu.h
--- a/include/net/llc_pdu.h	Wed Jun 18 23:42:08 2003
+++ b/include/net/llc_pdu.h	Wed Jun 18 23:42:08 2003
@@ -39,8 +39,8 @@
 #define LLC_PDU_CMD_RSP_MASK	0x01
 #define LLC_PDU_CMD		0
 #define LLC_PDU_RSP		1
-#define LLC_PDU_IS_CMD(pdu)    ((pdu->ssap & LLC_PDU_RSP) ? 1 : 0)
-#define LLC_PDU_IS_RSP(pdu)    ((pdu->ssap & LLC_PDU_RSP) ? 0 : 1)
+#define LLC_PDU_IS_CMD(pdu)    ((pdu->ssap & LLC_PDU_RSP) ? 0 : 1)
+#define LLC_PDU_IS_RSP(pdu)    ((pdu->ssap & LLC_PDU_RSP) ? 1 : 0)
 
 /* Get PDU type from 2 lowest-order bits of control field first byte */
 #define LLC_PDU_TYPE_I_MASK    0x01	/* 16-bit control field */
@@ -53,18 +53,18 @@
 #define LLC_PDU_TYPE_U	3	/* first two bits */
 
 #define LLC_PDU_TYPE_IS_I(pdu) \
-	((!(pdu->ctrl_1 & LLC_PDU_TYPE_I_MASK)) ? 0 : 1)
+	((!(pdu->ctrl_1 & LLC_PDU_TYPE_I_MASK)) ? 1 : 0)
 
 #define LLC_PDU_TYPE_IS_U(pdu) \
-	(((pdu->ctrl_1 & LLC_PDU_TYPE_U_MASK) == LLC_PDU_TYPE_U) ? 0 : 1)
+	(((pdu->ctrl_1 & LLC_PDU_TYPE_U_MASK) == LLC_PDU_TYPE_U) ? 1 : 0)
 
 #define LLC_PDU_TYPE_IS_S(pdu) \
-	(((pdu->ctrl_1 & LLC_PDU_TYPE_S_MASK) == LLC_PDU_TYPE_S) ? 0 : 1)
+	(((pdu->ctrl_1 & LLC_PDU_TYPE_S_MASK) == LLC_PDU_TYPE_S) ? 1 : 0)
 
 /* U-format PDU control field masks */
 #define LLC_U_PF_BIT_MASK      0x10	/* P/F bit mask */
-#define LLC_U_PF_IS_1(pdu)     ((pdu->ctrl_1 & LLC_U_PF_BIT_MASK) ? 0 : 1)
-#define LLC_U_PF_IS_0(pdu)     ((!(pdu->ctrl_1 & LLC_U_PF_BIT_MASK)) ? 0 : 1)
+#define LLC_U_PF_IS_1(pdu)     ((pdu->ctrl_1 & LLC_U_PF_BIT_MASK) ? 1 : 0)
+#define LLC_U_PF_IS_0(pdu)     ((!(pdu->ctrl_1 & LLC_U_PF_BIT_MASK)) ? 1 : 0)
 
 #define LLC_U_PDU_CMD_MASK     0xEC	/* cmd/rsp mask */
 #define LLC_U_PDU_CMD(pdu)     (pdu->ctrl_1 & LLC_U_PDU_CMD_MASK)
@@ -119,8 +119,8 @@
 
 #define LLC_I_PF_BIT_MASK      0x01
 
-#define LLC_I_PF_IS_0(pdu)     ((!(pdu->ctrl_2 & LLC_I_PF_BIT_MASK)) ? 0 : 1)
-#define LLC_I_PF_IS_1(pdu)     ((pdu->ctrl_2 & LLC_I_PF_BIT_MASK) ? 0 : 1)
+#define LLC_I_PF_IS_0(pdu)     ((!(pdu->ctrl_2 & LLC_I_PF_BIT_MASK)) ? 1 : 0)
+#define LLC_I_PF_IS_1(pdu)     ((pdu->ctrl_2 & LLC_I_PF_BIT_MASK) ? 1 : 0)
 
 /* S-PDU supervisory commands and responses */
 
@@ -136,8 +136,8 @@
 #define LLC_2_PDU_RSP_RNR      0x04	/* rx not ready rsp */
 
 #define LLC_S_PF_BIT_MASK      0x01
-#define LLC_S_PF_IS_0(pdu)     ((!(pdu->ctrl_2 & LLC_S_PF_BIT_MASK)) ? 0 : 1)
-#define LLC_S_PF_IS_1(pdu)     ((pdu->ctrl_2 & LLC_S_PF_BIT_MASK) ? 0 : 1)
+#define LLC_S_PF_IS_0(pdu)     ((!(pdu->ctrl_2 & LLC_S_PF_BIT_MASK)) ? 1 : 0)
+#define LLC_S_PF_IS_1(pdu)     ((pdu->ctrl_2 & LLC_S_PF_BIT_MASK) ? 1 : 0)
 
 #define PDU_SUPV_GET_Nr(pdu)   ((pdu->ctrl_2 & 0xFE) >> 1)
 #define PDU_GET_NEXT_Vr(sn)    (++sn & ~LLC_2_SEQ_NBR_MODULO)
diff -Nru a/include/net/sctp/structs.h b/include/net/sctp/structs.h
--- a/include/net/sctp/structs.h	Wed Jun 18 23:42:09 2003
+++ b/include/net/sctp/structs.h	Wed Jun 18 23:42:09 2003
@@ -313,6 +313,7 @@
 	/* What is our base endpointer? */
 	struct sctp_endpoint *ep;
 
+	struct sctp_bind_bucket *bind_hash;
 	/* Various Socket Options.  */
 	__u16 default_stream;
 	__u32 default_ppid;
diff -Nru a/include/net/sock.h b/include/net/sock.h
--- a/include/net/sock.h	Wed Jun 18 23:42:08 2003
+++ b/include/net/sock.h	Wed Jun 18 23:42:08 2003
@@ -133,7 +133,6 @@
   *	@sk_forward_alloc - space allocated forward
   *	@sk_allocation - allocation mode
   *	@sk_sndbuf - size of send buffer in bytes
-  *	@sk_prev - pointer to previous sock in the list this sock is in
   *	@sk_flags - %SO_LINGER (l_onoff), %SO_BROADCAST, %SO_KEEPALIVE, %SO_OOBINLINE settings
   *	@sk_no_check - %SO_NO_CHECK setting, wether or not checkup packets
   *	@sk_debug - %SO_DEBUG setting
@@ -206,7 +205,6 @@
 	int			sk_forward_alloc;
 	unsigned int		sk_allocation;
 	int			sk_sndbuf;
-	struct sock		*sk_prev;
 	unsigned long 		sk_flags;
 	char		 	sk_no_check;
 	unsigned char		sk_debug;
@@ -291,19 +289,51 @@
 	node->pprev = NULL;
 }
 
-static __inline__ int sk_del_node_init(struct sock *sk)
+static __inline__ void __sk_del_node(struct sock *sk)
+{
+	__hlist_del(&sk->sk_node);
+}
+
+static __inline__ int __sk_del_node_init(struct sock *sk)
 {
 	if (sk_hashed(sk)) {
-		__hlist_del(&sk->sk_node);
+		__sk_del_node(sk);
 		sk_node_init(&sk->sk_node);
 		return 1;
 	}
 	return 0;
 }
 
-static __inline__ void sk_add_node(struct sock *sk, struct hlist_head *list)
+static inline void __sock_put(struct sock *sk);
+
+static __inline__ int sk_del_node_init(struct sock *sk)
+{
+	int rc = __sk_del_node_init(sk);
+
+	if (rc) {
+		/* paranoid for a while -acme */
+		WARN_ON(atomic_read(&sk->sk_refcnt) == 1);
+		__sock_put(sk);
+	}
+	return rc;
+}
+
+static __inline__ void __sk_add_node(struct sock *sk, struct hlist_head *list)
 {
 	hlist_add_head(&sk->sk_node, list);
+}
+
+static inline void sock_hold(struct sock *sk);
+
+static __inline__ void sk_add_node(struct sock *sk, struct hlist_head *list)
+{
+	sock_hold(sk);
+	__sk_add_node(sk, list);
+}
+
+static __inline__ void __sk_del_bind_node(struct sock *sk)
+{
+	__hlist_del(&sk->sk_bind_node);
 }
 
 static __inline__ void sk_add_bind_node(struct sock *sk,
diff -Nru a/include/net/syncppp.h b/include/net/syncppp.h
--- a/include/net/syncppp.h	Wed Jun 18 23:42:06 2003
+++ b/include/net/syncppp.h	Wed Jun 18 23:42:06 2003
@@ -48,6 +48,7 @@
 	struct timer_list	pp_timer;
 	struct net_device	*pp_if;
 	char		pp_link_state;	/* Link status */
+	spinlock_t      lock;
 };
 
 struct ppp_device
diff -Nru a/include/net/tcp.h b/include/net/tcp.h
--- a/include/net/tcp.h	Wed Jun 18 23:42:06 2003
+++ b/include/net/tcp.h	Wed Jun 18 23:42:06 2003
@@ -1475,7 +1475,8 @@
 			TCP_INC_STATS(TcpEstabResets);
 
 		sk->sk_prot->unhash(sk);
-		if (sk->sk_prev && !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
+		if (tcp_sk(sk)->bind_hash &&
+		    !(sk->sk_userlocks & SOCK_BINDPORT_LOCK))
 			tcp_put_port(sk);
 		/* fall through */
 	default:
diff -Nru a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/scsi/scsi_cmnd.h	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,164 @@
+#ifndef _SCSI_SCSI_CMND_H
+#define _SCSI_SCSI_CMND_H
+
+#include <linux/list.h>
+#include <linux/types.h>
+
+struct request;
+struct scatterlist;
+struct scsi_device;
+struct scsi_request;
+
+
+/* embedded in scsi_cmnd */
+struct scsi_pointer {
+	char *ptr;		/* data pointer */
+	int this_residual;	/* left in this buffer */
+	struct scatterlist *buffer;	/* which buffer */
+	int buffers_residual;	/* how many buffers left */
+
+        dma_addr_t dma_handle;
+
+	volatile int Status;
+	volatile int Message;
+	volatile int have_data_in;
+	volatile int sent_command;
+	volatile int phase;
+};
+
+struct scsi_cmnd {
+	int     sc_magic;
+
+	struct scsi_device *device;
+	unsigned short state;
+	unsigned short owner;
+	struct scsi_request *sc_request;
+
+	struct list_head list;  /* scsi_cmnd participates in queue lists */
+
+	struct list_head eh_entry; /* entry for the host eh_cmd_q */
+	int eh_state;		/* Used for state tracking in error handlr */
+	int eh_eflags;		/* Used by error handlr */
+	void (*done) (struct scsi_cmnd *);	/* Mid-level done function */
+
+	/*
+	 * A SCSI Command is assigned a nonzero serial_number when internal_cmnd
+	 * passes it to the driver's queue command function.  The serial_number
+	 * is cleared when scsi_done is entered indicating that the command has
+	 * been completed.  If a timeout occurs, the serial number at the moment
+	 * of timeout is copied into serial_number_at_timeout.  By subsequently
+	 * comparing the serial_number and serial_number_at_timeout fields
+	 * during abort or reset processing, we can detect whether the command
+	 * has already completed.  This also detects cases where the command has
+	 * completed and the SCSI Command structure has already being reused
+	 * for another command, so that we can avoid incorrectly aborting or
+	 * resetting the new command.
+	 */
+	unsigned long serial_number;
+	unsigned long serial_number_at_timeout;
+
+	int retries;
+	int allowed;
+	int timeout_per_command;
+	int timeout_total;
+	int timeout;
+
+	/*
+	 * We handle the timeout differently if it happens when a reset, 
+	 * abort, etc are in process. 
+	 */
+	unsigned volatile char internal_timeout;
+
+	unsigned char cmd_len;
+	unsigned char old_cmd_len;
+	unsigned char sc_data_direction;
+	unsigned char sc_old_data_direction;
+
+	/* These elements define the operation we are about to perform */
+#define MAX_COMMAND_SIZE	16
+	unsigned char cmnd[MAX_COMMAND_SIZE];
+	unsigned request_bufflen;	/* Actual request size */
+
+	struct timer_list eh_timeout;	/* Used to time out the command. */
+	void *request_buffer;		/* Actual requested buffer */
+
+	/* These elements define the operation we ultimately want to perform */
+	unsigned char data_cmnd[MAX_COMMAND_SIZE];
+	unsigned short old_use_sg;	/* We save  use_sg here when requesting
+					 * sense info */
+	unsigned short use_sg;	/* Number of pieces of scatter-gather */
+	unsigned short sglist_len;	/* size of malloc'd scatter-gather list */
+	unsigned short abort_reason;	/* If the mid-level code requests an
+					 * abort, this is the reason. */
+	unsigned bufflen;	/* Size of data buffer */
+	void *buffer;		/* Data buffer */
+
+	unsigned underflow;	/* Return error if less than
+				   this amount is transferred */
+	unsigned old_underflow;	/* save underflow here when reusing the
+				 * command for error handling */
+
+	unsigned transfersize;	/* How much we are guaranteed to
+				   transfer with each SCSI transfer
+				   (ie, between disconnect / 
+				   reconnects.   Probably == sector
+				   size */
+
+	int resid;		/* Number of bytes requested to be
+				   transferred less actual number
+				   transferred (0 if not supported) */
+
+	struct request *request;	/* The command we are
+				   	   working on */
+
+#define SCSI_SENSE_BUFFERSIZE 	64
+	unsigned char sense_buffer[SCSI_SENSE_BUFFERSIZE];		/* obtained by REQUEST SENSE
+						 * when CHECK CONDITION is
+						 * received on original command 
+						 * (auto-sense) */
+
+	unsigned flags;
+
+	/* Low-level done function - can be used by low-level driver to point
+	 *        to completion function.  Not used by mid/upper level code. */
+	void (*scsi_done) (struct scsi_cmnd *);
+
+	/*
+	 * The following fields can be written to by the host specific code. 
+	 * Everything else should be left alone. 
+	 */
+	struct scsi_pointer SCp;	/* Scratchpad used by some host adapters */
+
+	unsigned char *host_scribble;	/* The host adapter is allowed to
+					   * call scsi_malloc and get some memory
+					   * and hang it here.     The host adapter
+					   * is also expected to call scsi_free
+					   * to release this memory.  (The memory
+					   * obtained by scsi_malloc is guaranteed
+					   * to be at an address < 16Mb). */
+
+	int result;		/* Status code from lower level driver */
+
+	unsigned char tag;	/* SCSI-II queued command tag */
+	unsigned long pid;	/* Process ID, starts at 0 */
+};
+
+/*
+ * These are the values that scsi_cmd->state can take.
+ */
+#define SCSI_STATE_TIMEOUT         0x1000
+#define SCSI_STATE_FINISHED        0x1001
+#define SCSI_STATE_FAILED          0x1002
+#define SCSI_STATE_QUEUED          0x1003
+#define SCSI_STATE_UNUSED          0x1006
+#define SCSI_STATE_DISCONNECTING   0x1008
+#define SCSI_STATE_INITIALIZING    0x1009
+#define SCSI_STATE_BHQUEUE         0x100a
+#define SCSI_STATE_MLQUEUE         0x100b
+
+
+extern struct scsi_cmnd *scsi_get_command(struct scsi_device *, int);
+extern void scsi_put_command(struct scsi_cmnd *);
+extern void scsi_io_completion(struct scsi_cmnd *, int, int);
+
+#endif /* _SCSI_SCSI_CMND_H */
diff -Nru a/include/scsi/scsi_device.h b/include/scsi/scsi_device.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/scsi/scsi_device.h	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,106 @@
+#ifndef _SCSI_SCSI_DEVICE_H
+#define _SCSI_SCSI_DEVICE_H
+
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/spinlock.h>
+
+struct request_queue;
+struct scsi_cmnd;
+
+
+struct scsi_device {
+	struct class_device	sdev_classdev;
+
+	struct list_head    siblings;   /* list of all devices on this host */
+	struct list_head    same_target_siblings; /* just the devices sharing same target id */
+	struct Scsi_Host *host;
+	struct request_queue *request_queue;
+	volatile unsigned short device_busy;	/* commands actually active on low-level */
+	spinlock_t sdev_lock;           /* also the request queue_lock */
+	spinlock_t list_lock;
+	struct list_head cmd_list;	/* queue of in use SCSI Command structures */
+	struct list_head starved_entry;
+	struct scsi_cmnd *current_cmnd;	/* currently active command */
+	unsigned short queue_depth;	/* How deep of a queue we want */
+	unsigned short last_queue_full_depth; /* These two are used by */
+	unsigned short last_queue_full_count; /* scsi_track_queue_full() */
+	unsigned long last_queue_full_time;/* don't let QUEUE_FULLs on the same
+					   jiffie count on our counter, they
+					   could all be from the same event. */
+
+	unsigned int id, lun, channel;
+
+	unsigned int manufacturer;	/* Manufacturer of device, for using 
+					 * vendor-specific cmd's */
+	unsigned sector_size;	/* size in bytes */
+
+	int access_count;	/* Count of open channels/mounts */
+
+	void *hostdata;		/* available to low-level driver */
+	char devfs_name[256];	/* devfs junk */
+	char type;
+	char scsi_level;
+	unsigned char inquiry_len;	/* valid bytes in 'inquiry' */
+	unsigned char * inquiry;	/* INQUIRY response data */
+	char * vendor;		/* [back_compat] point into 'inquiry' ... */
+	char * model;		/* ... after scan; point to static string */
+	char * rev;		/* ... "nullnullnullnull" before scan */
+	unsigned char current_tag;	/* current tag */
+	struct scsi_target      *sdev_target;   /* used only for single_lun */
+
+	unsigned online:1;
+
+	unsigned writeable:1;
+	unsigned removable:1;
+	unsigned changed:1;	/* Data invalid due to media change */
+	unsigned busy:1;	/* Used to prevent races */
+	unsigned lockable:1;	/* Able to prevent media removal */
+	unsigned locked:1;      /* Media removal disabled */
+	unsigned borken:1;	/* Tell the Seagate driver to be 
+				 * painfully slow on this device */
+	unsigned disconnect:1;	/* can disconnect */
+	unsigned soft_reset:1;	/* Uses soft reset option */
+	unsigned sdtr:1;	/* Device supports SDTR messages */
+	unsigned wdtr:1;	/* Device supports WDTR messages */
+	unsigned ppr:1;		/* Device supports PPR messages */
+	unsigned tagged_supported:1;	/* Supports SCSI-II tagged queuing */
+	unsigned tagged_queue:1;/* This is going away!!!!  Look at simple_tags
+				   instead!!!  Please fix your driver now!! */
+	unsigned simple_tags:1;	/* simple queue tag messages are enabled */
+	unsigned ordered_tags:1;/* ordered queue tag messages are enabled */
+	unsigned single_lun:1;	/* Indicates we should only allow I/O to
+				 * one of the luns for the device at a 
+				 * time. */
+	unsigned was_reset:1;	/* There was a bus reset on the bus for 
+				 * this device */
+	unsigned expecting_cc_ua:1; /* Expecting a CHECK_CONDITION/UNIT_ATTN
+				     * because we did a bus reset. */
+	unsigned use_10_for_rw:1; /* first try 10-byte read / write */
+	unsigned use_10_for_ms:1; /* first try 10-byte mode sense/select */
+	unsigned no_start_on_add:1;	/* do not issue start on add */
+
+	unsigned int device_blocked;	/* Device returned QUEUE_FULL. */
+
+	unsigned int max_device_blocked; /* what device_blocked counts down from  */
+#define SCSI_DEFAULT_DEVICE_BLOCKED	3
+
+	struct device sdev_driverfs_dev;
+};
+#define	to_scsi_device(d)	\
+	container_of(d, struct scsi_device, sdev_driverfs_dev)
+
+extern struct scsi_device *scsi_add_device(struct Scsi_Host *,
+		uint, uint, uint);
+extern int scsi_remove_device(struct scsi_device *);
+extern void scsi_set_device_offline(struct scsi_device *);
+
+extern int scsi_device_get(struct scsi_device *);
+extern void scsi_device_put(struct scsi_device *);
+
+extern void scsi_adjust_queue_depth(struct scsi_device *, int, int);
+extern int scsi_track_queue_full(struct scsi_device *, int);
+
+extern int scsi_set_medium_removal(struct scsi_device *, char);
+
+#endif /* _SCSI_SCSI_DEVICE_H */
diff -Nru a/include/scsi/scsi_eh.h b/include/scsi/scsi_eh.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/scsi/scsi_eh.h	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,21 @@
+#ifndef _SCSI_SCSI_EH_H
+#define _SCSI_SCSI_EH_H
+
+extern void scsi_add_timer(struct scsi_cmnd *, int,
+			   void (*)(struct scsi_cmnd *));
+extern int scsi_delete_timer(struct scsi_cmnd *);
+extern void scsi_report_bus_reset(struct Scsi_Host *, int);
+extern void scsi_report_device_reset(struct Scsi_Host *, int, int);
+extern int scsi_block_when_processing_errors(struct scsi_device *);
+extern void scsi_sleep(int);
+
+/*
+ * Reset request from external source
+ */
+#define SCSI_TRY_RESET_DEVICE	1
+#define SCSI_TRY_RESET_BUS	2
+#define SCSI_TRY_RESET_HOST	3
+
+extern int scsi_reset_provider(struct scsi_device *, int);
+
+#endif /* _SCSI_SCSI_EH_H */
diff -Nru a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/scsi/scsi_host.h	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,525 @@
+#ifndef _SCSI_SCSI_HOST_H
+#define _SCSI_SCSI_HOST_H
+
+#include <linux/device.h>
+#include <linux/list.h>
+#include <linux/types.h>
+
+struct block_device;
+struct module;
+struct scsi_cmnd;
+struct scsi_device;
+struct Scsi_Host;
+struct scsi_host_cmd_pool;
+
+
+/*
+ * The various choices mean:
+ * NONE: Self evident.	Host adapter is not capable of scatter-gather.
+ * ALL:	 Means that the host adapter module can do scatter-gather,
+ *	 and that there is no limit to the size of the table to which
+ *	 we scatter/gather data.
+ * Anything else:  Indicates the maximum number of chains that can be
+ *	 used in one scatter-gather request.
+ */
+#define SG_NONE 0
+#define SG_ALL 0xff
+
+
+#define DISABLE_CLUSTERING 0
+#define ENABLE_CLUSTERING 1
+
+
+struct scsi_host_template {
+	struct module *module;
+	const char *name;
+
+	/*
+	 * Used to initialize old-style drivers.  For new-style drivers
+	 * just perform all work in your module initialization function.
+	 *
+	 * Status:  OBSOLETE
+	 */
+	int (* detect)(struct scsi_host_template *);
+
+	/*
+	 * Used as unload callback for hosts with old-style drivers.
+	 *
+	 * Status: OBSOLETE
+	 */
+	int (* release)(struct Scsi_Host *);
+
+	/*
+	 * The info function will return whatever useful information the
+	 * developer sees fit.  If not provided, then the name field will
+	 * be used instead.
+	 *
+	 * Status: OPTIONAL
+	 */
+	const char *(* info)(struct Scsi_Host *);
+
+	/*
+	 * Ioctl interface
+	 *
+	 * Status: OPTIONAL
+	 */
+	int (* ioctl)(struct scsi_device *dev, int cmd, void *arg);
+	
+	/*
+	 * The queuecommand function is used to queue up a scsi
+	 * command block to the LLDD.  When the driver finished
+	 * processing the command the done callback is invoked.
+	 *
+	 * If queuecommand returns 0, then the HBA has accepted the
+	 * command.  The done() function must be called on the command
+	 * when the driver has finished with it. (you may call done on the
+	 * command before queuecommand returns, but in this case you
+	 * *must* return 0 from queuecommand).
+	 *
+	 * Queuecommand may also reject the command, in which case it may
+	 * not touch the command and must not call done() for it.
+	 *
+	 * There are two possible rejection returns:
+	 *
+	 *   SCSI_MLQUEUE_DEVICE_BUSY: Block this device temporarily, but
+	 *   allow commands to other devices serviced by this host.
+	 *
+	 *   SCSI_MLQUEUE_HOST_BUSY: Block all devices served by this
+	 *   host temporarily.
+	 *
+         * For compatibility, any other non-zero return is treated the
+         * same as SCSI_MLQUEUE_HOST_BUSY.
+	 *
+	 * NOTE: "temporarily" means either until the next command for#
+	 * this device/host completes, or a period of time determined by
+	 * I/O pressure in the system if there are no other outstanding
+	 * commands.
+	 *
+	 * STATUS: REQUIRED
+	 */
+	int (* queuecommand)(struct scsi_cmnd *,
+			     void (*done)(struct scsi_cmnd *));
+
+	/*
+	 * This is an error handling strategy routine.  You don't need to
+	 * define one of these if you don't want to - there is a default
+	 * routine that is present that should work in most cases.  For those
+	 * driver authors that have the inclination and ability to write their
+	 * own strategy routine, this is where it is specified.  Note - the
+	 * strategy routine is *ALWAYS* run in the context of the kernel eh
+	 * thread.  Thus you are guaranteed to *NOT* be in an interrupt
+	 * handler when you execute this, and you are also guaranteed to
+	 * *NOT* have any other commands being queued while you are in the
+	 * strategy routine. When you return from this function, operations
+	 * return to normal.
+	 *
+	 * See scsi_error.c scsi_unjam_host for additional comments about
+	 * what this function should and should not be attempting to do.
+	 *
+	 * Status: REQUIRED	(at least one of them)
+	 */
+	int (* eh_strategy_handler)(struct Scsi_Host *);
+	int (* eh_abort_handler)(struct scsi_cmnd *);
+	int (* eh_device_reset_handler)(struct scsi_cmnd *);
+	int (* eh_bus_reset_handler)(struct scsi_cmnd *);
+	int (* eh_host_reset_handler)(struct scsi_cmnd *);
+
+	/*
+	 * Old EH handlers, no longer used. Make them warn the user of old
+	 * drivers by using a wrong type
+	 *
+	 * Status: MORE THAN OBSOLETE
+	 */
+	int (* abort)(int);
+	int (* reset)(int, int);
+
+	/*
+	 * Before the mid layer attempts to scan for a new device where none
+	 * currently exists, it will call this entry in your driver.  Should
+	 * your driver need to allocate any structs or perform any other init
+	 * items in order to send commands to a currently unused target/lun
+	 * combo, then this is where you can perform those allocations.  This
+	 * is specifically so that drivers won't have to perform any kind of
+	 * "is this a new device" checks in their queuecommand routine,
+	 * thereby making the hot path a bit quicker.
+	 *
+	 * Return values: 0 on success, non-0 on failure
+	 *
+	 * Deallocation:  If we didn't find any devices at this ID, you will
+	 * get an immediate call to slave_destroy().  If we find something
+	 * here then you will get a call to slave_configure(), then the
+	 * device will be used for however long it is kept around, then when
+	 * the device is removed from the system (or * possibly at reboot
+	 * time), you will then get a call to slave_detach().  This is
+	 * assuming you implement slave_configure and slave_destroy.
+	 * However, if you allocate memory and hang it off the device struct,
+	 * then you must implement the slave_destroy() routine at a minimum
+	 * in order to avoid leaking memory
+	 * each time a device is tore down.
+	 *
+	 * Status: OPTIONAL
+	 */
+	int (* slave_alloc)(struct scsi_device *);
+
+	/*
+	 * Once the device has responded to an INQUIRY and we know the
+	 * device is online, we call into the low level driver with the
+	 * struct scsi_device *.  If the low level device driver implements
+	 * this function, it *must* perform the task of setting the queue
+	 * depth on the device.  All other tasks are optional and depend
+	 * on what the driver supports and various implementation details.
+	 * 
+	 * Things currently recommended to be handled at this time include:
+	 *
+	 * 1.  Setting the device queue depth.  Proper setting of this is
+	 *     described in the comments for scsi_adjust_queue_depth.
+	 * 2.  Determining if the device supports the various synchronous
+	 *     negotiation protocols.  The device struct will already have
+	 *     responded to INQUIRY and the results of the standard items
+	 *     will have been shoved into the various device flag bits, eg.
+	 *     device->sdtr will be true if the device supports SDTR messages.
+	 * 3.  Allocating command structs that the device will need.
+	 * 4.  Setting the default timeout on this device (if needed).
+	 * 5.  Anything else the low level driver might want to do on a device
+	 *     specific setup basis...
+	 * 6.  Return 0 on success, non-0 on error.  The device will be marked
+	 *     as offline on error so that no access will occur.  If you return
+	 *     non-0, your slave_detach routine will never get called for this
+	 *     device, so don't leave any loose memory hanging around, clean
+	 *     up after yourself before returning non-0
+	 *
+	 * Status: OPTIONAL
+	 */
+	int (* slave_configure)(struct scsi_device *);
+
+	/*
+	 * Immediately prior to deallocating the device and after all activity
+	 * has ceased the mid layer calls this point so that the low level
+	 * driver may completely detach itself from the scsi device and vice
+	 * versa.  The low level driver is responsible for freeing any memory
+	 * it allocated in the slave_alloc or slave_configure calls. 
+	 *
+	 * Status: OPTIONAL
+	 */
+	void (* slave_destroy)(struct scsi_device *);
+
+	/*
+	 * This function determines the bios parameters for a given
+	 * harddisk.  These tend to be numbers that are made up by
+	 * the host adapter.  Parameters:
+	 * size, device, list (heads, sectors, cylinders)
+	 *
+	 * Status: OPTIONAL
+	 */
+	int (* bios_param)(struct scsi_device *, struct block_device *,
+			sector_t, int []);
+
+	/*
+	 * Can be used to export driver statistics and other infos to the
+	 * world outside the kernel ie. userspace and it also provides an
+	 * interface to feed the driver with information.
+	 *
+	 * Status: OBSOLETE
+	 */
+	int (*proc_info)(struct Scsi_Host *, char *, char **, off_t, int, int);
+
+	/*
+	 * Name of proc directory
+	 */
+	char *proc_name;
+
+	/*
+	 * Used to store the procfs directory if a driver implements the
+	 * proc_info method.
+	 */
+	struct proc_dir_entry *proc_dir;
+
+	/*
+	 * This determines if we will use a non-interrupt driven
+	 * or an interrupt driven scheme,  It is set to the maximum number
+	 * of simultaneous commands a given host adapter will accept.
+	 */
+	int can_queue;
+
+	/*
+	 * In many instances, especially where disconnect / reconnect are
+	 * supported, our host also has an ID on the SCSI bus.  If this is
+	 * the case, then it must be reserved.  Please set this_id to -1 if
+	 * your setup is in single initiator mode, and the host lacks an
+	 * ID.
+	 */
+	int this_id;
+
+	/*
+	 * This determines the degree to which the host adapter is capable
+	 * of scatter-gather.
+	 */
+	unsigned short sg_tablesize;
+
+	/*
+	 * If the host adapter has limitations beside segment count
+	 */
+	unsigned short max_sectors;
+
+	/*
+	 * This specifies "machine infinity" for host templates which don't
+	 * limit the transfer size.  Note this limit represents an absolute
+	 * maximum, and may be over the transfer limits allowed for
+	 * individual devices (e.g. 256 for SCSI-1)
+	 */
+#define SCSI_DEFAULT_MAX_SECTORS	1024
+
+	/*
+	 * True if this host adapter can make good use of linked commands.
+	 * This will allow more than one command to be queued to a given
+	 * unit on a given host.  Set this to the maximum number of command
+	 * blocks to be provided for each device.  Set this to 1 for one
+	 * command block per lun, 2 for two, etc.  Do not set this to 0.
+	 * You should make sure that the host adapter will do the right thing
+	 * before you try setting this above 1.
+	 */
+	short cmd_per_lun;
+
+	/*
+	 * present contains counter indicating how many boards of this
+	 * type were found when we did the scan.
+	 */
+	unsigned char present;
+
+	/*
+	 * true if this host adapter uses unchecked DMA onto an ISA bus.
+	 */
+	unsigned unchecked_isa_dma:1;
+
+	/*
+	 * true if this host adapter can make good use of clustering.
+	 * I originally thought that if the tablesize was large that it
+	 * was a waste of CPU cycles to prepare a cluster list, but
+	 * it works out that the Buslogic is faster if you use a smaller
+	 * number of segments (i.e. use clustering).  I guess it is
+	 * inefficient.
+	 */
+	unsigned use_clustering:1;
+
+	/*
+	 * True for emulated SCSI host adapters (e.g. ATAPI)
+	 */
+	unsigned emulated:1;
+
+	unsigned highmem_io:1;
+
+	/* 
+	 * True if the driver wishes to use the generic block layer
+	 * tag queueing functions
+	 */
+	unsigned use_blk_tcq:1;
+
+	/*
+	 * Countdown for host blocking with no commands outstanding
+	 */
+	unsigned int max_host_blocked;
+
+	/*
+	 * Default value for the blocking.  If the queue is empty,
+	 * host_blocked counts down in the request_fn until it restarts
+	 * host operations as zero is reached.  
+	 *
+	 * FIXME: This should probably be a value in the template
+	 */
+#define SCSI_DEFAULT_HOST_BLOCKED	7
+
+	/*
+	 * Pointer to the sysfs class properties for this host
+	 */
+	struct class_device_attribute **shost_attrs;
+
+	/*
+	 * Pointer to the SCSI device properties for this host
+	 */
+	struct device_attribute **sdev_attrs;
+
+	/*
+	 * List of hosts per template.
+	 *
+	 * This is only for use by scsi_module.c for legacy templates.
+	 * For these access to it is synchronized implicitly by
+	 * module_init/module_exit.
+	 */
+	struct list_head legacy_hosts;
+};
+
+struct Scsi_Host {
+	struct list_head	my_devices;
+	struct scsi_host_cmd_pool *cmd_pool;
+	spinlock_t		free_list_lock;
+	struct list_head	free_list;   /* backup store of cmd structs */
+	struct list_head	starved_list;
+
+	spinlock_t		default_lock;
+	spinlock_t		*host_lock;
+
+	struct list_head	eh_cmd_q;
+	struct task_struct    * ehandler;  /* Error recovery thread. */
+	struct semaphore      * eh_wait;   /* The error recovery thread waits on
+                                          this. */
+	struct completion     * eh_notify; /* wait for eh to begin or end */
+	struct semaphore      * eh_action; /* Wait for specific actions on the
+                                          host. */
+	unsigned int            eh_active:1; /* Indicates the eh thread is awake and active if
+                                          this is true. */
+	unsigned int            eh_kill:1; /* set when killing the eh thread */
+	wait_queue_head_t       host_wait;
+	struct scsi_host_template *hostt;
+	volatile unsigned short host_busy;   /* commands actually active on low-level */
+	volatile unsigned short host_failed; /* commands that failed. */
+    
+	unsigned short host_no;  /* Used for IOCTL_GET_IDLUN, /proc/scsi et al. */
+	int resetting; /* if set, it means that last_reset is a valid value */
+	unsigned long last_reset;
+
+	/*
+	 * These three parameters can be used to allow for wide scsi,
+	 * and for host adapters that support multiple busses
+	 * The first two should be set to 1 more than the actual max id
+	 * or lun (i.e. 8 for normal systems).
+	 */
+	unsigned int max_id;
+	unsigned int max_lun;
+	unsigned int max_channel;
+
+	/*
+	 * This is a unique identifier that must be assigned so that we
+	 * have some way of identifying each detected host adapter properly
+	 * and uniquely.  For hosts that do not support more than one card
+	 * in the system at one time, this does not need to be set.  It is
+	 * initialized to 0 in scsi_register.
+	 */
+	unsigned int unique_id;
+
+	/*
+	 * The maximum length of SCSI commands that this host can accept.
+	 * Probably 12 for most host adapters, but could be 16 for others.
+	 * For drivers that don't set this field, a value of 12 is
+	 * assumed.  I am leaving this as a number rather than a bit
+	 * because you never know what subsequent SCSI standards might do
+	 * (i.e. could there be a 20 byte or a 24-byte command a few years
+	 * down the road?).  
+	 */
+	unsigned char max_cmd_len;
+
+	int this_id;
+	int can_queue;
+	short cmd_per_lun;
+	short unsigned int sg_tablesize;
+	short unsigned int max_sectors;
+
+	unsigned in_recovery:1;
+	unsigned unchecked_isa_dma:1;
+	unsigned use_clustering:1;
+	unsigned highmem_io:1;
+	unsigned use_blk_tcq:1;
+
+	/*
+	 * Host has requested that no further requests come through for the
+	 * time being.
+	 */
+	unsigned host_self_blocked:1;
+    
+	/*
+	 * Host uses correct SCSI ordering not PC ordering. The bit is
+	 * set for the minority of drivers whose authors actually read
+	 * the spec ;)
+	 */
+	unsigned reverse_ordering:1;
+
+	/*
+	 * Host has rejected a command because it was busy.
+	 */
+	unsigned int host_blocked;
+
+	/*
+	 * Value host_blocked counts down from
+	 */
+	unsigned int max_host_blocked;
+
+	/* 
+	 * Support for sysfs
+	 */
+	struct device host_gendev;
+	struct class_device class_dev;
+
+	/* legacy crap */
+	unsigned long base;
+	unsigned long io_port;
+	unsigned char n_io_port;
+	unsigned char dma_channel;
+	unsigned int  irq;
+
+
+	/*
+	 * List of hosts per template.
+	 *
+	 * This is only for use by scsi_module.c for legacy templates.
+	 * For these access to it is synchronized implicitly by
+	 * module_init/module_exit.
+	 */
+	struct list_head sht_legacy_list;
+
+	/*
+	 * We should ensure that this is aligned, both for better performance
+	 * and also because some compilers (m68k) don't automatically force
+	 * alignment to a long boundary.
+	 */
+	unsigned long hostdata[0]  /* Used for storage of host specific stuff */
+		__attribute__ ((aligned (sizeof(unsigned long))));
+};
+#define		dev_to_shost(d)		\
+	container_of(d, struct Scsi_Host, host_gendev)
+#define		class_to_shost(d)	\
+	container_of(d, struct Scsi_Host, class_dev)
+
+extern struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *, int);
+extern int scsi_add_host(struct Scsi_Host *, struct device *);
+extern int scsi_remove_host(struct Scsi_Host *);
+extern void scsi_host_get(struct Scsi_Host *);
+extern void scsi_host_put(struct Scsi_Host *t);
+extern struct Scsi_Host *scsi_host_lookup(unsigned short);
+
+extern u64 scsi_calculate_bounce_limit(struct Scsi_Host *);
+
+static inline void scsi_assign_lock(struct Scsi_Host *shost, spinlock_t *lock)
+{
+	shost->host_lock = lock;
+}
+
+static inline void scsi_set_device(struct Scsi_Host *shost,
+                                   struct device *dev)
+{
+        shost->host_gendev.parent = dev;
+}
+
+static inline struct device *scsi_get_device(struct Scsi_Host *shost)
+{
+        return shost->host_gendev.parent;
+}
+
+extern void scsi_sysfs_release_attributes(struct scsi_host_template *);
+
+extern void scsi_unblock_requests(struct Scsi_Host *);
+extern void scsi_block_requests(struct Scsi_Host *);
+
+/*
+ * These two functions are used to allocate and free a pseudo device
+ * which will connect to the host adapter itself rather than any
+ * physical device.  You must deallocate when you are done with the
+ * thing.  This physical pseudo-device isn't real and won't be available
+ * from any high-level drivers.
+ */
+extern void scsi_free_host_dev(struct scsi_device *);
+extern struct scsi_device *scsi_get_host_dev(struct Scsi_Host *);
+
+/* legacy interfaces */
+extern struct Scsi_Host *scsi_register(struct scsi_host_template *, int);
+extern void scsi_unregister(struct Scsi_Host *);
+
+#endif /* _SCSI_SCSI_HOST_H */
diff -Nru a/include/scsi/scsi_request.h b/include/scsi/scsi_request.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/scsi/scsi_request.h	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,58 @@
+#ifndef _SCSI_SCSI_REQUEST_H
+#define _SCSI_SCSI_REQUEST_H
+
+#include <scsi/scsi_cmnd.h>
+
+struct request;
+struct scsi_cmnd;
+struct scsi_device;
+struct Scsi_Host;
+
+
+/*
+ * This is essentially a slimmed down version of Scsi_Cmnd.  The point of
+ * having this is that requests that are injected into the queue as result
+ * of things like ioctls and character devices shouldn't be using a
+ * Scsi_Cmnd until such a time that the command is actually at the head
+ * of the queue and being sent to the driver.
+ */
+struct scsi_request {
+	int     sr_magic;
+	int     sr_result;	/* Status code from lower level driver */
+	unsigned char sr_sense_buffer[SCSI_SENSE_BUFFERSIZE];		/* obtained by REQUEST SENSE
+						 * when CHECK CONDITION is
+						 * received on original command 
+						 * (auto-sense) */
+
+	struct Scsi_Host *sr_host;
+	struct scsi_device *sr_device;
+	struct scsi_cmnd *sr_command;
+	struct request *sr_request;	/* A copy of the command we are
+				   working on */
+	unsigned sr_bufflen;	/* Size of data buffer */
+	void *sr_buffer;		/* Data buffer */
+	int sr_allowed;
+	unsigned char sr_data_direction;
+	unsigned char sr_cmd_len;
+	unsigned char sr_cmnd[MAX_COMMAND_SIZE];
+	void (*sr_done) (struct scsi_cmnd *);	/* Mid-level done function */
+	int sr_timeout_per_command;
+	unsigned short sr_use_sg;	/* Number of pieces of scatter-gather */
+	unsigned short sr_sglist_len;	/* size of malloc'd scatter-gather list */
+	unsigned sr_underflow;	/* Return error if less than
+				   this amount is transferred */
+ 	void *upper_private_data;	/* reserved for owner (usually upper
+ 					   level driver) of this request */
+};
+
+extern struct scsi_request *scsi_allocate_request(struct scsi_device *);
+extern void scsi_release_request(struct scsi_request *);
+extern void scsi_wait_req(struct scsi_request *, const void *cmnd,
+			  void *buffer, unsigned bufflen,
+			  int timeout, int retries);
+extern void scsi_do_req(struct scsi_request *, const void *cmnd,
+			void *buffer, unsigned bufflen,
+			void (*done) (struct scsi_cmnd *),
+			int timeout, int retries);
+
+#endif /* _SCSI_SCSI_REQUEST_H */
diff -Nru a/include/scsi/scsi_tcq.h b/include/scsi/scsi_tcq.h
--- /dev/null	Wed Dec 31 16:00:00 1969
+++ b/include/scsi/scsi_tcq.h	Wed Jun 18 23:42:09 2003
@@ -0,0 +1,94 @@
+#ifndef _SCSI_SCSI_TCQ_H
+#define _SCSI_SCSI_TCQ_H
+
+#include <linux/blkdev.h>
+#include <scsi/scsi_cmnd.h>
+#include <scsi/scsi_device.h>
+
+
+#define MSG_SIMPLE_TAG	0x20
+#define MSG_HEAD_TAG	0x21
+#define MSG_ORDERED_TAG	0x22
+
+#define SCSI_NO_TAG	(-1)    /* identify no tag in use */
+
+
+/**
+ * scsi_activate_tcq - turn on tag command queueing
+ * @SDpnt:	device to turn on TCQ for
+ * @depth:	queue depth
+ *
+ * Notes:
+ *	Eventually, I hope depth would be the maximum depth
+ *	the device could cope with and the real queue depth
+ *	would be adjustable from 0 to depth.
+ **/
+static inline void scsi_activate_tcq(struct scsi_device *sdev, int depth)
+{
+        if (sdev->tagged_supported) {
+		if (!blk_queue_tagged(sdev->request_queue))
+			blk_queue_init_tags(sdev->request_queue, depth);
+		scsi_adjust_queue_depth(sdev, MSG_ORDERED_TAG, depth);
+        }
+}
+
+/**
+ * scsi_deactivate_tcq - turn off tag command queueing
+ * @SDpnt:	device to turn off TCQ for
+ **/
+static inline void scsi_deactivate_tcq(struct scsi_device *sdev, int depth)
+{
+	if (blk_queue_tagged(sdev->request_queue))
+		blk_queue_free_tags(sdev->request_queue);
+	scsi_adjust_queue_depth(sdev, 0, depth);
+}
+
+/**
+ * scsi_populate_tag_msg - place a tag message in a buffer
+ * @SCpnt:	pointer to the Scsi_Cmnd for the tag
+ * @msg:	pointer to the area to place the tag
+ *
+ * Notes:
+ *	designed to create the correct type of tag message for the 
+ *	particular request.  Returns the size of the tag message.
+ *	May return 0 if TCQ is disabled for this device.
+ **/
+static inline int scsi_populate_tag_msg(struct scsi_cmnd *cmd, char *msg)
+{
+        struct request *req = cmd->request;
+
+        if (blk_rq_tagged(req)) {
+		if (req->flags & REQ_HARDBARRIER)
+        	        *msg++ = MSG_ORDERED_TAG;
+        	else
+        	        *msg++ = MSG_SIMPLE_TAG;
+        	*msg++ = req->tag;
+        	return 2;
+	}
+
+	return 0;
+}
+
+/**
+ * scsi_find_tag - find a tagged command by device
+ * @SDpnt:	pointer to the ScSI device
+ * @tag:	the tag number
+ *
+ * Notes:
+ *	Only works with tags allocated by the generic blk layer.
+ **/
+static inline struct scsi_cmnd *scsi_find_tag(struct scsi_device *sdev, int tag)
+{
+
+        struct request *req;
+
+        if (tag != SCSI_NO_TAG) {
+        	req = blk_queue_find_tag(sdev->request_queue, tag);
+	        return req ? (struct scsi_cmnd *)req->special : NULL;
+	}
+
+	/* single command, look in space */
+	return sdev->current_cmnd;
+}
+
+#endif /* _SCSI_SCSI_TCQ_H */
diff -Nru a/kernel/compat.c b/kernel/compat.c
--- a/kernel/compat.c	Wed Jun 18 23:42:07 2003
+++ b/kernel/compat.c	Wed Jun 18 23:42:07 2003
@@ -354,6 +354,8 @@
 
 	if (put_compat_rusage(ru, &r))
 		return -EFAULT;
+
+	return 0;
 }
 
 asmlinkage long
diff -Nru a/kernel/ksyms.c b/kernel/ksyms.c
--- a/kernel/ksyms.c	Wed Jun 18 23:42:05 2003
+++ b/kernel/ksyms.c	Wed Jun 18 23:42:05 2003
@@ -604,5 +604,6 @@
 /* debug */
 EXPORT_SYMBOL(dump_stack);
 EXPORT_SYMBOL(ptrace_notify);
+EXPORT_SYMBOL(console_printk);
 
-EXPORT_SYMBOL(current_kernel_time); 
+EXPORT_SYMBOL(current_kernel_time);
diff -Nru a/net/atm/clip.c b/net/atm/clip.c
--- a/net/atm/clip.c	Wed Jun 18 23:42:09 2003
+++ b/net/atm/clip.c	Wed Jun 18 23:42:09 2003
@@ -140,8 +140,8 @@
 					DPRINTK("releasing vcc %p->%p of "
 					    "entry %p\n",clip_vcc,clip_vcc->vcc,
 					    entry);
-					atm_async_release_vcc(clip_vcc->vcc,
-					    -ETIMEDOUT);
+					vcc_release_async(clip_vcc->vcc,
+							  -ETIMEDOUT);
 				}
 			if (entry->vccs ||
 			    time_before(jiffies, entry->expires)) {
diff -Nru a/net/atm/common.c b/net/atm/common.c
--- a/net/atm/common.c	Wed Jun 18 23:42:09 2003
+++ b/net/atm/common.c	Wed Jun 18 23:42:09 2003
@@ -239,15 +239,16 @@
 }
 
 
-void atm_async_release_vcc(struct atm_vcc *vcc,int reply)
+void vcc_release_async(struct atm_vcc *vcc, int reply)
 {
-	set_bit(ATM_VF_CLOSE,&vcc->flags);
+	set_bit(ATM_VF_CLOSE, &vcc->flags);
 	vcc->reply = reply;
+	vcc->sk->sk_err = -reply;
 	wake_up(&vcc->sleep);
 }
 
 
-EXPORT_SYMBOL(atm_async_release_vcc);
+EXPORT_SYMBOL(vcc_release_async);
 
 
 static int adjust_tp(struct atm_trafprm *tp,unsigned char aal)
@@ -276,8 +277,8 @@
 }
 
 
-static int atm_do_connect_dev(struct atm_vcc *vcc,struct atm_dev *dev,int vpi,
-    int vci)
+static int __vcc_connect(struct atm_vcc *vcc, struct atm_dev *dev, int vpi,
+			 int vci)
 {
 	int error;
 
@@ -334,29 +335,26 @@
 }
 
 
-static int atm_do_connect(struct atm_vcc *vcc,int itf,int vpi,int vci)
+int vcc_connect(struct socket *sock, int itf, short vpi, int vci)
 {
 	struct atm_dev *dev;
-	int return_val;
-
-	dev = atm_dev_lookup(itf);
-	if (!dev)
-		return_val =  -ENODEV;
-	else {
-		return_val = atm_do_connect_dev(vcc,dev,vpi,vci);
-		if (return_val) atm_dev_release(dev);
-	}
-
-	return return_val;
-}
+	struct atm_vcc *vcc = ATM_SD(sock);
+	int error;
 
+	DPRINTK("vcc_connect (vpi %d, vci %d)\n",vpi,vci);
+	if (sock->state == SS_CONNECTED)
+		return -EISCONN;
+	if (sock->state != SS_UNCONNECTED)
+		return -EINVAL;
+	if (!(vpi || vci))
+		return -EINVAL;
 
-int atm_connect_vcc(struct atm_vcc *vcc,int itf,short vpi,int vci)
-{
 	if (vpi != ATM_VPI_UNSPEC && vci != ATM_VCI_UNSPEC)
 		clear_bit(ATM_VF_PARTIAL,&vcc->flags);
-	else if (test_bit(ATM_VF_PARTIAL,&vcc->flags)) return -EINVAL;
-	DPRINTK("atm_connect (TX: cl %d,bw %d-%d,sdu %d; "
+	else
+		if (test_bit(ATM_VF_PARTIAL,&vcc->flags))
+			return -EINVAL;
+	DPRINTK("vcc_connect (TX: cl %d,bw %d-%d,sdu %d; "
 	    "RX: cl %d,bw %d-%d,sdu %d,AAL %s%d)\n",
 	    vcc->qos.txtp.traffic_class,vcc->qos.txtp.min_pcr,
 	    vcc->qos.txtp.max_pcr,vcc->qos.txtp.max_sdu,
@@ -364,141 +362,135 @@
 	    vcc->qos.rxtp.max_pcr,vcc->qos.rxtp.max_sdu,
 	    vcc->qos.aal == ATM_AAL5 ? "" : vcc->qos.aal == ATM_AAL0 ? "" :
 	    " ??? code ",vcc->qos.aal == ATM_AAL0 ? 0 : vcc->qos.aal);
-	if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) return -EBADFD;
+	if (!test_bit(ATM_VF_HASQOS, &vcc->flags))
+		return -EBADFD;
 	if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS ||
 	    vcc->qos.rxtp.traffic_class == ATM_ANYCLASS)
 		return -EINVAL;
 	if (itf != ATM_ITF_ANY) {
-		int error;
-
-		error = atm_do_connect(vcc,itf,vpi,vci);
-		if (error) return error;
-	}
-	else {
-		struct atm_dev *dev = NULL;
+		dev = atm_dev_lookup(itf);
+		error = __vcc_connect(vcc, dev, vpi, vci);
+		if (error) {
+			atm_dev_release(dev);
+			return error;
+		}
+	} else {
 		struct list_head *p, *next;
 
+		dev = NULL;
 		spin_lock(&atm_dev_lock);
 		list_for_each_safe(p, next, &atm_devs) {
 			dev = list_entry(p, struct atm_dev, dev_list);
 			atm_dev_hold(dev);
 			spin_unlock(&atm_dev_lock);
-			if (!atm_do_connect_dev(vcc,dev,vpi,vci))
+			if (!__vcc_connect(vcc, dev, vpi, vci))
 				break;
 			atm_dev_release(dev);
 			dev = NULL;
 			spin_lock(&atm_dev_lock);
 		}
 		spin_unlock(&atm_dev_lock);
-		if (!dev) return -ENODEV;
+		if (!dev)
+			return -ENODEV;
 	}
 	if (vpi == ATM_VPI_UNSPEC || vci == ATM_VCI_UNSPEC)
 		set_bit(ATM_VF_PARTIAL,&vcc->flags);
-	return 0;
-}
-
-
-int atm_connect(struct socket *sock,int itf,short vpi,int vci)
-{
-	int error;
-
-	DPRINTK("atm_connect (vpi %d, vci %d)\n",vpi,vci);
-	if (sock->state == SS_CONNECTED) return -EISCONN;
-	if (sock->state != SS_UNCONNECTED) return -EINVAL;
-	if (!(vpi || vci)) return -EINVAL;
-	error = atm_connect_vcc(ATM_SD(sock),itf,vpi,vci);
-	if (error) return error;
 	if (test_bit(ATM_VF_READY,&ATM_SD(sock)->flags))
 		sock->state = SS_CONNECTED;
 	return 0;
 }
 
 
-int atm_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
-		int total_len, int flags)
+int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
+		int size, int flags)
 {
-	DECLARE_WAITQUEUE(wait,current);
+	struct sock *sk = sock->sk;
 	struct atm_vcc *vcc;
 	struct sk_buff *skb;
-	int eff_len,error;
-	void *buff;
-	int size;
+	int copied, error = -EINVAL;
 
-	if (sock->state != SS_CONNECTED) return -ENOTCONN;
-	if (flags & ~MSG_DONTWAIT) return -EOPNOTSUPP;
-	if (m->msg_iovlen != 1) return -ENOSYS; /* fix this later @@@ */
-	buff = m->msg_iov->iov_base;
-	size = m->msg_iov->iov_len;
+	if (sock->state != SS_CONNECTED)
+		return -ENOTCONN;
+	if (flags & ~MSG_DONTWAIT)		/* only handle MSG_DONTWAIT */
+		return -EOPNOTSUPP;
 	vcc = ATM_SD(sock);
-	add_wait_queue(&vcc->sleep,&wait);
-	set_current_state(TASK_INTERRUPTIBLE);
-	error = 1; /* <= 0 is error */
-	while (!(skb = skb_dequeue(&vcc->sk->sk_receive_queue))) {
-		if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
-		    test_bit(ATM_VF_CLOSE,&vcc->flags)) {
-			error = vcc->reply;
-			break;
-		}
-		if (!test_bit(ATM_VF_READY,&vcc->flags)) {
-			error = 0;
-			break;
-		}
-		if (flags & MSG_DONTWAIT) {
-			error = -EAGAIN;
-			break;
-		}
-		schedule();
-		set_current_state(TASK_INTERRUPTIBLE);
-		if (signal_pending(current)) {
-			error = -ERESTARTSYS;
-			break;
-		}
-	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&vcc->sleep,&wait);
-	if (error <= 0) return error;
-	sock_recv_timestamp(m, vcc->sk, skb);
-	eff_len = skb->len > size ? size : skb->len;
-	if (skb->len > size) /* Not fit ?  Report it... */
-		m->msg_flags |= MSG_TRUNC;
-	if (vcc->dev->ops->feedback)
-		vcc->dev->ops->feedback(vcc,skb,(unsigned long) skb->data,
-		    (unsigned long) buff,eff_len);
-	DPRINTK("RcvM %d -= %d\n", atomic_read(&vcc->sk->sk_rmem_alloc),
-		skb->truesize);
-	atm_return(vcc,skb->truesize);
-	error = copy_to_user(buff,skb->data,eff_len) ? -EFAULT : 0;
-	kfree_skb(skb);
-	return error ? error : eff_len;
+	if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
+	    test_bit(ATM_VF_CLOSE,&vcc->flags))
+		return vcc->reply;
+	if (!test_bit(ATM_VF_READY, &vcc->flags))
+		return 0;
+
+	skb = skb_recv_datagram(sk, flags, flags & MSG_DONTWAIT, &error);
+	if (!skb)
+		return error;
+
+	copied = skb->len; 
+	if (copied > size) {
+		copied = size; 
+		msg->msg_flags |= MSG_TRUNC;
+	}
+
+        error = skb_copy_datagram_iovec(skb, 0, msg->msg_iov, copied);
+        if (error)
+                return error;
+        sock_recv_timestamp(msg, sk, skb);
+        if (vcc->dev->ops->feedback)
+                vcc->dev->ops->feedback(vcc, skb, (unsigned long) skb->data,
+                    (unsigned long) msg->msg_iov->iov_base, copied);
+        DPRINTK("RcvM %d -= %d\n", atomic_read(&vcc->sk->rmem_alloc), skb->truesize);
+        atm_return(vcc, skb->truesize);
+        skb_free_datagram(sk, skb);
+        return copied;
 }
 
 
-int atm_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
+int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
 		int total_len)
 {
-	DECLARE_WAITQUEUE(wait,current);
+	struct sock *sk = sock->sk;
+	DEFINE_WAIT(wait);
 	struct atm_vcc *vcc;
 	struct sk_buff *skb;
 	int eff,error;
 	const void *buff;
 	int size;
 
-	if (sock->state != SS_CONNECTED) return -ENOTCONN;
-	if (m->msg_name) return -EISCONN;
-	if (m->msg_iovlen != 1) return -ENOSYS; /* fix this later @@@ */
+	lock_sock(sk);
+	if (sock->state != SS_CONNECTED) {
+		error = -ENOTCONN;
+		goto out;
+	}
+	if (m->msg_name) {
+		error = -EISCONN;
+		goto out;
+	}
+	if (m->msg_iovlen != 1) {
+		error = -ENOSYS; /* fix this later @@@ */
+		goto out;
+	}
 	buff = m->msg_iov->iov_base;
 	size = m->msg_iov->iov_len;
 	vcc = ATM_SD(sock);
-	if (test_bit(ATM_VF_RELEASED,&vcc->flags) ||
-	    test_bit(ATM_VF_CLOSE,&vcc->flags))
-		return vcc->reply;
-	if (!test_bit(ATM_VF_READY,&vcc->flags)) return -EPIPE;
-	if (!size) return 0;
-	if (size < 0 || size > vcc->qos.txtp.max_sdu) return -EMSGSIZE;
+	if (test_bit(ATM_VF_RELEASED, &vcc->flags) ||
+	    test_bit(ATM_VF_CLOSE, &vcc->flags)) {
+		error = vcc->reply;
+		goto out;
+	}
+	if (!test_bit(ATM_VF_READY, &vcc->flags)) {
+		error = -EPIPE;
+		goto out;
+	}
+	if (!size) {
+		error = 0;
+		goto out;
+	}
+	if (size < 0 || size > vcc->qos.txtp.max_sdu) {
+		error = -EMSGSIZE;
+		goto out;
+	}
 	/* verify_area is done by net/socket.c */
 	eff = (size+3) & ~3; /* align to word boundary */
-	add_wait_queue(&vcc->sleep,&wait);
-	set_current_state(TASK_INTERRUPTIBLE);
+	prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
 	error = 0;
 	while (!(skb = alloc_tx(vcc,eff))) {
 		if (m->msg_flags & MSG_DONTWAIT) {
@@ -506,7 +498,6 @@
 			break;
 		}
 		schedule();
-		set_current_state(TASK_INTERRUPTIBLE);
 		if (signal_pending(current)) {
 			error = -ERESTARTSYS;
 			break;
@@ -520,19 +511,24 @@
 			error = -EPIPE;
 			break;
 		}
+		prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
 	}
-	set_current_state(TASK_RUNNING);
-	remove_wait_queue(&vcc->sleep,&wait);
-	if (error) return error;
+	finish_wait(&vcc->sleep, &wait);
+	if (error)
+		goto out;
 	skb->dev = NULL; /* for paths shared with net_device interfaces */
 	ATM_SKB(skb)->atm_options = vcc->atm_options;
 	if (copy_from_user(skb_put(skb,size),buff,size)) {
 		kfree_skb(skb);
-		return -EFAULT;
+		error = -EFAULT;
+		goto out;
 	}
 	if (eff != size) memset(skb->data+size,0,eff-size);
 	error = vcc->dev->ops->send(vcc,skb);
-	return error ? error : size;
+	error = error ? error : size;
+out:
+	release_sock(sk);
+	return error;
 }
 
 
@@ -563,129 +559,51 @@
 }
 
 
-static void copy_aal_stats(struct k_atm_aal_stats *from,
-    struct atm_aal_stats *to)
-{
-#define __HANDLE_ITEM(i) to->i = atomic_read(&from->i)
-	__AAL_STAT_ITEMS
-#undef __HANDLE_ITEM
-}
-
-
-static void subtract_aal_stats(struct k_atm_aal_stats *from,
-    struct atm_aal_stats *to)
-{
-#define __HANDLE_ITEM(i) atomic_sub(to->i,&from->i)
-	__AAL_STAT_ITEMS
-#undef __HANDLE_ITEM
-}
-
-
-static int fetch_stats(struct atm_dev *dev,struct atm_dev_stats *arg,int zero)
+int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg)
 {
-	struct atm_dev_stats tmp;
-	int error = 0;
-
-	copy_aal_stats(&dev->stats.aal0,&tmp.aal0);
-	copy_aal_stats(&dev->stats.aal34,&tmp.aal34);
-	copy_aal_stats(&dev->stats.aal5,&tmp.aal5);
-	if (arg) error = copy_to_user(arg,&tmp,sizeof(tmp));
-	if (zero && !error) {
-		subtract_aal_stats(&dev->stats.aal0,&tmp.aal0);
-		subtract_aal_stats(&dev->stats.aal34,&tmp.aal34);
-		subtract_aal_stats(&dev->stats.aal5,&tmp.aal5);
-	}
-	return error ? -EFAULT : 0;
-}
-
-
-int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg)
-{
-	struct atm_dev *dev;
-	struct list_head *p;
 	struct atm_vcc *vcc;
-	int *tmp_buf, *tmp_p;
-	void *buf;
-	int error,len,size,number, ret_val;
+	int error;
 
-	ret_val = 0;
 	vcc = ATM_SD(sock);
 	switch (cmd) {
 		case SIOCOUTQ:
 			if (sock->state != SS_CONNECTED ||
-			    !test_bit(ATM_VF_READY,&vcc->flags)) {
-				ret_val =  -EINVAL;
+			    !test_bit(ATM_VF_READY, &vcc->flags)) {
+				error =  -EINVAL;
 				goto done;
 			}
-			ret_val = put_user(vcc->sk->sk_sndbuf -
-					   atomic_read(&vcc->sk->sk_wmem_alloc),
-			    (int *) arg) ? -EFAULT : 0;
+			error = put_user(vcc->sk->sk_sndbuf -
+					 atomic_read(&vcc->sk->sk_wmem_alloc),
+					 (int *) arg) ? -EFAULT : 0;
 			goto done;
 		case SIOCINQ:
 			{
 				struct sk_buff *skb;
 
 				if (sock->state != SS_CONNECTED) {
-					ret_val = -EINVAL;
+					error = -EINVAL;
 					goto done;
 				}
 				skb = skb_peek(&vcc->sk->sk_receive_queue);
-				ret_val = put_user(skb ? skb->len : 0,(int *) arg)
-				    ? -EFAULT : 0;
+				error = put_user(skb ? skb->len : 0,
+					 	 (int *) arg) ? -EFAULT : 0;
 				goto done;
 			}
-		case ATM_GETNAMES:
-			if (get_user(buf,
-				     &((struct atm_iobuf *) arg)->buffer)) {
-				ret_val = -EFAULT;
-				goto done;
-			}
-			if (get_user(len,
-				     &((struct atm_iobuf *) arg)->length)) {
-				ret_val = -EFAULT;
-				goto done;
-			}
-			size = 0;
-			spin_lock(&atm_dev_lock);
-			list_for_each(p, &atm_devs)
-				size += sizeof(int);
-			if (size > len) {
-				spin_unlock(&atm_dev_lock);
-				ret_val = -E2BIG;
-				goto done;
-			}
-			tmp_buf = kmalloc(size, GFP_ATOMIC);
-			if (!tmp_buf) {
-				spin_unlock(&atm_dev_lock);
-				ret_val = -ENOMEM;
-				goto done;
-			}
-			tmp_p = tmp_buf;
-			list_for_each(p, &atm_devs) {
-				dev = list_entry(p, struct atm_dev, dev_list);
-				*tmp_p++ = dev->number;
-			}
-			spin_unlock(&atm_dev_lock);
-		        ret_val = ((copy_to_user(buf, tmp_buf, size)) ||
-			    put_user(size, &((struct atm_iobuf *) arg)->length)
-			    ) ? -EFAULT : 0;
-			kfree(tmp_buf);
-			goto done;
 		case SIOCGSTAMP: /* borrowed from IP */
 			if (!vcc->sk->sk_stamp.tv_sec) {
-				ret_val = -ENOENT;
+				error = -ENOENT;
 				goto done;
 			}
-			ret_val = copy_to_user((void *)arg, &vcc->sk->sk_stamp,
-			    sizeof(struct timeval)) ? -EFAULT : 0;
+			error = copy_to_user((void *)arg, &vcc->sk->sk_stamp,
+					     sizeof(struct timeval)) ? -EFAULT : 0;
 			goto done;
 		case ATM_SETSC:
 			printk(KERN_WARNING "ATM_SETSC is obsolete\n");
-			ret_val = 0;
+			error = 0;
 			goto done;
 		case ATMSIGD_CTRL:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			/*
@@ -696,28 +614,28 @@
 			 * have the same privledges that /proc/kcore needs
 			 */
 			if (!capable(CAP_SYS_RAWIO)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			error = sigd_attach(vcc);
-			if (!error) sock->state = SS_CONNECTED;
-			ret_val = error;
+			if (!error)
+				sock->state = SS_CONNECTED;
 			goto done;
 #if defined(CONFIG_ATM_CLIP) || defined(CONFIG_ATM_CLIP_MODULE)
 		case SIOCMKCLIP:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (try_atm_clip_ops()) {
-				ret_val = atm_clip_ops->clip_create(arg);
+				error = atm_clip_ops->clip_create(arg);
 				module_put(atm_clip_ops->owner);
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
 		case ATMARPD_CTRL:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 #if defined(CONFIG_ATM_CLIP_MODULE)
@@ -728,48 +646,47 @@
 				error = atm_clip_ops->atm_init_atmarp(vcc);
 				if (!error)
 					sock->state = SS_CONNECTED;
-				ret_val = error;
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
 		case ATMARP_MKIP:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (try_atm_clip_ops()) {
-				ret_val = atm_clip_ops->clip_mkip(vcc, arg);
+				error = atm_clip_ops->clip_mkip(vcc, arg);
 				module_put(atm_clip_ops->owner);
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
 		case ATMARP_SETENTRY:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (try_atm_clip_ops()) {
-				ret_val = atm_clip_ops->clip_setentry(vcc, arg);
+				error = atm_clip_ops->clip_setentry(vcc, arg);
 				module_put(atm_clip_ops->owner);
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
 		case ATMARP_ENCAP:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (try_atm_clip_ops()) {
-				ret_val = atm_clip_ops->clip_encap(vcc, arg);
+				error = atm_clip_ops->clip_encap(vcc, arg);
 				module_put(atm_clip_ops->owner);
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
 #endif
 #if defined(CONFIG_ATM_LANE) || defined(CONFIG_ATM_LANE_MODULE)
                 case ATMLEC_CTRL:
                         if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 #if defined(CONFIG_ATM_LANE_MODULE)
@@ -781,37 +698,36 @@
 				module_put(atm_lane_ops->owner);
 				if (error >= 0)
 					sock->state = SS_CONNECTED;
-				ret_val =  error;
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
                 case ATMLEC_MCAST:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (try_atm_lane_ops()) {
-				ret_val = atm_lane_ops->mcast_attach(vcc, (int) arg);
+				error = atm_lane_ops->mcast_attach(vcc, (int) arg);
 				module_put(atm_lane_ops->owner);
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
                 case ATMLEC_DATA:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (try_atm_lane_ops()) {
-				ret_val = atm_lane_ops->vcc_attach(vcc, (void *) arg);
+				error = atm_lane_ops->vcc_attach(vcc, (void *) arg);
 				module_put(atm_lane_ops->owner);
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
 #endif
 #if defined(CONFIG_ATM_MPOA) || defined(CONFIG_ATM_MPOA_MODULE)
 		case ATMMPC_CTRL:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 #if defined(CONFIG_ATM_MPOA_MODULE)
@@ -823,63 +739,62 @@
 				module_put(atm_mpoa_ops->owner);
 				if (error >= 0)
 					sock->state = SS_CONNECTED;
-				ret_val = error;
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
 		case ATMMPC_DATA:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (try_atm_mpoa_ops()) {
-				ret_val = atm_mpoa_ops->vcc_attach(vcc, arg);
+				error = atm_mpoa_ops->vcc_attach(vcc, arg);
 				module_put(atm_mpoa_ops->owner);
 			} else
-				ret_val = -ENOSYS;
+				error = -ENOSYS;
 			goto done;
 #endif
 #if defined(CONFIG_ATM_TCP) || defined(CONFIG_ATM_TCP_MODULE)
 		case SIOCSIFATMTCP:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (!atm_tcp_ops.attach) {
-				ret_val = -ENOPKG;
+				error = -ENOPKG;
 				goto done;
 			}
-			fops_get (&atm_tcp_ops);
-			error = atm_tcp_ops.attach(vcc,(int) arg);
-			if (error >= 0) sock->state = SS_CONNECTED;
-			else            fops_put (&atm_tcp_ops);
-			ret_val = error;
+			fops_get(&atm_tcp_ops);
+			error = atm_tcp_ops.attach(vcc, (int) arg);
+			if (error >= 0)
+				sock->state = SS_CONNECTED;
+			else
+				fops_put (&atm_tcp_ops);
 			goto done;
 		case ATMTCP_CREATE:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (!atm_tcp_ops.create_persistent) {
-				ret_val = -ENOPKG;
+				error = -ENOPKG;
 				goto done;
 			}
 			error = atm_tcp_ops.create_persistent((int) arg);
-			if (error < 0) fops_put (&atm_tcp_ops);
-			ret_val = error;
+			if (error < 0)
+				fops_put (&atm_tcp_ops);
 			goto done;
 		case ATMTCP_REMOVE:
 			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
+				error = -EPERM;
 				goto done;
 			}
 			if (!atm_tcp_ops.remove_persistent) {
-				ret_val = -ENOPKG;
+				error = -ENOPKG;
 				goto done;
 			}
 			error = atm_tcp_ops.remove_persistent((int) arg);
-			fops_put (&atm_tcp_ops);
-			ret_val = error;
+			fops_put(&atm_tcp_ops);
 			goto done;
 #endif
 		default:
@@ -887,182 +802,23 @@
 	}
 #if defined(CONFIG_PPPOATM) || defined(CONFIG_PPPOATM_MODULE)
 	if (pppoatm_ioctl_hook) {
-		ret_val = pppoatm_ioctl_hook(vcc, cmd, arg);
-		if (ret_val != -ENOIOCTLCMD)
+		error = pppoatm_ioctl_hook(vcc, cmd, arg);
+		if (error != -ENOIOCTLCMD)
 			goto done;
 	}
 #endif
 #if defined(CONFIG_ATM_BR2684) || defined(CONFIG_ATM_BR2684_MODULE)
 	if (br2684_ioctl_hook) {
-		ret_val = br2684_ioctl_hook(vcc, cmd, arg);
-		if (ret_val != -ENOIOCTLCMD)
+		error = br2684_ioctl_hook(vcc, cmd, arg);
+		if (error != -ENOIOCTLCMD)
 			goto done;
 	}
 #endif
-	if (get_user(buf,&((struct atmif_sioc *) arg)->arg)) {
-		ret_val = -EFAULT;
-		goto done;
-	}
-	if (get_user(len,&((struct atmif_sioc *) arg)->length)) {
-		ret_val = -EFAULT;
-		goto done;
-	}
-	if (get_user(number,&((struct atmif_sioc *) arg)->number)) {
-		ret_val = -EFAULT;
-		goto done;
-	}
-	if (!(dev = atm_dev_lookup(number))) {
-		ret_val = -ENODEV;
-		goto done;
-	}
-	
-	size = 0;
-	switch (cmd) {
-		case ATM_GETTYPE:
-			size = strlen(dev->type)+1;
-			if (copy_to_user(buf,dev->type,size)) {
-				ret_val = -EFAULT;
-				goto done_release;
-			}
-			break;
-		case ATM_GETESI:
-			size = ESI_LEN;
-			if (copy_to_user(buf,dev->esi,size)) {
-				ret_val = -EFAULT;
-				goto done_release;
-			}
-			break;
-		case ATM_SETESI:
-			{
-				int i;
 
-				for (i = 0; i < ESI_LEN; i++)
-					if (dev->esi[i]) {
-						ret_val = -EEXIST;
-						goto done_release;
-					}
-			}
-			/* fall through */
-		case ATM_SETESIF:
-			{
-				unsigned char esi[ESI_LEN];
-
-				if (!capable(CAP_NET_ADMIN)) {
-					ret_val = -EPERM;
-					goto done_release;
-				}
-				if (copy_from_user(esi,buf,ESI_LEN)) {
-					ret_val = -EFAULT;
-					goto done_release;
-				}
-				memcpy(dev->esi,esi,ESI_LEN);
-				ret_val =  ESI_LEN;
-				goto done_release;
-			}
-		case ATM_GETSTATZ:
-			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
-				goto done_release;
-			}
-			/* fall through */
-		case ATM_GETSTAT:
-			size = sizeof(struct atm_dev_stats);
-			error = fetch_stats(dev,buf,cmd == ATM_GETSTATZ);
-			if (error) {
-				ret_val = error;
-				goto done_release;
-			}
-			break;
-		case ATM_GETCIRANGE:
-			size = sizeof(struct atm_cirange);
-			if (copy_to_user(buf,&dev->ci_range,size)) {
-				ret_val = -EFAULT;
-				goto done_release;
-			}
-			break;
-		case ATM_GETLINKRATE:
-			size = sizeof(int);
-			if (copy_to_user(buf,&dev->link_rate,size)) {
-				ret_val = -EFAULT;
-				goto done_release;
-			}
-			break;
-		case ATM_RSTADDR:
-			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
-				goto done_release;
-			}
-			atm_reset_addr(dev);
-			break;
-		case ATM_ADDADDR:
-		case ATM_DELADDR:
-			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
-				goto done_release;
-			}
-			{
-				struct sockaddr_atmsvc addr;
-
-				if (copy_from_user(&addr,buf,sizeof(addr))) {
-					ret_val = -EFAULT;
-					goto done_release;
-				}
-				if (cmd == ATM_ADDADDR)
-					ret_val = atm_add_addr(dev,&addr);
-				else
-					ret_val = atm_del_addr(dev,&addr);
-				goto done_release;
-			}
-		case ATM_GETADDR:
-			size = atm_get_addr(dev,buf,len);
-			if (size < 0)
-				ret_val = size;
-			else
-			/* may return 0, but later on size == 0 means "don't
-			   write the length" */
-				ret_val = put_user(size,
-						   &((struct atmif_sioc *) arg)->length) ? -EFAULT : 0;
-			goto done_release;
-		case ATM_SETLOOP:
-			if (__ATM_LM_XTRMT((int) (long) buf) &&
-			    __ATM_LM_XTLOC((int) (long) buf) >
-			    __ATM_LM_XTRMT((int) (long) buf)) {
-				ret_val = -EINVAL;
-				goto done_release;
-			}
-			/* fall through */
-		case ATM_SETCIRANGE:
-		case SONET_GETSTATZ:
-		case SONET_SETDIAG:
-		case SONET_CLRDIAG:
-		case SONET_SETFRAMING:
-			if (!capable(CAP_NET_ADMIN)) {
-				ret_val = -EPERM;
-				goto done_release;
-			}
-			/* fall through */
-		default:
-			if (!dev->ops->ioctl) {
-				ret_val = -EINVAL;
-				goto done_release;
-			}
-			size = dev->ops->ioctl(dev,cmd,buf);
-			if (size < 0) {
-				ret_val = (size == -ENOIOCTLCMD ? -EINVAL : size);
-				goto done_release;
-			}
-	}
-	
-	if (size)
-		ret_val =  put_user(size,&((struct atmif_sioc *) arg)->length) ?
-			-EFAULT : 0;
-	else
-		ret_val = 0;
-done_release:
-	atm_dev_release(dev);
+	error = atm_dev_ioctl(cmd, arg);
 
 done:
-	return ret_val;
+	return error;
 }
 
 
@@ -1120,14 +876,16 @@
 	return check_tp(&qos->rxtp);
 }
 
-
-static int atm_do_setsockopt(struct socket *sock,int level,int optname,
-    void *optval,int optlen)
+int vcc_setsockopt(struct socket *sock, int level, int optname,
+		   char *optval, int optlen)
 {
 	struct atm_vcc *vcc;
 	unsigned long value;
 	int error;
 
+	if (__SO_LEVEL_MATCH(optname, level) && optlen != __SO_SIZE(optname))
+		return -EINVAL;
+
 	vcc = ATM_SD(sock);
 	switch (optname) {
 		case SO_ATMQOS:
@@ -1161,10 +919,16 @@
 }
 
 
-static int atm_do_getsockopt(struct socket *sock,int level,int optname,
-    void *optval,int optlen)
+int vcc_getsockopt(struct socket *sock, int level, int optname,
+		   char *optval, int *optlen)
 {
 	struct atm_vcc *vcc;
+	int len;
+
+	if (get_user(len, optlen))
+		return -EFAULT;
+	if (__SO_LEVEL_MATCH(optname, level) && len != __SO_SIZE(optname))
+		return -EINVAL;
 
 	vcc = ATM_SD(sock);
 	switch (optname) {
@@ -1195,28 +959,7 @@
 			break;
 	}
 	if (!vcc->dev || !vcc->dev->ops->getsockopt) return -EINVAL;
-	return vcc->dev->ops->getsockopt(vcc,level,optname,optval,optlen);
-}
-
-
-int atm_setsockopt(struct socket *sock,int level,int optname,char *optval,
-    int optlen)
-{
-	if (__SO_LEVEL_MATCH(optname, level) && optlen != __SO_SIZE(optname))
-		return -EINVAL;
-	return atm_do_setsockopt(sock,level,optname,optval,optlen);
-}
-
-
-int atm_getsockopt(struct socket *sock,int level,int optname,
-    char *optval,int *optlen)
-{
-	int len;
-
-	if (get_user(len,optlen)) return -EFAULT;
-	if (__SO_LEVEL_MATCH(optname, level) && len != __SO_SIZE(optname))
-		return -EINVAL;
-	return atm_do_getsockopt(sock,level,optname,optval,len);
+	return vcc->dev->ops->getsockopt(vcc, level, optname, optval, len);
 }
 
 
diff -Nru a/net/atm/common.h b/net/atm/common.h
--- a/net/atm/common.h	Wed Jun 18 23:42:08 2003
+++ b/net/atm/common.h	Wed Jun 18 23:42:08 2003
@@ -12,19 +12,18 @@
 
 int atm_create(struct socket *sock,int protocol,int family);
 int atm_release(struct socket *sock);
-int atm_connect(struct socket *sock,int itf,short vpi,int vci);
-int atm_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
-		int total_len, int flags);
-int atm_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
+int vcc_connect(struct socket *sock, int itf, short vpi, int vci);
+int vcc_recvmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *msg,
+		int size, int flags);
+int vcc_sendmsg(struct kiocb *iocb, struct socket *sock, struct msghdr *m,
 		int total_len);
 unsigned int atm_poll(struct file *file,struct socket *sock,poll_table *wait);
-int atm_ioctl(struct socket *sock,unsigned int cmd,unsigned long arg);
-int atm_setsockopt(struct socket *sock,int level,int optname,char *optval,
-    int optlen);
-int atm_getsockopt(struct socket *sock,int level,int optname,char *optval,
-    int *optlen);
+int vcc_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg);
+int vcc_setsockopt(struct socket *sock, int level, int optname, char *optval,
+		   int optlen);
+int vcc_getsockopt(struct socket *sock, int level, int optname, char *optval,
+		   int *optlen);
 
-int atm_connect_vcc(struct atm_vcc *vcc,int itf,short vpi,int vci);
 void atm_release_vcc_sk(struct sock *sk,int free_sk);
 void atm_shutdown_dev(struct atm_dev *dev);
 
diff -Nru a/net/atm/lec.c b/net/atm/lec.c
--- a/net/atm/lec.c	Wed Jun 18 23:42:08 2003
+++ b/net/atm/lec.c	Wed Jun 18 23:42:08 2003
@@ -1079,7 +1079,7 @@
 		clear_bit(ATM_VF_READY,&entry->vcc->flags);
                 entry->vcc->push(entry->vcc, NULL);
 #endif
-		atm_async_release_vcc(entry->vcc, -EPIPE);
+		vcc_release_async(entry->vcc, -EPIPE);
                 entry->vcc = NULL;
         }
         if (entry->recv_vcc) {
@@ -1089,7 +1089,7 @@
 		clear_bit(ATM_VF_READY,&entry->recv_vcc->flags);
                 entry->recv_vcc->push(entry->recv_vcc, NULL);
 #endif
-		atm_async_release_vcc(entry->recv_vcc, -EPIPE);
+		vcc_release_async(entry->recv_vcc, -EPIPE);
                 entry->recv_vcc = NULL;
         }        
 }
diff -Nru a/net/atm/mpoa_caches.c b/net/atm/mpoa_caches.c
--- a/net/atm/mpoa_caches.c	Wed Jun 18 23:42:08 2003
+++ b/net/atm/mpoa_caches.c	Wed Jun 18 23:42:08 2003
@@ -212,7 +212,7 @@
 			client->eg_ops->put(eg_entry);
 			return;
 		}
-		atm_async_release_vcc(vcc, -EPIPE);
+		vcc_release_async(vcc, -EPIPE);
 	}
 
 	return;
@@ -447,7 +447,7 @@
 			client->in_ops->put(in_entry);
 			return;
 		}
-		atm_async_release_vcc(vcc, -EPIPE);
+		vcc_release_async(vcc, -EPIPE);
 	}
 
 	return;
diff -Nru a/net/atm/pvc.c b/net/atm/pvc.c
--- a/net/atm/pvc.c	Wed Jun 18 23:42:06 2003
+++ b/net/atm/pvc.c	Wed Jun 18 23:42:06 2003
@@ -31,20 +31,29 @@
 static int pvc_bind(struct socket *sock,struct sockaddr *sockaddr,
     int sockaddr_len)
 {
+	struct sock *sk = sock->sk;
 	struct sockaddr_atmpvc *addr;
 	struct atm_vcc *vcc;
+	int error;
 
 	if (sockaddr_len != sizeof(struct sockaddr_atmpvc)) return -EINVAL;
 	addr = (struct sockaddr_atmpvc *) sockaddr;
 	if (addr->sap_family != AF_ATMPVC) return -EAFNOSUPPORT;
+	lock_sock(sk);
 	vcc = ATM_SD(sock);
-	if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) return -EBADFD;
+	if (!test_bit(ATM_VF_HASQOS, &vcc->flags)) {
+		error = -EBADFD;
+		goto out;
+	}
 	if (test_bit(ATM_VF_PARTIAL,&vcc->flags)) {
 		if (vcc->vpi != ATM_VPI_UNSPEC) addr->sap_addr.vpi = vcc->vpi;
 		if (vcc->vci != ATM_VCI_UNSPEC) addr->sap_addr.vci = vcc->vci;
 	}
-	return atm_connect(sock,addr->sap_addr.itf,addr->sap_addr.vpi,
-	    addr->sap_addr.vci);
+	error = vcc_connect(sock, addr->sap_addr.itf, addr->sap_addr.vpi,
+			    addr->sap_addr.vci);
+out:
+	release_sock(sk);
+	return error;
 }
 
 
@@ -54,6 +63,31 @@
 	return pvc_bind(sock,sockaddr,sockaddr_len);
 }
 
+static int pvc_setsockopt(struct socket *sock, int level, int optname,
+			  char *optval, int optlen)
+{
+	struct sock *sk = sock->sk;
+	int error;
+
+	lock_sock(sk);
+	error = vcc_setsockopt(sock, level, optname, optval, optlen);
+	release_sock(sk);
+	return error;
+}
+
+
+static int pvc_getsockopt(struct socket *sock, int level, int optname,
+		          char *optval, int *optlen)
+{
+	struct sock *sk = sock->sk;
+	int error;
+
+	lock_sock(sk);
+	error = vcc_getsockopt(sock, level, optname, optval, optlen);
+	release_sock(sk);
+	return error;
+}
+
 
 static int pvc_getname(struct socket *sock,struct sockaddr *sockaddr,
     int *sockaddr_len,int peer)
@@ -72,7 +106,7 @@
 }
 
 
-static struct proto_ops SOCKOPS_WRAPPED(pvc_proto_ops) = {
+static struct proto_ops pvc_proto_ops = {
 	.family =	PF_ATMPVC,
 
 	.release =	atm_release,
@@ -82,20 +116,16 @@
 	.accept =	sock_no_accept,
 	.getname =	pvc_getname,
 	.poll =		atm_poll,
-	.ioctl =	atm_ioctl,
+	.ioctl =	vcc_ioctl,
 	.listen =	sock_no_listen,
 	.shutdown =	pvc_shutdown,
-	.setsockopt =	atm_setsockopt,
-	.getsockopt =	atm_getsockopt,
-	.sendmsg =	atm_sendmsg,
-	.recvmsg =	atm_recvmsg,
+	.setsockopt =	pvc_setsockopt,
+	.getsockopt =	pvc_getsockopt,
+	.sendmsg =	vcc_sendmsg,
+	.recvmsg =	vcc_recvmsg,
 	.mmap =		sock_no_mmap,
 	.sendpage =	sock_no_sendpage,
 };
-
-
-#include <linux/smp_lock.h>
-SOCKOPS_WRAP(pvc_proto, PF_ATMPVC);
 
 
 static int pvc_create(struct socket *sock,int protocol)
diff -Nru a/net/atm/resources.c b/net/atm/resources.c
--- a/net/atm/resources.c	Wed Jun 18 23:42:09 2003
+++ b/net/atm/resources.c	Wed Jun 18 23:42:09 2003
@@ -12,6 +12,7 @@
 #include <linux/ctype.h>
 #include <linux/string.h>
 #include <linux/atmdev.h>
+#include <linux/sonet.h>
 #include <linux/kernel.h> /* for barrier */
 #include <linux/module.h>
 #include <linux/bitops.h>
@@ -19,6 +20,7 @@
 
 #include "common.h"
 #include "resources.h"
+#include "addr.h"
 
 
 #ifndef NULL
@@ -170,6 +172,240 @@
 		dev->ops->dev_close(dev);
 	atm_dev_deregister(dev);
 }
+
+
+static void copy_aal_stats(struct k_atm_aal_stats *from,
+    struct atm_aal_stats *to)
+{
+#define __HANDLE_ITEM(i) to->i = atomic_read(&from->i)
+	__AAL_STAT_ITEMS
+#undef __HANDLE_ITEM
+}
+
+
+static void subtract_aal_stats(struct k_atm_aal_stats *from,
+    struct atm_aal_stats *to)
+{
+#define __HANDLE_ITEM(i) atomic_sub(to->i, &from->i)
+	__AAL_STAT_ITEMS
+#undef __HANDLE_ITEM
+}
+
+
+static int fetch_stats(struct atm_dev *dev, struct atm_dev_stats *arg, int zero)
+{
+	struct atm_dev_stats tmp;
+	int error = 0;
+
+	copy_aal_stats(&dev->stats.aal0, &tmp.aal0);
+	copy_aal_stats(&dev->stats.aal34, &tmp.aal34);
+	copy_aal_stats(&dev->stats.aal5, &tmp.aal5);
+	if (arg)
+		error = copy_to_user(arg, &tmp, sizeof(tmp));
+	if (zero && !error) {
+		subtract_aal_stats(&dev->stats.aal0, &tmp.aal0);
+		subtract_aal_stats(&dev->stats.aal34, &tmp.aal34);
+		subtract_aal_stats(&dev->stats.aal5, &tmp.aal5);
+	}
+	return error ? -EFAULT : 0;
+}
+
+
+int atm_dev_ioctl(unsigned int cmd, unsigned long arg)
+{
+	void *buf;
+	int error, len, number, size = 0;
+	struct atm_dev *dev;
+	struct list_head *p;
+	int *tmp_buf, *tmp_p;
+
+	switch (cmd) {
+		case ATM_GETNAMES:
+			if (get_user(buf, &((struct atm_iobuf *) arg)->buffer))
+				return -EFAULT;
+			if (get_user(len, &((struct atm_iobuf *) arg)->length))
+				return -EFAULT;
+			spin_lock(&atm_dev_lock);
+			list_for_each(p, &atm_devs)
+				size += sizeof(int);
+			if (size > len) {
+				spin_unlock(&atm_dev_lock);
+				return -E2BIG;
+			}
+			tmp_buf = kmalloc(size, GFP_ATOMIC);
+			if (!tmp_buf) {
+				spin_unlock(&atm_dev_lock);
+				return -ENOMEM;
+			}
+			tmp_p = tmp_buf;
+			list_for_each(p, &atm_devs) {
+				dev = list_entry(p, struct atm_dev, dev_list);
+				*tmp_p++ = dev->number;
+			}
+			spin_unlock(&atm_dev_lock);
+		        error = ((copy_to_user(buf, tmp_buf, size)) ||
+					put_user(size, &((struct atm_iobuf *) arg)->length))
+						? -EFAULT : 0;
+			kfree(tmp_buf);
+			return error;
+		default:
+			break;
+	}
+
+	if (get_user(buf, &((struct atmif_sioc *) arg)->arg))
+		return -EFAULT;
+	if (get_user(len, &((struct atmif_sioc *) arg)->length))
+		return -EFAULT;
+	if (get_user(number, &((struct atmif_sioc *) arg)->number))
+		return -EFAULT;
+
+	if (!(dev = atm_dev_lookup(number)))
+		return -ENODEV;
+	
+	switch (cmd) {
+		case ATM_GETTYPE:
+			size = strlen(dev->type) + 1;
+			if (copy_to_user(buf, dev->type, size)) {
+				error = -EFAULT;
+				goto done;
+			}
+			break;
+		case ATM_GETESI:
+			size = ESI_LEN;
+			if (copy_to_user(buf, dev->esi, size)) {
+				error = -EFAULT;
+				goto done;
+			}
+			break;
+		case ATM_SETESI:
+			{
+				int i;
+
+				for (i = 0; i < ESI_LEN; i++)
+					if (dev->esi[i]) {
+						error = -EEXIST;
+						goto done;
+					}
+			}
+			/* fall through */
+		case ATM_SETESIF:
+			{
+				unsigned char esi[ESI_LEN];
+
+				if (!capable(CAP_NET_ADMIN)) {
+					error = -EPERM;
+					goto done;
+				}
+				if (copy_from_user(esi, buf, ESI_LEN)) {
+					error = -EFAULT;
+					goto done;
+				}
+				memcpy(dev->esi, esi, ESI_LEN);
+				error =  ESI_LEN;
+				goto done;
+			}
+		case ATM_GETSTATZ:
+			if (!capable(CAP_NET_ADMIN)) {
+				error = -EPERM;
+				goto done;
+			}
+			/* fall through */
+		case ATM_GETSTAT:
+			size = sizeof(struct atm_dev_stats);
+			error = fetch_stats(dev, buf, cmd == ATM_GETSTATZ);
+			if (error)
+				goto done;
+			break;
+		case ATM_GETCIRANGE:
+			size = sizeof(struct atm_cirange);
+			if (copy_to_user(buf, &dev->ci_range, size)) {
+				error = -EFAULT;
+				goto done;
+			}
+			break;
+		case ATM_GETLINKRATE:
+			size = sizeof(int);
+			if (copy_to_user(buf, &dev->link_rate, size)) {
+				error = -EFAULT;
+				goto done;
+			}
+			break;
+		case ATM_RSTADDR:
+			if (!capable(CAP_NET_ADMIN)) {
+				error = -EPERM;
+				goto done;
+			}
+			atm_reset_addr(dev);
+			break;
+		case ATM_ADDADDR:
+		case ATM_DELADDR:
+			if (!capable(CAP_NET_ADMIN)) {
+				error = -EPERM;
+				goto done;
+			}
+			{
+				struct sockaddr_atmsvc addr;
+
+				if (copy_from_user(&addr, buf, sizeof(addr))) {
+					error = -EFAULT;
+					goto done;
+				}
+				if (cmd == ATM_ADDADDR)
+					error = atm_add_addr(dev, &addr);
+				else
+					error = atm_del_addr(dev, &addr);
+				goto done;
+			}
+		case ATM_GETADDR:
+			error = atm_get_addr(dev, buf, len);
+			if (error < 0)
+				goto done;
+			size = error;
+			/* may return 0, but later on size == 0 means "don't
+			   write the length" */
+			error = put_user(size, &((struct atmif_sioc *) arg)->length)
+				? -EFAULT : 0;
+			goto done;
+		case ATM_SETLOOP:
+			if (__ATM_LM_XTRMT((int) (long) buf) &&
+			    __ATM_LM_XTLOC((int) (long) buf) >
+			    __ATM_LM_XTRMT((int) (long) buf)) {
+				error = -EINVAL;
+				goto done;
+			}
+			/* fall through */
+		case ATM_SETCIRANGE:
+		case SONET_GETSTATZ:
+		case SONET_SETDIAG:
+		case SONET_CLRDIAG:
+		case SONET_SETFRAMING:
+			if (!capable(CAP_NET_ADMIN)) {
+				error = -EPERM;
+				goto done;
+			}
+			/* fall through */
+		default:
+			if (!dev->ops->ioctl) {
+				error = -EINVAL;
+				goto done;
+			}
+			size = dev->ops->ioctl(dev, cmd, buf);
+			if (size < 0) {
+				error = (size == -ENOIOCTLCMD ? -EINVAL : size);
+				goto done;
+			}
+	}
+	
+	if (size)
+		error = put_user(size, &((struct atmif_sioc *) arg)->length)
+			? -EFAULT : 0;
+	else
+		error = 0;
+done:
+	atm_dev_release(dev);
+	return error;
+}
+
 
 struct sock *alloc_atm_vcc_sk(int family)
 {
diff -Nru a/net/atm/resources.h b/net/atm/resources.h
--- a/net/atm/resources.h	Wed Jun 18 23:42:08 2003
+++ b/net/atm/resources.h	Wed Jun 18 23:42:08 2003
@@ -16,6 +16,7 @@
 
 struct sock *alloc_atm_vcc_sk(int family);
 void free_atm_vcc_sk(struct sock *sk);
+int atm_dev_ioctl(unsigned int cmd, unsigned long arg);
 
 
 #ifdef CONFIG_PROC_FS
diff -Nru a/net/atm/signaling.c b/net/atm/signaling.c
--- a/net/atm/signaling.c	Wed Jun 18 23:42:08 2003
+++ b/net/atm/signaling.c	Wed Jun 18 23:42:08 2003
@@ -124,14 +124,16 @@
 			clear_bit(ATM_VF_REGIS,&vcc->flags);
 			clear_bit(ATM_VF_READY,&vcc->flags);
 			vcc->reply = msg->reply;
+			vcc->sk->sk_err = -msg->reply;
 			break;
 		case as_indicate:
 			vcc = *(struct atm_vcc **) &msg->listen_vcc;
 			DPRINTK("as_indicate!!!\n");
+			lock_sock(vcc->sk);
 			if (vcc->sk->sk_ack_backlog ==
 			    vcc->sk->sk_max_ack_backlog) {
 				sigd_enq(0,as_reject,vcc,NULL,NULL);
-				return 0;
+				goto as_indicate_complete;
 			}
 			vcc->sk->sk_ack_backlog++;
 			skb_queue_tail(&vcc->sk->sk_receive_queue, skb);
@@ -140,11 +142,14 @@
 				    &vcc->sleep);
 				vcc->callback(vcc);
 			}
+as_indicate_complete:
+			release_sock(vcc->sk);
 			return 0;
 		case as_close:
 			set_bit(ATM_VF_RELEASED,&vcc->flags);
 			clear_bit(ATM_VF_READY,&vcc->flags);
 			vcc->reply = msg->reply;
+			vcc->sk->sk_err = -msg->reply;
 			break;
 		case as_modify:
 			modify_qos(vcc,msg);
@@ -202,6 +207,7 @@
 		    !test_bit(ATM_VF_META,&vcc->flags)) {
 			set_bit(ATM_VF_RELEASED,&vcc->flags);
 			vcc->reply = -EUNATCH;
+			vcc->sk->sk_err = EUNATCH;
 			wake_up(&vcc->sleep);
 		}
 		vcc = vcc->next;
diff -Nru a/net/atm/svc.c b/net/atm/svc.c
--- a/net/atm/svc.c	Wed Jun 18 23:42:08 2003
+++ b/net/atm/svc.c	Wed Jun 18 23:42:08 2003
@@ -59,18 +59,18 @@
 
 static void svc_disconnect(struct atm_vcc *vcc)
 {
-	DECLARE_WAITQUEUE(wait,current);
+	DEFINE_WAIT(wait);
 	struct sk_buff *skb;
 
 	DPRINTK("svc_disconnect %p\n",vcc);
 	if (test_bit(ATM_VF_REGIS,&vcc->flags)) {
-		add_wait_queue(&vcc->sleep,&wait);
+		prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
 		sigd_enq(vcc,as_close,NULL,NULL,NULL);
 		while (!test_bit(ATM_VF_RELEASED,&vcc->flags) && sigd) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
 			schedule();
+			prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
 		}
-		remove_wait_queue(&vcc->sleep,&wait);
+		finish_wait(&vcc->sleep, &wait);
 	}
 	/* beware - socket is still in use by atmsigd until the last
 	   as_indicate has been answered */
@@ -107,80 +107,138 @@
 static int svc_bind(struct socket *sock,struct sockaddr *sockaddr,
     int sockaddr_len)
 {
-	DECLARE_WAITQUEUE(wait,current);
+	DEFINE_WAIT(wait);
+	struct sock *sk = sock->sk;
 	struct sockaddr_atmsvc *addr;
 	struct atm_vcc *vcc;
+	int error;
 
-	if (sockaddr_len != sizeof(struct sockaddr_atmsvc)) return -EINVAL;
-	if (sock->state == SS_CONNECTED) return -EISCONN;
-	if (sock->state != SS_UNCONNECTED) return -EINVAL;
+	if (sockaddr_len != sizeof(struct sockaddr_atmsvc))
+		return -EINVAL;
+	lock_sock(sk);
+	if (sock->state == SS_CONNECTED) {
+		error = -EISCONN;
+		goto out;
+	}
+	if (sock->state != SS_UNCONNECTED) {
+		error = -EINVAL;
+		goto out;
+	}
 	vcc = ATM_SD(sock);
-	if (test_bit(ATM_VF_SESSION,&vcc->flags)) return -EINVAL;
+	if (test_bit(ATM_VF_SESSION, &vcc->flags)) {
+		error = -EINVAL;
+		goto out;
+	}
 	addr = (struct sockaddr_atmsvc *) sockaddr;
-	if (addr->sas_family != AF_ATMSVC) return -EAFNOSUPPORT;
+	if (addr->sas_family != AF_ATMSVC) {
+		error = -EAFNOSUPPORT;
+		goto out;
+	}
 	clear_bit(ATM_VF_BOUND,&vcc->flags);
 	    /* failing rebind will kill old binding */
 	/* @@@ check memory (de)allocation on rebind */
-	if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) return -EBADFD;
+	if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) {
+		error = -EBADFD;
+		goto out;
+	}
 	vcc->local = *addr;
 	vcc->reply = WAITING;
-	add_wait_queue(&vcc->sleep,&wait);
+	prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
 	sigd_enq(vcc,as_bind,NULL,NULL,&vcc->local);
 	while (vcc->reply == WAITING && sigd) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule();
+		prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
 	}
-	remove_wait_queue(&vcc->sleep,&wait);
+	finish_wait(&vcc->sleep, &wait);
 	clear_bit(ATM_VF_REGIS,&vcc->flags); /* doesn't count */
-	if (!sigd) return -EUNATCH;
-        if (!vcc->reply) set_bit(ATM_VF_BOUND,&vcc->flags);
-	return vcc->reply;
+	if (!sigd) {
+		error = -EUNATCH;
+		goto out;
+	}
+        if (!vcc->reply)
+		set_bit(ATM_VF_BOUND,&vcc->flags);
+	error = vcc->reply;
+out:
+	release_sock(sk);
+	return error;
 }
 
 
 static int svc_connect(struct socket *sock,struct sockaddr *sockaddr,
     int sockaddr_len,int flags)
 {
-	DECLARE_WAITQUEUE(wait,current);
+	DEFINE_WAIT(wait);
+	struct sock *sk = sock->sk;
 	struct sockaddr_atmsvc *addr;
 	struct atm_vcc *vcc = ATM_SD(sock);
 	int error;
 
 	DPRINTK("svc_connect %p\n",vcc);
-	if (sockaddr_len != sizeof(struct sockaddr_atmsvc)) return -EINVAL;
-	if (sock->state == SS_CONNECTED) return -EISCONN;
-	if (sock->state == SS_CONNECTING) {
-		if (vcc->reply == WAITING) return -EALREADY;
-		sock->state = SS_UNCONNECTED;
-		if (vcc->reply) return vcc->reply;
+	lock_sock(sk);
+	if (sockaddr_len != sizeof(struct sockaddr_atmsvc)) {
+		error = -EINVAL;
+		goto out;
 	}
-	else {
-		int error;
 
-		if (sock->state != SS_UNCONNECTED) return -EINVAL;
-		if (test_bit(ATM_VF_SESSION,&vcc->flags)) return -EINVAL;
+	switch (sock->state) {
+	default:
+		error = -EINVAL;
+		goto out;
+	case SS_CONNECTED:
+		error = -EISCONN;
+		goto out;
+	case SS_CONNECTING:
+		if (vcc->reply == WAITING) {
+			error = -EALREADY;
+			goto out;
+		}
+		sock->state = SS_UNCONNECTED;
+		if (vcc->reply) {
+			error = vcc->reply;
+			goto out;
+		}
+		break;
+	case SS_UNCONNECTED:
+		if (test_bit(ATM_VF_SESSION, &vcc->flags)) {
+			error = -EINVAL;
+			goto out;
+		}
 		addr = (struct sockaddr_atmsvc *) sockaddr;
-		if (addr->sas_family != AF_ATMSVC) return -EAFNOSUPPORT;
-		if (!test_bit(ATM_VF_HASQOS,&vcc->flags)) return -EBADFD;
+		if (addr->sas_family != AF_ATMSVC) {
+			error = -EAFNOSUPPORT;
+			goto out;
+		}
+		if (!test_bit(ATM_VF_HASQOS, &vcc->flags)) {
+			error = -EBADFD;
+			goto out;
+		}
 		if (vcc->qos.txtp.traffic_class == ATM_ANYCLASS ||
-		    vcc->qos.rxtp.traffic_class == ATM_ANYCLASS)
-			return -EINVAL;
+		    vcc->qos.rxtp.traffic_class == ATM_ANYCLASS) {
+			error = -EINVAL;
+			goto out;
+		}
 		if (!vcc->qos.txtp.traffic_class &&
-		    !vcc->qos.rxtp.traffic_class) return -EINVAL;
+		    !vcc->qos.rxtp.traffic_class) {
+			error = -EINVAL;
+			goto out;
+		}
 		vcc->remote = *addr;
 		vcc->reply = WAITING;
-		add_wait_queue(&vcc->sleep,&wait);
+		prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
 		sigd_enq(vcc,as_connect,NULL,NULL,&vcc->remote);
 		if (flags & O_NONBLOCK) {
-			remove_wait_queue(&vcc->sleep,&wait);
+			finish_wait(&vcc->sleep, &wait);
 			sock->state = SS_CONNECTING;
-			return -EINPROGRESS;
+			error = -EINPROGRESS;
+			goto out;
 		}
 		error = 0;
 		while (vcc->reply == WAITING && sigd) {
-			set_current_state(TASK_INTERRUPTIBLE);
 			schedule();
-			if (!signal_pending(current)) continue;
+			if (!signal_pending(current)) {
+				prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
+				continue;
+			}
 			DPRINTK("*ABORT*\n");
 			/*
 			 * This is tricky:
@@ -196,13 +254,13 @@
 			 */
 			sigd_enq(vcc,as_close,NULL,NULL,NULL);
 			while (vcc->reply == WAITING && sigd) {
-				set_current_state(TASK_UNINTERRUPTIBLE);
+				prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
 				schedule();
 			}
 			if (!vcc->reply)
 				while (!test_bit(ATM_VF_RELEASED,&vcc->flags)
 				    && sigd) {
-					set_current_state(TASK_UNINTERRUPTIBLE);
+					prepare_to_wait(&vcc->sleep, &wait, TASK_INTERRUPTIBLE);
 					schedule();
 				}
 			clear_bit(ATM_VF_REGIS,&vcc->flags);
@@ -212,10 +270,17 @@
 			error = -EINTR;
 			break;
 		}
-		remove_wait_queue(&vcc->sleep,&wait);
-		if (error) return error;
-		if (!sigd) return -EUNATCH;
-		if (vcc->reply) return vcc->reply;
+		finish_wait(&vcc->sleep, &wait);
+		if (error)
+			goto out;
+		if (!sigd) {
+			error = -EUNATCH;
+			goto out;
+		}
+		if (vcc->reply) {
+			error = vcc->reply;
+			goto out;
+		}
 	}
 /*
  * Not supported yet
@@ -228,56 +293,73 @@
 /*
  * #endif
  */
-	if (!(error = atm_connect(sock,vcc->itf,vcc->vpi,vcc->vci)))
+	if (!(error = vcc_connect(sock, vcc->itf, vcc->vpi, vcc->vci)))
 		sock->state = SS_CONNECTED;
 	else (void) svc_disconnect(vcc);
+out:
+	release_sock(sk);
 	return error;
 }
 
 
 static int svc_listen(struct socket *sock,int backlog)
 {
-	DECLARE_WAITQUEUE(wait,current);
+	DEFINE_WAIT(wait);
+	struct sock *sk = sock->sk;
 	struct atm_vcc *vcc = ATM_SD(sock);
+	int error;
 
 	DPRINTK("svc_listen %p\n",vcc);
+	lock_sock(sk);
 	/* let server handle listen on unbound sockets */
-	if (test_bit(ATM_VF_SESSION,&vcc->flags)) return -EINVAL;
+	if (test_bit(ATM_VF_SESSION,&vcc->flags)) {
+		error = -EINVAL;
+		goto out;
+	}
 	vcc->reply = WAITING;
-	add_wait_queue(&vcc->sleep,&wait);
+	prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
 	sigd_enq(vcc,as_listen,NULL,NULL,&vcc->local);
 	while (vcc->reply == WAITING && sigd) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule();
+		prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
+	}
+	finish_wait(&vcc->sleep, &wait);
+	if (!sigd) {
+		error = -EUNATCH;
+		goto out;
 	}
-	remove_wait_queue(&vcc->sleep,&wait);
-	if (!sigd) return -EUNATCH;
 	set_bit(ATM_VF_LISTEN,&vcc->flags);
 	vcc->sk->sk_max_ack_backlog = backlog > 0 ? backlog :
 						    ATM_BACKLOG_DEFAULT;
-	return vcc->reply;
+	error = vcc->reply;
+out:
+	release_sock(sk);
+	return error;
 }
 
 
 static int svc_accept(struct socket *sock,struct socket *newsock,int flags)
 {
+	struct sock *sk = sock->sk;
 	struct sk_buff *skb;
 	struct atmsvc_msg *msg;
 	struct atm_vcc *old_vcc = ATM_SD(sock);
 	struct atm_vcc *new_vcc;
 	int error;
 
+	lock_sock(sk);
+
 	error = svc_create(newsock,0);
 	if (error)
-		return error;
+		goto out;
 
 	new_vcc = ATM_SD(newsock);
 
 	DPRINTK("svc_accept %p -> %p\n",old_vcc,new_vcc);
 	while (1) {
-		DECLARE_WAITQUEUE(wait,current);
+		DEFINE_WAIT(wait);
 
-		add_wait_queue(&old_vcc->sleep,&wait);
+		prepare_to_wait(&old_vcc->sleep, &wait, TASK_INTERRUPTIBLE);
 		while (!(skb = skb_dequeue(&old_vcc->sk->sk_receive_queue)) &&
 		       sigd) {
 			if (test_bit(ATM_VF_RELEASED,&old_vcc->flags)) break;
@@ -289,46 +371,63 @@
 				error = -EAGAIN;
 				break;
 			}
-			set_current_state(TASK_INTERRUPTIBLE);
+			release_sock(sk);
 			schedule();
+			lock_sock(sk);
 			if (signal_pending(current)) {
 				error = -ERESTARTSYS;
 				break;
 			}
+			prepare_to_wait(&old_vcc->sleep, &wait, TASK_INTERRUPTIBLE);
+		}
+		finish_wait(&old_vcc->sleep, &wait);
+		if (error)
+			goto out;
+		if (!skb) {
+			error = -EUNATCH;
+			goto out;
 		}
-		remove_wait_queue(&old_vcc->sleep,&wait);
-		if (error) return error;
-		if (!skb) return -EUNATCH;
 		msg = (struct atmsvc_msg *) skb->data;
 		new_vcc->qos = msg->qos;
 		set_bit(ATM_VF_HASQOS,&new_vcc->flags);
 		new_vcc->remote = msg->svc;
 		new_vcc->local = msg->local;
 		new_vcc->sap = msg->sap;
-		error = atm_connect(newsock,msg->pvc.sap_addr.itf,
-		    msg->pvc.sap_addr.vpi,msg->pvc.sap_addr.vci);
+		error = vcc_connect(newsock, msg->pvc.sap_addr.itf,
+				    msg->pvc.sap_addr.vpi, msg->pvc.sap_addr.vci);
 		dev_kfree_skb(skb);
 		old_vcc->sk->sk_ack_backlog--;
 		if (error) {
 			sigd_enq2(NULL,as_reject,old_vcc,NULL,NULL,
 			    &old_vcc->qos,error);
-			return error == -EAGAIN ? -EBUSY : error;
+			error = error == -EAGAIN ? -EBUSY : error;
+			goto out;
 		}
 		/* wait should be short, so we ignore the non-blocking flag */
 		new_vcc->reply = WAITING;
-		add_wait_queue(&new_vcc->sleep,&wait);
+		prepare_to_wait(&new_vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
 		sigd_enq(new_vcc,as_accept,old_vcc,NULL,NULL);
 		while (new_vcc->reply == WAITING && sigd) {
-			set_current_state(TASK_UNINTERRUPTIBLE);
+			release_sock(sk);
 			schedule();
+			lock_sock(sk);
+			prepare_to_wait(&new_vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
+		}
+		finish_wait(&new_vcc->sleep, &wait);
+		if (!sigd) {
+			error = -EUNATCH;
+			goto out;
 		}
-		remove_wait_queue(&new_vcc->sleep,&wait);
-		if (!sigd) return -EUNATCH;
 		if (!new_vcc->reply) break;
-		if (new_vcc->reply != -ERESTARTSYS) return new_vcc->reply;
+		if (new_vcc->reply != -ERESTARTSYS) {
+			error = new_vcc->reply;
+			goto out;
+		}
 	}
 	newsock->state = SS_CONNECTED;
-	return 0;
+out:
+	release_sock(sk);
+	return error;
 }
 
 
@@ -347,17 +446,17 @@
 
 int svc_change_qos(struct atm_vcc *vcc,struct atm_qos *qos)
 {
-	DECLARE_WAITQUEUE(wait,current);
+	DEFINE_WAIT(wait);
 
 	vcc->reply = WAITING;
-	add_wait_queue(&vcc->sleep,&wait);
+	prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
 	sigd_enq2(vcc,as_modify,NULL,NULL,&vcc->local,qos,0);
 	while (vcc->reply == WAITING && !test_bit(ATM_VF_RELEASED,&vcc->flags)
 	    && sigd) {
-		set_current_state(TASK_UNINTERRUPTIBLE);
 		schedule();
+		prepare_to_wait(&vcc->sleep, &wait, TASK_UNINTERRUPTIBLE);
 	}
-	remove_wait_queue(&vcc->sleep,&wait);
+	finish_wait(&vcc->sleep, &wait);
 	if (!sigd) return -EUNATCH;
 	return vcc->reply;
 }
@@ -366,33 +465,57 @@
 static int svc_setsockopt(struct socket *sock,int level,int optname,
     char *optval,int optlen)
 {
+	struct sock *sk = sock->sk;
 	struct atm_vcc *vcc;
+	int error = 0;
 
 	if (!__SO_LEVEL_MATCH(optname, level) || optname != SO_ATMSAP ||
-	    optlen != sizeof(struct atm_sap))
-		return atm_setsockopt(sock,level,optname,optval,optlen);
+	    optlen != sizeof(struct atm_sap)) {
+		error = vcc_setsockopt(sock, level, optname, optval, optlen);
+		goto out;
+	}
 	vcc = ATM_SD(sock);
-	if (copy_from_user(&vcc->sap,optval,optlen)) return -EFAULT;
-	set_bit(ATM_VF_HASSAP,&vcc->flags);
-	return 0;
+	if (copy_from_user(&vcc->sap, optval, optlen)) {
+		error = -EFAULT;
+		goto out;
+	}
+	set_bit(ATM_VF_HASSAP, &vcc->flags);
+out:
+	release_sock(sk);
+	return error;
 }
 
 
 static int svc_getsockopt(struct socket *sock,int level,int optname,
     char *optval,int *optlen)
 {
-	int len;
+	struct sock *sk = sock->sk;
+	int error = 0, len;
 
-	if (!__SO_LEVEL_MATCH(optname, level) || optname != SO_ATMSAP)
-		return atm_getsockopt(sock,level,optname,optval,optlen);
-	if (get_user(len,optlen)) return -EFAULT;
-	if (len != sizeof(struct atm_sap)) return -EINVAL;
-	return copy_to_user(optval,&ATM_SD(sock)->sap,sizeof(struct atm_sap)) ?
-	    -EFAULT : 0;
+	lock_sock(sk);
+	if (!__SO_LEVEL_MATCH(optname, level) || optname != SO_ATMSAP) {
+		error = vcc_getsockopt(sock, level, optname, optval, optlen);
+		goto out;
+	}
+	if (get_user(len, optlen)) {
+		error = -EFAULT;
+		goto out;
+	}
+	if (len != sizeof(struct atm_sap)) {
+		error = -EINVAL;
+		goto out;
+	}
+	if (copy_to_user(optval, &ATM_SD(sock)->sap, sizeof(struct atm_sap))) {
+		error = -EFAULT;
+		goto out;
+	}
+out:
+	release_sock(sk);
+	return error;
 }
 
 
-static struct proto_ops SOCKOPS_WRAPPED(svc_proto_ops) = {
+static struct proto_ops svc_proto_ops = {
 	.family =	PF_ATMSVC,
 
 	.release =	svc_release,
@@ -402,20 +525,17 @@
 	.accept =	svc_accept,
 	.getname =	svc_getname,
 	.poll =		atm_poll,
-	.ioctl =	atm_ioctl,
+	.ioctl =	vcc_ioctl,
 	.listen =	svc_listen,
 	.shutdown =	svc_shutdown,
 	.setsockopt =	svc_setsockopt,
 	.getsockopt =	svc_getsockopt,
-	.sendmsg =	atm_sendmsg,
-	.recvmsg =	atm_recvmsg,
+	.sendmsg =	vcc_sendmsg,
+	.recvmsg =	vcc_recvmsg,
 	.mmap =		sock_no_mmap,
 	.sendpage =	sock_no_sendpage,
 };
 
-
-#include <linux/smp_lock.h>
-SOCKOPS_WRAP(svc_proto, PF_ATMSVC);
 
 static int svc_create(struct socket *sock,int protocol)
 {
diff -Nru a/net/bluetooth/af_bluetooth.c b/net/bluetooth/af_bluetooth.c
--- a/net/bluetooth/af_bluetooth.c	Wed Jun 18 23:42:06 2003
+++ b/net/bluetooth/af_bluetooth.c	Wed Jun 18 23:42:06 2003
@@ -143,15 +143,13 @@
 {
 	write_lock_bh(&l->lock);
 	sk_add_node(sk, &l->head);
-	sock_hold(sk);
 	write_unlock_bh(&l->lock);
 }
 
 void bt_sock_unlink(struct bt_sock_list *l, struct sock *sk)
 {
 	write_lock_bh(&l->lock);
-	if (sk_del_node_init(sk))
-		__sock_put(sk);
+	sk_del_node_init(sk);
 	write_unlock_bh(&l->lock);
 }
 
diff -Nru a/net/core/dev.c b/net/core/dev.c
--- a/net/core/dev.c	Wed Jun 18 23:42:07 2003
+++ b/net/core/dev.c	Wed Jun 18 23:42:07 2003
@@ -1018,6 +1018,66 @@
 #define illegal_highdma(dev, skb)	(0)
 #endif
 
+extern void skb_release_data(struct sk_buff *);
+
+/* Keep head the same: replace data */
+int __skb_linearize(struct sk_buff *skb, int gfp_mask)
+{
+	unsigned int size;
+	u8 *data;
+	long offset;
+	struct skb_shared_info *ninfo;
+	int headerlen = skb->data - skb->head;
+	int expand = (skb->tail + skb->data_len) - skb->end;
+
+	if (skb_shared(skb))
+		BUG();
+
+	if (expand <= 0)
+		expand = 0;
+
+	size = skb->end - skb->head + expand;
+	size = SKB_DATA_ALIGN(size);
+	data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
+	if (!data)
+		return -ENOMEM;
+
+	/* Copy entire thing */
+	if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len))
+		BUG();
+
+	/* Set up shinfo */
+	ninfo = (struct skb_shared_info*)(data + size);
+	atomic_set(&ninfo->dataref, 1);
+	ninfo->tso_size = skb_shinfo(skb)->tso_size;
+	ninfo->tso_segs = skb_shinfo(skb)->tso_segs;
+	ninfo->nr_frags = 0;
+	ninfo->frag_list = NULL;
+
+	/* Offset between the two in bytes */
+	offset = data - skb->head;
+
+	/* Free old data. */
+	skb_release_data(skb);
+
+	skb->head = data;
+	skb->end  = data + size;
+
+	/* Set up new pointers */
+	skb->h.raw   += offset;
+	skb->nh.raw  += offset;
+	skb->mac.raw += offset;
+	skb->tail    += offset;
+	skb->data    += offset;
+
+	/* We are no longer a clone, even if we were. */
+	skb->cloned    = 0;
+
+	skb->tail     += skb->data_len;
+	skb->data_len  = 0;
+	return 0;
+}
+
 /**
  *	dev_queue_xmit - transmit a buffer
  *	@skb: buffer to transmit
@@ -1039,7 +1099,7 @@
 
 	if (skb_shinfo(skb)->frag_list &&
 	    !(dev->features & NETIF_F_FRAGLIST) &&
-	    skb_linearize(skb, GFP_ATOMIC))
+	    __skb_linearize(skb, GFP_ATOMIC))
 		goto out_kfree_skb;
 
 	/* Fragmented skb is linearized if device does not support SG,
@@ -1048,7 +1108,7 @@
 	 */
 	if (skb_shinfo(skb)->nr_frags &&
 	    (!(dev->features & NETIF_F_SG) || illegal_highdma(dev, skb)) &&
-	    skb_linearize(skb, GFP_ATOMIC))
+	    __skb_linearize(skb, GFP_ATOMIC))
 		goto out_kfree_skb;
 
 	/* If packet is not checksummed and device does not support
@@ -1356,7 +1416,7 @@
 		if (!skb)
 			goto out;
 	}
-	if (skb_is_nonlinear(skb) && skb_linearize(skb, GFP_ATOMIC))
+	if (skb_is_nonlinear(skb) && __skb_linearize(skb, GFP_ATOMIC))
 		goto out_kfree;
 
 #ifdef CONFIG_SMP
diff -Nru a/net/core/skbuff.c b/net/core/skbuff.c
--- a/net/core/skbuff.c	Wed Jun 18 23:42:08 2003
+++ b/net/core/skbuff.c	Wed Jun 18 23:42:08 2003
@@ -181,7 +181,7 @@
 		skb_get(list);
 }
 
-static void skb_release_data(struct sk_buff *skb)
+void skb_release_data(struct sk_buff *skb)
 {
 	if (!skb->cloned ||
 	    atomic_dec_and_test(&(skb_shinfo(skb)->dataref))) {
@@ -410,64 +410,6 @@
 
 	copy_skb_header(n, skb);
 	return n;
-}
-
-/* Keep head the same: replace data */
-int skb_linearize(struct sk_buff *skb, int gfp_mask)
-{
-	unsigned int size;
-	u8 *data;
-	long offset;
-	struct skb_shared_info *ninfo;
-	int headerlen = skb->data - skb->head;
-	int expand = (skb->tail + skb->data_len) - skb->end;
-
-	if (skb_shared(skb))
-		BUG();
-
-	if (expand <= 0)
-		expand = 0;
-
-	size = skb->end - skb->head + expand;
-	size = SKB_DATA_ALIGN(size);
-	data = kmalloc(size + sizeof(struct skb_shared_info), gfp_mask);
-	if (!data)
-		return -ENOMEM;
-
-	/* Copy entire thing */
-	if (skb_copy_bits(skb, -headerlen, data, headerlen + skb->len))
-		BUG();
-
-	/* Set up shinfo */
-	ninfo = (struct skb_shared_info*)(data + size);
-	atomic_set(&ninfo->dataref, 1);
-	ninfo->tso_size = skb_shinfo(skb)->tso_size;
-	ninfo->tso_segs = skb_shinfo(skb)->tso_segs;
-	ninfo->nr_frags = 0;
-	ninfo->frag_list = NULL;
-
-	/* Offset between the two in bytes */
-	offset = data - skb->head;
-
-	/* Free old data. */
-	skb_release_data(skb);
-
-	skb->head = data;
-	skb->end  = data + size;
-
-	/* Set up new pointers */
-	skb->h.raw   += offset;
-	skb->nh.raw  += offset;
-	skb->mac.raw += offset;
-	skb->tail    += offset;
-	skb->data    += offset;
-
-	/* We are no longer a clone, even if we were. */
-	skb->cloned    = 0;
-
-	skb->tail     += skb->data_len;
-	skb->data_len  = 0;
-	return 0;
 }
 
 
diff -Nru a/net/decnet/af_decnet.c b/net/decnet/af_decnet.c
--- a/net/decnet/af_decnet.c	Wed Jun 18 23:42:07 2003
+++ b/net/decnet/af_decnet.c	Wed Jun 18 23:42:07 2003
@@ -276,7 +276,7 @@
 		return;
 
 	write_lock_bh(&dn_hash_lock);
-	hlist_del(&sk->sk_node);
+	sk_del_node_init(sk);
 	DN_SK(sk)->addrloc = 0;
 	list = listen_hash(&DN_SK(sk)->addr);
 	sk_add_node(sk, list);
diff -Nru a/net/econet/af_econet.c b/net/econet/af_econet.c
--- a/net/econet/af_econet.c	Wed Jun 18 23:42:07 2003
+++ b/net/econet/af_econet.c	Wed Jun 18 23:42:07 2003
@@ -96,8 +96,7 @@
 static void econet_remove_socket(struct hlist_head *list, struct sock *sk)
 {
 	write_lock_bh(&econet_lock);
-	if (sk_del_node_init(sk))
-		sock_put(sk);
+	sk_del_node_init(sk);
 	write_unlock_bh(&econet_lock);
 }
 
@@ -105,7 +104,6 @@
 {
 	write_lock_bh(&econet_lock);
 	sk_add_node(sk, list);
-	sock_hold(sk);
 	write_unlock_bh(&econet_lock);
 }
 
diff -Nru a/net/ipv4/igmp.c b/net/ipv4/igmp.c
--- a/net/ipv4/igmp.c	Wed Jun 18 23:42:09 2003
+++ b/net/ipv4/igmp.c	Wed Jun 18 23:42:09 2003
@@ -178,7 +178,7 @@
 
 	in_dev->mr_gq_running = 1;
 	if (!mod_timer(&in_dev->mr_gq_timer, jiffies+tv+2))
-		atomic_inc(&in_dev->refcnt);
+		in_dev_hold(in_dev);
 }
 
 static void igmp_ifc_start_timer(struct in_device *in_dev, int delay)
@@ -186,7 +186,7 @@
 	int tv = net_random() % delay;
 
 	if (!mod_timer(&in_dev->mr_ifc_timer, jiffies+tv+2))
-		atomic_inc(&in_dev->refcnt);
+		in_dev_hold(in_dev);
 }
 
 static void igmp_mod_timer(struct ip_mc_list *im, int max_delay)
@@ -387,8 +387,17 @@
 		if (type == IGMPV3_ALLOW_NEW_SOURCES ||
 		    type == IGMPV3_BLOCK_OLD_SOURCES)
 			return skb;
-		if (pmc->crcount || isquery)
+		if (pmc->crcount || isquery) {
+			/* make sure we have room for group header and at
+			 * least one source.
+			 */
+			if (skb && AVAILABLE(skb) < sizeof(struct igmpv3_grec)+
+			    sizeof(__u32)) {
+				igmpv3_sendpack(skb);
+				skb = 0; /* add_grhead will get a new one */
+			}
 			skb = add_grhead(skb, pmc, type, &pgr);
+		}
 		return skb;
 	}
 	pih = skb ? (struct igmpv3_report *)skb->h.igmph : 0;
@@ -661,6 +670,7 @@
 
 	in_dev->mr_gq_running = 0;
 	igmpv3_send_report(in_dev, 0);
+	__in_dev_put(in_dev);
 }
 
 static void igmp_ifc_timer_expire(unsigned long data)
@@ -672,6 +682,7 @@
 		in_dev->mr_ifc_count--;
 		igmp_ifc_start_timer(in_dev, IGMP_Unsolicited_Report_Interval);
 	}
+	__in_dev_put(in_dev);
 }
 
 static void igmp_ifc_event(struct in_device *in_dev)
@@ -773,7 +784,7 @@
 		/* cancel the interface change timer */
 		in_dev->mr_ifc_count = 0;
 		if (del_timer(&in_dev->mr_ifc_timer))
-			atomic_dec(&in_dev->refcnt);
+			__in_dev_put(in_dev);
 		/* clear deleted report items */
 		igmpv3_clear_delrec(in_dev);
 	} else if (len < 12) {
@@ -1188,10 +1199,10 @@
 #ifdef CONFIG_IP_MULTICAST
 	in_dev->mr_ifc_count = 0;
 	if (del_timer(&in_dev->mr_ifc_timer))
-		atomic_dec(&in_dev->refcnt);
+		__in_dev_put(in_dev);
 	in_dev->mr_gq_running = 0;
 	if (del_timer(&in_dev->mr_gq_timer))
-		atomic_dec(&in_dev->refcnt);
+		__in_dev_put(in_dev);
 #endif
 
 	for (i=in_dev->mc_list; i; i=i->next)
diff -Nru a/net/ipv4/raw.c b/net/ipv4/raw.c
--- a/net/ipv4/raw.c	Wed Jun 18 23:42:07 2003
+++ b/net/ipv4/raw.c	Wed Jun 18 23:42:07 2003
@@ -91,17 +91,14 @@
 	write_lock_bh(&raw_v4_lock);
 	sk_add_node(sk, head);
 	sock_prot_inc_use(sk->sk_prot);
- 	sock_hold(sk);
 	write_unlock_bh(&raw_v4_lock);
 }
 
 static void raw_v4_unhash(struct sock *sk)
 {
  	write_lock_bh(&raw_v4_lock);
-	if (sk_del_node_init(sk)) {
+	if (sk_del_node_init(sk))
 		sock_prot_dec_use(sk->sk_prot);
-		__sock_put(sk);
-	}
 	write_unlock_bh(&raw_v4_lock);
 }
 
diff -Nru a/net/ipv4/tcp.c b/net/ipv4/tcp.c
--- a/net/ipv4/tcp.c	Wed Jun 18 23:42:06 2003
+++ b/net/ipv4/tcp.c	Wed Jun 18 23:42:06 2003
@@ -1909,7 +1909,7 @@
 	BUG_TRAP(sk_unhashed(sk));
 
 	/* If it has not 0 inet_sk(sk)->num, it must be bound */
-	BUG_TRAP(!inet_sk(sk)->num || sk->sk_prev);
+	BUG_TRAP(!inet_sk(sk)->num || tcp_sk(sk)->bind_hash);
 
 #ifdef TCP_DEBUG
 	if (sk->sk_zapped) {
@@ -2164,7 +2164,7 @@
 	tcp_sack_reset(tp);
 	__sk_dst_reset(sk);
 
-	BUG_TRAP(!inet->num || sk->sk_prev);
+	BUG_TRAP(!inet->num || tp->bind_hash);
 
 	sk->sk_error_report(sk);
 	return err;
diff -Nru a/net/ipv4/tcp_ipv4.c b/net/ipv4/tcp_ipv4.c
--- a/net/ipv4/tcp_ipv4.c	Wed Jun 18 23:42:06 2003
+++ b/net/ipv4/tcp_ipv4.c	Wed Jun 18 23:42:06 2003
@@ -156,9 +156,9 @@
 	struct tcp_bind_bucket *tb;
 
 	spin_lock(&head->lock);
-	tb = (struct tcp_bind_bucket *)sk->sk_prev;
+	tb = tcp_sk(sk)->bind_hash;
 	sk_add_bind_node(child, &tb->owners);
-	child->sk_prev	  = (struct sock *)tb;
+	tcp_sk(child)->bind_hash = tb;
 	spin_unlock(&head->lock);
 }
 
@@ -174,7 +174,7 @@
 {
 	inet_sk(sk)->num = snum;
 	sk_add_bind_node(sk, &tb->owners);
-	sk->sk_prev       = (struct sock *)tb;
+	tcp_sk(sk)->bind_hash = tb;
 }
 
 static inline int tcp_bind_conflict(struct sock *sk, struct tcp_bind_bucket *tb)
@@ -279,9 +279,9 @@
 		   (!sk->sk_reuse || sk->sk_state == TCP_LISTEN))
 		tb->fastreuse = 0;
 success:
-	if (!sk->sk_prev)
+	if (!tcp_sk(sk)->bind_hash)
 		tcp_bind_hash(sk, tb, snum);
-	BUG_TRAP(sk->sk_prev == (struct sock *)tb);
+	BUG_TRAP(tcp_sk(sk)->bind_hash == tb);
  	ret = 0;
 
 fail_unlock:
@@ -301,9 +301,9 @@
 	struct tcp_bind_bucket *tb;
 
 	spin_lock(&head->lock);
-	tb = (struct tcp_bind_bucket *)sk->sk_prev;
-	__hlist_del(&sk->sk_bind_node);
-	sk->sk_prev = NULL;
+	tb = tcp_sk(sk)->bind_hash;
+	__sk_del_bind_node(sk);
+	tcp_sk(sk)->bind_hash = NULL;
 	inet->num = 0;
 	tcp_bucket_destroy(tb);
 	spin_unlock(&head->lock);
@@ -359,7 +359,7 @@
 		lock = &tcp_ehash[sk->sk_hashent].lock;
 		write_lock(lock);
 	}
-	sk_add_node(sk, list);
+	__sk_add_node(sk, list);
 	sock_prot_inc_use(sk->sk_prot);
 	write_unlock(lock);
 	if (listen_possible && sk->sk_state == TCP_LISTEN)
@@ -392,7 +392,7 @@
 		write_lock_bh(&head->lock);
 	}
 
-	if (sk_del_node_init(sk))
+	if (__sk_del_node_init(sk))
 		sock_prot_dec_use(sk->sk_prot);
 	write_unlock_bh(lock);
 
@@ -608,7 +608,7 @@
 	inet->sport = htons(lport);
 	sk->sk_hashent = hash;
 	BUG_TRAP(sk_unhashed(sk));
-	sk_add_node(sk, &head->chain);
+	__sk_add_node(sk, &head->chain);
 	sock_prot_inc_use(sk->sk_prot);
 	write_unlock(&head->lock);
 
@@ -730,7 +730,7 @@
  	}
 
  	head  = &tcp_bhash[tcp_bhashfn(snum)];
- 	tb  = (struct tcp_bind_bucket *)sk->sk_prev;
+ 	tb  = tcp_sk(sk)->bind_hash;
 	spin_lock_bh(&head->lock);
 	if (sk_head(&tb->owners) == sk && !sk->sk_bind_node.next) {
 		__tcp_v4_hash(sk, 0);
@@ -2101,7 +2101,7 @@
 	__skb_queue_purge(&tp->ucopy.prequeue);
 
 	/* Clean up a referenced TCP bind bucket. */
-	if (sk->sk_prev)
+	if (tp->bind_hash)
 		tcp_put_port(sk);
 
 	/* If sendmsg cached page exists, toss it. */
diff -Nru a/net/ipv4/tcp_minisocks.c b/net/ipv4/tcp_minisocks.c
--- a/net/ipv4/tcp_minisocks.c	Wed Jun 18 23:42:08 2003
+++ b/net/ipv4/tcp_minisocks.c	Wed Jun 18 23:42:08 2003
@@ -301,15 +301,15 @@
 	 */
 	bhead = &tcp_bhash[tcp_bhashfn(inet_sk(sk)->num)];
 	spin_lock(&bhead->lock);
-	tw->tw_tb = (struct tcp_bind_bucket *)sk->sk_prev;
-	BUG_TRAP(sk->sk_prev);
+	tw->tw_tb = tcp_sk(sk)->bind_hash;
+	BUG_TRAP(tcp_sk(sk)->bind_hash);
 	tw_add_bind_node(tw, &tw->tw_tb->owners);
 	spin_unlock(&bhead->lock);
 
 	write_lock(&ehead->lock);
 
 	/* Step 2: Remove SK from established hash. */
-	if (sk_del_node_init(sk))
+	if (__sk_del_node_init(sk))
 		sock_prot_dec_use(sk->sk_prot);
 
 	/* Step 3: Hash TW into TIMEWAIT half of established hash table. */
@@ -620,7 +620,7 @@
 
 		/* SANITY */
 		sk_node_init(&newsk->sk_node);
-		newsk->sk_prev = NULL;
+		tcp_sk(newsk)->bind_hash = NULL;
 
 		/* Clone the TCP header template */
 		inet_sk(newsk)->dport = req->rmt_port;
diff -Nru a/net/ipv4/udp.c b/net/ipv4/udp.c
--- a/net/ipv4/udp.c	Wed Jun 18 23:42:06 2003
+++ b/net/ipv4/udp.c	Wed Jun 18 23:42:06 2003
@@ -189,7 +189,6 @@
 
 		sk_add_node(sk, h);
 		sock_prot_inc_use(sk->sk_prot);
-		sock_hold(sk);
 	}
 	write_unlock_bh(&udp_hash_lock);
 	return 0;
@@ -210,7 +209,6 @@
 	if (sk_del_node_init(sk)) {
 		inet_sk(sk)->num = 0;
 		sock_prot_dec_use(sk->sk_prot);
-		__sock_put(sk);
 	}
 	write_unlock_bh(&udp_hash_lock);
 }
diff -Nru a/net/ipv6/ip6_tunnel.c b/net/ipv6/ip6_tunnel.c
--- a/net/ipv6/ip6_tunnel.c	Wed Jun 18 23:42:06 2003
+++ b/net/ipv6/ip6_tunnel.c	Wed Jun 18 23:42:06 2003
@@ -230,8 +230,6 @@
 	dev->init = ip6ip6_tnl_dev_init;
 	memcpy(&t->parms, p, sizeof (*p));
 	t->parms.name[IFNAMSIZ - 1] = '\0';
-	if (t->parms.hop_limit > 255)
-		t->parms.hop_limit = -1;
 	strcpy(dev->name, t->parms.name);
 	if (!dev->name[0]) {
 		int i = 0;
@@ -952,7 +950,7 @@
 	ipv6_addr_copy(&t->parms.laddr, &p->laddr);
 	ipv6_addr_copy(&t->parms.raddr, &p->raddr);
 	t->parms.flags = p->flags;
-	t->parms.hop_limit = (p->hop_limit <= 255 ? p->hop_limit : -1);
+	t->parms.hop_limit = p->hop_limit;
 	t->parms.encap_limit = p->encap_limit;
 	t->parms.flowinfo = p->flowinfo;
 	ip6ip6_tnl_link_config(t);
diff -Nru a/net/ipv6/mcast.c b/net/ipv6/mcast.c
--- a/net/ipv6/mcast.c	Wed Jun 18 23:42:09 2003
+++ b/net/ipv6/mcast.c	Wed Jun 18 23:42:09 2003
@@ -930,7 +930,7 @@
 
 	idev->mc_gq_running = 1;
 	if (!mod_timer(&idev->mc_gq_timer, jiffies+tv+2))
-		atomic_inc(&idev->refcnt);
+		in6_dev_hold(idev);
 }
 
 static void mld_ifc_start_timer(struct inet6_dev *idev, int delay)
@@ -938,7 +938,7 @@
 	int tv = net_random() % delay;
 
 	if (!mod_timer(&idev->mc_ifc_timer, jiffies+tv+2))
-		atomic_inc(&idev->refcnt);
+		in6_dev_hold(idev);
 }
 
 /*
@@ -1037,7 +1037,7 @@
 		/* cancel the interface change timer */
 		idev->mc_ifc_count = 0;
 		if (del_timer(&idev->mc_ifc_timer))
-			atomic_dec(&idev->refcnt);
+			__in6_dev_put(idev);
 		/* clear deleted report items */
 		mld_clear_delrec(idev);
 	} else if (len >= 28) {
@@ -1321,8 +1321,17 @@
 		if (type == MLD2_ALLOW_NEW_SOURCES ||
 		    type == MLD2_BLOCK_OLD_SOURCES)
 			return skb;
-		if (pmc->mca_crcount || isquery)
+		if (pmc->mca_crcount || isquery) {
+			/* make sure we have room for group header and at
+			 * least one source.
+			 */
+			if (skb && AVAILABLE(skb) < sizeof(struct mld2_grec)+
+			    sizeof(struct in6_addr)) {
+				mld_sendpack(skb);
+				skb = 0; /* add_grhead will get a new one */
+			}
 			skb = add_grhead(skb, pmc, type, &pgr);
+		}
 		return skb;
 	}
 	pmr = skb ? (struct mld2_report *)skb->h.raw : 0;
@@ -1895,6 +1904,7 @@
 
 	idev->mc_gq_running = 0;
 	mld_send_report(idev, 0);
+	__in6_dev_put(idev);
 }
 
 static void mld_ifc_timer_expire(unsigned long data)
@@ -1907,6 +1917,7 @@
 		if (idev->mc_ifc_count)
 			mld_ifc_start_timer(idev, idev->mc_maxdelay);
 	}
+	__in6_dev_put(idev);
 }
 
 static void mld_ifc_event(struct inet6_dev *idev)
@@ -1945,10 +1956,10 @@
 	read_lock_bh(&idev->lock);
 	idev->mc_ifc_count = 0;
 	if (del_timer(&idev->mc_ifc_timer))
-		atomic_dec(&idev->refcnt);
+		__in6_dev_put(idev);
 	idev->mc_gq_running = 0;
 	if (del_timer(&idev->mc_gq_timer))
-		atomic_dec(&idev->refcnt);
+		__in6_dev_put(idev);
 
 	for (i = idev->mc_list; i; i=i->next)
 		igmp6_group_dropped(i);
diff -Nru a/net/ipv6/raw.c b/net/ipv6/raw.c
--- a/net/ipv6/raw.c	Wed Jun 18 23:42:07 2003
+++ b/net/ipv6/raw.c	Wed Jun 18 23:42:07 2003
@@ -64,17 +64,14 @@
 	write_lock_bh(&raw_v6_lock);
 	sk_add_node(sk, list);
 	sock_prot_inc_use(sk->sk_prot);
- 	sock_hold(sk);
  	write_unlock_bh(&raw_v6_lock);
 }
 
 static void raw_v6_unhash(struct sock *sk)
 {
  	write_lock_bh(&raw_v6_lock);
-	if (sk_del_node_init(sk)) {
+	if (sk_del_node_init(sk))
 		sock_prot_dec_use(sk->sk_prot);
-		__sock_put(sk);
-	}
 	write_unlock_bh(&raw_v6_lock);
 }
 
diff -Nru a/net/ipv6/tcp_ipv6.c b/net/ipv6/tcp_ipv6.c
--- a/net/ipv6/tcp_ipv6.c	Wed Jun 18 23:42:07 2003
+++ b/net/ipv6/tcp_ipv6.c	Wed Jun 18 23:42:07 2003
@@ -225,9 +225,9 @@
 		tb->fastreuse = 0;
 
 success:
-	if (!sk->sk_prev)
+	if (!tcp_sk(sk)->bind_hash)
 		tcp_bind_hash(sk, tb, snum);
-	BUG_TRAP(sk->sk_prev == (struct sock *)tb);
+	BUG_TRAP(tcp_sk(sk)->bind_hash == tb);
 	ret = 0;
 
 fail_unlock:
@@ -1947,7 +1947,7 @@
 	__skb_queue_purge(&tp->ucopy.prequeue);
 
 	/* Clean up a referenced TCP bind bucket. */
-	if (sk->sk_prev)
+	if (tcp_sk(sk)->bind_hash)
 		tcp_put_port(sk);
 
 	/* If sendmsg cached page exists, toss it. */
diff -Nru a/net/ipv6/udp.c b/net/ipv6/udp.c
--- a/net/ipv6/udp.c	Wed Jun 18 23:42:08 2003
+++ b/net/ipv6/udp.c	Wed Jun 18 23:42:08 2003
@@ -160,7 +160,6 @@
 	if (sk_unhashed(sk)) {
 		sk_add_node(sk, &udp_hash[snum & (UDP_HTABLE_SIZE - 1)]);
 		sock_prot_inc_use(sk->sk_prot);
-		sock_hold(sk);
 	}
 	write_unlock_bh(&udp_hash_lock);
 	return 0;
@@ -181,7 +180,6 @@
 	if (sk_del_node_init(sk)) {
 		inet_sk(sk)->num = 0;
 		sock_prot_dec_use(sk->sk_prot);
-		__sock_put(sk);
 	}
 	write_unlock_bh(&udp_hash_lock);
 }
diff -Nru a/net/ipv6/xfrm6_policy.c b/net/ipv6/xfrm6_policy.c
--- a/net/ipv6/xfrm6_policy.c	Wed Jun 18 23:42:06 2003
+++ b/net/ipv6/xfrm6_policy.c	Wed Jun 18 23:42:06 2003
@@ -60,8 +60,16 @@
 	read_lock_bh(&policy->lock);
 	for (dst = policy->bundles; dst; dst = dst->next) {
 		struct xfrm_dst *xdst = (struct xfrm_dst*)dst;
-		if (!ipv6_addr_cmp(&xdst->u.rt6.rt6i_dst.addr, &fl->fl6_dst) &&
-		    !ipv6_addr_cmp(&xdst->u.rt6.rt6i_src.addr, &fl->fl6_src) &&
+		struct in6_addr fl_dst_prefix, fl_src_prefix;
+
+		ipv6_addr_prefix(&fl_dst_prefix,
+				 &fl->fl6_dst,
+				 xdst->u.rt6.rt6i_dst.plen);
+		ipv6_addr_prefix(&fl_src_prefix,
+				 &fl->fl6_src,
+				 xdst->u.rt6.rt6i_src.plen);
+		if (!ipv6_addr_cmp(&xdst->u.rt6.rt6i_dst.addr, &fl_dst_prefix) &&
+		    !ipv6_addr_cmp(&xdst->u.rt6.rt6i_src.addr, &fl_src_prefix) &&
 		    __xfrm6_bundle_ok(xdst, fl)) {
 			dst_clone(dst);
 			break;
@@ -133,7 +141,6 @@
 	dst_prev->child = &rt->u.dst;
 	for (dst_prev = dst; dst_prev != &rt->u.dst; dst_prev = dst_prev->child) {
 		struct xfrm_dst *x = (struct xfrm_dst*)dst_prev;
-		x->u.rt.fl = *fl;
 
 		dst_prev->dev = rt->u.dst.dev;
 		if (rt->u.dst.dev)
@@ -157,6 +164,8 @@
 		x->u.rt6.rt6i_node     = rt0->rt6i_node;
 		x->u.rt6.rt6i_gateway  = rt0->rt6i_gateway;
 		memcpy(&x->u.rt6.rt6i_gateway, &rt0->rt6i_gateway, sizeof(x->u.rt6.rt6i_gateway)); 
+		x->u.rt6.rt6i_dst      = rt0->rt6i_dst;
+		x->u.rt6.rt6i_src      = rt0->rt6i_src;	
 		header_len -= x->u.dst.xfrm->props.header_len;
 		trailer_len -= x->u.dst.xfrm->props.trailer_len;
 	}
diff -Nru a/net/ipx/af_ipx.c b/net/ipx/af_ipx.c
--- a/net/ipx/af_ipx.c	Wed Jun 18 23:42:06 2003
+++ b/net/ipx/af_ipx.c	Wed Jun 18 23:42:06 2003
@@ -142,7 +142,6 @@
 	spin_lock_bh(&intrfc->if_sklist_lock);
 	sk_del_node_init(sk);
 	spin_unlock_bh(&intrfc->if_sklist_lock);
-	sock_put(sk);
 	ipxitf_put(intrfc);
 out:
 	return;
@@ -229,7 +228,6 @@
 static void ipxitf_insert_socket(struct ipx_interface *intrfc, struct sock *sk)
 {
 	ipxitf_hold(intrfc);
-	sock_hold(sk);
 	spin_lock_bh(&intrfc->if_sklist_lock);
 	ipx_sk(sk)->intrfc = intrfc;
 	sk_add_node(sk, &intrfc->if_sklist);
@@ -269,7 +267,7 @@
 
 #ifdef CONFIG_IPX_INTERN
 static struct sock *ipxitf_find_internal_socket(struct ipx_interface *intrfc,
-						unsigned char *node,
+						unsigned char *ipx_node,
 						unsigned short port)
 {
 	struct sock *s;
@@ -282,7 +280,7 @@
 		struct ipx_opt *ipxs = ipx_sk(s);
 
 		if (ipxs->port == port &&
-		    !memcmp(node, ipxs->node, IPX_NODE_LEN))
+		    !memcmp(ipx_node, ipxs->node, IPX_NODE_LEN))
 			goto found;
 	}
 	s = NULL;
diff -Nru a/net/key/af_key.c b/net/key/af_key.c
--- a/net/key/af_key.c	Wed Jun 18 23:42:06 2003
+++ b/net/key/af_key.c	Wed Jun 18 23:42:06 2003
@@ -115,15 +115,13 @@
 {
 	pfkey_table_grab();
 	sk_add_node(sk, &pfkey_table);
-	sock_hold(sk);
 	pfkey_table_ungrab();
 }
 
 static void pfkey_remove(struct sock *sk)
 {
 	pfkey_table_grab();
-	if (sk_del_node_init(sk))
-		__sock_put(sk);
+	sk_del_node_init(sk);
 	pfkey_table_ungrab();
 }
 
diff -Nru a/net/llc/llc_c_ac.c b/net/llc/llc_c_ac.c
--- a/net/llc/llc_c_ac.c	Wed Jun 18 23:42:09 2003
+++ b/net/llc/llc_c_ac.c	Wed Jun 18 23:42:09 2003
@@ -102,13 +102,13 @@
 	if (ev->type == LLC_CONN_EV_TYPE_PDU) {
 		struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
-		if (!LLC_PDU_IS_RSP(pdu) &&
-		    !LLC_PDU_TYPE_IS_U(pdu) &&
+		if (LLC_PDU_IS_RSP(pdu) &&
+		    LLC_PDU_TYPE_IS_U(pdu) &&
 		    LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM) {
 			reason = LLC_DISC_REASON_RX_DM_RSP_PDU;
 			rc = 0;
-		} else if (!LLC_PDU_IS_CMD(pdu) &&
-			   !LLC_PDU_TYPE_IS_U(pdu) &&
+		} else if (LLC_PDU_IS_CMD(pdu) &&
+			   LLC_PDU_TYPE_IS_U(pdu) &&
 			   LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC) {
 			reason = LLC_DISC_REASON_RX_DISC_CMD_PDU;
 			rc = 0;
@@ -146,13 +146,13 @@
 
 	switch (ev->type) {
 	case LLC_CONN_EV_TYPE_PDU:
-		if (!LLC_PDU_IS_RSP(pdu) &&
-		    !LLC_PDU_TYPE_IS_U(pdu) &&
+		if (LLC_PDU_IS_RSP(pdu) &&
+		    LLC_PDU_TYPE_IS_U(pdu) &&
 		    LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR) {
 			reason = LLC_RESET_REASON_LOCAL;
 			rc = 0;
-		} else if (!LLC_PDU_IS_CMD(pdu) &&
-			   !LLC_PDU_TYPE_IS_U(pdu) &&
+		} else if (LLC_PDU_IS_CMD(pdu) &&
+			   LLC_PDU_TYPE_IS_U(pdu) &&
 			   LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME) {
 			reason = LLC_RESET_REASON_REMOTE;
 			rc = 0;
@@ -198,9 +198,9 @@
 {
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-	if (!LLC_PDU_IS_RSP(pdu) &&
-	    !LLC_PDU_TYPE_IS_I(pdu) &&
-	    !LLC_I_PF_IS_1(pdu) && llc_sk(sk)->ack_pf)
+	if (LLC_PDU_IS_RSP(pdu) &&
+	    LLC_PDU_TYPE_IS_I(pdu) &&
+	    LLC_I_PF_IS_1(pdu) && llc_sk(sk)->ack_pf)
 		llc_conn_ac_clear_remote_busy(sk, skb);
 	return 0;
 }
@@ -310,7 +310,7 @@
 	struct llc_opt *llc = llc_sk(sk);
 
 	llc->rx_pdu_hdr = *((u32 *)pdu);
-	if (!LLC_PDU_IS_CMD(pdu))
+	if (LLC_PDU_IS_CMD(pdu))
 		llc_pdu_decode_pf_bit(skb, &f_bit);
 	else
 		f_bit = 0;
@@ -1228,7 +1228,7 @@
 {
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-	if (!LLC_PDU_IS_RSP(pdu)) {
+	if (LLC_PDU_IS_RSP(pdu)) {
 		u8 f_bit;
 
 		llc_pdu_decode_pf_bit(skb, &f_bit);
diff -Nru a/net/llc/llc_c_ev.c b/net/llc/llc_c_ev.c
--- a/net/llc/llc_c_ev.c	Wed Jun 18 23:42:06 2003
+++ b/net/llc/llc_c_ev.c	Wed Jun 18 23:42:06 2003
@@ -170,7 +170,7 @@
 {
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
-	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_U(pdu) &&
+	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
 	       LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_DISC ? 0 : 1;
 }
 
@@ -178,7 +178,7 @@
 {
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
-	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_U(pdu) &&
+	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
 	       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_DM ? 0 : 1;
 }
 
@@ -186,7 +186,7 @@
 {
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
-	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_U(pdu) &&
+	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
 	       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_FRMR ? 0 : 1;
 }
 
@@ -195,8 +195,8 @@
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
 	return llc_conn_space(sk, skb) &&
-	       !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
-	       !LLC_I_PF_IS_0(pdu) &&
+	       LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
+	       LLC_I_PF_IS_0(pdu) &&
 	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
 }
 
@@ -205,8 +205,8 @@
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
 	return llc_conn_space(sk, skb) &&
-	       !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
-	       !LLC_I_PF_IS_1(pdu) &&
+	       LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
+	       LLC_I_PF_IS_1(pdu) &&
 	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
 }
 
@@ -217,8 +217,8 @@
 	u8 vr = llc_sk(sk)->vR;
 	u8 ns = LLC_I_GET_NS(pdu);
 
-	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
-	       !LLC_I_PF_IS_0(pdu) && ns != vr &&
+	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
+	       LLC_I_PF_IS_0(pdu) && ns != vr &&
 	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
 }
 
@@ -229,8 +229,8 @@
 	u8 vr = llc_sk(sk)->vR;
 	u8 ns = LLC_I_GET_NS(pdu);
 
-	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
-	       !LLC_I_PF_IS_1(pdu) && ns != vr &&
+	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
+	       LLC_I_PF_IS_1(pdu) && ns != vr &&
 	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
 }
 
@@ -240,7 +240,7 @@
 	struct llc_pdu_sn * pdu = llc_pdu_sn_hdr(skb);
 	u8 vr = llc_sk(sk)->vR;
 	u8 ns = LLC_I_GET_NS(pdu);
-	u16 rc = !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
+	u16 rc = LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
 		 llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
 	if (!rc)
 		dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
@@ -253,8 +253,8 @@
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
 	return llc_conn_space(sk, skb) &&
-	       !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
-	       !LLC_I_PF_IS_0(pdu) &&
+	       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
+	       LLC_I_PF_IS_0(pdu) &&
 	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
 }
 
@@ -262,8 +262,8 @@
 {
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
-	       !LLC_I_PF_IS_1(pdu) &&
+	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
+	       LLC_I_PF_IS_1(pdu) &&
 	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
 }
 
@@ -272,7 +272,7 @@
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
 	return llc_conn_space(sk, skb) &&
-	       !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
+	       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
 	       LLC_I_GET_NS(pdu) == llc_sk(sk)->vR ? 0 : 1;
 }
 
@@ -283,8 +283,8 @@
 	u8 vr = llc_sk(sk)->vR;
 	u8 ns = LLC_I_GET_NS(pdu);
 
-	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
-	       !LLC_I_PF_IS_0(pdu) && ns != vr &&
+	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
+	       LLC_I_PF_IS_0(pdu) && ns != vr &&
 	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
 }
 
@@ -295,8 +295,8 @@
 	u8 vr = llc_sk(sk)->vR;
 	u8 ns = LLC_I_GET_NS(pdu);
 
-	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) &&
-	       !LLC_I_PF_IS_1(pdu) && ns != vr &&
+	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) &&
+	       LLC_I_PF_IS_1(pdu) && ns != vr &&
 	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
 }
 
@@ -307,7 +307,7 @@
 	u8 vr = llc_sk(sk)->vR;
 	u8 ns = LLC_I_GET_NS(pdu);
 
-	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
+	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
 	       !llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
 }
 
@@ -317,7 +317,7 @@
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 	u8 vr = llc_sk(sk)->vR;
 	u8 ns = LLC_I_GET_NS(pdu);
-	u16 rc = !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
+	u16 rc = LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_I(pdu) && ns != vr &&
 		 llc_util_ns_inside_rx_window(ns, vr, llc_sk(sk)->rw) ? 0 : 1;
 	if (!rc)
 		dprintk("%s: matched, state=%d, ns=%d, vr=%d\n",
@@ -329,8 +329,8 @@
 {
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
-	       !LLC_S_PF_IS_0(pdu) &&
+	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
+	       LLC_S_PF_IS_0(pdu) &&
 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
 }
 
@@ -338,8 +338,8 @@
 {
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
-	       !LLC_S_PF_IS_1(pdu) &&
+	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
+	       LLC_S_PF_IS_1(pdu) &&
 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_REJ ? 0 : 1;
 }
 
@@ -347,8 +347,8 @@
 {
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
-	       !LLC_S_PF_IS_0(pdu) &&
+	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
+	       LLC_S_PF_IS_0(pdu) &&
 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
 }
 
@@ -356,8 +356,8 @@
 {
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
-	       !LLC_S_PF_IS_1(pdu) &&
+	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
+	       LLC_S_PF_IS_1(pdu) &&
 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
 }
 
@@ -365,7 +365,7 @@
 {
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
-	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
+	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_REJ ? 0 : 1;
 }
 
@@ -373,8 +373,8 @@
 {
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
-	       !LLC_S_PF_IS_0(pdu) &&
+	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
+	       LLC_S_PF_IS_0(pdu) &&
 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
 }
 
@@ -382,8 +382,8 @@
 {
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
-	       !LLC_S_PF_IS_1(pdu) &&
+	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
+	       LLC_S_PF_IS_1(pdu) &&
 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RNR ? 0 : 1;
 }
 
@@ -391,8 +391,8 @@
 {
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
-	       !LLC_S_PF_IS_0(pdu) &&
+	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
+	       LLC_S_PF_IS_0(pdu) &&
 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
 }
 
@@ -400,8 +400,8 @@
 {
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
-	       !LLC_S_PF_IS_1(pdu) &&
+	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
+	       LLC_S_PF_IS_1(pdu) &&
 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RNR ? 0 : 1;
 }
 
@@ -409,8 +409,8 @@
 {
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
-	       !LLC_S_PF_IS_0(pdu) &&
+	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
+	       LLC_S_PF_IS_0(pdu) &&
 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
 }
 
@@ -418,8 +418,8 @@
 {
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
-	       !LLC_S_PF_IS_1(pdu) &&
+	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
+	       LLC_S_PF_IS_1(pdu) &&
 	       LLC_S_PDU_CMD(pdu) == LLC_2_PDU_CMD_RR ? 0 : 1;
 }
 
@@ -428,8 +428,8 @@
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
 	return llc_conn_space(sk, skb) &&
-	       !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
-	       !LLC_S_PF_IS_0(pdu) &&
+	       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
+	       LLC_S_PF_IS_0(pdu) &&
 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
 }
 
@@ -438,8 +438,8 @@
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
 	return llc_conn_space(sk, skb) &&
-	       !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_S(pdu) &&
-	       !LLC_S_PF_IS_1(pdu) &&
+	       LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_S(pdu) &&
+	       LLC_S_PF_IS_1(pdu) &&
 	       LLC_S_PDU_RSP(pdu) == LLC_2_PDU_RSP_RR ? 0 : 1;
 }
 
@@ -447,7 +447,7 @@
 {
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
-	return !LLC_PDU_IS_CMD(pdu) && !LLC_PDU_TYPE_IS_U(pdu) &&
+	return LLC_PDU_IS_CMD(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
 	       LLC_U_PDU_CMD(pdu) == LLC_2_PDU_CMD_SABME ? 0 : 1;
 }
 
@@ -455,7 +455,7 @@
 {
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
-	return !LLC_PDU_IS_RSP(pdu) && !LLC_PDU_TYPE_IS_U(pdu) &&
+	return LLC_PDU_IS_RSP(pdu) && LLC_PDU_TYPE_IS_U(pdu) &&
 	       LLC_U_PDU_RSP(pdu) == LLC_2_PDU_RSP_UA ? 0 : 1;
 }
 
@@ -464,11 +464,11 @@
 	u16 rc = 1;
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-	if (!LLC_PDU_IS_CMD(pdu)) {
-		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
-			if (!LLC_I_PF_IS_1(pdu))
+	if (LLC_PDU_IS_CMD(pdu)) {
+		if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
+			if (LLC_I_PF_IS_1(pdu))
 				rc = 0;
-		} else if (!LLC_PDU_TYPE_IS_U(pdu) && !LLC_U_PF_IS_1(pdu))
+		} else if (LLC_PDU_TYPE_IS_U(pdu) && LLC_U_PF_IS_1(pdu))
 			rc = 0;
 	}
 	return rc;
@@ -479,15 +479,15 @@
 	u16 rc = 1;
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-	if (!LLC_PDU_IS_CMD(pdu)) {
-		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
-			if (!LLC_I_PF_IS_0(pdu))
+	if (LLC_PDU_IS_CMD(pdu)) {
+		if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
+			if (LLC_I_PF_IS_0(pdu))
 				rc = 0;
-		} else if (!LLC_PDU_TYPE_IS_U(pdu))
+		} else if (LLC_PDU_TYPE_IS_U(pdu))
 			switch (LLC_U_PDU_CMD(pdu)) {
 			case LLC_2_PDU_CMD_SABME:
 			case LLC_2_PDU_CMD_DISC:
-				if (!LLC_U_PF_IS_0(pdu))
+				if (LLC_U_PF_IS_0(pdu))
 					rc = 0;
 				break;
 			}
@@ -500,10 +500,10 @@
 	u16 rc = 1;
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
-	if (!LLC_PDU_IS_CMD(pdu)) {
-		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu))
+	if (LLC_PDU_IS_CMD(pdu)) {
+		if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
 			rc = 0;
-		else if (!LLC_PDU_TYPE_IS_U(pdu))
+		else if (LLC_PDU_TYPE_IS_U(pdu))
 			switch (LLC_U_PDU_CMD(pdu)) {
 			case LLC_2_PDU_CMD_SABME:
 			case LLC_2_PDU_CMD_DISC:
@@ -519,16 +519,16 @@
 	u16 rc = 1;
 	struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-	if (!LLC_PDU_IS_RSP(pdu)) {
-		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) {
-			if (!LLC_I_PF_IS_1(pdu))
+	if (LLC_PDU_IS_RSP(pdu)) {
+		if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) {
+			if (LLC_I_PF_IS_1(pdu))
 				rc = 0;
-		} else if (!LLC_PDU_TYPE_IS_U(pdu))
+		} else if (LLC_PDU_TYPE_IS_U(pdu))
 			switch (LLC_U_PDU_RSP(pdu)) {
 			case LLC_2_PDU_RSP_UA:
 			case LLC_2_PDU_RSP_DM:
 			case LLC_2_PDU_RSP_FRMR:
-				if (!LLC_U_PF_IS_1(pdu))
+				if (LLC_U_PF_IS_1(pdu))
 					rc = 0;
 				break;
 			}
@@ -541,10 +541,10 @@
 	u16 rc = 1;
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
-	if (!LLC_PDU_IS_RSP(pdu)) {
-		if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu))
+	if (LLC_PDU_IS_RSP(pdu)) {
+		if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
 			rc = 0;
-		else if (!LLC_PDU_TYPE_IS_U(pdu))
+		else if (LLC_PDU_TYPE_IS_U(pdu))
 			switch (LLC_U_PDU_RSP(pdu)) {
 			case LLC_2_PDU_RSP_UA:
 			case LLC_2_PDU_RSP_DM:
@@ -562,9 +562,9 @@
 	u16 rc = 1;
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
-	if (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu))
+	if (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu))
 		rc = 0;
-	else if (!LLC_PDU_TYPE_IS_U(pdu))
+	else if (LLC_PDU_TYPE_IS_U(pdu))
 		switch (LLC_U_PDU_CMD(pdu)) {
 		case LLC_2_PDU_CMD_SABME:
 		case LLC_2_PDU_CMD_DISC:
@@ -585,8 +585,8 @@
 	u8 vs = llc_sk(sk)->vS;
 	u8 nr = LLC_I_GET_NR(pdu);
 
-	if (!LLC_PDU_IS_CMD(pdu) &&
-	    (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) &&
+	if (LLC_PDU_IS_CMD(pdu) &&
+	    (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
 	    nr != vs && llc_util_nr_inside_tx_window(sk, nr)) {
 		dprintk("%s: matched, state=%d, vs=%d, nr=%d\n",
 			__FUNCTION__, llc_sk(sk)->state, vs, nr);
@@ -603,8 +603,8 @@
 	u8 vs = llc_sk(sk)->vS;
 	u8 nr = LLC_I_GET_NR(pdu);
 
-	if (!LLC_PDU_IS_RSP(pdu) &&
-	    (!LLC_PDU_TYPE_IS_I(pdu) || !LLC_PDU_TYPE_IS_S(pdu)) &&
+	if (LLC_PDU_IS_RSP(pdu) &&
+	    (LLC_PDU_TYPE_IS_I(pdu) || LLC_PDU_TYPE_IS_S(pdu)) &&
 	    nr != vs && llc_util_nr_inside_tx_window(sk, nr)) {
 		rc = 0;
 		dprintk("%s: matched, state=%d, vs=%d, nr=%d\n",
diff -Nru a/net/llc/llc_conn.c b/net/llc/llc_conn.c
--- a/net/llc/llc_conn.c	Wed Jun 18 23:42:06 2003
+++ b/net/llc/llc_conn.c	Wed Jun 18 23:42:06 2003
@@ -356,7 +356,7 @@
 	while ((skb = skb_dequeue(&sk->sk_write_queue)) != NULL) {
 		struct llc_pdu_sn *pdu = llc_pdu_sn_hdr(skb);
 
-		if (!LLC_PDU_TYPE_IS_I(pdu) &&
+		if (LLC_PDU_TYPE_IS_I(pdu) &&
 		    !(skb->dev->flags & IFF_LOOPBACK)) {
 			struct sk_buff *skb2 = skb_clone(skb, GFP_ATOMIC);
 
diff -Nru a/net/llc/llc_evnt.c b/net/llc/llc_evnt.c
--- a/net/llc/llc_evnt.c	Wed Jun 18 23:42:06 2003
+++ b/net/llc/llc_evnt.c	Wed Jun 18 23:42:06 2003
@@ -68,8 +68,8 @@
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
 	return ev->type == LLC_STATION_EV_TYPE_PDU &&
-	       !LLC_PDU_IS_CMD(pdu) &&			/* command PDU */
-	       !LLC_PDU_TYPE_IS_U(pdu) &&		/* U type PDU */
+	       LLC_PDU_IS_CMD(pdu) &&			/* command PDU */
+	       LLC_PDU_TYPE_IS_U(pdu) &&		/* U type PDU */
 	       LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_XID &&
 	       !pdu->dsap ? 0 : 1;			/* NULL DSAP value */
 }
@@ -81,8 +81,8 @@
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
 	return ev->type == LLC_STATION_EV_TYPE_PDU &&
-	       !LLC_PDU_IS_RSP(pdu) &&			/* response PDU */
-	       !LLC_PDU_TYPE_IS_U(pdu) &&		/* U type PDU */
+	       LLC_PDU_IS_RSP(pdu) &&			/* response PDU */
+	       LLC_PDU_TYPE_IS_U(pdu) &&		/* U type PDU */
 	       LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_XID &&
 	       !pdu->dsap &&				/* NULL DSAP value */
 	       !station->xid_r_count ? 0 : 1;
@@ -95,8 +95,8 @@
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
 	return ev->type == LLC_STATION_EV_TYPE_PDU &&
-	       !LLC_PDU_IS_RSP(pdu) &&			/* response PDU */
-	       !LLC_PDU_TYPE_IS_U(pdu) &&		/* U type PDU */
+	       LLC_PDU_IS_RSP(pdu) &&			/* response PDU */
+	       LLC_PDU_TYPE_IS_U(pdu) &&		/* U type PDU */
 	       LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_XID &&
 	       !pdu->dsap &&				/* NULL DSAP value */
 	       station->xid_r_count == 1 ? 0 : 1;
@@ -109,8 +109,8 @@
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
 	return ev->type == LLC_STATION_EV_TYPE_PDU &&
-	       !LLC_PDU_IS_CMD(pdu) &&			/* command PDU */
-	       !LLC_PDU_TYPE_IS_U(pdu) &&		/* U type PDU */
+	       LLC_PDU_IS_CMD(pdu) &&			/* command PDU */
+	       LLC_PDU_TYPE_IS_U(pdu) &&		/* U type PDU */
 	       LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_TEST &&
 	       !pdu->dsap ? 0 : 1;			/* NULL DSAP */
 }
diff -Nru a/net/llc/llc_s_ev.c b/net/llc/llc_s_ev.c
--- a/net/llc/llc_s_ev.c	Wed Jun 18 23:42:08 2003
+++ b/net/llc/llc_s_ev.c	Wed Jun 18 23:42:08 2003
@@ -33,8 +33,8 @@
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
-	return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_CMD(pdu) &&
-	       !LLC_PDU_TYPE_IS_U(pdu) &&
+	return ev->type == LLC_SAP_EV_TYPE_PDU && LLC_PDU_IS_CMD(pdu) &&
+	       LLC_PDU_TYPE_IS_U(pdu) &&
 	       LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_UI ? 0 : 1;
 }
 
@@ -62,8 +62,8 @@
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
-	return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_CMD(pdu) &&
-	       !LLC_PDU_TYPE_IS_U(pdu) &&
+	return ev->type == LLC_SAP_EV_TYPE_PDU && LLC_PDU_IS_CMD(pdu) &&
+	       LLC_PDU_TYPE_IS_U(pdu) &&
 	       LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_XID ? 0 : 1;
 }
 
@@ -72,8 +72,8 @@
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
-	return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_RSP(pdu) &&
-	       !LLC_PDU_TYPE_IS_U(pdu) &&
+	return ev->type == LLC_SAP_EV_TYPE_PDU && LLC_PDU_IS_RSP(pdu) &&
+	       LLC_PDU_TYPE_IS_U(pdu) &&
 	       LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_XID ? 0 : 1;
 }
 
@@ -91,8 +91,8 @@
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
-	return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_CMD(pdu) &&
-	       !LLC_PDU_TYPE_IS_U(pdu) &&
+	return ev->type == LLC_SAP_EV_TYPE_PDU && LLC_PDU_IS_CMD(pdu) &&
+	       LLC_PDU_TYPE_IS_U(pdu) &&
 	       LLC_U_PDU_CMD(pdu) == LLC_1_PDU_CMD_TEST ? 0 : 1;
 }
 
@@ -101,8 +101,8 @@
 	struct llc_sap_state_ev *ev = llc_sap_ev(skb);
 	struct llc_pdu_un *pdu = llc_pdu_un_hdr(skb);
 
-	return ev->type == LLC_SAP_EV_TYPE_PDU && !LLC_PDU_IS_RSP(pdu) &&
-	       !LLC_PDU_TYPE_IS_U(pdu) &&
+	return ev->type == LLC_SAP_EV_TYPE_PDU && LLC_PDU_IS_RSP(pdu) &&
+	       LLC_PDU_TYPE_IS_U(pdu) &&
 	       LLC_U_PDU_RSP(pdu) == LLC_1_PDU_CMD_TEST ? 0 : 1;
 }
 
diff -Nru a/net/llc/llc_sap.c b/net/llc/llc_sap.c
--- a/net/llc/llc_sap.c	Wed Jun 18 23:42:08 2003
+++ b/net/llc/llc_sap.c	Wed Jun 18 23:42:08 2003
@@ -35,7 +35,6 @@
 	write_lock_bh(&sap->sk_list.lock);
 	llc_sk(sk)->sap = sap;
 	sk_add_node(sk, &sap->sk_list.list);
-	sock_hold(sk);
 	write_unlock_bh(&sap->sk_list.lock);
 }
 
@@ -50,8 +49,7 @@
 void llc_sap_unassign_sock(struct llc_sap *sap, struct sock *sk)
 {
 	write_lock_bh(&sap->sk_list.lock);
-	if (sk_del_node_init(sk))
-		sock_put(sk);
+	sk_del_node_init(sk);
 	write_unlock_bh(&sap->sk_list.lock);
 }
 
diff -Nru a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
--- a/net/netlink/af_netlink.c	Wed Jun 18 23:42:07 2003
+++ b/net/netlink/af_netlink.c	Wed Jun 18 23:42:07 2003
@@ -193,7 +193,6 @@
 		if (nlk_sk(sk)->pid == 0) {
 			nlk_sk(sk)->pid = pid;
 			sk_add_node(sk, &nl_table[sk->sk_protocol]);
-			sock_hold(sk);
 			err = 0;
 		}
 	}
@@ -204,8 +203,7 @@
 static void netlink_remove(struct sock *sk)
 {
 	netlink_table_grab();
-	if (sk_del_node_init(sk))
-		__sock_put(sk);
+	sk_del_node_init(sk);
 	netlink_table_ungrab();
 }
 
diff -Nru a/net/netsyms.c b/net/netsyms.c
--- a/net/netsyms.c	Wed Jun 18 23:42:07 2003
+++ b/net/netsyms.c	Wed Jun 18 23:42:07 2003
@@ -148,7 +148,7 @@
 EXPORT_SYMBOL(sock_wfree);
 EXPORT_SYMBOL(sock_wmalloc);
 EXPORT_SYMBOL(sock_rmalloc);
-EXPORT_SYMBOL(skb_linearize);
+EXPORT_SYMBOL(__skb_linearize);
 EXPORT_SYMBOL(skb_checksum);
 EXPORT_SYMBOL(skb_checksum_help);
 EXPORT_SYMBOL(skb_recv_datagram);
@@ -563,6 +563,7 @@
 EXPORT_SYMBOL(unregister_netdevice);
 EXPORT_SYMBOL(synchronize_net);
 EXPORT_SYMBOL(netdev_state_change);
+EXPORT_SYMBOL(netdev_boot_setup_check);
 EXPORT_SYMBOL(dev_new_index);
 EXPORT_SYMBOL(dev_get_by_flags);
 EXPORT_SYMBOL(__dev_get_by_flags);
diff -Nru a/net/packet/af_packet.c b/net/packet/af_packet.c
--- a/net/packet/af_packet.c	Wed Jun 18 23:42:08 2003
+++ b/net/packet/af_packet.c	Wed Jun 18 23:42:08 2003
@@ -758,8 +758,7 @@
 		return 0;
 
 	write_lock_bh(&packet_sklist_lock);
-	if (sk_del_node_init(sk))
-		__sock_put(sk);
+	sk_del_node_init(sk);
 	write_unlock_bh(&packet_sklist_lock);
 
 	/*
@@ -984,7 +983,6 @@
 
 	write_lock_bh(&packet_sklist_lock);
 	sk_add_node(sk, &packet_sklist);
-	sock_hold(sk);
 	write_unlock_bh(&packet_sklist_lock);
 	return(0);
 
diff -Nru a/net/sctp/endpointola.c b/net/sctp/endpointola.c
--- a/net/sctp/endpointola.c	Wed Jun 18 23:42:06 2003
+++ b/net/sctp/endpointola.c	Wed Jun 18 23:42:06 2003
@@ -209,7 +209,7 @@
 	sctp_bind_addr_free(&ep->base.bind_addr);
 
 	/* Remove and free the port */
-	if (ep->base.sk->sk_prev)
+	if (sctp_sk(ep->base.sk)->bind_hash)
 		sctp_put_port(ep->base.sk);
 
 	/* Give up our hold on the sock. */
diff -Nru a/net/sctp/socket.c b/net/sctp/socket.c
--- a/net/sctp/socket.c	Wed Jun 18 23:42:09 2003
+++ b/net/sctp/socket.c	Wed Jun 18 23:42:09 2003
@@ -3078,9 +3078,9 @@
 	 */
 success:
 	inet_sk(sk)->num = snum;
-	if (!sk->sk_prev) {
+	if (!sctp_sk(sk)->bind_hash) {
 		sk_add_bind_node(sk, &pp->sk_list);
-		sk->sk_prev = (struct sock *) pp;
+		sctp_sk(sk)->bind_hash = pp;
 	}
 	ret = 0;
 
@@ -3328,7 +3328,7 @@
 /* Caller must hold hashbucket lock for this tb with local BH disabled */
 static void sctp_bucket_destroy(struct sctp_bind_bucket *pp)
 {
-	if (!hlist_empty(&pp->sk_list)) {
+	if (hlist_empty(&pp->sk_list)) {
 		if (pp->next)
 			pp->next->pprev = pp->pprev;
 		*(pp->pprev) = pp->next;
@@ -3345,9 +3345,9 @@
 	struct sctp_bind_bucket *pp;
 
 	sctp_spin_lock(&head->lock);
-	pp = (struct sctp_bind_bucket *)sk->sk_prev;
-	hlist_del(&sk->sk_bind_node);
-	sk->sk_prev = NULL;
+	pp = sctp_sk(sk)->bind_hash;
+	__sk_del_bind_node(sk);
+	sctp_sk(sk)->bind_hash = NULL;
 	inet_sk(sk)->num = 0;
 	sctp_bucket_destroy(pp);
 	sctp_spin_unlock(&head->lock);
diff -Nru a/net/sunrpc/cache.c b/net/sunrpc/cache.c
--- a/net/sunrpc/cache.c	Wed Jun 18 23:42:07 2003
+++ b/net/sunrpc/cache.c	Wed Jun 18 23:42:07 2003
@@ -310,14 +310,17 @@
 		cp = & current_detail->hash_table[current_index];
 		ch = *cp;
 		for (; ch; cp= & ch->next, ch= *cp) {
-			if (atomic_read(&ch->refcnt))
-				continue;
-			if (ch->expiry_time < get_seconds()
-			    || ch->last_refresh < current_detail->flush_time
-				)
-				break;
 			if (current_detail->nextcheck > ch->expiry_time)
 				current_detail->nextcheck = ch->expiry_time+1;
+			if (ch->expiry_time >= get_seconds()
+			    && ch->last_refresh >= current_detail->flush_time
+				)
+				continue;
+			if (test_and_clear_bit(CACHE_PENDING, &ch->flags))
+				queue_loose(current_detail, ch);
+
+			if (atomic_read(&ch->refcnt))
+				continue;
 		}
 		if (ch) {
 			cache_get(ch);
@@ -464,6 +467,31 @@
 		dreq = list_entry(pending.next, struct cache_deferred_req, recent);
 		list_del_init(&dreq->recent);
 		dreq->revisit(dreq, 0);
+	}
+}
+
+void cache_clean_deferred(void *owner)
+{
+	struct cache_deferred_req *dreq, *tmp;
+	struct list_head pending;
+
+
+	INIT_LIST_HEAD(&pending);
+	spin_lock(&cache_defer_lock);
+	
+	list_for_each_entry_safe(dreq, tmp, &cache_defer_list, recent) {
+		if (dreq->owner == owner) {
+			list_del(&dreq->hash);
+			list_move(&dreq->recent, &pending);
+			cache_defer_cnt--;
+		}
+	}
+	spin_unlock(&cache_defer_lock);
+
+	while (!list_empty(&pending)) {
+		dreq = list_entry(pending.next, struct cache_deferred_req, recent);
+		list_del_init(&dreq->recent);
+		dreq->revisit(dreq, 1);
 	}
 }
 
diff -Nru a/net/sunrpc/svc.c b/net/sunrpc/svc.c
--- a/net/sunrpc/svc.c	Wed Jun 18 23:42:09 2003
+++ b/net/sunrpc/svc.c	Wed Jun 18 23:42:09 2003
@@ -98,6 +98,8 @@
 				  sk_list);
 		svc_delete_socket(svsk);
 	}
+	
+	cache_clean_deferred(serv);
 
 	/* Unregister service with the portmapper */
 	svc_register(serv, 0, 0);
diff -Nru a/net/sunrpc/svcauth_unix.c b/net/sunrpc/svcauth_unix.c
--- a/net/sunrpc/svcauth_unix.c	Wed Jun 18 23:42:08 2003
+++ b/net/sunrpc/svcauth_unix.c	Wed Jun 18 23:42:08 2003
@@ -195,12 +195,12 @@
 	ipm.m_addr.s_addr =
 		htonl((((((b1<<8)|b2)<<8)|b3)<<8)|b4);
 	ipm.h.flags = 0;
-	if (dom)
+	if (dom) {
 		ipm.m_client = container_of(dom, struct unix_domain, h);
-	else
+		ipm.m_add_change = ipm.m_client->addr_changes;
+	} else
 		set_bit(CACHE_NEGATIVE, &ipm.h.flags);
 	ipm.h.expiry_time = expiry;
-	ipm.m_add_change = ipm.m_client->addr_changes;
 
 	ipmp = ip_map_lookup(&ipm, 1);
 	if (ipmp)
diff -Nru a/net/sunrpc/svcsock.c b/net/sunrpc/svcsock.c
--- a/net/sunrpc/svcsock.c	Wed Jun 18 23:42:06 2003
+++ b/net/sunrpc/svcsock.c	Wed Jun 18 23:42:06 2003
@@ -681,8 +681,17 @@
 	dprintk("svc: socket %p TCP (listen) state change %d\n",
 			sk, sk->sk_state);
 
-	if  (sk->sk_state != TCP_ESTABLISHED) {
-		/* Aborted connection, SYN_RECV or whatever... */
+	if  (sk->sk_state != TCP_LISTEN) {
+		/*
+		 * This callback may called twice when a new connection
+		 * is established as a child socket inherits everything
+		 * from a parent LISTEN socket.
+		 * 1) data_ready method of the parent socket will be called
+		 *    when one of child sockets become ESTABLISHED.
+		 * 2) data_ready method of the child socket may be called
+		 *    when it receives data before the socket is accepted.
+		 * In case of 2, we should ignore it silently.
+		 */
 		goto out;
 	}
 	if (!(svsk = (struct svc_sock *) sk->sk_user_data)) {
@@ -1060,6 +1069,8 @@
 
 		set_bit(SK_CHNGBUF, &svsk->sk_flags);
 		set_bit(SK_DATA, &svsk->sk_flags);
+		if (sk->sk_state != TCP_ESTABLISHED) 
+			set_bit(SK_CLOSE, &svsk->sk_flags);
 	}
 }
 
@@ -1211,7 +1222,6 @@
 	}
 
 	rqstp->rq_secure  = ntohs(rqstp->rq_addr.sin_port) < 1024;
-	rqstp->rq_userset = 0;
 	rqstp->rq_chandle.defer = svc_defer;
 
 	if (serv->sv_stats)
@@ -1443,7 +1453,7 @@
 static void svc_revisit(struct cache_deferred_req *dreq, int too_many)
 {
 	struct svc_deferred_req *dr = container_of(dreq, struct svc_deferred_req, handle);
-	struct svc_serv *serv = dr->serv;
+	struct svc_serv *serv = dreq->owner;
 	struct svc_sock *svsk;
 
 	if (too_many) {
@@ -1481,7 +1491,7 @@
 		if (dr == NULL)
 			return NULL;
 
-		dr->serv = rqstp->rq_server;
+		dr->handle.owner = rqstp->rq_server;
 		dr->prot = rqstp->rq_prot;
 		dr->addr = rqstp->rq_addr;
 		dr->argslen = rqstp->rq_arg.len >> 2;
diff -Nru a/net/unix/af_unix.c b/net/unix/af_unix.c
--- a/net/unix/af_unix.c	Wed Jun 18 23:42:08 2003
+++ b/net/unix/af_unix.c	Wed Jun 18 23:42:08 2003
@@ -211,15 +211,13 @@
 
 static void __unix_remove_socket(struct sock *sk)
 {
-	if (sk_del_node_init(sk))
-		__sock_put(sk);
+	sk_del_node_init(sk);
 }
 
 static void __unix_insert_socket(struct hlist_head *list, struct sock *sk)
 {
 	BUG_TRAP(sk_unhashed(sk));
 	sk_add_node(sk, list);
-	sock_hold(sk);
 }
 
 static inline void unix_remove_socket(struct sock *sk)
diff -Nru a/net/wanrouter/af_wanpipe.c b/net/wanrouter/af_wanpipe.c
--- a/net/wanrouter/af_wanpipe.c	Wed Jun 18 23:42:09 2003
+++ b/net/wanrouter/af_wanpipe.c	Wed Jun 18 23:42:09 2003
@@ -982,8 +982,7 @@
 
 	set_bit(1,&wanpipe_tx_critical);
 	write_lock(&wanpipe_sklist_lock);
-	if (sk_del_node_init(sk))
-		__sock_put(sk);
+	sk_del_node_init(sk);
 	write_unlock(&wanpipe_sklist_lock);
 	clear_bit(1,&wanpipe_tx_critical);
 
@@ -1143,8 +1142,7 @@
 	}
 	
 	write_lock(&wanpipe_sklist_lock);
-	if (sk_del_node_init(sk))
-		__sock_put(sk);
+	sk_del_node_init(sk);
 	write_unlock(&wanpipe_sklist_lock);
 
 
@@ -1206,8 +1204,7 @@
 	 * appropriate locks */
 	
 	write_lock(&wanpipe_sklist_lock);
-	if (sk_del_node_init(init))
-		__sock_put(sk);
+	sk_del_node_init(sk);
 	write_unlock(&wanpipe_sklist_lock);
 
 	sk->sk_socket = NULL;
@@ -1536,7 +1533,6 @@
 	set_bit(1,&wanpipe_tx_critical);
 	write_lock(&wanpipe_sklist_lock);
 	sk_add_node(sk, &wanpipe_sklist);
-	sock_hold(sk);
 	write_unlock(&wanpipe_sklist_lock);
 	clear_bit(1,&wanpipe_tx_critical);
 
@@ -2434,7 +2430,6 @@
 	set_bit(1,&wanpipe_tx_critical);
 	write_lock(&wanpipe_sklist_lock);
 	sk_add_node(newsk, &wanpipe_sklist);
-	sock_hold(sk);
 	write_unlock(&wanpipe_sklist_lock);
 	clear_bit(1,&wanpipe_tx_critical);
 
diff -Nru a/net/x25/af_x25.c b/net/x25/af_x25.c
--- a/net/x25/af_x25.c	Wed Jun 18 23:42:09 2003
+++ b/net/x25/af_x25.c	Wed Jun 18 23:42:09 2003
@@ -154,8 +154,7 @@
 static void x25_remove_socket(struct sock *sk)
 {
 	write_lock_bh(&x25_list_lock);
-	if (sk_del_node_init(sk))
-		sock_put(sk);
+	sk_del_node_init(sk);
 	write_unlock_bh(&x25_list_lock);
 }
 
@@ -219,7 +218,6 @@
 {
 	write_lock_bh(&x25_list_lock);
 	sk_add_node(sk, &x25_list);
-	sock_hold(sk);
 	write_unlock_bh(&x25_list_lock);
 }